Modbus : Lecture bit au dela de l'adresse 1023

Bonjour,

J’ai un souci de zone mémoire qui ne peut pas être lue en binaire mais bien en mot.

Débuté il y a 25 ans, je me suis fait un système de domotique avec un automate Wago et une supervision que j’ai entièrement
écrite en VB et qui tourne sur un PC en 24/7
J’ai découvert HA il y a peu et je voudrais m’en servir pour avoir une interface sur GSM/Tablette (pas envie de tout ré-écrire sous Android)
et pour avoir un accès de l’extérieur.

J’ai configuré HA pour faire une communication modbus avec l’automate.
D’une manière générale ca fonctionne, mais j’ai un souci pour lire une zone mémoire.
Je voudrais lire QX052.05 mais il s’affiche en Unavailable

binary_sensors:
  - name: PLC_TestBit1349
        address: 1349   # QX052.05 = 512+16*52+05 = 1349
        slave: 1
        scan_interval: 2
        input_type: discrete_input

En faisant des tests par tatonements j’ai identifié que HA peut lire que jusqu’à l’adresse 1023, après ça devient Unavailable
Ce qui est vraiment étrange, c’est que si je vais lire la mémoire 52 au format mot ça passe.

     sensors:
      - name:      TestAna52
        address: 564   # 512+52
        slave: 1
        scan_interval: 2
        state_class: measurement
        unit_of_measurement: xx
        input_type: input
        data_type: int16
        scale: 1
        offset: 0
        precision: 1

Est-ce que quelqu’un aurait une explication ?
Il y a des limitations dans HA avec la lecture de bits ?
Ou alors il faut y accéder autrement qu’a partir de 512 ?
J’espère que non, je n’ai pas envie de devoir modifier le programme automate juste pour HA.

J’ai essayé discrete_input, input et coil : même résultat

Merci d’avance

1 « J'aime »

SAlut une piste peut etre
avec un ESP 32 et un firmware maison sous ESPHOME

je ne sais pas si il y a cette limitation

J’ai deja évoqué des cas où les adresses modbus sont décalés :
http://melec.rateauweb.eu/MELEC_V2/systeme/documentations/TGBT%20communicant/Documentation%20constructeur/WAGO/Adressage%20des%20données.pdf

Moi je lis du wago en modbus TCP aux adresses 12288 + index

A voir si tout simplement en fonction de la ref du wago c’est possible de lire au dela de 1023.

Est ce que tu y arrives avec un modbusdoctor par exemple, en dehors de HA pour valider la com et l’accès à la variable.

D’après cette doc les requêtes de type bit se font à l’adresse 4096 pas 256 à voir.

Je lis sans problème des adresses Modbus au delà de 1024:


0x1000 = 4096
0x4600 = 17920

1 « J'aime »

Hello,

HA (mais en fait pymodbus car c’est la librairie utilisée) peut lire au-delà de 1023:

- name: "energie_building"
  type: tcp
  host: 192.168.1.9
  port: 502
  sensors:
    - name: Building Serial Number
      unique_id: building_sn
      slave: 1
      address: 1280
      count: 5
      data_type: string
      scan_interval: 0 # read at HA start up only
      
    - name: Building Counter firmware
      unique_id: building_fw
      slave: 1
      address: 1536
      #count: 1
      scan_interval: 0 # read at HA start up only

    - name: Building data rt1
      unique_id: building_data_rt1
      slave: 1
      address: 0
      count: 32
      data_type: custom
      structure: ">7I9i"

    - name: Building active energy Data
      unique_id: building_active_energy_Data
      slave: 1
      address: 256
      count: 24
      data_type: custom
      structure: ">hihihihihihihihi"

Petit conseil, si tu lis beaucoup de valeur et qu’elles se suivent, lis en groupe et ensuite sépare avec un template.

Exemple, je lis 16 valeurs (7 entiers non signés et 9 entiers) avec un appel:

    - name: Building data rt1
      unique_id: building_data_rt1
      slave: 1
      address: 0
      count: 32
      data_type: custom
      structure: ">7I9i"

Et je crée des templates:

  - name: "building_V1N"
    state: "{{ states('sensor.building_data_rt1').split(',')[0] | multiply(0.001) | round(3) }}"
    state_class: total_increasing
    unit_of_measurement: "V"
  - name: "building_V2N"
    state: "{{ states('sensor.building_data_rt1').split(',')[1] | multiply(0.001) | round(3) }}"
    state_class: total_increasing
    unit_of_measurement: "V"
  - name: "building_V3N"
    state: "{{ states('sensor.building_data_rt1').split(',')[2] | multiply(0.001) | round(3) }}"
    state_class: total_increasing
    unit_of_measurement: "V"
  - name: "building_V12"
    state: "{{ states('sensor.building_data_rt1').split(',')[3] | multiply(0.001) | round(3) }}"
    state_class: total_increasing
    unit_of_measurement: "V"
  - name: "building_V23"
    state: "{{ states('sensor.building_data_rt1').split(',')[4] | multiply(0.001) | round(3) }}"
    state_class: total_increasing
    unit_of_measurement: "V"
  - name: "building_V31"
    state: "{{ states('sensor.building_data_rt1').split(',')[5] | multiply(0.001) | round(3) }}"
    state_class: total_increasing
    unit_of_measurement: "V"
   ## etc

