Esphomelib - library to greatly simplify Home Assistant integration with ESP32

Ok, let me know if you need some testing. Hope I can help

Thanks that indeed works. However I would prefer for my node to get a IP from DHCP. Just for the upload it would be nice to set an ip since somehow the hassio is no able to resolve the hostname…

For the command line version that is pretty much already possible (using the --upload-port parameter). Problem is I don’t know 1. how to integrate such option into the dashboard visually and 2. how to do it in CSS/HTML (I’m still very suprised how I got the dashboard looking how it looks now in the first place :slight_smile:)

Great project. I am trying to migrate from ESPEasy and am looking for some advise or best practice:
I have a Wemos D1 Mini Pro and a BME280 sensor connected.

My configuration:

mqtt:
  ...
  topic_prefix: esphome/esp04_bedroom

This prefixes the MQTT messages with esphome just to separate them from other applications.

sensor:
  - platform: bme280
    address: 0x76
    temperature:
      id: esp04_bedroom_temperature
      name: Temperature
    humidity:
      id: esp04_bedroom_humidity
      name: Humidity
    pressure:
      id: esp04_bedroom_pressure
      name: Pressure
      filters:
        - lambda: return x / 0.9765179;
        - sliding_window_moving_average:
            window_size: 15
            send_every: 15
    # Result in 300s update with sliding window moving average filter
    update_interval: 20s

The id definition makes the MQTT messages easily distinguishable - that’s a good start.
However, when turning on MQTT auto discovery Home Assistant finds the three sensors, and their friendly name is taken from the configuration above. However, the entity ID is also produced from that same name, and because I already had a temperature sensor, the new one is now called sensor.temperature_2. When I add more of these, I’d get more entity IDs like temperature_3, temperature_4, etc.
I know I could rename my sensor in esphomelib for example ESP04 Bedroom Temperature to get HA to produce a better distinguishable entity ID, but then I would need to manually override the friendly name in HA. My understanding is that at the moment HA does not support MQTT sensors in its entity registry, so I can’t manually change the entity ID.
When manually defining MQTT sensors I usually set an entity_namespace but that does not seem to be possible in the MQTT discovery mode?

I am wondering how you guys deal with multiple sensors, MQTT discovery, entity IDs and friendly names?

Well it does look great indeed!

as fro the rotary encoder - is it possible to set the value also via mitt from home-assistant?

I usually just call all sensors with a long string like “Bedroom Temperature” and if I want to add them to a group called “Bedroom” i just manually override the friendly name in the Hass customize: section.

Side notes:

  • id: doesn’t do anything unless you plan to use these sensors in esphomelib automations. It’s just an internal identifier and has no effect on MQTT/the webserver.
  • If you have multiple sensors with the name Temperature on the same ESP, they will both publish on the same MQTT state topic (I believe it would be esp04/sensor/temperature/state in this case).

@snizzleorg Rotary encoders are sensors, so they only send states and you can’t manually set it. However, I think a solution to your problem would be a new differential: sensor filter. This new filter would compute the difference to the last value (i.e. the last rotary encoder value) and pass that on. So in your automation you could then have a light.turn_on call like this:

# pseudocode!
sensor:
  - platform: rotary_encoder
    id: my_encoder
    filters:
      - differential:
    on_value:
      - light.turn_on:
          id: my_light
          brightness: !lambda >-
            # x is the difference of the last encoder value to the new value
            return id(my_light).get_remote_values().get_brightness() + x / 100.0;

Do you think that would solve your problem?

1 Like

Thanks @OttoWinter

I solved this now on the home assistant side with an automation using something like:

{{  state.light.bedroom_lights.attributes.brightness + (trigger.to_state.state | int) - (trigger.from_state.state | int) }}

your solution seems more elegant though.

I’m curious as to why you are using light.turn_on though and not just a new sensor?

OK, so this is another good reason to go with a more elaborate sensor name and then override the friendly name in HA. I’ll give this approach a try.

Is it possible to store values somehow? I want to build an RFID reader that buzzes people in when the correct RFID is detected. So I need to store the RFIDs on the ESP.

Ideally it should be possible to “upload” the authorised RFIDs via MQTT.

@OttoWinter, Hi Otto,
With three of my sensors I am getting these strange pressure results:
image
I don’t know how to solve this. Same result with BMP180 sensor

Used esapeasy to check my sensors. No problems at all.
Used the same settings with the I2C port and this resulted in an error with the sensor address in esphomeyaml
Had to swap the i2c wiring and then it works with the strange pressure result.

I thought the differential filter is already existing. But it seems this is not the case yet? I think that this would be very welcome!

Hello @OttoWinter

First of all, thank you for great library, which helps to simplify work with Home Assistant.
I used it for a while, but now I need some more from the lib. Basically, i have ESP-01 based relay, which is being controlled by some weird way, not a standard GPIO, but writing some bytes sequence to serial port.
I’m not very familiar with complex C++ topics, so, i’m kind of stuck.
as far as i understand, I need to create custom BinaryOutput component, inherited from BinaryOutput, and overriding write_enabled() function with the code I need. Then use simple_switch component, to control my custom binary switch from HomeAssistant. Here is my code. It doesn’t work (surprise!). If you can explain or show some direction to dig into - it would be greatly appreciated.

#include "esphomelib.h"

using namespace esphomelib;

byte relON[] = {0xA0, 0x01, 0x01, 0xA2};
byte relOFF[] = {0xA0, 0x01, 0x00, 0xA1};
static const char *TAG = "RelaySwitch";

class RelayBinaryOutput : public Component, public output::BinaryOutput
{
  public:
    void write_enabled(bool value) override;
};

