Number to Text

I need help.
For two days, I’ve been trying to write the value of a numeric component to a text sensor using

        - text_sensor.template.publish:
            id: pool_anzeige
            state: {{ states.number.pool_hysterese.state}}  

It works without problems:

        - text_sensor.template.publish:
            id: pool_anzeige
            state: "AUTOMATIK :"    

It works in Home Assistant, too.
In the Template-Editor:

{{ states.number.pool_hysterese.state}}

The result is: 3.0 (string)

I tried using lambdas and conversions, but to no avail.

ESPHome does not use jinja templates it uses lambdas.

        - text_sensor.template.publish:
            id: pool_anzeige
            state: !lambda "return id(my_number).state;"

Also you need to import the number into ESPHome from Home Assistant (assuming the number was not created in the ESPHome device).

e.g.

sensor:
  - platform: homeassistant
    id: my_number
    entity_id: number.pool_hysterese

The number was created in ESPHome.

  - platform: template
    name: "Hysterese_"  
    id: hyst_
    optimistic: true
    min_value: 0
    max_value: 6
    step: 1
    restore_value: true

With:

        - text_sensor.template.publish:
            id: pool_anzeige
            state: !lambda "return id(hyst_).state;"  
error: could not convert 'hyst_->esphome::template_::TemplateNumber::<anonymous>.esphome::number::Number::state' from 'float' to 'std::string' {aka 'std::__cxx11::basic_string<char>'}
  113 |             state: !lambda "return id(hyst_).state;"
      |              ~~~~~~~^~~~~
      |                     |
      |                     float
*** [.pioenvs/pool-127-esp/src/main.cpp.o] Error 1

Try with:
String(id(hyst_).state)

error: could not convert 'String(hyst_->esphome::template_::TemplateNumber::<anonymous>.esphome::number::Number::state)' from 'String' to 'std::string' {aka 'std::__cxx11::basic_string<char>'}
  113 |             state: !lambda "return String(id(hyst_).state);"
      |              ^~~~~~~~~~~~~~~~~~~~
      |              |
      |              String

I swear, converting from one type to another in ESPHome is like dark magic. You don’t mention which platform you’re using for compilation (arduino versus ESP-IDF), and it matters. String might work on one platform but not the other. I convert a number to a string for one of my devices that uses ESP-IDF and am able to use:

return id(ha_time).state.c_str();

So for your case you might try:

state: !lambda "return id(hyst_).state.c_str();"

I agree that

1 Like

This lambda should work, you could use it in your publish or just directly in the template text sensor:

    lambda: |-
      char buffer[50]; // Allocate sufficient buffer size
      sprintf(buffer, "%.1f", id(hyst_).state); // Format to 1 decimal places.  Add any other formatting using printf syntax
      std::string str(buffer); // Convert char array to string
      return str;

Sorry,
I haven’t been doing this long; I wasn’t aware there were two different platforms.

error: request for member 'c_str' in 'hyst_->esphome::template_::TemplateNumber::<anonymous>.esphome::number::Number::state', which is of non-class type 'float'
  113 |             state: !lambda "return id(hyst_).state.c_str();"

Processing pool-127-esp (board: d1_mini; framework: arduino; platform: platformio/[email protected])

#zoogara
I used it like this:

       - text_sensor.template.publish:
            id: pool_anzeige
            state:
            lambda: |-
              char buffer[50]; // Allocate sufficient buffer size
              sprintf(buffer, "%.1f", id(hyst_).state); // Format to 1 decimal places.  Add any other formatting using printf syntax
              std::string str(buffer); // Convert char array to string
              return str; 

Error:

  on_multi_click: 
    - timing: 
        - ON for at most 1s
        - OFF for at most 1s
        - ON for at most 1s
        - OFF for at least 0.2s
      then: 
        - number.increment: minddiff_
    - timing: 
        - ON for at most 1s
        - OFF for at least 0.5s
      then: 
        - number.increment: hyst_
        - text_sensor.template.publish: 
            id: pool_anzeige
            
            Must be string, got <class 'NoneType'>. did you forget putting quotes around the value?.
            state: 
            
            [lambda] is an invalid option for [text_sensor.template.publish]. Please check the indentation.
            lambda: |-
              char buffer[50]; // Allocate sufficient buffer size
              sprintf(buffer, "%.1f", id(hyst_).state); // Format to 1 decimal places.  Add any other formatting using printf syntax
state: !lambda: |-
   ....         
          

This is how it works:

            id: pool_anzeige
            state: !lambda |-
                      char buffer[50]; // Allocate sufficient buffer size
                      sprintf(buffer, "%.1f", id(hyst_).state); // Format to 1 decimal places.  Add any other formatting using printf syntax
                      std::string str(buffer); // Convert char array to string
                      return str; 

Thank you so much for your help.
I couldn’t have done it alone.

Can be simplified to:

return str_sprintf("%.1f", id(hyst_).state);

1 Like

Value typing is far too complicated for a system with the goal of making ESP development easy. The reason I use ESPHome is so that I don’t have to learn C.

I still only have a partial understanding of how this enables me to write to my video projector’s UART:

        - uart.write:
            id: projector
            # e.g. data: "KEY 16\r\n"
            data: !lambda |-
              std::string str = command;
              std::vector<uint8_t> vec(str.begin(), str.end());
              return vec;
2 Likes