[Framework] Homie for ESP8266

Sorry I did not see your post. Thanks for the kind word. :slight_smile:

Unfortunately, Adafruit’s broker, being shared, is too restricted. You can only publish/subscribe to (username)/feeds/(feed name, ID, or key). If you read the Homie convention on GitHub you will notice this is a problem.

I can not see anything about in the the wiki that says it can not use adfruit:)

This seems like an easier way to configure it rather then using the app on the phone. Does the settings get flashed aswell when you rewrite arduino code to it?

It would be really nice if we could get it to work with ardafruit aswell as mosquitto. For instance if I am brewing beer at my mates house i can threw an esp with dht11 in there, a powersupply and then just log on to ardfruit and plot the temperature.

Maybe I am missing something? For openhab purposes i would of course use mosquitto and the mqtt binding. But when testing out new sensor etc it would be nice to keep it off openhab.

Here are two sketeches that I got working.

WeMos D1 mini with DHT22 shield:

// This sketch is designed to work with an WeMos D1 min and the WeMos DHT SHield


#include <Homie.h>
#include <DHT.h>

#define DHTPIN D4     // what pin we're connected to


// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)


const int TEMPERATURE_INTERVAL = 10;
unsigned long last_temperature_sent = 0;

const int HUMIDITY_INTERVAL = 10;
unsigned long last_humidity_sent = 0;

HomieNode temperatureNode("temperature", "temperature");
HomieNode humidityNode("humidity", "humidity");

DHT dht(DHTPIN, DHTTYPE);

void setupHandler() {
  // Do what you want to prepare your sensor
}


void getSendTemperature() {
  if (millis() - last_temperature_sent >= TEMPERATURE_INTERVAL * 1000UL || last_temperature_sent == 0) {
    float temperature = dht.readTemperature();

    if (isnan(temperature)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }

    Serial.print("Temperature: ");
    Serial.print(temperature);
    Serial.println(" °C");
    if (Homie.setNodeProperty(temperatureNode, "temperature", String(temperature), true)) {
      last_temperature_sent = millis();
    } else {
      Serial.println("Sending failed");
    }
  }
}

void getSendHumid() {
  if (millis() - last_humidity_sent >= HUMIDITY_INTERVAL * 1000UL || last_humidity_sent == 0) {
    float humidity = dht.readHumidity();

    if (isnan(humidity)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }

    Serial.print("Humidity: ");
    Serial.print(humidity);
    Serial.println(" %");
    if (Homie.setNodeProperty(humidityNode, "humidity", String(humidity), true)) {
      last_humidity_sent = millis();
    } else {
      Serial.println("Sending failed");
    }
  }
}


void loopHandler() {
  getSendTemperature();
  getSendHumid();   

}

void setup() {
  Homie.setFirmware("awesome-temperature", "1.0.0");
  Homie.registerNode(temperatureNode);
  Homie.registerNode(humidityNode);
  Homie.setSetupFunction(setupHandler);
  Homie.setLoopFunction(loopHandler);
  Homie.setup();
}

void loop() {
  Homie.loop();
}

NodeMCU v1.0 with LED and push button:

#include <Homie.h>

const int PIN_LED = D2;
const int PIN_BUTTON = D1;

int buttonOLD=LOW;

HomieNode light("light", "light");

bool lightOnHandler(String message) {
  if (message == "true") {
    digitalWrite(PIN_LED, HIGH);
    Homie.setNodeProperty(light, "on", "true"); // Update the state of the light
    Serial.println("Light is on");
  } else if (message == "false") {
    digitalWrite(PIN_LED, LOW);
    Homie.setNodeProperty(light, "on", "false");
    Serial.println("Light is off");
  } else {
    return false;
  }

  return true;
}



HomieNode buttonNode("button", "button");

void loopHandler() {
  
  if ( digitalRead(PIN_BUTTON) == HIGH && buttonOLD == LOW)
  {
    Homie.setNodeProperty(buttonNode, "event", "push", false);
    Homie.setNodeProperty(buttonNode, "pressed", "true", true);
    buttonOLD=HIGH;
  }

  if ( digitalRead(PIN_BUTTON) == LOW && buttonOLD == HIGH)
  {
    Homie.setNodeProperty(buttonNode, "pressed", "false", true);
    buttonOLD=LOW;
  }
  
}



