Sonoff-HomeAssistant (Alternative firmware for Sonoff Switches for use with mqtt/HA)

Hi
Can you also support https://www.itead.cc/sonoff-dual.html?

At the moment I am bilding my christmas lights. I would like to control with one board about 8 GPIO. Can you show me how I where I have to put the other GPIO’s in to your code so I get the same stability )

The dual is completely different. It has an additional processor. Haven’t started yet. It’s on the list for sure as is the Pow. On the weekend I am going to release firmware for the LED strip. Working OK and just testing fully before I release it.

1 Like

Can you help me to revise your program to activate the RELAY & LED only once when the sonoff has been switch ON (230V). I tried to revise your program but there is a problem on what I did, it always activate the RELAY&LED when the connection lost to the wifi then connect again. I only want to activate the RELAY & LED one time only when it power ON (230V). please help… thanks

Please describe your situation a little bit better. What exactly is happening to your network / switches / etc.

Sonoff-LEDS

I’ve finished the code for the Sonoff LED strip.

https://www.itead.cc/sonoff-led.html?acc=70efdf2ec9b086079795c442636b55fb

Inside the linked file below is everything you need to get going. Not sure how many people are interested in this product but it’s pretty good. Can easily replace the main lighting in your room because it’s VERY bright, and stays very cool at max brightness. I think for the price they are on a winner here. Anyway will release here first before I go to Github. Good luck.

http://gofile.me/6sw88/GWI1xY1Ur

NOTE: Once you replace the firmware in the LEDS, just like the Sonoff switches, there’s no going back to iTead’s software.

Kman

1 Like

Nice one @KmanOz !
Be interested to know your use cases on these, been wondering how I can use them around the house. Any pics of them in action?

I only have 1 unit and it’s on the workbench. Will definitely order some more. They’re not your typical strip of LEDS for mood lighting. These are so bright that they can literally light up a room and are designed for that exact purpose. I’ll come back with some usage (watts) in the next couple of days and see how efficient they are as well :smiley: Impressed though.

1 Like

Hey! I’ve been trying to make this tutorial work for just one switch, and after fiddling for way too long and not making it work, I decided to check out what the esp8266 says in serial port.

I get the “wifi failed” message periodically, so I guess my chip doesn’t even make it to my router.

Any ideas why? I quadruple checked my wifi ssid and password, and they’re fine, I had no issues with other esp devices connecting to my network before.

Any help is appreciated, thanks.

Some additional information:

I’ve logged in to my router’s admin page to see if the chip makes any connections, and YES!

It gets an IP address, I can see for sure it’s there by its MAC address, but I still get the “WIFI FAILED” error message every once in a while.

hi KmanOz,
thanks for the response. I connect the sonoff in the light ceiling, which can be turn off the power of the sonoff when switching off using the normal switch on the wall. i’m trying to experiment if can be program the sonoff as normally close on the relay so whenever they use the wall switch the light will turn ON right away even if it is not yet connected on the network. In my case i managed to make the relay normally close of the sonoff when it boot but when the sonoff is switch off using the homeassistant and it reconnect to the network it will turn ON the light automatically. i want to remove the part of turning ON light when sonoff reconnect to the network.

1 Like

LOL thanks!

Installed your code on some more modules. Rock solid every time. One feature that would be really helpful would be being able to set ssid and pw without having to reflash. That would save having to disassemble the unit every time the wifi password is changed.

Hi sorry to hear. I can tell you this beyond any shadow of a doubt, the chances are the unit (read the ESP8266 chip) is defective rather than the code itself. I’ve programmed more than I can remember and occasionally you get a chip that just doesn’t want to play right. I have a unit here that will connect to Wifi, load code and do nothing no matter what I try so basically it’s useless. It’s a shame you only have 1, otherwise you could have tested on the other to confirm.

Anywayl there’s a couple of things you can try. First, see if it’s a signal issue by physically plugging the unit in closer to the router and see how stable it becomes. Secondly find and change this in the code just in case it’s timing out just when it’s about to connect.

int kRetries = 10;

Make it :

int kRetries = 20;

If on the other hand you move it closer and it keeps resetting (4 fast flashes of the status LED) then you may just have a defective unit or your router model and the ESP chip just don’t like each other. just like me and celery :smiley:

I agree. I also will make the mqtt topic changeable via WiFi. That way anything that’s likely to change, can be done via WiFi. Leave it with me :smiley:

If the unit is being switched off by HomeAssistant, why is reconnecting to the network? The power will still be on the Sonoff.

Do you mean you are switching the Sonoff OFF completely by your wall switch NOT HomeAssistant?

I think I understand what he is asking for and can agree if it were a customization change.

For me I have GE smart bulbs. These bulbs come on when power is applied that way they still act as normal bulbs when used with light switches.

The same functionality would have the switch come on as soon as power is applied or as quickly as code would allowed.

it is reconnecting everytime i restart the homeAssistant, RPI. Sometimes in the middle of the night after i turn it OFF using HA it will turn ON by itself because it reconnect to the network, i’m not sure why but i think my wifi is not stable.

yes i’m switching the Sonoff OFF completely using the wall switch then if someone turn ON the wall switch i can turn OFF using homeAssistant.

this is the code that i change, so my setup will turn ON the light after i switch ON the wall switch then if i turn it off using HA then i restart my router or RPI it will turn ON by itself.

