homieiot / homie-esp8266

💡 ESP8266 framework for Homie, a lightweight MQTT convention for the IoT
http://homieiot.github.io/homie-esp8266
MIT License
1.36k stars 308 forks source link

setProperty in setupHandler fails with more than 2 properties in 2.0.0-dev #266

Closed egon0 closed 7 years ago

egon0 commented 7 years ago

for testing purposes i extended the TemperatureSensor sketch like this:

#include <Homie.h>

#define FW_NAME "awesome-thp"
#define FW_VERSION "0.0.1"

/* Magic sequence for Autodetectable Binary Upload */
const char *__FLAGGED_FW_NAME = "\xbf\x84\xe4\x13\x54" FW_NAME "\x93\x44\x6b\xa7\x75";
const char *__FLAGGED_FW_VERSION = "\x6a\x3f\x3e\x0e\xe1" FW_VERSION "\xb0\x30\x48\xd4\x1a";
/* End of magic sequence for Autodetectable Binary Upload */

const int TEMPERATURE_INTERVAL = 300;

unsigned long lastTemperatureSent = 0;

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

void setupHandler() {
  temperatureNode.setProperty("unit").send("C");
  humidityNode.setProperty("unit").send("%");
  pressureNode.setProperty("unit").send("hPa");
}

void loopHandler() {
  if (millis() - lastTemperatureSent >= TEMPERATURE_INTERVAL * 1000UL || lastTemperatureSent == 0) {
    float temperature = 22; // Fake temperature here, for the example
    Homie.getLogger() << "Temperature: " << temperature << " °C" << endl;
    temperatureNode.setProperty("degrees").send(String(temperature));
    lastTemperatureSent = millis();
  }
}

void setup() {
  Serial.begin(115200);
  Serial << endl << endl;
  Homie_setFirmware(FW_NAME, FW_VERSION);
  Homie.setSetupFunction(setupHandler).setLoopFunction(loopHandler);

  temperatureNode.advertise("unit");
  temperatureNode.advertise("degrees");

  humidityNode.advertise("unit");
  humidityNode.advertise("percent");

  pressureNode.advertise("unit");
  pressureNode.advertise("hPa");

  Homie.setup();
}

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

as soon as i add the third Node (in my case named pressureNode) the setProperty calls in the setupHandler fail silently for all nodes and the unit property is never propagated. if i remove the pressureNode stuff, the two remaining unit properties for temperatureNode and humidityNode get propagated correctly.

egon0 commented 7 years ago

with a small workaround, all values, properties etc. in one node everything works (but its a little bit ugly imho):

#include <Homie.h>

#define FW_NAME "awesome-thp"
#define FW_VERSION "0.0.1"

/* Magic sequence for Autodetectable Binary Upload */
const char *__FLAGGED_FW_NAME = "\xbf\x84\xe4\x13\x54" FW_NAME "\x93\x44\x6b\xa7\x75";
const char *__FLAGGED_FW_VERSION = "\x6a\x3f\x3e\x0e\xe1" FW_VERSION "\xb0\x30\x48\xd4\x1a";
/* End of magic sequence for Autodetectable Binary Upload */

const int TEMPERATURE_INTERVAL = 10;

unsigned long lastTemperatureSent = 0;

HomieNode thpNode("thp", "thp");

void setupHandler() {
  thpNode.setProperty("t-unit").send("C");
  thpNode.setProperty("h-unit").send("%");
  thpNode.setProperty("p-unit").send("hPa");
  thpNode.setProperty("l-unit").send("lux");
}

void loopHandler() {
  if (millis() - lastTemperatureSent >= TEMPERATURE_INTERVAL * 1000UL || lastTemperatureSent == 0) {
    float temperature = 22; // Fake temperature here, for the example
    float humidity = 54.12;
    float pressure = 1001.34;
    float lumi = 899;
    Homie.getLogger() << "Temperature: " << temperature << " °C" << endl;
    Homie.getLogger() << "Humidity: " << humidity << " %" << endl;
    Homie.getLogger() << "Pressure: " << pressure << " hPa" << endl;
    Homie.getLogger() << "Luminance: " << lumi << " lux" << endl;
    thpNode.setProperty("degrees").send(String(temperature));
    thpNode.setProperty("percent").send(String(humidity));
    thpNode.setProperty("hpa").send(String(pressure));
    thpNode.setProperty("lux").send(String(lumi));
    lastTemperatureSent = millis();
  }
}

void setup() {
  Serial.begin(115200);
  Serial << endl << endl;
  Homie_setFirmware(FW_NAME, FW_VERSION);
  Homie.setSetupFunction(setupHandler).setLoopFunction(loopHandler);

  thpNode.advertise("t-unit");
  thpNode.advertise("degrees");

  thpNode.advertise("h-unit");
  thpNode.advertise("percent");

  thpNode.advertise("p-unit");
  thpNode.advertise("hpa");

  thpNode.advertise("l-unit");
  thpNode.advertise("lux");

  Homie.setup();
}

void loop() {
  Homie.loop();
}
brodtm commented 7 years ago

I have been running into the same problem too. One thing that I am noticing is that when I am in an environment that has a lot of APs the code does not work properly. When I am in an area with few access points the same code works as expected. e.g. 5 APs visible when running the 'WiFiScan' example vs 26 APs. Very frustrating to discover that tested code fails just by being in a different environment. I had to go down to a single HomieNode in this case!

marvinroger commented 7 years ago

I don't know what can be done at our level to solve that... Maybe change the Wi-Fi channel?

egon0 commented 7 years ago

I havn't found a relation with the channel or the number of wifis in the neighbourhood. Also with 1.5 the problem doesn't exist.

marvinroger commented 7 years ago

Related to https://github.com/marvinroger/homie-esp8266/issues/345