Je suis pas expert en modbus (loin de là :smiley: ) mais QX052.05 ça veut pas dire le 5e bit de ta valeur QX052?

Est-ce que tu lis d’autres QX dans ton code?

Tu peux également utiliser python et essayer de lire ta valeur avec pymodbus et ensuite de voir ce que ça retourne et comment extraire juste l’information qui t’intéresse et comment la formatter:

1 « J'aime »

Merci à tous pour vos réponses rapides.

Tikismoke : A partir de 12288 ce sont les mémoires persistantes. Mon problème c’est pour la mémoire volatile.
Et d’après la doc ci-dessous, 4096 c’est QX256 or j’ai besoin du QX52
Pyroaction : Tu vas lire des mots, et effectivement je n’ai pas de problème avec les mots.
Cloom : Je n’ai pas besoin des autres bits du mot dans HA, mais merci de l’info.

Je pense avoir trouvé la réponse dans la doc ci-dessous.




On y voit qu’effectivement, quand on va lire en bit, on est limité aux 512 premiers bits (soit seulement 32 mots)
Les sorties commencent à 512, donc 512+512=1024. Voila l’explication de mon problème pour lire 1349.

Par contre je ne comprend pas pourquoi cette limite dans le protocole, d’autant que la prochaine zone utilisable est à 4096.
On perd de 1024 à 4096 alors qu’on en aurait bien besoin.

Et donc en résumé, il y a moyen de lire et écrire des mots aussi bien en entrée qu’en sortie des adresses 0 à 511.
Par contre pour les accès bits, on est limité aux adresses mots de 0 à 31 puis de 256 à 511.
De 32 à 255…bin pas possible…mais pourquoi donc ?

J’ai revérifié comment j’avais fais dans la supervision que j’ai écrite en VB.
Et bien en fait j’avais fait un système d’optimisation des lectures de bits en lisant des mots dans l’automate et en masquant les bits dans le VB.
Donc d’un point de vue Modbus je ne fais que les lectures de mots.
C’est pour cela que je n’avais pas conscience de cette spécificité du protocole.

Bon, maintenant reste à savoir comment faire dans HA pour gérer un bit du mot 52…
Je voudrais afficher un statut binaire. Donc le mieux (surtout le plus adapté) est d’utiliser une carte ‹ bouton ›…j’ai bon ?
Il y a moyen de masquer une valeur numérique directement dans le bouton ?
Ou alors il faut passer par un template comme l’a proposé Cloom ?
Ou je dois faire ma propre carte ?
Quelle est la méthode la plus simple ?

Merci

Les joies de l’implémentation modbus de certains fabricants. Une fois de plus ne regarde pas chez soffrel c’est encore pire :rofl:.

Sinon tu peux faire comme beaucoup d’intégrateur, ne jamais lire/écrire les e/s directement dans codesys. Tu passe tout par des variables Mw,Md,etc qui elles sont accessibles en permanence complétement et tu fais un bloc recopie des E/S.
Pour info chez Schneider les %I,%Q ne sont pas accessibles en modbus par exemple.

J’ai retrouvé cette notice en français, c’est les mêmes tables que ce que tu décris :

Il faut lire au format mot, puis faire un template pour extraire ton bit 5.

sensors:
      - name: TestAna52
        address: 564   # 512+52
        slave: 1
        scan_interval: 2
        state_class: measurement
        unit_of_measurement: xx
        input_type: input
        data_type: int16
        scale: 1
        offset: 0
        precision: 1

Les bits ont les poids suivants:
bit 0 = 1
bit 1 = 2
bit 2 = 4
bit 3 = 8
bit 4 = 16
bit 5 = 32
bit 6 = 64 …

Template:

template:
  - binary_sensor:
      - name: bit_5
        unique_id: bit_5
        state: "{{ states('sensor.TestAna52')|int|bitwise_and(32) }}"
1 « J'aime »

@hpph as-tu testé? Est-ce que la solution donnée par @Pyroaction fonctionne?

Si c’est le cas n’hésite pas à mettre son post en solution de ton sujet :slight_smile: :white_check_mark: