Garage Door Monitor and Control using ESP8266

Hi,

I’m trying to setup a remote garage door monitor and control IoT thing. This is my hardware:

Philmore N.O./N.C. Magnetic Reed Switch, SPDT : 30-10072
Adafruit Assembled Feather HUZZAH w/ ESP8266 WiFi
Adafruit Non-Latching Mini Relay FeatherWing
Adafruit Assembled Terminal Block Breakout FeatherWing for all Feathers (optional)

I’m running gateway version 1.0.0. Here is my ESP8266 code:

/**

  • Simple server compliant with Mozilla’s proposed WoT API
  • Originally based on the HelloServer example
  • Tested on ESP8266, ESP32, Arduino boards with WINC1500 modules (shields or
  • MKR1000)
  • This Source Code Form is subject to the terms of the Mozilla Public
  • License, v. 2.0. If a copy of the MPL was not distributed with this
  • file, You can obtain one at http://mozilla.org/MPL/2.0/.
    */

#define TRUE 1
#define FALSE 0

#define OPEN 1
#define CLOSE 0

#define REDLED 0
#define BLUELED 2
#define RELAYOUT 15
#define SWITCHIN 14

#define DELAY 500

#define ARDUINOJSON_USE_LONG_LONG 1

#include <Arduino.h>
#include “Thing.h”
#include “WebThingAdapter.h”

int firstpass = TRUE;
int lastCX = FALSE;
int lastST = OPEN;

// wifi credentials here (and keep it private)
const char *ssid = “GONZALEZ_WSL”;
const char *password = “Brow@4222”;

WebThingAdapter *adapter = NULL;

const char * DeviceTypes[] = { “DoorSensor”, “PushButton”, nullptr };

ThingDevice device(“door”, “Garage Door”, DeviceTypes);

ThingProperty DoorStatus( “open”, “Whether the door is open”, BOOLEAN, “OpenProperty”);
ThingProperty DoorControl( “GarageDoorControl”, “Control the Door”, BOOLEAN, “OnOffProperty” );

ThingPropertyValue openValue;

ThingEvent openEvt(“open”, “The garage door has opened”, BOOLEAN, “OpenEvent”);
ThingEvent closeEvt(“closed”, “The garage door has closed”, BOOLEAN, “CloseEvent”);

void setup(void) {
pinMode( SWITCHIN, INPUT_PULLUP ); // Garage dor reed switch
pinMode( RELAYOUT, OUTPUT ); // Output to drive relay
pinMode( REDLED, OUTPUT ); // Red LED
pinMode( BLUELED, OUTPUT ); // Blue LED

Serial.begin(115200);

delay( 500 );

Serial.println("");
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");

// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
digitalWrite( BLUELED, LOW );
digitalWrite( REDLED, HIGH );

delay(500);
Serial.print(".");

digitalWrite( BLUELED, HIGH );
digitalWrite( REDLED, LOW );

}

Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

Serial.println(WiFi.localIP());

adapter = new WebThingAdapter(“Garage_Door”, WiFi.localIP());

DoorStatus.title = “Status”;
device.addProperty(&DoorStatus);

device.description = “Web connected garage door”;
DoorControl.title = “Open/Close”;
device.addProperty(&DoorControl);

device.addEvent(&openEvt);
device.addEvent(&closeEvt);

adapter->addDevice(&device);

adapter->begin();

Serial.println(“HTTP server started”);
Serial.print(“http://”);
Serial.print(WiFi.localIP());
Serial.print("/things/");
Serial.println(device.id);

ThingPropertyValue initialOn = {.boolean = FALSE};
DoorControl.setValue(initialOn);
(void)DoorControl.changedValueOrNull();

}

void loop(void) {

if( firstpass ) {
digitalWrite( RELAYOUT, LOW );
firstpass = FALSE;
}

adapter->update();
// Read garage door status
if ( digitalRead( SWITCHIN )== HIGH ) // if garage door is CLOSED
{
openValue.boolean = TRUE;
digitalWrite( BLUELED, HIGH );
digitalWrite( REDLED, LOW );
}
else // else garage door is OPEN
{
openValue.boolean = FALSE;
digitalWrite( BLUELED, LOW );
digitalWrite( REDLED, HIGH );
}

if (openValue.boolean != lastST)
{
lastST = openValue.boolean;

if( lastST == OPEN )
   {    
   ThingEventObject *ev = new ThingEventObject("open", BOOLEAN, openValue, "2020-12-05 00:00:00+00:00");
   device.queueEventObject(ev);
   lastST = openValue.boolean;
   }
 else
   {
   ThingEventObject *ev = new ThingEventObject("close", BOOLEAN, openValue, "2020-12-05 23:59:00+00:00");
   device.queueEventObject(ev);
   lastST = openValue.boolean;
   }

}

DoorStatus.setValue(openValue);

bool on = DoorControl.getValue().boolean; //Get value from web page
if (on != lastCX)
{
lastCX = on;
Serial.println(“Received OPEN request”);
digitalWrite( RELAYOUT, HIGH);
delay(2000);
digitalWrite( RELAYOUT, LOW );
}

delay(DELAY);
}

Everything works. When I open the reed switch the state change is reflected on the web page. I can use the Open/Close toggle to cause the relay to operate. These are the issues I’m seeing:

  1. When I go to ADD my ESP8266 two different devices show up in the list.

Is there something in my ESP8266 code that is causing two devices to show?

  1. I would like to get a running text log of every time the door opens or closes either by local actions (button mounted in the garage or car remote) or by interaction with the webpage. The code to decide which action caused the door to change state is straight forward. I’m having problems with getting EVENT’s to work. The code will generate an EVENT and I can see the events at https:///things/door/events but not at the website. Can anyone explain how to get the events to show up on the webpage?

  2. The Open/Close device I used to control the door works, but a push button would be a better device to use to mimic the real button installed in the garage. I’ve read that the PushButton device does not send information from the web page to the ESP8266. Is that correct? Can the definition be changed (or a new device created) to cause information to flow from the web page to the ESP8266?

TIA

I am working on a similar project using the ESP8266 with a single relay and MQTT. The door sensors I am using are standard zigbee door sensors. The MQTT works with my phone app perfectly. However, I discovered the MQTT addon (Homie) for Gateway doesn’t really do anything except show the MQTT topics, but with no data or any way to configure as switches/state.

With that said, I would like to try your code, as this looks like a much better solution. Just don’t know if I can get to it until after Christmas. Looking thru your code, I see no reason why it would show up twice. Weird. I will hopefully be able to better get my head around it after flashing your code. I will also have to change out the zigbee door sensors for actual reed switches, which is not really a big deal.

EDIT: I also run Home Assistant, which works with MQTT much better and my project does work there. Just not in the Gateway.

Bump.

Still trying to get an Event to flow from the 8266 to the gateway.

Any ideas?

@jgonzal1- if you can load the MicroBlocks VM firmware onto your ESP8266 board, you can use the WebThings library in the MicroBlocks IDE. It’s quite easy to use. I have connected a simple MC-38 reed switch to an ESP32 to create a door sensor, and I have used a pushbutton (with separate MCU) to generate events. But I have not tried to create one web thing defined as a door sensor with events. As long as there’s enough memory for streaming the JSON TD, it seems that it should work. If I have time this week (and don’t forget) I’ll give it a try.

Thank you for the suggestion. I’m so very close to getting this whole setup to work that I’m reluctant to start over with a new software base on the ESP8266. Everything works but the passing of text events from the ESP8266 to the gateway. I can generate an Event and I see them at https://IP_address/things/door/events. They are just not being sent to the gateway. I feel that I’m as close as one (or two) calls from success. I’ve been searching the internets looking for an example. There is one example and I’ve copied it exactly but no events at the gateway.

I remember reading that the gateway has to subscribe to receive Events but I haven’t been able to find how that works.

I’ll keep searching and trying different things.

Thanks.

I am not familiar with events yet, but I found the hard way that property updates need to be notified to be picked-up by the gateway. Maybe Events follow a similar mechanism.

For properties, you need to invoke a notification function thus (python syntax here as this is what I use):

webthingobject.properties[propertyname].value.notify_of_external_update(value_to_send)

Were you able to get this to work? I made some modifications to the date-time-adapter, and it uses a few events. You can look through the latest code. It does send the events, and when I create a rule with the date-time-adapter on the left side I can choose “When DateAdapter event Sunset occurs, …” from the properties. It works to open blinds and such.