void setup() {
pinMode(LED, OUTPUT);
pinMode(RELAY, OUTPUT);
pinMode(BUTTON, INPUT);

digitalWrite(LED, LOW); //////////////////////////////revise
digitalWrite(RELAY, HIGH); //////////////////////////revise

btn_timer.attach(0.05, button);

mqttClient.set_callback(callback);

WiFi.mode(WIFI_STA);
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();
}
digitalWrite(LED, LOW); ////////////////////////revise
digitalWrite(RELAY, HIGH); /////////////////////revise
}

help me to revise your code that it will turn ON the light after i switch ON the wall switch(POWER 230V ON Sonoff) and then after i turn it OFF using HA then if it reconnect to the network or i restart the router it won’t switch ON the light by itself.

It will because you run your Mosquito broker on RPi. If you have a large mqtt network (many devices) that rely on a stable mqtt platform I recommend you setup a separate mosquito server that stays on irrespective of what HA does. That way you can restart HA and it won’t effect your network and connected devices.

The basis of any good Home Automation system is the network. You need to make sure you have a stable platform for everything to work. What your seeing is normal for the Sonoff switch. When your Mosquito server goes down you will notice that the Sonoff will flash 4 times fast quite frequently because it’s trying to re-establish the connection to the broker.

That’s basically a reboot.

My code will reboot the switch if it loses the network. With the way the code is written right now, it’s a reboot whether you turn the power on after it’s been turned off, or it loses WiFi or mqtt. There is no way to tell the difference.

Let me think about what you need. There is no quick solution I can come up with right now but it may be possible with a bit more thought.

Thanks

I will work this into an update. There will be an option to turn on the load at startup or leave it off.

Hi KmanOz.

Was using your code with a sonoff TH10 + a DS18B20 sensor. I needed this sensor as it was the only waterproof one I could find and my application is for an aquarium. Found out it required different libraries. The updated code, should you need it, is below:

#include <OneWire.h>
#include <DallasTemperature.h>
#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)

// Data wire is conntected to the digital pin 14
#define ONE_WIRE_BUS 14
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

#define MQTT_CLIENT     "AquariumTH10"                      // mqtt client_id (Must be unique for each Sonoff)
#define MQTT_SERVER     "192.168.0.20"                      // mqtt server
#define MQTT_PORT       1883                                // mqtt port
#define MQTT_TOPIC      "automation/aquarium/TH10"          // mqtt topic (Must be unique for each Sonoff)
#define MQTT_USER       "xx"                                // mqtt user
#define MQTT_PASS       "xx"                         // mqtt password

#define WIFI_SSID       "xx"                           // wifi ssid
#define WIFI_PASS       "xx#"                          // wifi password

#define VERSION    "\n\n-----------------  Sonoff TH Powerpoint v1.0t  -----------------"

extern "C" { 
  #include "user_interface.h" 
}

bool sendStatus = false;
bool requestRestart = false;
bool tempReport = 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(RELAY, HIGH);
  }
  else if (pub.payload_string() == "off") {
    digitalWrite(RELAY, LOW);
  }
  else if (pub.payload_string() == "reset") {
    requestRestart = true;
  }
  else if (pub.payload_string() == "temp") {
    tempReport = 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.mode(WIFI_STA);
  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, LOW);
    }
    else {
      Serial.println(" FAILED!");
      Serial.println("\n----------------------------------------------------------------");
      Serial.println();
    }
  }
  else {
    Serial.println(" WiFi FAILED!");
    Serial.println("\n----------------------------------------------------------------");
    Serial.println();
  }
  getTemp();
}

void loop() { 
  mqttClient.loop();
  timedTasks();
  checkStatus();
  if (tempReport) {
    getTemp();
  }
}

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(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(RELAY) == LOW)  {
      mqttClient.publish(MQTT::Publish(MQTT_TOPIC"/stat", "off").set_retain().set_qos(1));
      Serial.println("Relay . . . . . . . . . . . . . . . . . . OFF");
    } else {
      mqttClient.publish(MQTT::Publish(MQTT_TOPIC"/stat", "on").set_retain().set_qos(1));
      Serial.println("Relay . . . . . . . . . . . . . . . . . . ON");
    }
    sendStatus = false;
  }
  if (requestRestart) {
    blinkLED(LED, 400, 4);
    ESP.restart();
  }
}

void getTemp() {

  // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
  sensors.requestTemperatures(); 
  
  Serial.print("Temp read . . . . . . . . . . . . . . . . . ");
  float getT;
  char message_buff[60];
  
  // Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire
  getT = sensors.getTempCByIndex(0);
  
  if(digitalRead(LED) == LOW)  {
    blinkLED(LED, 100, 1);
  } else {
    blinkLED(LED, 100, 1);
    digitalWrite(LED, HIGH);
  }
    
  if (isnan(getT)) {
    mqttClient.publish(MQTT::Publish(MQTT_TOPIC"/debug","\"DHT Read Error\"").set_retain().set_qos(1));
   Serial.println("ERROR");
    tempReport = false;
    return;
  }
  String pubString = "{\"Temp\": "+String(getT)+"}";
  Serial.println (pubString);
  pubString.toCharArray(message_buff, pubString.length()+1);
  mqttClient.publish(MQTT::Publish(MQTT_TOPIC"/temp", message_buff).set_retain().set_qos(1));
  Serial.println("OK"); 
  tempReport = false;
}


void timedTasks() {
  if ((millis() > TTasks + (kUpdFreq*6000)) || (millis() < TTasks)) { 
    TTasks = millis();
    checkConnection();
    tempReport = true;
  }
}