void RelayBinaryOutput::write_enabled(bool value)
{
    if (value)
    {
        ESP_LOGI(TAG, "Turning on the relay");
        Serial.begin(9600);
        Serial.write(relON, sizeof(relON));
        Serial.begin(115200);
    }
    else
    {
        ESP_LOGI(TAG, "Turning off the relay");
        Serial.begin(9600);
        Serial.write(relOFF, sizeof(relOFF));
        Serial.begin(115200);
    }
}

void setup()
{
    // put your setup code here, to run once:
    App.set_name("relay1");
    App.init_log();
    App.init_wifi("yyyy", "xxxxx");
    App.init_ota()->start_safe_mode();
    App.init_mqtt("192.168.55.29", "", "");
    auto *relay_switch = new RelayBinaryOutput();
    App.register_component(relay_switch);
    App.make_simple_switch("relay_state", relay_switch);

    App.setup();
}

void loop()
{
    App.loop();

}

Also, it may be makes sense to add more examples of custom components. This may also help people to contribute additional compinents.

Thank you.

Had a chance to play with this on some ESP32 boards I haven’t touched except for testing. I played around with doing a RGB LED and wow pretty damn easy. I just did the manual method on a computer that had the older version of Python installed, worked great. Impressed with those PWM drivers on the ESP32 compared to the ESP8266!

@brugk000 I think that error might have been caused by this bug here: https://github.com/OttoWinter/esphomelib/pull/98. Could you try with this and see if it’s working?

@Sergey_Morozik What exactly is not working? Compiling or running? When it’s about compiling, make sure to set use_build_flags to false in the esphomeyaml: section.

When it’s running:

  1. You’re initialising Serial with Serial.begin(9600) before the write and after that again. Is that intended?
  2. The init_log() line is also initialising the logs which could interfere with sending commands to your relay… I think you can disable the UART logs by setting the baud rate parameter to 0.

And yes I do want to write more guides. But there’s just so many things that I want to work on that I have to prioritise certain things. Custom sensors guides are a priority, but also take a heck of a long time to write + need to be updated each time I do an API change.

@digiblur Yep those LEDC drivers are pretty darn good :slight_smile:

@OttoWinter
Thanks for reply. No, it’s builds with no issues.

It just doesn’t do, what it supposed to do. I’m not even sure, if it calls write_enable() function. I’ve added some debug output before IF in write_enabled() function, and never got this output. Not sure, how else I can debug it.
It definitely subscribes and receives commands from MQTT, I see it in log.
But most likely, handler function never being called, or - called with wrong params. But it’s less likely, because, as I said

void RelayBinaryOutput::write_enabled(bool value)
Serial.println("Callback!");
{
    if (value)
    {

never outputs to console. And of course I see no reaction from relay.
So, I’m not sure, if I created component and use it correctly.
C++ style OOP is not my strongest skill…

Regarding Serial.setup.
Yes, the thing is, that there is some chip, that expects control sequence on UART on 9600. Then, after I finish sending sequence, I return Serial to 115200 back, to make sure library logging etc will work correctly.
Possible, there is some more elegant solution to change serial speed on the fly - but I didn’t find…

Regarding guides. Current one, you have on GitHub wiki is informative enough to create almost any sensor. It’s pretty nice and clear.
But completely opposite;osite situation, with creating some control (output) components. I expected it will be easier :slight_smile:

Stupid question maybe but can I run the IR reciever and IR transmitter on one ESP8266? (Or ESP32)

Basically I want to send an IR command from a remote that’ll trigger automation to fire out a bunch of IR commands one by one.

Thanks

Both should work fine at the same time :slight_smile: On the ESP8266 you however can’t receive IR codes while it’s sending, but I guess that’s not a big problem.

@Sergey_Morozik I will check that code later today. Two things that could at least partially explain the issue:

  • ESP_LOGI(TAG, "Turning on the relay") writes to the internal buffer of the hardware UART controller. When you call Serial.begin(9600) right afterwards the internal buffer might be cleared and you might not see the message in the logs.
  • The same with Serial.begin(115200);. It’s probably best to call Serial.flush(); right before both of these calls.

Thank you for reply. I finally resolved the issue.
Ended up with initialization serial on 9600 in setup function, and remove 9600/115200 switching.
At this point everything works great. Here is working code:

#include "esphomelib.h"

using namespace esphomelib;

byte relON[] = {0xA0, 0x01, 0x01, 0xA2};
byte relOFF[] = {0xA0, 0x01, 0x00, 0xA1};

class RelayBinaryOutput : public Component, public output::BinaryOutput
{
  public:

    void write_enabled(bool value) override;

};

void RelayBinaryOutput::write_enabled(bool value)
{
    if (value)
    {
        Serial.write(relON, sizeof(relON));
    }
    else
    {
        Serial.write(relOFF, sizeof(relOFF));
    }
}

void setup()
{
    // put your setup code here, to run once:
    App.set_name("relay1");
    App.init_log(1);
    App.init_wifi("xxxxxxx", "xxxxxxxx");
    App.init_ota()->start_safe_mode();
    App.init_mqtt("192.168.55.29", "", "");
    auto *relay_switch = new RelayBinaryOutput();
    App.register_component(relay_switch);
    relay_switch->write_enabled(true);
    App.make_simple_switch("relay_state", relay_switch);
    Serial.begin(9600);
    App.setup();
}

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

This relay module is pretty popular, so hopefully my experience will be helpful for somebody…

Tryed it but didn’t do the trick. Great work tho on this.
I am just waiting and testing some other things

As soon as it supports miflora…I’ll give it a go… that’s what I’m still missing