Klima Haier ESPHome - sensory

Panowie, prośba o wsparcie, bo cały wczorajszy dzień nie poradziłem sobie z tematem, który powinien zająć chwilkę.
Mam w domu klimatyzacje Haier, kiedyś zintegrowałem ją z HA za pomocą ESPHome - jest gotowy dodatek. Układ zaprogramowany - wsadzony w USB - działa.
W świąteczny okres wyciągnąłem z szuflady panel LCD na ESP32, bo zauważyła, że w ESPHome pojawił się odpowiedni wątek.

Początek poszedł gładko, oparłem się na konfiguracji opublikowanej w necie, przez chyba holenderskiego, fana HA.

Odczytanie temperatury i wilgotności z czujnika zigbee - bez kłopotu.
Trochę więcej czasu na odczytanie wartości zadanej temperatury z klimatyzacji “temperature”.

Bez kłopot sterownie oczekiwaną temperaturą klimatyzacji. No i wtedy się zaciąłem.
Cały dzień aby odczytać stan klimatyzacji “hvac_mode”. Bez skutku.
W pierwszej kolejności próbowałem zwykły sensor - tak jak “temperaturę”

  - platform: homeassistant
    id: clima_sensor
    entity_id: climate.ac_haier_01_haier_smartair2_climate_2
    attribute: "temperature" 
    on_value:
     then:
         - lvgl.label.update:
            id: aktualna_nastawa_temp
            text: 
              format: "  %.0f°C"
              args: ["id(clima_sensor).state"]  

  - platform: homeassistant
    id: clima_mode
    entity_id: climate.ac_haier_01_haier_smartair2_climate_2
    attribute: "hvac_mode" 
    on_value:
      then:
        - if:
            condition: 
              lambda: 'return id(clima_mode).state == 0x4;'
            then:  
              - lvgl.label.update:
                  id: climate_mode_graf
                  text_color: ${magenta}

Wpisane 0x4 - bo tak wynika z logów modułu klimatyzacji.
Potem pomyślałem, że to może tekst, więc pomyślał, że to może powinien być sensor tekstowy:

  - platform: homeassistant
    name: "HVACmode"
    entity_id: climate.ac_haier_01_haier_smartair2_climate_2
    attribute: "hvac_mode"
    id: hvac_mode_text_sensor     

  - platform: homeassistant
    name: "HVACstate"
    entity_id: climate.ac_haier_01_haier_smartair2_climate_2
    attribute: "hvac_value"
    id: hvac_state_text_sensor    

NIc nie pomaga. dołożyłem logi, aby widzieć co się dzieje.

  - interval: 5s
    then:
      - logger.log: "HVAC mode"
      - logger.log: "id(hvac_mode_text_sensor).state"    
      - logger.log:      
          format: "Current HVAC State TXT: %s"
          args: ["id(hvac_state_text_sensor).state.c_str()"]
      - logger.log:      
          format: "Current HVAC State: %f"
          args: ["id(clima_mode).state"]

Skutek taki, że przy logach gdzie oczekiwałbym tekstu mam nic,
A przy logach gdzie oczekiwałbym cyfry mam “nan”.
Doczytałem, że “nan” to złe formatowanie, ale próbowałem wszystkiego co przeczytałem i nic.
GPT - nie pomaga, kręci się w kółko.
Pozwalam sobie więc na ten wątek licząc na pomoc.

NaN to “Not a Number”, ale w szczególnym i częstym zbiegu okoliczności to po prostu brak wartości.

Integracja homeassistant w ESPHome zachowuje się tak, że zmienna otrzymuje wartość jedynie w momencie publikacji tej wartości w HA (czyli zasadniczo wartość musi się zmienić by została opublikowana, chyba że zmusisz encję w HA do cyklicznego publikowania stanu).

No tak, ale zmiana trybu pracy klimatyzacji nic nie daje. Cały czas “nan”. Jak w narzędziach deweloperskich patrzę na stany, to klima ma atrybut “hvac_modes” z “s” na końcu, ale dodanie tego nic nie zmienia.

Pokaż dokładnie co masz i co chcesz dokładnie wyciągnąć.

Nie mogło działać bez “s” na końcu… jeśli sprawdzasz stan nieistniejącego atrybutu to z pewnością nie ma poprawnych wskazań.

To po kolei. W narzędziach widzę taki widok.


Stąd moje próby również z atrybutem hvac_modes, ale czy będzie “s” czy nie to i tak nie mogę wyciągnąć tej informacji. To w odpowiedzi na pytanie co chce wyciągnąć - tryb pracy, czyli hvac_mode. Bez problemu wyciągam “temperature” - czyli ustawioną temperaturę.
Jak oczekuje stringu,

  - platform: homeassistant
    id: clima_mode
    entity_id: climate.ac_haier_01_haier_smartair2_climate_2
    attribute: "hvac_mode" 
    on_value:
      then:
        - logger.log:
            format: "Aktualny tryb HVAC: %s"
            args: ["id(clima_mode).state"]

to przy kompilacji mam taki komunikat:

error: format '%s' expects argument of type 'char*', but argument 5 has type 'double' [-Werror=format=] $dry,

Jak zrobię w ten sposób:

  - platform: homeassistant
    id: clima_mode
    entity_id: climate.ac_haier_01_haier_smartair2_climate_2
    attribute: "hvac_mode" 
    on_value:
      then:
        - logger.log:
            format: "Aktualny tryb HVAC: %.0f"
            args: ["id(clima_mode).state"]

