Décoder une trame reçue par UART

Bonjour et bonne année a tous,
J’ai deux applications que je voulais utiliser sous ESPHome pour l’intégrer à HA mais j’avoue que je sèche sur le sujet.

Au départ je pensais que ESPHome permettait juste de créer des capteurs ou commandes en WIFI pour HA mais j’ai l’impression qu’on peut y mettre de intelligence.

J’ai un panneau solaire avec un micro-onduleur qui envoie les infos de productions sur un lien UART. J’ai fait un sketch arduino pour récupérer ces infos et les afficher sur un ecran OLED. Je voudrais donc brancher ce lien sur un WemosD1mini sur l’UART HW (ou SW ?) pour renvoyer ces infos vers HA.
La deuxième application c’est un compteur geiger en kit qui envoi lui aussi ses infos sur un lien UART.

Dans les deux cas, il faut faire l’acquisition et scanner la chaîne pour retourner les valeurs.
Si j’ai bien configuré un UART je ne sais pas comment parser les chaînes reçues pour faire ressortir les valeurs.

Est-ce que quelqu’un peut m’expliquer comment faire ça ? Il faut passer par un custom component ?

Est-ce que vous connaissez un cours, ou un tuto un peu pousser pour comprendre comment ESPHome se programme ?

Bonjour,

je ne sais pas si tu a déjà cherché et trouvé cela :

je pense qu’avec cela et en mode debug tu devrais trouver et pouvoir lire les trames reçues …? a tester

sinon,
si tu a déjà fait du développement sur arduino, tu peux, avec peu de conversion le mettre sur un wemos et envoyer directement les infos a HA via mqtt …

Bonjour et merci de ta réponse.

En pratique oui j’avais configuré le module UART Bus mais je ne voyais rien remonter ni dans HA ni dans les logs.

J’ai continué a fouiller et j’ai creuser ces pistes :
https://esphome.io/custom/uart.html

https://esphome.io/custom/uart.html

Après la lecture de tout ça (et même un peu plus…) je pense que je commence a entrevoir la philo de EspHome :slight_smile:

J’arrive maintenant a lire ce qui remonte de l’uart, le « décommuter » en plusieurs variables et les renvoyer dans HA :slight_smile: :smiley:

Du coup je partage !

esphome:
  name: test-uart
  includes:
    - uart_read_line_sensor.h
    
esp8266:
  board: d1_mini

# Enable logging
logger:
  level: DEBUG 
  baud_rate: 115200 

# Enable Home Assistant API
api:


ota:
  password: "xxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.0.53
    gateway: 192.168.0.1
    subnet: 255.255.255.0
  output_power: 10dB
  fast_connect: true
  power_save_mode: HIGH

web_server:
  port: 80

captive_portal:

switch:
  - platform: gpio
    pin: D4
    inverted: true
    name: "LED"

uart:
  id: uart_bus
#  tx_pin: D8
  rx_pin: D7
  baud_rate: 9600
  debug:
    direction: BOTH
    dummy_receiver: false
    after:
      delimiter: "\n"
    sequence:
      - lambda: UARTDebug::log_string(direction, bytes);


sensor:
- platform: custom
  lambda: |-
    auto my_geiger_sensor = new UartReadLineSensor(id(uart_bus));
    App.register_component(my_geiger_sensor);
    return {my_geiger_sensor->CPM_sensor, my_geiger_sensor->Sivert_sensor, my_geiger_sensor->VCC_sensor };
  sensors:
  - name: "GEIGER CPM Sensor"
    unit_of_measurement: CPM
    accuracy_decimals: 0
  - name: "GEIGER Sivert Sensor"
    unit_of_measurement: uSv/h
    accuracy_decimals: 3
  - name: "GEIGER Vcc Sensor"
    unit_of_measurement: V
    accuracy_decimals: 2

Et dans le même répertoire le fichier uart_read_line_sensor.h

#include "esphome.h"

#define BUFFER_LENGTH 32

  /*
        Classe UartReadLineSensor : 
            Classe de lecture et décommutation des données provenant du Geiger Kit;
            Format : chaine CPM, valeur uSv/h, valeur Vcc
            1ère chaine : "CPM,uSv/h,Vcc"
    */

class UartReadLineSensor : public Component, public UARTDevice, public Sensor {

//----------------------------------------------------------------------------
 public:
  UartReadLineSensor(UARTComponent *parent) : UARTDevice(parent) {
  /*
        Constructeur : On initialise les variables
    */
    buffer[0] = 0;
    CPM = 0;
    Siv = 0.0;
    Vcc = 0.0;
  }

  /*
        Déclarations publiques pour remonter chaque grandeur
    */
    Sensor *CPM_sensor = new Sensor();
    Sensor *Sivert_sensor = new Sensor();
    Sensor *VCC_sensor = new Sensor();

//----------------------------------------------------------------------------
  void setup() override {
    // nothing to do here
  }

//----------------------------------------------------------------------------
  /*
      Récupère les caractères recus sur l'UART dans un cahr * buffer
    */
  int readline(int readch, char *buffer, int len)
  {
    static int pos = 0;
    int rpos;

    if (readch > 0) {
      switch (readch) {
        case '\n': // Ignore new-lines
//          break;
        case '\r': // Return on CR
          rpos = pos;
          pos = 0;  // Reset position index ready for next time
          return rpos;
        default:
          if (pos < len-1) {
            buffer[pos++] = readch;
            buffer[pos] = 0;
          }
      }
    }
    // No end of line has been found, so return -1.
    return -1;
  }

//----------------------------------------------------------------------------
  /*
      Boucle principale
    */
  void loop() override {

// Si caractère dispo sur l'UART
    while (available()) {
    
    // Récupère le tout dans buffer
        int lng = readline(read(), buffer, BUFFER_LENGTH);
    
    // Si valide
        if(lng > 0) {
            ESP_LOGD("UartReadLineSensor", "RX message: %s",buffer);
            
            // Vérif que ce n'est pas la première chaine
            if (strcmp(buffer,"CPM,uSv/h,Vcc") == 0) {
                return;
            }
            
            // remplace les ',' par ' ' 
            for (int i=0; i<lng; i++) {
                if (buffer[i] == ',') {
                    buffer[i] = ' ';
                }
            }

            ESP_LOGD("UartReadLineSensor", "RX message: %s",buffer);

            // récupère les valeurs dans la chaine
            int nbArg = sscanf(buffer, "%d %f %f",&CPM, &Siv, &Vcc);

            ESP_LOGD("UartReadLineSensor", "nbArg: %d",nbArg);
            ESP_LOGD("UartReadLineSensor", "CPM: %d",CPM);
            ESP_LOGD("UartReadLineSensor", "Siv: %f",Siv);
            ESP_LOGD("UartReadLineSensor", "Vcc: %f",Vcc);

            // Renvoie les valeurs des grandeurs
            CPM_sensor->publish_state(CPM);
            Sivert_sensor->publish_state(Siv);
            VCC_sensor->publish_state(Vcc);
      }
    }
  }

private:
    char buffer[BUFFER_LENGTH];
    int CPM;
    float Siv;
    float Vcc;
};
1 « J'aime »