30A MQTT relay with timer: software

 Posted by:   Posted on:   Updated on:  2023-01-23T20:08:14Z

Configure MQTT Dash application for the ESP8266 relay with timer

In the previous post I built an ESP8266 controlled 30A relay to automate an irrigation pump. I added a time display to this device because I want to have timer function, to set the pump on for a specified amount of time. I will not be using a web server to control the relay because I want to be able to switch it on from outside of the local network and it is difficult to obtain a properly secured HTTP server on ESP8266. I already did it, but this MCU has limited resources for such purpose.

Since I run a self-hosted MQTT broker on an Orange Pi Zero SBC I will make use of the MQTT capabilities. Orange Pi has a capable CPU for proper SSL encryption and I already made the server secure with self signed SSL certificate. ESP8266 can connect to the server in the local network on the unsecured listener port and that is not an issue since I have control over the devices my local network. Even so, WiFi is password protected. And ESP8266 uses credentials to connect to MQTT broker.

MQTT relay controls in MQTT Dash app
MQTT relay controls in MQTT Dash app

Code adjustments

The Arduino code is provided at the end of this post. I will not talk too much about it, because there is not much to explain about the ~300 lines of code. I tested it both on ESP8266 and ESP32 and it performed as expected. At the beginning you must change some parameters to make it work for you.

#define MCU_ESP8266 /* MCU_ESP8266 for ESP8266 boards or MCU_ESP32 for ESP32 */
#define DEV_NAME "Pump"
#define DEV_TYPE "Switch"

#ifdef MCU_ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFi.h>
#include <ESPmDNS.h>

#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>
#include <TM1637Display.h>

#define PIN_RLY D5 /* Relay control pin (output) */
#define PIN_BTN D6 /* Button pin (input) */
#define PIN_CLK D2 /* TM1637 clock pin (output) */
#define PIN_DIO D1 /* TM1637 data pin (output) */
#define PIN_ERR D7 /* Error LED pin (output) */

/* WiFi settings */
const char *ssid = "...";
const char *password = "...";
const char *mdns_name = DEV_TYPE "-" DEV_NAME;
// #define USE_DHCP /* when enabled the following IP config is ignored */
const IPAddress ip(192, 168, 1, 5);
const IPAddress gateway(192, 168, 1, 1);
const IPAddress subnet(255, 255, 255, 0);

/* MQTT Server settings */
const IPAddress mqttIP(192, 168, 1, 4);
const unsigned int mqttPort = 1883;
const char *mqtt_user = "...";
const char *mqtt_pass = "...";

/* OTA Firmware update */
const char* otaPassword = "admin";

/* Publishes to: */
const char *mqttStatusCheck = DEV_TYPE "/" DEV_NAME "/Status/Check";
const char *mqttStatusText = DEV_TYPE "/" DEV_NAME "/Status/Text";
const char *mqttTimerRemain = DEV_TYPE "/" DEV_NAME "/Timer/Remaining";

/* Subscribes to: */
const char *mqttStatusRequest = DEV_TYPE "/" DEV_NAME "/Status/Request";
const char *mqttTimerSet = DEV_TYPE "/" DEV_NAME "/Timer/Set";

/* Strings */
#define WILL_MSG "Not connected."
#define OFF_MSG "The pump is off."
#define OFF_TIME_MSG "The pump is off. \nPrevious on time is %d minutes."
#define ON_MSG "The pump is on since %d minutes."
#define ON_TIMER_MSG "The pump is on for %d minutes out of %d minutes in total."
#define FWUPD_MSG "Firmware update started."

The above pin configuration matches the PCB I designed in the previous post. Note that for ESP32, you must modify pins accordingly. There is one general purpose input pin for the switch, which is polled regularly for changes. The remaining 4 pins are general purpose outputs, two for TM1637 data bus, one for the relay and one for the error LED. This LED is active low and when blinking it indicates WiFi/MQTT not connected. When it goes off, connection is established.