To się kompiluje, ale w logach nie mam nic, również przy zmianie stanu. Odświeża mi się za to wartość ustawionej temperatury, bo jest inna dla chłodzenia a inna dla grzania:

[11:28:03][D][homeassistant.sensor:022]: 'climate.ac_haier_01_haier_smartair2_climate_2::temperature': Got attribute state 21.00
[11:28:03][D][sensor:094]: 'clima_sensor': Sending state 21.00000  with 1 decimals of accuracy

Powinno być tak:

# Example configuration entry ESPHome
sensor:
  - platform: homeassistant
    id: clima_mode
    entity_id: climate.ac_haier_01_haier_smartair2_climate_2

    on_value:

bo status encji climate.ac_haier_01_haier_smartair2_climate_2 to heat czyli aktualny tryb pracy, jeden z możliwych trybów do wyboru jakie są dostępne w atrybutach hvac_modes.

No tak, nigdy bym na to nie wpadł.
Ale co nie znaczy, że posunąłem się do przodu, bo nie wiem jak to teraz porównać

Takie działanie:

  - platform: homeassistant
    id: clima_mode
    entity_id: climate.ac_haier_01_haier_smartair2_climate_2
    on_value:
      then:
        - if:
            condition:
              lambda: 'return id(clima_mode).state == "heat";'
            then:  
              ........

daje taki błąd:

error: comparison with string literal results in unspecified behavior [-Werror=address]
               lambda: 'return id(clima_mode).state == "heat";'

próbowałem też coś takiego;

            lambda: 'return id(clima_mode).state == CLIMATE_MODE_HEAT;'

Nie wyrzuca błędu podczas kompilacji, ale nie działa.
Mam w logach za to coś takiego:

[13:43:18][W][homeassistant.sensor:015]: 'climate.ac_haier_01_haier_smartair2_climate_2': Can't convert 'heat' to number!

Ale nie wiem, co z tym i dlaczego. choć jasno z tego wynika, że informacja, że tryb jest 'heat" jest dostępna.
Tylko jak to wybadać?

Edit moderator:
Po raz ostatni poprawiam post w celu poprawnego zamieszczania kodu w postach.

Sensor z natury to wartość liczbowa (number) a Ty próbujesz porównać text (string), jest o tym informacja w błędach:
error: comparison with string literal results in unspecified behavior
Can't convert 'heat' to number!
dlatego nie wiem czy zaproponowany przeze mnie przykład działa poprawnie, tego nie potwierdziłeś - nie napisałeś. W zależności od tej informacji można próbować porównywać wartość typu raw czyli Sensor Component — ESPHome albo zmienić koncepcję i zastosować Home Assistant Text Sensor — ESPHome albo zastosować filtr 'x.c_str()' albo tak:

if (strcmp(id(ZMIENNA).state.c_str(), "heat") == 0) {
  ..... );
}

Jeszcze mam kilka pomysłów ale wariacji i if’ów jest za dużo aby to opisywać, trzeba mieć działający punkt odniesienia :grin:.

To:

if (strcmp(id(ZMIENNA).state.c_str(), "heat") == 0) {
  ..... );
}

Daje takie błąd:

error: request for member 'c_str' in 'clima_mode->esphome::homeassistant::HomeassistantSensor::<anonymous>.esphome::sensor::Sensor::state', which is of non-class type 'float'
             lambda: 'return (strcmp(id(clima_mode).state.c_str(), "cool") == 0);'

Próbowałem coś takiego:

lambda: 'return String(id(clima_mode).state).c_str() == "off";'

A to daje taki błąd:

error: no matching function for call to 'std::__cxx11::basic_string<char>::basic_string(float&)'
             lambda: 'return String(id(clima_mode).state).c_str() == "heat";'

Porównywanie z cyframi, też nie działa. Zacząłem myśleć, że błąd jest po stronie esphome w Haier, ale przecież z pulpitu HA normalnie widzę stany klimatyzacji.

OK, już się nauczyłem, przepraszam i Spokojnych Świąt.

To proponuję sprawdzić na text_sensor. Niestety nie dam rady tego sprawdzić u siebie z powodu braku czasu - encję typu climate w HA mam, ESP w szufladzie też jakieś leży ale czasu ciągle brakuje.

Działa. Dziękuje.
Wcześniej też próbowałem txt_sensor, ale z atrybutem.
Przy okazje tego mojego projektu mam jeszcze inne pytania, ale to już po Świętach i w osobnych wątkach.

Spokojnych Świąt.

Zadziałało tak:

text_sensor:
  - platform: homeassistant
    id: clima_mode_txt
    entity_id: climate.ac_haier_01_haier_smartair2_climate_2   
      - if:
          condition: 
            lambda: 'return id(clima_mode_txt).state == "heat";'
          then:
             - logger.log: "Tryb pracy: heat"
      - if:
          condition: 
            lambda: 'return id(clima_mode_txt).state == "cool";'
          then:
             - logger.log: "Tryb pracy: cool"
      - if:
          condition: 
            lambda: 'return id(clima_mode_txt).state == "off";'
          then:
             - logger.log: "Tryb pracy: off"    
[17:02:54][D][text_sensor:064]: 'ha2esp_date': Sending state 'Poniedziałek, 23.12'
[17:02:54][D][main:1179]: Tryb pracy: heat