Hi guys, I have been playing with a sonoff using MQTT and a Mosquitto server on my Synology diskstation.
But could not see a way to get control of the sonoff on my vera (with Mysensors) as it does not support MQTT.
I started to play with the ESP8266 MQTT gateway, the gateway has an NRF radio but is Not connected to the vera as an actual gateway.
(I just opened a second page on Mysensors to check something and saw Efflon posted a MQTT Sonoff post but his uses home assistant which supports MQTT so I think mine is different enough to keep going)
Ok so, here is the working chain:
-
"Alexa switch on mains plug 1"
-
Alexa talks to HA Bridge (also running on my Synology) where mains plug 1 is the friendly name of Vera virtual switch device no 181 id 20;10 parent 3
-
HA Bridge talks to Vera in html to switch on the Virtual switch with id 20;10 (I have a 433Txnode with id 20 and 6 switches) with parent id 3(Mysensors plugin)
-
Message then goes out the Mysensors serial gateway and is broadcast over NRF (20/10/1/1/2 1)
-
The ESP8266_MQTT_gateway picks up the message on NRF and sends it on to the MQTT broker (mygateway1-out/20/10/1/1/2 with message 1)
-
The SONOFF unit is subscribed to the broker and picks up the message and switches on.
if you press the button on the sonoff it works in reverse as far as Vera, sending a message to mygateway1-in/20/10/1/1/2 0 or 1 switching the state of the virtual switch.
The ESP8266 MQTT gateway code was unchanged.
Sonoff MQTT code from esp8266.com
The only change was to the topic name
/*
It connects to an MQTT server then:
- on 0 switches off relay
- on 1 switches on relay
- on 2 switches the state of the relay
- sends 0 on off relay
- sends 1 on on relay
It will reconnect to the server if the connection is lost using a blocking
reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
achieve the same result without blocking the main loop.
The current state is stored in EEPROM and restored on bootup
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Bounce2.h>
#include <EEPROM.h>
const char* ssid = "ssid";
const char* password = "password";
const char* mqtt_server = "broker IP address";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
//const char* outTopic = "Sonoff1out";
const char* outTopic = "mygateway1-in/20/10/1/1/2";
//const char* inTopic = "Sonoff1in";
const char* inTopic = "mygateway1-out/20/10/1/1/2";
int relay_pin = 12;
int button_pin = 0;
bool relayState = LOW;
// Instantiate a Bounce object :
Bounce debouncer = Bounce();
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
extButton();
for(int i = 0; i<500; i++){
extButton();
delay(1);
}
Serial.print(".");
}
digitalWrite(13, LOW);
delay(500);
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500);
digitalWrite(13, HIGH);
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == '0') {
digitalWrite(relay_pin, LOW); // Turn the LED on (Note that LOW is the voltage level
Serial.println("relay_pin -> LOW");
relayState = LOW;
EEPROM.write(0, relayState); // Write state to EEPROM
EEPROM.commit();
} else if ((char)payload[0] == '1') {
digitalWrite(relay_pin, HIGH); // Turn the LED off by making the voltage HIGH
Serial.println("relay_pin -> HIGH");
relayState = HIGH;
EEPROM.write(0, relayState); // Write state to EEPROM
EEPROM.commit();
} else if ((char)payload[0] == '2') {
relayState = !relayState;
digitalWrite(relay_pin, relayState); // Turn the LED off by making the voltage HIGH
Serial.print("relay_pin -> switched to ");
Serial.println(relayState);
EEPROM.write(0, relayState); // Write state to EEPROM
EEPROM.commit();
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(outTopic, "Sonoff1 booted");
// ... and resubscribe
client.subscribe(inTopic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
for(int i = 0; i<5000; i++){
extButton();
delay(1);
}
}
}
}
void extButton() {
debouncer.update();
// Call code if Bounce fell (transition from HIGH to LOW) :
if ( debouncer.fell() ) {
Serial.println("Debouncer fell");
// Toggle relay state :
relayState = !relayState;
digitalWrite(relay_pin,relayState);
EEPROM.write(0, relayState); // Write state to EEPROM
if (relayState == 1){
client.publish(outTopic, "1");
}
else if (relayState == 0){
client.publish(outTopic, "0");
}
}
}
void setup() {
EEPROM.begin(512); // Begin eeprom to store on/off state
pinMode(relay_pin, OUTPUT); // Initialize the relay pin as an output
pinMode(button_pin, INPUT); // Initialize the relay pin as an output
pinMode(13, OUTPUT);
relayState = EEPROM.read(0);
digitalWrite(relay_pin,relayState);
debouncer.attach(button_pin); // Use the bounce2 library to debounce the built in button
debouncer.interval(50); // Input must be low for 50 ms
digitalWrite(13, LOW); // Blink to indicate setup
delay(500);
digitalWrite(13, HIGH);
delay(500);
Serial.begin(115200);
setup_wifi(); // Connect to wifi
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
extButton();
}
//- See more at: http://www.esp8266.com/viewtopic.php?f=29&t=8746#sthash.vhv33y8Q.dpuf
You don't need to add any extra gateways to Vera, you just add Virtual Switches and program each sonoff (or any other ESP8266) with the different Broker topics needed.