How change sensor value using lambda?

Hello
I trying to override some sensors’ state by using lambdas. I’m using ESPHome for monitoring my solar inverter through the modbus component. when there’s low sunlight, the inverter starts to shutdown, but never updates some values to 0 (or null) when shutting down.leaving my ESPHome with “old data” that will be never updated until the inverter turns on again during morning.
I been reading a specific register that always updates to whatever thing the inverter is doing (well, it’s called inverter status :stuck_out_tongue: )

I been reading a docs how-to accomplish this automation, but i’m kinda stuck, my code doesn’t update the sensor values.
TL;DR: The point is, when ESPHome receives the status “I’m shutting down”, set the state of some sensors to 0

  - platform: template
    id: conversion
    lambda: |-
      if ((id(estado).state = 0)) {
                id(generador).publish_state(0);
                id(voltajeac).publish_state(0);
                id(hertz).publish_state(0);
                id(corrienteac).publish_state(0);
                id(temp).publish_state(0);
                id(panel3a).publish_state(0);
                id(panel3v).publish_state(0);
                id(panel1a).publish_state(0);
                id(panel1v).publish_state(0);
                id(potenciasolardc).publish_state(0);
                return {};
                   }      

estado is the id of sensor where saves the inverter status. 0 is the state received when the inverter is preparing to shut down.

Any help is appreciated, thank you. :slight_smile:

It might be that you have to do this:
if ((id(estado).state == 0))

1 Like

Thank you for your reply, but that didn’t work. :frowning:

@thusassistint is right, you need the comparison operator == in this expression.

What happens? What is in your logs? Are you sure your estado state ever becomes zero? If you want us to help you please be a bit more verbose.

My bad @thusassistint!

It might be that you have to do this:
if ((id(estado).state == 0))

You were right, my mistake was a silly. :sweat_smile:
After that I made another (silly) mistake and I accidentally deleted the .state and at first it didn’t worked until I realized that. 🤦‍♂
With that, my code works now, but the I realized a new problem. There’s a wait window between the last reply and making the new request; during this time the inverter can shutdown and ESPHome wouldn’t receive any new data (corner case I think?). I think this kind of problem, I don’t think with my current code will work. Any idea of how to add some short-of timeout?

At first I tested it global variables and worked, then I realized i deleted the .state in estado ; that was the reason why the solution did not work for me. :sweat_smile:

Or not exactly a timeout.
Detecting a empty (null?) rx buffer would work too (and faster!). :thinking:

@SkateWarp
Hey, could you maybe help me in this matter?
I am also trying to manipulate a sensor value manually (by an MQTT message).
This is my sensor:

sensor:
  - platform: pulse_counter
    device_class: gas
    pin:
      number: D4
      mode: INPUT_PULLUP
    name: 'Gas Consumption'
    unit_of_measurement: 'm³/d'
    update_interval: 60s
    internal_filter: 10ms
    icon: 'mdi:fire'
    accuracy_decimals: 3
    filters:
      - multiply: 14.40 #0.01  # (1/100 pulses per m³)
      - sliding_window_moving_average:
          window_size: 1440
          send_every: 5
    total:
      id: gas_consumption_total
      unit_of_measurement: 'm³'
      device_class: gas
      name: 'Gas Consumption Total'
      icon: 'mdi:fire'
      accuracy_decimals: 2
      filters:
        - multiply: 0.01

And this is my MQTT lambda:

mqtt:
  on_message:
    topic: gasmeter/set_total_value
    qos: 0
    then:
    - lambda: |-
        float payload = esphome::parse_number<float>(x).value();
        id(gas_consumption_total).publish_state(payload);

By this I want to define a new value for the total pulse counter part of the sensor. But the sensor remains at it’s current value (0) :thinking::

[10:06:14][D][pulse_counter:180]: 'Gas Consumption': Total : 0 pulses
[10:06:14][D][sensor:126]: 'Gas Consumption Total': Sending state 0.00000 m³ with 2 decimals of accuracy

What am I missing?
Thank you!

Okay, in the meantime I think I have found a solution. I just call the specific service to set the total value:

mqtt:
  on_message:
    topic: gasmeter/set_total_value
    qos: 0
    then:
      - pulse_counter.set_total_pulses:
          id: gas_pulse_counter
          value: !lambda 'return esphome::parse_number<float>(x).value();'
1 Like