void setup() {
  pinMode(PIN_LED, OUTPUT);
  digitalWrite(PIN_LED, LOW);
  Homie.setFirmware("awesome-light" ,"1.0.0");
  light.subscribe("on", lightOnHandler);
  Homie.registerNode(light);
  Homie.registerNode(buttonNode);
  Homie.setLoopFunction(loopHandler);
  Homie.setup();
}

void loop() {
  Homie.loop(); 
}

Infact, the last sketch works for push button and switch.
When the button is pushed/pressed it sends two messages to mwtt (“event=pushed” and “pressed=true”)
When the button is released it sends just “pressed=false”.

Just delete the code you don’t need. :slight_smile:
I will try to integrate these examples in GitHub and make a pull request.

Feel free to improve there sketches!!

@christoph_wempe
Hey Christophe, can you see if you can work a debouncer into your button sketch to stop it reporting if someone flicks the button ON-OFF-ON really quick?

I’m trying to do an OPEN/CLOSE sensor for my Garage/Gate and when the garage opens the magnetic reed switch will sometimes flicks status quite a few times really quickly hence the need for a debouncer…

The easiest (quick and dirty) way would be to insert a delay after “buttonOLD=HIGH;”.

delay(1000);  // 1 second

Sorry for partially hijacking this thread, but I just came across this:
http://www.icstation.com/remote-wifi-wireless-remote-control-switch-androidios-p-7364.html

With some google I found out that this is a relay, 5V power supply and an ESP8266 in a box. Would it be possible to reflash this device with Homie. $7.99 would be a good deal who is not willing to bother with building the hardware.

1 Like

Szia Csongor!

It seems possible to reflash these devices. Take a look around here:

Just read the Homie convention, you’ll understand.

The app actually sends the configuration JSON through the API. And no, the settings are stored on the SPIFFS (the filesystem) which is not erased when you upload sketches.

As said above, it just won’t work. But you can use CloudMQTT if you want an online alternative, even if you would have to build your own dashboard.[quote=“christoph_wempe, post:23, topic:8674”]
I will try to integrate these examples in GitHub and make a pull request.
[/quote]

Thanks! :blush:

It is, as @Gorgo said. It’s even perfect for it as it has a built-in LED and a push button to reset it.

I’ve just added an Itead Sonoff example based on what I’ve read about it. It is untested for now, so if you are able to make it work please report. :slight_smile:

@TommySharp I’ve successfully tested the new [DoorSensor example] (https://github.com/marvinroger/homie-esp8266/blob/master/examples/DoorSensor/DoorSensor.ino), feel free to try it.

1 Like

Sorry for all this newbie question, but I am not a computer guys so I am a bit lost.

MQTT broker has an ip adress and a port where it listen to messages from, this can either be locally 127.0.0.1 or on a public ip such as io.adafruit.com, it seems to always listen on port 1883.

So the ESP sends data to the broker, such as temperature. So first you set up your broker and register your feed(https://learn.adafruit.com/mqtt-adafruit-io-and-you/getting-started-on-adafruit-io), this is basically a variable name if I understands it correct, so lets call it LivingRoomTemperature.

So now we need to connect to the broker and send values to that variable(feed) : So we create the node object first:
HomieNode temperatureNode("LivingRoomTemperature", "temperature");
where the second parameter is variable type such as boolean,integer or? I have some problem finding in https://github.com/marvinroger/homie-esp8266/wiki/7.-API-reference which types are allowed.

So if we have a dht22 connected to the esp we will also have a humidty node:
HomieNode humidityNode("LivingRoomHumidity", "humidity");

So now we have set up our two variables, but then we need to let the broker now that we are ready to go:
Homie.registerNode(temperatureNode);
Homie.registerNode(humidityNode);

So then the broker knows that the variabel called temperatureNode on the brokerserver will come from IP XXX.X.XX

After that is setup we can send data to that variabel:

Homie.setNodeProperty(temperatureNode, “temperature”, String(temperature), true))
parameter 2 is the variable type I guess, but what is the last parameter?

So I guess why we can use ardafruit is that homie can only send to localhost due to limitiations in firewall in the router or what am I missing on that part?

So I guess I will download this and try to get going right?

http://www.eclipse.org/downloads/download.php?file=/mosquitto/binary/win32/mosquitto-1.4.8-install-win32.exe

How can I make temperature plots,
Homie.setNodeProperty(temperatureNode, “temperature”, String(temperature), true))