Edit WiFi credentials. I used a static IP configuration for ESP8266 client, yet you can uncomment #define USE_DHCP to ignore IP settings and use DHCP. MQTT server is configured for a local unsecured broker with credentials login. Adjust as needed. There are 3rd party MQTT services available which allow a limited number of connections for free. I like to keep my data at home and have full control over it. OTA firmware update is enabled and default password is admin.

Next you can see the topics this device publishes and subscribes to. I'll show you how to configure your Android phone. And at last there are the status messages which you may edit/translate.

App configuration

I use MQTT Dash from Routix software to connect to my self-hosted MQTT server. I have a domain name from my ISP which always points to my public IP address and I opened the secured listener port of the server for internet connections.

Launch the app and tap the plus button in the top right corner to add a server. Tap the save button in the same corner after you inserted name, address, port (and user/password). For my server I have to check the box for self-signed certificates. Make sure metrics management is allowed, otherwise you will not be allowed to add widgets. After you save it, tap its name on the list and it should connect. You are prompted with an empty screen.

Yet in this screen there is a plus button. Use it to add widgets. To make a correlation with the code, on the phone you have to subscribe to all the topics the ESP8266 publishes to. And you will publish to all the topics ESP8266 is subscribed to.

Add MQTT server in MQTT Dash
Add MQTT server in MQTT Dash

For the current implementation, the following widgets are needed: switch, text and range. A switch will trigger the relay on/off. The text widget will display current status. Note that the code does not allow triggering the relay on/off at intervals lower than 10 seconds. To trigger the relay, a client (the phone in this case) will publish the message "1" to "Switch/Pump/Status/Request" and wait for a response in "Switch/Pump/Status/Check". ESP8266 responds with the real relay status by publishing to this topic.

The controller also publishes status information to "Switch/Pump/Status/Text", this being another topic the phone has to subscribe. Let's see how the two are configured.

Add on/off button and text status information
Add on/off button and text status information

Make sure you disable immediate update after publishing, because the actual status is available in a different topic. Use whatever icon and color combination you want. The text status is a subscribe only widget, with no publish topic.

There is a different topic of timer functionality. When a non-zero value is published, it is considered time in minutes. If this publish event happens while the relay is off, it will get switched on. Otherwise, it it was already on, it will continue to be on during the set time.

If zero is published, time limit is reset. It the relay was on when this event occurred, it will stay on for an unlimited time. The timer can be overridden and the relay can be turned off anytime using on/off button.

I added a button with a predefined time of 5 minutes, yet it could have been any other value. And a range widget for setting any time between 0 and 120 minutes. Both widgets use the same topics: "Switch/Pump/Timer/Set" and "Switch/Pump/Timer/Remaining". The subscribing topic updates with remaining time every minute.

Add timer widgets
Add timer widgets

Do not check Retained for any of the widgets. Otherwise, in case you send a relay on command while the device is offline, it will process it as soon as it gets online.

Final thoughts

This post was an example of how you can use MQTT and development boards with WiFi connection to automate various things. With the above configuration, the relay can be triggered from anywhere in the world over a secure connection.

The firmware is suitable for ESP8266 and ESP32 and can be flashed on ready made boards. There are ESP8266 relay boards available to buy online. The current version supports only one relay.


Release 1.0 (2022.04.17)

Release 2.0 (2023.01.23)

  • Source code: esp8266_mqtt_pump_relay.zip.
  • Asynchronous routines.
  • Additional library dependencies (URLs are listed at the beginning of the code).
  • Can work without Wi-Fi or MQTT connection.
  • Connection configuration is still hardcoded.
  • New: all of the configuration variables and defines are stored in a separate header named config.h.
  • New: basic HTTP web server, which can be accessed on mDNS domain or device IP.

No comments :

Post a Comment

Please read the comments policy before publishing your comment.