Création d'un sensor "status" avec plusieurs état depuis un topic MQTT

Mon problème

Je souhaiterais créer un sensor status qui peut avoir plus de 20 états différents et qui proviendra d’un topic MQTT

Ma configuration

Je viens d’installer un module maison fourni par Razmoket d’un autre forum sur mon robot tondeuse Husqvarna (mon robot est tellement vieux que je ne peux pas passer par l’API Husqvarna et son intégration).
Ce module émet ces informations sur un broker MQTT sous différent topics.

Je voudrais pouvoir créer un sensor sous HA qui me traduirait les codes reçus sur le topic Automower/AM_G2/State/Status comme ceci :

code MQTT Description code sensor
18 Batterie faible low_batt
1014 En charge in_charge
1002 En tonte in_mowing

:warning: la liste des codes est assez longues, au moins 20 codes connus aujourd’hui et il m’en manque

J’ai regardé un peu la doc des sensors créés via MQTT mais j’ai un peu de mal à comprendre comment je peux faire la traduction des codes.
Est-ce que je dois faire comme cela :

sensor:
  - platform: mqtt
    name: "Status Tondeuse"
    state_topic: "Automower/AM_G2/State/Status"
    value_template: |-
      {% if states(entity_id) == 18 %}
        {{ value | low_batt }}
      {% else %}
        {% if states(entity_id) == 1014 %}
          {{ value | in_charge }}
        {% else %}
          {% if states(entity_id) == 1002 %}
            {{ value | in_mowing }}
          {% else %}
            {% if states(entity_id) == 1002 %}
              {{ value | xxxxxxx  }}
            {% else %}
              {{ value | unknown_code }}
            {% endif %}
          {% endif %}
        {% endif %}
      {% endif %}

Je me vois pas faire ça pour plus de 20 cas, ça va devenir illisible …
Est-ce qu’il y aurait un autre moyen ?

Salut.

Il n’y a pas tellement plus souple.
Tu peux améliorer un peu le template avec soit

If
Elif
Elif
...
Else

C’est plus lisible que les if/else imbriqués

Soit avec la fonction map

Mais à part ça…

1 « J'aime »

Un truc de ce genre là :

sensor:
  - platform: mqtt
    name: "Status Tondeuse"
    state_topic: "Automower/AM_G2/State/Status"
    value_template: |-
      {% set mapper =  {
          '18' : 'low_batt',
          '1002' : 'in_mowing',
          '1014' : 'in_charge',
          ...
          }
      %}
      {% set state = <_qu_est-ce_que_je_mets_ici> %}
      {{ mapper[state] if state in mapper else 'Unknown' }}

Mais je vois pas ce que je mets dans la ligne {% set state = ... %} :thinking:

Le tableau mapper permet la correspondance entre la valeur 18 pour que ça retourne low_batt, avec 1002 pour avoir in_moving etc…
Sachant que la dernière ligne mapper[state] équivaut à donne moi la valeur de mapper[] correspondant à state, tu as pas une idée de par quoi remplacer <_qu_est-ce_que_je_mets_ici> ?

Je te donne une piste (syntaxiquement c’est moche leur exemple)

:thinking:

Je pencherais pour value mais :disappointed_relieved:

Ce qui donnerait :

sensor:
  - platform: mqtt
    name: "Status Tondeuse"
    state_topic: "Automower/AM_G2/State/Status"
    value_template: |-
      {% set mapper =  {
          '18' : 'low_batt',
          '1002' : 'in_mowing',
          '1014' : 'in_charge',
          ...
          }
      %}
      {% set state = value %}
      {{ mapper[state] if state in mapper else 'Unknown' }}

Et comment s’appellera ce sensor ? (le nom que l’on retrouvera dans les outils de développement).
Est-ce que je peux mettre un friendly name plutôt comme ceci :

sensor:
  - platform: template
    sensors:
      automower_status:
        friendly_name: "Status Tondeuse"
        platform: mqtt
        state_topic: "Automower/AM_G2/State/Status"
        value_template: |-
          {% set mapper =  {
              '18' : 'low_batt',
              '1002' : 'in_mowing',
              '1014' : 'in_charge',
              ...
              }
          %}
          {% set state = value %}
          {{ mapper[state] if state in mapper else 'Unknown' }}

C’est ça. Attention quand même à ce que donne le MQTT brut… (json, valeur ?)
Pour valider tu peux commencer par créer un sensor qui sort juste 18 (sans la partie mapper)

C’est écrit dans ton exemple => name (sans les espaces qui sont remplacés par _)

Oui mais en plus, le name est indispensable ça sera l’équivalent de l’ID ici

A l’occasion si tu as le tableau avec la totalité des codes je suis preneur, ça peut correspondre aux codes de robonect

Voici les codes et leur description que le développeur m’a gentiment mis à disposition :

