Showing posts with label home automation. Show all posts
Showing posts with label home automation. Show all posts

Wednesday, April 29, 2020

FlexRadio: Remote Control ON/OFF State

-----
FlexRadio makes controlling the ON/OFF state of their ham radio rigs simple.   Basically a "short" across the RCA jack on the back labeled REM ON will start the rig and an "open" will power the rig down.
-----
Here's how we did it for the FlexRadio 6400 (video below).

- From SmartSMR go to Setting / Radio Setup.... (I wish SmartSDR would just use CTRL R for this and similar for other menu commands).   In the screen make "Remote on: Enabled":
- Now you need some hardware.  Most hams will have plenty of the wire, wall warts, and connectors gathering dust that are in the diagram below.   However, two items may need to be purchased.  Don't worry; they're cheap:

     - This 120VAC outlet that can be controlled via your smart phone.  Cost from Amazon ~$10.
- A simple relay to "short/open" the REM ON labeled RCA jack on the back of the rig.  Cost for three was ~$8 from Amazon.

-----
You will need to download an app for your smart phone to control the AC outlet.  Then hook things up like this (click to enlarge image):

-----
Here's vid of the whole enchilada in action:
-----
It took us more time to document the project than to actually do it.   It's simple.  Hope to catch you on the air.   dit dit.
-----
 

Wednesday, February 26, 2020

ESP8266 Doorbell Sends SMS and Updates Google Sheet

-----
On-line shopping has changed the way goods are acquired.  For most packages it is not necessary to be around for the dropoff.  But... for the important stuff it is.  Those packages always seem to show up right when you are in the backyard for mere seconds causing that frustrating "Personal Signature Required for Delivery" note on the door.  This is our DIY effort to solve that problem.
-----
Needed:
     - ESP8266 (microcontroller with WiFi)
     - 1M ohm resistor
     - reed switch
     - IFTTT account (using the WebHook applet)
     - wire and stuff
     - fundamental knowledge on Arduino sketches (simple code edits).
-----
The connections are simple:

 ----
And the rig will look something like this:
-----
A 1M ohm resister connected from 3.3V to the A0 [ADC] input on the ESP8266 keeps the A0 reading at maximum value.   The normally open reed switch is placed right on top of the coils that activate the doorbell.  These coils act like that electromagnet you build in grade school to ring the doorbell and cause the reed switch to close.  This drops the impedance to the 1M resistor and changes the ADC value on the A0 pin for detection of the doorbell.  Then the SMS is sent to your phone and a Google Drive Sheet is updated.
-----
-----
The sketch you need to upload to the the ESP8266 looks like this:
```````````````````````````````````````````````````````````````````````````````
/*
 *  FEB2020
 *  Door Bell Monitoring
 *  WhiskeyTangoHotel.Com
 * 
 *  Build details at:
 *  http://www.whiskeytangohotel.com/2020/02/esp8266-doorbell-sends-sms-and-updates.html
 * 
 *  On Doorbell ring:
 *    Logs to Google Drive (as an appending spreadsheet)
 *    Sends SMS to cell phone
 * 
 *  ESP8266 uC
*/

// For the Wireless
#include <ESP8266WiFi.h>

// WiFi Connection Information
const char* ssid = "yourssid";    // PRIVATE: Enter your personal setup information.
const char* password = "yourwifipassword"; // PRIVATE: Enter your personal setup information.

// IFTTT Information for WebHook widget
String MAKER_SECRET_KEY = "yourIFTTTprivatekey";  // PRIVATE: Enter your personal setup information. Your IFTTT Webhook key here
String TRIGGER_NAME_google_drive = "googlebell";    // this is the Maker IFTTT trigger name for google drive spreadsheet logging
String TRIGGER_NAME_SMS = "doorbell";              // this is the Maker IFTTT trigger name to send SMS.
const char* host = "maker.ifttt.com";
String url_SMS;                      // url that gets built for the IFTTT Webhook sending SMS
String url_google_drive;            // url that gets built for the IFTTT Webhook logging to google drive spreadsheet
String Status ="**_Starting_on:";  // Status payload for Google Sheet.  We log all starts and reboots

// Define and set up some variables
int sensorValue = 0;  // reading from A0.  This pin detects the doorbell (ADC reading between 0-1024)

// Define pins
const int led = 2;     // Blue on board LED is on PIN2.  Active LOW.  Blinks it between reads
const int bell = A0;  // analog input for the doorbell transducer. 1MOhm on board in // with 1MOhm from the reed switch pickup

// Program control variables
int Seconds_dwell_after_detect = 8;  // Prevents logging flood and debounce.   Sensor reads, LED flashing, etc.
int logging = 1; // If 1 then SMS and log to cloud.  Any other value (0) turns it off.

void setup(){  // This is run once.
  pinMode(led, OUTPUT);  // set up the onbaord LED pin as an output.    
  Serial.begin(115200);  // turn on the serial monitor for debug

  // wait until serial port opens for native USB devices
  while (! Serial) {
    delay(10);
  }
 
  // Is the WiFi working?
  WiFi.begin(ssid, password);
  Serial.println("");
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("Trying to connect to ");
    Serial.print(ssid);
    Serial.print(" on ");
    Serial.println(WiFi.localIP());
    for (int x = 0; x < 20; x++) { // 
      digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED. Shows program is trying to WiFi connect
      //Serial.println("Server Start blink loop....");
      delay(5);   // Delay so short the LED looks like it is always on
    } // endfor WiFi blink connect
  }
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.println(WiFi.localIP());

  for (int x = 0; x < 10; x++) { // 5 slow LED blinks to slow WIFI Connected.
  digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED.
  Serial.println("WIFI is Connected....");
  delay(500);   } // endif for WIFI Connected blink


  // Use WiFiClient class to create TCP connections for WiFi logging
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");  // Boo!!!
    return;
  }

  // Trigger the IFTTT Webhook Channel to update a Google sheet with the activity of the server starting/restarting
  // This can help log power outs, etc.  For first run we defined String Status for identify a startup condition.
  // Create the request for IFTTT google drive
  url_google_drive = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_google_drive + "/with/key/" + MAKER_SECRET_KEY + "?value1=" + String(Status);
  Serial.println (url_google_drive);
  Serial.println(" "); 
   
  // This sends the request to the IFTTT server
  client.print(String("POST ") + url_google_drive + " HTTP/1.1\r\n" +
  "Host: " + host + "\r\n" +
  "Connection: close\r\n\r\n"); 
  delay(500);  // Delay for web traffic; maybe not required. 

  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
     String line = client.readStringUntil('\r');    }

  String Status = "Payload_String_for_Google_Sheet";
}
 
void loop(){   // Loop forever or until the Dallas Cowboys win a Super Bowl
  // Read the A0 pin and post based on the delay values set above.
  // The blue onboard LED will fast blink while polling
  sensorValue = analogRead(bell);
  //Serial.println (sensorValue);   //debug only

  // Fast Blink Blue LED while waiting for doorbell press
  digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED. Shows program is running
  Serial.println("Waiting for DoorBell....");
  delay(50);   

  // Use WiFiClient class to create TCP connections for IFTT
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
 
  if (sensorValue < 200 || sensorValue > 300) {  //  A0 values between 200-300 are normal.  Increases (apprx doubles) when DB is pressed
      Serial.println("----------Doorbell Dectected----------");

      if (logging == 1) { // is logging turned on? Non "1" is for debug...  Typically would be set = 1
        Serial.println("***** Logging is ON *****");

        // Build the IFTTT Webhoo Channel for SMS url
        url_SMS = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_SMS + "/with/key/" + MAKER_SECRET_KEY;
        client.print(String("POST ") + url_SMS + " HTTP/1.1\r\n" +
        "Host: " + host + "\r\n" +
        "Connection: close\r\n\r\n");
        Serial.println(" ");
        Serial.println("SMS payload to IFTTT is:");
        Serial.println(url_SMS);   
        Serial.println(" ");  

        // This must be run before any IFTTT webhook
        const int httpPort = 80;
        if (!client.connect(host, httpPort)) {
          Serial.println("connection failed");
          return;
        }
           
        // Set up IFTTT Webhook Channel to update a Google sheet with the activity. 
        Status ="__Doorbell_on:";
        url_google_drive = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_google_drive + "/with/key/" + MAKER_SECRET_KEY + "?value1=" + String(Status);
        client.print(String("POST ") + url_google_drive + " HTTP/1.1\r\n" +
        "Host: " + host + "\r\n" +
        "Connection: close\r\n\r\n");
        Serial.println(" ");
        Serial.println("IFTTT url payload to Google Drive is:");
        Serial.println(url_google_drive);
        Serial.println(" ");
   
      } else {   // We are not sending to IFTTT.  Debug mode
         Serial.println("Logging is OFF.");
         Serial.println(" ");
      } // endif/else logging 
   
    for (int x = 0; x < Seconds_dwell_after_detect*2; x++) { // DoorBell dectected. Pause and LED flash for visual acknowledgement
      digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED
      Serial.println("Doorbell dectected,  Now in BLINK Loop....");
      delay(500);   } // endfor DoorBell Dwell loop  
       
  }   // end doorbell A0 pressed
}  // end of endless loop
-----
That's it and thanks for stopping by!!!

Thursday, August 24, 2017

ToF Laser to Monitor Cat Food Levels


 -----
We live in great times.  There was once a day when the only way to determine if the cat feeder needed more kibble was to actually look at it with your own eyes like some Neanderthal.  Thankfully technology and the magical world of IoT has changed all of that.
----
For this project we use a WiFi enable ESP8266 and a STMicro VL53L0X ToF Sensor mounted to a breakout board.  If you don't find a need to measure feline food consumption the project still provides Arduino code that can be extremely useful for your other IoT projects:
  • Logging data to a Google Drive Spreadsheet (via IFTTT)
  • Logging data to AT&T's M2X machine to machine servers (think nice graphs)
  • Sending SMSs to your mobile device (via IFTTT)
All of the above services are free but; of course, you will need to establish an account if you do not have on.
----
What's happening?
The ESP8266 runs in Arduino mode (source code below) in an endless loop.  Every hour it polls the VL53L0X ToF Sensor mounted on the lid of the cat food feeder.
-----
Since we know how many centimeters the food is from the ToF sensor at full and at empty we are able to scale those values and report/log "percent full" status.  Those values are posted to a Google Drive Spreadsheet and to AT&T's M2X machine to machine servers for logging.  If the food level is considered CRITICALLY LOW a SMS message goes out to our mobile device.  Just to increase the geek factor, CRITICALLY LOW alerts are also displayed on our Pebble watch.
----
The Google Drive Spreadsheet looks like this:
-----
Here is the bad ass AT&T M2X machine to machine server graph (note the increase after we filled the feeder):
-----
The IFTTT SMS alerts are sent if the rig determines food levels critically low:

-----
So..... How's it done?  You will need these:
Easy; hook it up like this:
 And it will look something like this:
-----
 Mount it to the cat feeder and you end up with this:

-----
Now all that is left is to copy/paste the code below into the Arduino IDE.  Upload it to the ESP8266 and your cats will never go hungry again!
-----
/*
 *  AUG2017
 *  STMicro VL53L0X ToF Sensor for
 *  Cat Food Level Monitoring
 *  WhiskeyTangoHotel.Com
 * 
 *  Logs % full values to:
 *    Google Drive (as an appending spreadsheet)
 *    AT&T M2X for historical graphing
 *    Send SMS to cell phone if level condition is RED/CRITICAL
 * 
 *  uC setting for Ardunio IDE
 *  NoderMCU 1.0 (ESP-12E Module), 80MHz, 921600, 4M (3M SPIFFS)
 * 
*/

// For the STMicro VL53L0X ToF Sensor
// I2C SDA to ESP8266 Pin D2.  SCL to ESP8266 Pin D1
#include "Adafruit_VL53L0X.h"   // Thanks again ADAFRUIT!!!
Adafruit_VL53L0X lox = Adafruit_VL53L0X();

// For the Wireless
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

// WiFi Connection Information
const char* ssid = "YourNetworkHere";    // PRIVATE: Enter your personal setup information.
const char* password = "YourNetworkPasswordHere"; // PRIVATE: Enter your personal setup information.
ESP8266WebServer server(80);

// IFTTT Information for WebHook widget
String MAKER_SECRET_KEY = "YourIFTTTCodeHere"; // PRIVATE: Enter your personal setup information. Your IFTTT Webhook key here
String TRIGGER_NAME_google_drive = "Cat_Food";  // this is the Maker IFTTT trigger name for google drive spreadsheet logging
String TRIGGER_NAME_M2X = "cat_food_mx";   // this is the Maker IFTTT trigger name for M2X logging
String TRIGGER_NAME_SMS = "CriticalFoodLevel_SMS";  // this is the Maker IFTTT trigger name to send SMS if low is level is CRITICAL.
const char* host = "maker.ifttt.com";
String url_google_drive;  // url that gets built for the IFTTT Webhook logging to google drive spreadsheet
String url_M2X;   // url that gets built for the IFTTT Webhook logging to AT&T M2X service
String url_SMS;   // url that gets built for the IFTTT Webhook sending SMS if food level is critical

// Define and set up some variables
float Range_inches;  // How far the sensor is from the food at time of reading.  Sensor is on roof of feeder.
float Min_level = 5.0;   // Distance in inches before low food alarm level.  Food is far from sensor on feeder roof
float Max_level = 0.5;   // Distance in inches from sensor for full feeder level.  Food is close to sensor on feeder roof
float Percent_full;  // How full in xx.x% is the food based on the Min/Max_levels defined above
float Caution_alarm = 35.0;  // at xx.x% food level is considered low.  String Status YELLOW
float Critical_alarm = 25.0;  // at xx.x% food level is considered critically low. String Status RED
String Status = "***_Starting_with_Caution_at:_" + String(Caution_alarm) + "%_and_CRITICAL_at:_" + String(Critical_alarm) + "%";  // Update to Out of Range, NORMAL, LOW, CRITICAL, etc. "spaces" will error IFTTT Webhook; use "_"
int Run_number;  // how many times the sensor has been read

// Output pins
const int led = 2;  // Blue on board LED is on PIN2 for this NoderMCU 1.0 ESP8266.  Blink it between reads

// Program control variables
int Seconds_between_posts = 60 * 60;  // how often to post the results of the sensor read. NOT EXACT due to post delays, Sensor reads, LED flashing, etc.
int logging = 1; // If 1 then log to cloud.  Any other value (0) turns it off.  ESP8266 "Start/Restart" message is always logged. 


void setup(void){  // This is run once.
  pinMode(led, OUTPUT);  // set up the onbaord LED pin as an output. 
  Serial.begin(115200);  // turn on the serial monitor for debug

  // wait until serial port opens for native USB devices
  while (! Serial) {
    delay(1);
  }

  // Is the ToF sensor connecting via I2C?
  Serial.println("STMicro VL53L0X test");
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X!!!"));
    while(1);
  }
  // power
  Serial.println(F("VL53L0X Passed... \n\n"));
 
  // Is the WiFi working?
  WiFi.begin(ssid, password);
  Serial.println("");
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print("Trying to connect to ");
    Serial.print(ssid);
    Serial.print(" on ");
    Serial.print(WiFi.localIP());
    Serial.println(".");
  }
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
    Serial.println(" ");
  }

  // Use WiFiClient class to create TCP connections for WiFi logging
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");  // Boo!!!
    return;
  }

  server.begin();
  Serial.println("HTTP server started");  // Woo Hoo!!!

  // Write to Google Sheet via IFTTT Maker channel that the ESP8266 has started/restarted
  // Trigger the IFTTT Webhook Channel to update a Google sheet with the activity of the server starting/restarting
  // This can help log power outs, etc.  For first run we defined String Status for identify a startup condition.
  // Create the request for IFTTT google drive
  url_google_drive = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_google_drive + "/with/key/" + MAKER_SECRET_KEY + "?value1=" + String(Status);
  Serial.println("Status: " + Status);
  Serial.println(" ");
   
  // This sends the request to the IFTTT server
  client.print(String("POST ") + url_google_drive + " HTTP/1.1\r\n" +
  "Host: " + host + "\r\n" +
  "Connection: close\r\n\r\n"); 
  delay(500);  // Delay for web traffic; maybe not required. 
}

void loop(void){
  // Loop forever.  Read the sensor and post based on the delay values set above.
  // The blue onboard LED will blink between ToF reads.
 
  // Read the ToF.  Distance in mm  returned. 
  for (int x = 0; x < 10; x++) { // Quick toggle blue on  board LED to show measurement being taken.
    digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED. Shows program is running
    delay(100);    }  // endfor quick toogle Blue LED
  VL53L0X_RangingMeasurementData_t measure;

  Serial.println("-------------------------------------");
  Serial.println("Reading a measurement... ");
  lox.rangingTest(&measure, false);
  // Convert to inches because the USA, for some reason, doesn't want to adopt the metric system...
  Range_inches = measure.RangeMilliMeter/25.4;
  Run_number = Run_number + 1;

  // Scale and normalize the Min Max levels to 0% to 100%.  Clip the range in case of a the Max fill limit was exceeded or a misread.
  Percent_full = ((Range_inches - Min_level) / (Max_level - Min_level)) * 100.0;
  if (Percent_full > 100) {
    Percent_full = 100.00;
  }
  if (Percent_full < 0) {
    Percent_full = 0.0;
  }

  //Serial.println(String(Range_inches));  // Debug use
     
  // Is the ToF Sensor reading 'anything' for a distance?
  if (Range_inches > 100 ) {  // Something's weird.  Ranging error.  The ToF sensor is NOT over 100 inches fron the food. EVER!!!
      Status = "Run:" + String(Run_number) + "__ERROR:_***_Out_of_Range_***";
  } else {  // ToF made a successful reading so log the food level   
    if (Percent_full >= Caution_alarm) {  // above CAUTION LEVEL, All's good
      Status = "Run:" + String(Run_number) + "___GREEN---GOOD";
    } // endif GREEN---GOOD
 
    if (Percent_full < Caution_alarm && Percent_full > Critical_alarm) {  //  CAUTION Zone, YELLOW---REFILL_SOON
      Status = "Run:" + String(Run_number) + "___~~~YELLOW---REFILL_SOON~~~";
    } // end if YELLOW---REFILL_SOON"
 
    if (Percent_full <= Critical_alarm) {  //  CAUTION Zone, RED---REFILL_ASAP"
      Status = "Run:" + String(Run_number)+ "___!!!_RED---REFILL_ASAP_!!!";
      if (logging == 1) { // is logging turned on? Maninly for debug...  Typically would be set = 1
        // Set up IFTTT Webhook Channel to send the SMS. 
        // Use WiFiClient class to create TCP connections for IFTT SMS
        WiFiClient client;
        const int httpPort = 80;
        if (!client.connect(host, httpPort)) {
          Serial.println("connection failed");
          return;
        }     
        url_SMS = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_SMS + "/with/key/" + MAKER_SECRET_KEY+ "?value1=" + String(Percent_full);
        Serial.println("Critical Level: Sending SMS with payload:.");
        Serial.println(url_SMS);
        Serial.println(" ");
        client.print(String("POST ") + url_SMS + " HTTP/1.1\r\n" +
        "Host: " + host + "\r\n" +
        "Connection: close\r\n\r\n");
        //Serial.println("GOOGLE DRIVE URL:");
        //Serial.println(url_google_drive);
        delay(500);   // pause for webservices   
      }         
    } // endif RED---REFILL_ASAP
     
  }

  // Serial print to the monitor for debug
  Serial.println(String(Range_inches) + " inches down / " + String(Percent_full) + "% full");
  Serial.println("Status: " + Status);
  // Create the request for IFTTT Google Drive and M2X updates
  url_google_drive = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_google_drive + "/with/key/" + MAKER_SECRET_KEY + "?value1=" + String(Percent_full) + "%" + "&value2=" + Status;
  url_M2X = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_M2X + "/with/key/" + MAKER_SECRET_KEY + "?value1=" + String(Percent_full);
 
  // This sends the request to the IFTTT server.
  //Serial.println("Requesting URL...");   // debug
  //Serial.println(url);   // debug
  if (logging == 1) { // is logging turned on? Maninly for debug...  Typically would be set = 1
    //Serial.println("Logging is ON."); 
    // Set up IFTTT Webhook Channel to update a Google sheet with the activity. 
    // Use WiFiClient class to create TCP connections for IFTT Webhook logging
    WiFiClient client;
    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
      Serial.println("connection failed");
      return;
    }     
    client.print(String("POST ") + url_google_drive + " HTTP/1.1\r\n" +
    "Host: " + host + "\r\n" +
    "Connection: close\r\n\r\n");
    Serial.println(" ");
    Serial.println("IFTTT url payload to Google Drive:");
    Serial.println(url_google_drive);
    Serial.println(" ");
    delay(500);   // pause for webservices
 
    // Set up IFTTT Maker Channel to update a AT&T M2X Server with the activity. 
    // Use WiFiClient class to create TCP connections for IFTT Webhook logging
    //WiFiClient client;
    //const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
      Serial.println("connection failed");
      return;     }     
    client.print(String("POST ") + url_M2X + " HTTP/1.1\r\n" +
    "Host: " + host + "\r\n" +
    "Connection: close\r\n\r\n");
    Serial.println("IFTTT url payload for M2X:");
    Serial.println(url_M2X);
   
  } else {
     Serial.println("Logging is OFF.");
  } // endif/else logging 
 
  for (int x = 0; x < Seconds_between_posts; x++) { // Delay for next measurement.
    digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED. Shows program is running
    delay(1000);   } // endfor delay for read measurement
}
-----
Thanks and check out our other stuff!!!

Friday, January 6, 2017

ESP8266 WiFi Garage Door Opener from any Web Browser

The 'brain' is the ESP8266 uC.  It is available with on board WiFi and plenty of I/O for smaller projects.  All this for well under $10USD with programming options for NodeMCU, MicroPython, and the Arduino IDE.
-----
There seems to be an unstoppable drive in the hacker DIY community for web based garage door openers and we were compelled to respond.  The garage door opener we have opens/shuts from a push button switch that basically creates a short to connect two terminals on the garage door opening unit.  That allows easy implementation because all that is required is a ESP8266 controlled relay wired across those two terminals to create a switch closure.

In addition to activating the door any activity is logged to a Google Sheet via the IFTTT.com Maker Channel.  This is handy to track all activation usage and ESP8266 server restarts.
-----
The main components are the ESP8266, a relay module, a BS170 N-Channel MOSFET.
 
-----
Simple.  Connect the 'stuff' as shown in the schematic:
and it will look something like this:
----
Use the Arduino IDE to load the source code below into the ESP8266 then wire the Normally Open (NO) side of relay you are controlling to the two terminals on the garage door opener that active the motor when 'shorted' together.

A few comments on the application:
  • Control works from Android, iPhone, PC, etc.  Basically any browser.  In the source code below if a device can open "http://192.168.0.28/long_confusing_URL_to_activate_relay" it will activate the garage door.
  • There is a "TEST" URL in the source code (http://192.168.0.28/) that confirms the ESP8266 is online but does not activate the door.
  • Set a static IP for the ESP8266 in your WiFi router.  Otherwise it may be assigned a different local IP if the ESP8266 or WiFi router is restarted.
  • Use long/complex URLs.  That way those that are connected to your router don't have a 'obvious' URL to activate the rig or one they can remember if you demo it.
  • We only wanted control of the door when connected to the host WiFi router locally (LAN) and not from anyplace on the planet.  If you want extended control to the WWW open a port on your router, but be aware of the concerns. We wanted to limit use only to those authorized to connect the WiFi router locally (LAN).  Plus, we didn't want to risk accidentally activating the door from a remote location.
  • The source code has separate IFTTT.com Maker Channel triggers to log events.  We could use one Maker Channel trigger and just pass different GETPOST variables.  However, creating multiple Maker Channel triggers would easily allow usage tracking on individuals by assigning each one a unique trigger name. (/ZenaActivate, /KelsoActivate, etc...)
  • Any time the door is activated or the ESP8266 is restarted (power outage, etc) a Google Sheet is updated to log the event as shown below. 
 
-----
The Arduino IDE source code is:

/*
 *  Garage Door Opener via Web Browser and log to IFTTT.com
 *  ESP8266 NodeMCU Board using Arduino IDE
 *  WhiskyTangoHotel.Com    DEC2106
 * 
 *  Blue on board LED is active LOW on GPIO2 (D4 on silkscreen)
 *  Relay to control Garage Door is active HIGH on GPIO5 (D1 on silkscreen)
 * 
 *  Opening 192.168.0.28/long_confusing_URL_to_activate_relay is called.  Every effort is made to keep the relay off 
 *  so the door does not close/activate by accident.
 * 
 *  A 'test' message is display on browser to see if server is up by calling root at:.
 *  192.168.0.28/  This WILL NOT ACTIVATE THE RELAY.  Only tests the server
 * 
 *  The 'meat' is at 192.168.0.28/long_confusing_URL_to_activate_relay. This will send a msg to the browser AND open/close the door.
 * 
 */

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

// WiFi Information
const char* ssid = "YOUR-SSID";
const char* password = "ASCII-PASSCODE-FOR-YOUR-SSID";

// IFTTT Information
String MAKER_SECRET_KEY = "xxx-yyy-zzz-123-456-789"; // your maker key here
String TRIGGER_NAME = "IFTTT_Maker_name_to_activate_relay";  // this is the Maker IFTTT trigger name for relay activation
const char* host = "maker.ifttt.com";

ESP8266WebServer server(80);

// Output pins
const int led = 2;  // Blue on board LED
const int relay = 5;  // Relay control line

int randNumber;  // Random# generated just to show a change in the screen.  Help to verify updated page call.

void handleRoot() {
  // This is called if 192.168.0.28/ is requested.  The root.
  // The 'meat' is at /long_confusing_URL_to_activate_relay.
  // This is just here to test the ESP8266 connectivity of the WiFi network without moving the relay
  // Show a message and flash the on board LED.
  randNumber = random(1, 10000);  // Random number just to show a change on the webpage at reload.
  server.send(200, "text/plain", "Testing ESP8266.  Response is: " + String(randNumber));
  digitalWrite(led, 0);  // Active LOW.  Turn On board LED On
  delay(2000);
  digitalWrite(led, 1);  // Active LOW.  Turn On board LED Off
}

void handleNotFound(){
  digitalWrite(led, 1);  // Keep the LED off.
  digitalWrite(relay, 0);  // Keep Relay OFF
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

void setup(void){
  pinMode(led, OUTPUT);
  pinMode(relay, OUTPUT);
  digitalWrite(led, 1);  // LED Off
  digitalWrite(relay, 0);  // on power to relay
  Serial.begin(115200);  // serial prints to PC for debug use only
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print("Trying to connect to ");
    Serial.print(ssid);
    Serial.print(" on ");
    Serial.print(WiFi.localIP());
    Serial.println(".");
  }
  Serial.println("");
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
 
  // Write to Google Sheet via IFTTT Maker channel that the ESP8266 has started/restarted

  // Now we trigger the IFTTT Maker Channel to update a Google sheet with the activity of the server starting/restarting
  // This can help log power outs, etc. 
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
 
  // Create the request for IFTTT GARAGE_trigger_serverstart.  This can help log power outs, etc.
  String url = "https://maker.ifttt.com/trigger/GARAGE_trigger_serverstart/with/key/" + MAKER_SECRET_KEY;
  Serial.print("Requesting URL: ");
  Serial.println(url);
 
  // This sends the request to the IFTTT server
  client.print(String("POST ") + url + " HTTP/1.1\r\n" +
  "Host: " + host + "\r\n" +
  "Connection: close\r\n\r\n");
 
  delay(500);  // Delay to for web traffic; maybe not required.
  }

  server.on("/", handleRoot);

  server.on("/long_confusing_URL_to_activate_relay", [](){
    // This is called when 192.168.0.28/long_confusing_URL_to_activate_relay is called
    randNumber = random(1, 10000);  // Random number just to show a change on the webpage at reload.
    server.send(200, "text/plain", "Relay activated @ESP8266.  Code: " + String(randNumber));
    digitalWrite(led, 0);  // Active LOW.  Turn On board LED On
    digitalWrite(relay, 1);  // Relay ON

    // Know we trigger the IFTTT Maker Channel to update a Google sheet with the activity. 
    // Use WiFiClient class to create TCP connections
    WiFiClient client;
    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
      Serial.println("connection failed");
      return;
    }
 
    // Create the request for IFTTT
    String url = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME + "/with/key/" + MAKER_SECRET_KEY;
    Serial.print("Requesting URL: ");
    Serial.println(url);
 
    // This sends the request to the IFTTT server
    client.print(String("POST ") + url + " HTTP/1.1\r\n" +
    "Host: " + host + "\r\n" +
    "Connection: close\r\n\r\n");
   
    delay(2000);  // Delay to keep the relay closed.
    digitalWrite(led, 1);  // Active LOW.  Turn On board LED Off
    digitalWrite(relay, 0);  //Relay OFF
  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void){
  server.handleClient();
}
-----