this will just update the variabel value, so how can it also store the timestamp when it received the update?

Thanks for any feedback

There is no newbie question, we’ve all been there. MQTT is all about topics that you can post / subscribe to. Homie uses multiple topics to describe a device:

  • devices/<device ID>/$localip
  • devices/<device ID>/$online
  • devices/<device ID>/$name
  • … you can find every used topics in the Homie convention

Quoting Adafruit:

Adafruit IO’s MQTT API exposes feed data using special topics. You
can publish a new value for a feed to its topic, or you can subscribe to
a feed’s topic to be notified when the feed has a new value. Any one
of the following topic forms is valid for a feed:

  • (username)/feeds/(feed name, ID, or key)
  • (username)/f/(feed name, ID, or key)

When using the Adafruit broker, you cannot post to topics other than the one above. So you understand it is too limited and not adapted to Homie for ESP8266, right?[quote=“skatun, post:30, topic:8674”]
HomieNode temperatureNode(“LivingRoomTemperature”, “temperature”); where the second parameter is variable type such as boolean,integer or? I have some problem finding in Home · homieiot/homie-esp8266 Wiki · GitHub which types are allowed.
[/quote]

No it’s not, the second parameter is the type of the node you’re adding. It can be things like switch, shutters, temperature etc, you can put whatever you want. This is useful for a controller to discover the nodes available. For example, you can scan the topics and see there is a node of type humidity, so that a humidity icon will be shown on your dashboard (note you have to implement this yourself, this is very DIY).

Really, have you read the Homie convention I mentionned a lot of times before? The second parameter is the property of the node you are updating. The last parameter is whether or not you want the value to be persisted on the broker. I suggest you read more about how MQTT works.

No, there is no firewall issue or anything… It’s just the Adafruit broker is too limited.

You have to build it yourself, with a controller that will subscribe to your device topics. When a change happens, you will log somewhere the changed value and the current time.

So like object type or groups basically. I could call it number or boolean if I would like to though.

So homie is broader, but also uses special topics “devices/” has to be on that format and not on (username)/feeds/feed name
so looks pretty much the same to me, use a different way of writing to it and hence not compatible which other.

[quote=“marvinroger, post:31, topic:8674”]
Really, have you read the Homie convention I mentionned a lot of times before? The second parameter is the property of the node you are updating.
[/quote] Yes several times… It says how the string that sent to the broker is built up, however what the method takes in and then sends to broker was not quite clear to me and I just wanted to confirm it.

property = variable name = object type = constant for a non programmer they all seems to be the same:)

So thats if you to keep your data or not, great. Which tool do you use to plot graphs of the sensor data sent to the broker?

will you update the wiki at some point to show what the different homie methods takes in as arguments? Keep up the amazing work of bringing MQTT to the public, I am really impressed by your work and ardafruit.

I personnaly don’t for now, but I guess openHAB can, right?

I cannot explain more than what is written in the Getting started page, the step by step guide explains every parameters used. The API reference also explains each parameter.

Thanks. :slight_smile:

Thanks! It seems to at least do something now which I couldn’t get it to do before…

I wasn’t putting anything in the main Loop though, it looks like you have put in a deboucer update… Can you explain why it works when put there and not in the loopHandler loop?

One thing that isn’t quite right yet is that the debouncer doesn’t seem to work properly… In theory how it should work is that if the door is closed and if you open and close it again REALLY quickly then the ESP8266 shouldn’t even register that the door was opened. The idea behind this is that with magnetic reed switches sometimes when you open the door it will actually switch between OPEN/CLOSED a few times very quickly before it “settles” into it’s proper new OPEN state, the debouncer is supposed to eliminate all the additional status updates.

void loop() {
Homie.loop();
debouncer.update();
}

Your code was also working fine for me, using a push button to simulate the door. The difference between the loopHandler and the main loop is the main loop is called everytime, whereas the loopHandler is called when the MQTT connection is up. In your case this doesn’t change anything, but you might want to debounce even if the MQTT connection is down.

Then, try to increase the debouncer interval? Something like 1000ms to test, then adjust the value until you find the right compromise between responsiveness and safety.

