I’ve been trying for weeks to get the Sonoff switch to change states.
Here is the sketch I used (only changed my broker details and what was asked to change:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Ticker.h>
#define BUTTON 0 // (Don't Change for Sonoff)
#define RELAY 12 // (Don't Change for Sonoff)
#define LED 13 // (Don't Change for Sonoff)
#define MQTT_CLIENT "Sonoff_Living_Room_v1.0p" // mqtt client_id (Must be unique for each Sonoff)
#define MQTT_SERVER "192.168.0.100" // mqtt server
#define MQTT_PORT 1883 // mqtt port
#define MQTT_TOPIC "home/sonoff/living_room/1" // mqtt topic (Must be unique for each Sonoff)
#define MQTT_USER "user" // mqtt user
#define MQTT_PASS "pass" // mqtt password
#define WIFI_SSID "homewifi" // wifi ssid
#define WIFI_PASS "homepass" // wifi password
#define VERSION "\n\n------------------ Sonoff Powerpoint v1.0p -------------------"
extern "C" {
#include "user_interface.h"
}
bool sendStatus = false;
bool requestRestart = false;
int kUpdFreq = 1;
int kRetries = 10;
unsigned long TTasks;
unsigned long count = 0;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient, MQTT_SERVER, MQTT_PORT);
Ticker btn_timer;
void callback(const MQTT::Publish& pub) {
if (pub.payload_string() == "stat") {
}
else if (pub.payload_string() == "on") {
digitalWrite(LED, LOW);
digitalWrite(RELAY, HIGH);
}
else if (pub.payload_string() == "off") {
digitalWrite(LED, HIGH);
digitalWrite(RELAY, LOW);
}
else if (pub.payload_string() == "reset") {
requestRestart = true;
}
sendStatus = true;
}
void setup() {
pinMode(LED, OUTPUT);
pinMode(RELAY, OUTPUT);
pinMode(BUTTON, INPUT);
digitalWrite(LED, HIGH);
digitalWrite(RELAY, LOW);
btn_timer.attach(0.05, button);
mqttClient.set_callback(callback);
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.begin(115200);
Serial.println(VERSION);
Serial.print("\nESP ChipID: ");
Serial.print(ESP.getChipId(), HEX);
Serial.print("\nConnecting to "); Serial.print(WIFI_SSID); Serial.print(" Wifi");
while ((WiFi.status() != WL_CONNECTED) && kRetries --) {
delay(500);
Serial.print(" .");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println(" DONE");
Serial.print("IP Address is: "); Serial.println(WiFi.localIP());
Serial.print("Connecting to ");Serial.print(MQTT_SERVER);Serial.print(" Broker . .");
delay(500);
while (!mqttClient.connect(MQTT::Connect(MQTT_CLIENT).set_keepalive(90).set_auth(MQTT_USER, MQTT_PASS)) && kRetries --) {
Serial.print(" .");
delay(1000);
}
if(mqttClient.connected()) {
Serial.println(" DONE");
Serial.println("\n---------------------------- Logs ----------------------------");
Serial.println();
mqttClient.subscribe(MQTT_TOPIC);
blinkLED(LED, 40, 8);
digitalWrite(LED, HIGH);
}
else {
Serial.println(" FAILED!");
Serial.println("\n----------------------------------------------------------------");
Serial.println();
}
}
else {
Serial.println(" WiFi FAILED!");
Serial.println("\n----------------------------------------------------------------");
Serial.println();
}
}
void loop() {
mqttClient.loop();
timedTasks();
checkStatus();
}
void blinkLED(int pin, int duration, int n) {
for(int i=0; i<n; i++) {
digitalWrite(pin, HIGH);
delay(duration);
digitalWrite(pin, LOW);
delay(duration);
}
}
void button() {
if (!digitalRead(BUTTON)) {
count++;
}
else {
if (count > 1 && count <= 40) {
digitalWrite(LED, !digitalRead(LED));
digitalWrite(RELAY, !digitalRead(RELAY));
sendStatus = true;
}
else if (count >40){
Serial.println("\n\nSonoff Rebooting . . . . . . . . Please Wait");
requestRestart = true;
}
count=0;
}
}
void checkConnection() {
if (WiFi.status() == WL_CONNECTED) {
if (mqttClient.connected()) {
Serial.println("mqtt broker connection . . . . . . . . . . OK");
}
else {
Serial.println("mqtt broker connection . . . . . . . . . . LOST");
requestRestart = true;
}
}
else {
Serial.println("WiFi connection . . . . . . . . . . LOST");
requestRestart = true;
}
}
void checkStatus() {
if (sendStatus) {
if(digitalRead(LED) == LOW) {
mqttClient.publish(MQTT::Publish(MQTT_TOPIC"/stat", "on").set_retain().set_qos(1));
Serial.println("Relay . . . . . . . . . . . . . . . . . . ON");
} else {
mqttClient.publish(MQTT::Publish(MQTT_TOPIC"/stat", "off").set_retain().set_qos(1));
Serial.println("Relay . . . . . . . . . . . . . . . . . . OFF");
}
sendStatus = false;
}
if (requestRestart) {
blinkLED(LED, 400, 4);
ESP.restart();
}
}
void timedTasks() {
if ((millis() > TTasks + (kUpdFreq*60000)) || (millis() < TTasks)) {
TTasks = millis();
checkConnection();
}
}
Here is my HA Yaml code (changed the original code from switch to light):
light:
platform: mqtt
name: "Living Room"
state_topic: "home/sonoff/living_room/1/stat"
command_topic: "home/sonoff/living_room/1"
qos: 1
payload_on: "on"
payload_off: "off"
retain: true
Here is the strange thing. When check what message is being sent when trying to change the state via MQTTfx. Its show that the payload is “True” when Publishing to command_topic “home/sonoff/living_room/1”. The payload is not setting “on”
I can Publishing to command_topic “home/sonoff/living_room/1” with payload “on” via MQTTfx on the light turns on.
Please assist in anyway possible.
Cheers