Listing des codes
code MQTT Description code sensor
NULL Initialisation du serveur server_initialization
null Initialisation du serveur server_initialization
- Module wifi non détecté wifi_module_not_detected
0 Pas de connection wifi no_wifi_connection
1 wifi connecté wifi_connected
2 2 2
4 4 4
6 Moteur de roue gauche bloqué left_wheel_blocked
8 Moteur de roue droit bloqué right_wheel_blocked
10 10 10
12 Pas de signal de boucle no_loop_signal
14 Coincée trapped
16 Hors zone de tonte outside_perimeter_zone
18 Batterie faible low_battery
20 20 20
22 22 22
24 Dérapée skidding
26 Station de charge inaccessible base_station_unreachable
28 Nécessite charge manuelle needs_manual_load
30 Disque de coupe bloqué cutting_disk_blocked
32 Disque de coupe freiné cutting_disk_constrained
34 Tondeuse soulevée mower_lifted
36 36 36
38 Tondeuse retournée mower_upside_down
40 40 40
42 Capteur boucle AR défectueux ar_loop_sensor_defect
44 44 44
46 46 46
48 48 48
50 50 50
52 Pas de contact à la station de charge no_contact_at_charging_station
54 Pin expiré pin_expired
56 Capteur collision gauche défectueux left_shock_sensor_defective
58 Capteur collision droit défectueux right_shock_sensor_defective
60 60 60
1000 Sortie station station_output
1002 Tonte mowing
1004 1004 1004
1006 Démarrage tondeuse mower_start
1008 Démarrage tonte mowing_start
1010 1010 1010
1012 Signal démarrage de tonte signal_mowing_start
1014 Chargement charging
1016 Attente dans la station wait_in_station
1018 1018 1018
1020 1020 1020
1022 1022 1022
1024 Entrée dans la station enter_in_station
1026 1026 1026
1028 1028 1028
1030 1030 1030
1032 1032 1032
1034 1034 1034
1036 Mode « carré » square_mode
1038 Bloquée blocked
1040 Collision collision
1042 Recherche search
1044 Stop stop
1046 1046 1046
1048 Arrimée anchored
1050 Sortie de la station exit_station_
1052 Pressez YES pour démarrer press_yes_to_start
1054 1054 1054
1056 En attente (Mode Manuel/Home) waiting_(mode_manuel/home)
1058 Suivi du cable guide following_guide
1060 N-Signal trouvé n-signal_detected
1062 Zone éloignée inaccessible unreachable_zone
1064 Recherche search
1066 Problème de suivi zone éloignée far_zone_follow-up_problem
1068 1068 1068
1070 Suivi du guide 1 guide_1_follow-up
1072 Suivi du guide 2 guide_2_follow-up
1074 1074 1074
1076 1076 1076
1078 1078 1078
1080 1080 1080

Ces codes correspondent aux retours du status du firmware du module de Razmoket du forum automower.fans, je ne suis donc pas sûr qu’ils matchent avec les codes du Robonect :thinking:

En tout cas, si vous trouvez la description d’un code inconnu, n’hésitez pas à le remonter à Razmoket ou Poil de carotte du forum https://www.automower-fans.com/ ou à moi-même, je leur transmettrai.

et le code du mapper qui en découle :

le code du mapper
platform: mqtt
name: "automower status"
state_topic: "Automower/AM_G2/State/Status"
value_template: |-
  {% set mapper = {
      'NULL'   : 'server_initialization',
      'null'   : 'server_initialization',
      '-'      : 'wifi_module_not_detected',
      '0'      : 'no_wifi_connection',
      '1'      : 'wifi_connected',
      '6'      : 'left_wheel_blocked',
      '8'      : 'right_wheel_blocked',
      '12'     : 'no_loop_signal',
      '14'     : 'trapped',
      '16'     : 'outside_perimeter_zone',
      '18'     : 'low_battery',
      '24'     : 'skidding',
      '26'     : 'base_station_unreachable',
      '28'     : 'needs_manual_load',
      '30'     : 'cutting_disk_blocked',
      '32'     : 'cutting_disk_constrained',
      '34'     : 'mower_lifted',
      '38'     : 'mower_upside_down',
      '42'     : 'ar_loop_sensor_defect',
      '52'     : 'no_contact_at_charging_station',
      '54'     : 'pin_expired',
      '56'     : 'left_shock_sensor_defective',
      '58'     : 'right_shock_sensor_defective',
      '1000'   : 'station_output',
      '1002'   : 'mowing',
      '1006'   : 'mower_start',
      '1008'   : 'mowing_start',
      '1012'   : 'signal_mowing_start',
      '1014'   : 'charging',
      '1016'   : 'wait_in_station',
      '1024'   : 'enter_in_station',
      '1036'   : 'square_mode',
      '1038'   : 'blocked',
      '1040'   : 'collision',
      '1042'   : 'search',
      '1044'   : 'stop',
      '1048'   : 'anchored',
      '1050'   : 'exit_station_',
      '1052'   : 'press_yes_to_start',
      '1056'   : 'waiting_(mode_manuel/home)',
      '1058'   : 'following_guide',
      '1060'   : 'n-signal_detected',
      '1062'   : 'unreachable_zone',
      '1064'   : 'search',
      '1066'   : 'far_zone_follow-up_problem',
      '1070'   : 'guide_1_follow-up',
      '1072'   : 'guide_2_follow-up'
    }
  %}
  {% set state = value %}
  {{ mapper[state] if state in mapper else 'Unknown' }}
1 « J'aime »

@Pulpy-Luke , dans mes recherches, je suis tombé sur cette page, je sais pas si tu as vu la liste des codes de robonect en fin de page. Elle n’est pas très longue mais on ne sait jamais …

1 « J'aime »

Salut
Merci à toi. En fait j’ai déjà cette liste d’état
Fonctionnellement parlant, j’ai déjà tout à travers la récupération via MQTT : état + valeur texte (traduite en français) mais c’est comme toi j’ai les infos quand le code apparait