As a bit of a newbie I have been struggling for some hours now to get past the configuration stage. It worked for me once after loading up the bare minimum sketch. But after loading the “awesome relay” example for some reason I was then returned to the initial device ID and could not use the on-line configuration tool, and it seems that the Android app referred to is not available at present. I tried to see if I could upload the config.json file using the API or the direct flash methods mentioned, but I guess I don’t have sufficient understanding to make either method work.

I can reach the http server at 192.168.1.1 and the GET API functions are working. When I enter 192.168.1.1/device-info I get back a response like this:

{“device_id”:“82fd2ae0”,“homie_version”:“1.0.0”,“firmware”:{“name”:“awesome-LED”,“version”:“1.0.0”},“nodes”:[{“id”:“light”,“type”:“switch”}]}

Any help would be much appreciated!

What do you mean by “I was then returned to the initial device ID”? You are right, PhoneGap seems to have issue building the .apk, but this is an issue on their side, I cannot do anything about it right now. :confused:

Please try:

  • Upload the following sketch:
#include "FS.h"

void setup() {
  Serial.begin(115200);
  Serial.println("");
  Serial.println("Mounting FS...");
  if (!SPIFFS.begin()) {
    Serial.println("Failed to mount file system");
    return;
  }

  if (!SPIFFS.format()) {
    Serial.println("Failed to format the file system");
    return;
  }

  Serial.println("Done");
}

void loop() {
   delay(1000);
}

I’ve tried multiple boards, sketches… and I never had any issue, except once with a corrupted file system, that the first sketch I posted should fix.

@marvinroger
Thanks for the example of the door sensor. I can report it’s working as expected with Homie 1.1…

In reading the wiki again I saw a reference to changing the pin of the LED so I’m guessing you’ve just implemented this in 1.2 :slight_smile:

I deleted the Homie 1.1 files and loaded the new 1.2 library. I did not make any changes to the sketch and just re-uploaded it… The door sensor does not work any more, it posts the initial “Open” status of the door and then nothing after that. Reverting back to Homie 1.1 with the exact same sketch works again.

I’ll stick with Homie 1.1 for now as it’s working :slight_smile:
I have 2 garage doors so next challenge for me is to work out how to have two door sensors in one sketch.

Keep up the great work!

Many thanks for this Marvin. My problems in fact were the result of a
series of misunderstandings:

First and foremost, I did not realise that I need to load the page, then
disconnect from the network with internet access, and re-connect to the
WiFi of the ESP8266. Now that I understand the procedure, it worked
perfectly.

Second, I did nevertheless manage to get my node working using a direct
upload – once I had realised that the “data” directory must be in the
folder with the current sketch, not the general Arduino directory (where
“tools” is located for instance).

Third, I thought the device ID would be replaced by the device name, which
is not the case – the device ID remains and as far as I understand cannot
be customised.

Fourth, it took me a while to realise that in the MQTT communication it is
the device ID and not the device name that it used to identify it.

But now that I have understood all these points (I hope!) correctly, I look
forward to many future applications using your framework, I have managed to
control an LED and read from a DHT22 sensor using one Wemos D1 mini so the
way forward is now clear!

Some of the above misunderstandings are just silly but I may not be alone
in all of them, perhaps they can provide some inspiration for updating your
wiki – which is great by the way.

Thanks & keep up the good work!

I test everything on real hardware before releasing a new version… And the door example still work for me! I’ll test it again but this is weird :pensive:

You did! [quote=“Tim_Young, post:39, topic:8674”]
I thought the device ID would be replaced by the device name, whichis not the case – the device ID remains and as far as I understand cannotbe customised.

Fourth, it took me a while to realise that in the MQTT communication it isthe device ID and not the device name that it used to identify it.
[/quote]

Well, in a previous iteration of the framework, the device ID was actually the name of the device. But someone pointed out:

Device should not report itself as “devices/[devicename]/” but instead
report itself as devices/[chipid]/$name to avoid
collision between devices set with same name

I think this is a right design choice: the risk of conflict is very low and you can still customize the name of the device, which is exposed on the API and on the MQTT broker as $name. Don’t you think?

Alright, I’ll try to explicit a few things up.

Thanks to all of you for your feedbacks!