I can also use an ESP8266 relay board, MQTT and IFTTT like I did for my ancient lantern, but there were a couple of problems. First the MQTT code would stop working after a few days. Secondly I had not figured out how to share the device on Google Home with my wife.
Top: 230Vac to 5V@1A power supply. Bottom: ESP-01S with 1-channel relay adapter |
The watchdog timer is enabled by default, and is serviced by various routines in the library, so there is really no good way to use it except as a delayed reset. There is a good article on it here.
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
}
}
The reason for the failure seems to be mqtt.connect() or perhaps the WiFi router sometimes cannot detect there is no longer a connection. For now the best workaround seems to be to have an active MQTT input, that is to regularly 'publish' to the MQTT broker Adafruit. After a few minutes (normally less than 30) mqtt.connect() will eventually work and the device will reconnect.
Getting Google Home to share the device took a little more time. On the face of it, IFTTT allows me to share: I can publish my Applet for unlimited sharing. But that is too much sharing: letting a random user open my gate from the Internet is a not good idea.
I get my MQTT service from Adafruit, (which IFTTT needs to link the ESP8266 to Google Home) and I can share just my Adafruit feed for the autogate with my wife. Indeed she can activate the autogate from the Adafruit App, but Google Home will not link to a shared feed. Furthermore the Adafruit share turned out to be a global share as well, again an unacceptable security risk.
It turned out that if I got the wife to register with IFTTT and Adafruit, and if I duplicated the ESP8266 code using my wife's Adafruit account and secret key (AIO) the device will support both Adafruit feeds.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Client wife_mqtt(&wife_client, AIO_SERVER, AIO_SERVERPORT, AIO_WIFENAME, AIO_WIFEKEY);
// Setup feeds Adafruit_MQTT_Subscribe lantern = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME"/feeds/frontgate");
Adafruit_MQTT_Subscribe wife_autogate = Adafruit_MQTT_Subscribe(&wife_mqtt, AIO_WIFENAME"/feeds/frontgate");
Converting the Open/Close Google Home commands to autogate pulses is now easy:
while ((subscription = mqtt.readSubscription(2000))) {
if (subscription == &gate) {
Serial.print(F("Got: "));
Serial.println((char *)gate.lastread);
int gate_State = atoi((char *)gate.lastread);
Serial.print("Autogate openclose ");
Serial.println(gate_State);
digitalWrite(0, 1); // Issue a command to toggle gate
delay(500);
digitalWrite(0, 0); // Autogate CPU input is monostable. Issue command to reset
}
}
Tight fit: clockwise from top left: autogate control board, RF remote control module, 12V battery and ESP8266 relay module |
Here's a little youtube video of the result.
I am still a little unhappy with it: I would it like to feedback (ie 'publish' in MQTT-speak) actual gate open/close state, and I would have to manually dismantle and reprogram it should my parents come to visit. Also it would be nice to keep a log of the autogate usage, but perhaps that is a future project, an MQTT server. But in the spirit of DevOps, let's just put it up and look for those all-important gotchas that are so critical to a product's eventual success.
There you have it- a voice-controlled autogate. I have not looked very hard, but with a little luck, this should be one of the first homebrew Google Home autogate smart remotes.
Happy Trails.
Updated 2018-12-22 on device becoming unresponsive after WiFi reconnects
ReplyDelete