B+G E-Tech Smartmeter per Modbus + ESPHome

Da kann ich eigentlich nicht klagen …
Solange der ESP läuft kommen auch die Impulse sauber an.

Ich habe heute einen neuen Unterzähler montiert einen DS100-30B.
Ich nutze das Script aus dem ersten Post hier. Ich habe nur die Bus-Adresse angepasst.

CRC-Fehler kommen nicht. Daten aber auch nicht.

Das Log sieh so aus:

[13:56:51][C][modbus_controller:349]: ModbusController:
[13:56:51][C][modbus_controller:350]:   Address: 0x01
[13:56:51][C][modbus_controller:351]:   Max Command Retries: 4
[13:56:51][C][modbus_controller:352]:   Offline Skip Updates: 0
[13:56:51][D][modbus_controller:039]: Modbus command to device=1 register=0x140 no response received - removed from send queue
[13:56:52][D][modbus_controller:039]: Modbus command to device=1 register=0x400 no response received - removed from send queue
[13:56:54][D][modbus_controller:039]: Modbus command to device=1 register=0x40C no response received - removed from send queue
[13:56:56][D][modbus_controller:039]: Modbus command to device=1 register=0x436 no response received - removed from send queue
[13:56:58][D][modbus_controller:039]: Modbus command to device=1 register=0x118 no response received - removed from send queue
[13:56:59][W][modbus_controller:185]: Duplicate modbus command found: type=0x4 address=290 count=2
[13:56:59][W][modbus_controller:185]: Duplicate modbus command found: type=0x4 address=300 count=2
[13:56:59][W][modbus_controller:185]: Duplicate modbus command found: type=0x4 address=310 count=2
[13:56:59][W][modbus_controller:185]: Duplicate modbus command found: type=0x4 address=1088 count=2
[13:56:59][W][modbus_controller:185]: Duplicate modbus command found: type=0x4 address=1104 count=2
[13:57:00][D][modbus_controller:039]: Modbus command to device=1 register=0x122 no response received - removed from send queue
[13:57:02][D][modbus_controller:039]: Modbus command to device=1 register=0x12C no response received - removed from send queue
[13:57:04][D][modbus_controller:039]: Modbus command to device=1 register=0x136 no response received - removed from send queue
[13:57:06][D][modbus_controller:039]: Modbus command to device=1 register=0x440 no response received - removed from send queue
[13:57:08][D][modbus_controller:039]: Modbus command to device=1 register=0x450 no response received - removed from send queue
[13:57:09][W][modbus_controller:185]: Duplicate modbus command found: type=0x4 address=280 count=2
[13:57:09][W][modbus_controller:185]: Duplicate modbus command found: type=0x4 address=320 count=2
[13:57:09][W][modbus_controller:185]: Duplicate modbus command found: type=0x4 address=1024 count=6
[13:57:09][W][modbus_controller:185]: Duplicate modbus command found: type=0x4 address=1036 count=39
[13:57:09][W][modbus_controller:185]: Duplicate modbus command found: type=0x4 address=1078 count=4

Am Zähler habe ich keine EInstelliungen vorgenommen, sondern alles so gelassen, wie es bei der Auslieferung ist.
Bus-Adresse, und UART-Einstellungen scheinen zu passen, denn ändere ich die Bus-Adresse, bekomme ich nicht die Duplicate modebus command Zeilen.

Wie komme ich hier weiter?

PS:
Der Zähler hat ja eine IR-Schnittstelle. Weiß jemand, was da übertragen wird? In der Beschreibung zum Zähler habe ich dazu nichts gefunden.
Den Hauptzähler lese ich über IR aus. Da ist alles SML-kodiert. Ist das beim DS100 auch so?

Nachtrag:

Nachdem ich das Updateintervall erhöht habe, kommt Duplicate modbus command nicht mehr. Aber Daten kommen auch nicht.

Verbunden ist der UART-TTL-485-Converter zählerseitig A - A und B - B und auf der ESP-Seite TX - RX und RX - TX, VCC ist an 3,3V.
Es ist die Variante mit einem 74HC04 und dem XL485CS.

Ich habe versuchsweise TX und RX bei der Berbindung Adapter ESP getauscht mit den gleichen Ergebnis.

Vom Stromzähler geht nur A und B ab. Es gibt keinen Massebezug für das Signal. Der Adapter hat auf der MODBUS-Seite einen Anschluss für Masse, der aber nicht mit GND auf der anderen Seite verbunden ist.

Thomas

:crayon:by HarryP: Zusammenführung Doppelpost (bitte “bearbeiten” Funktion nutzen)

  • Hast Du die Busadresse des Zählers geändert oder die Originaleinstellung belassen? (also im Zähler selber)
  • Leitungen eventuell vertauscht?
  • DE und RE angeschlossen?
    Also bei mir hat der Zähler sofort ‘Guten Tag’ gesagt …
    Viele Grüße
    Solarix

… nochmal zur Klarstellung:
5 Verbindungen zwischen ESP und dem RS485-Modul!

  • VCC
  • GND
  • RX
  • TX
  • DE und RE gemeinsam an ein DO-Pin des ESP

Ich habe nur VCC, GND, TX und RX. Mein Adapter hat 2 IC und nicht nur den MAX.
Auslieferungszustand beim DS100-30B:
Busadresse 1
9600
1 StopBit
NONE

Es blinkt nur die LED auf dem Adapter für die Anfragen vom ESP. Rückantworten gibt es nicht.
Ich habe auch schon TX und RX getauscht und VCCV mit 5 und 3,3V probiert.

Grruß

Thomas

… dann müsste der Adapter ja selbst erkennen, wann er den Bus belegen muss. Technisch sicherlich problemlos machbar, aber ich hatte so ein Teil noch nicht ‘in der Hand’. Technische Daten? Irgendein Link?

Meine Konfiguration, ebenfalls am DS100-30B:

id: uartmodbus  
    tx_pin: GPIO14   # D5 (Software-UART)
    rx_pin: GPIO12   # D6 Software-UART kann evtl. Fehler verursachen,
    baud_rate: 9600                       
    data_bits: 8 
    parity: NONE     
    stop_bits: 1
modbus:
  id: modbuszaehler
  uart_id: uartmodbus
  flow_control_pin: D1    

Was hast Du denn hier eingetragen, wenn Du das Pin gar nicht brauchst?
Vielleicht steigt da die Modbus-Library aus?

Ich habe noch den Logger abgeschaltet (wegen eines anderen Zählers, der an der Standard UART hängt.

logger:
  baud_rate: 0

Vielleicht ist das Dein Problem?

Das ist der Controller:
https://esphome.io/components/modbus_controller.html

Baudrate für den Logger ist 0. Da 90% aller eingesetzten ESP nackte ESP8266 ohne Dev-Gedöns ringsrum sind (außer ESP32, da ist mir trotz Brille und Lupenlanpe beim Löten das Raster zu eng), ist das bei mir Standard, zumal ich auch an die meisten gar nicht mit einem Kabel (USB/Seriell) mehr ran käme, sobald sie verbaut sind.
Ich hatte auch schon mit und ohne flow_control_pin getestet.

Nu dann bleibt eigentlich nur noch der Modbus selber:
Abschlusswiderstand 120 Ohm am Zähler? (bei mir geht es auch komischerweise auch ohne, Kabel ist aber nur nen knappen Meter lang).
Prüfen, ob Abschlusswiderstand auf dem Modul vorhanden und angeschaltet ist (vielleicht Lötbrücke oder so was).
Und der Zähler hat Saft auf allen Phasen, Display leuchtet?

Hast Du einen Oszi und kannst mal schauen, was sich so tut? Eine typische UART-Kommunikation ist ja kaum zu übersehen (Masse des Oszi auf B, Probe an A geklemmt, Trigger auf negative Flanke, Triggerlevel auf etwa 1V, Run-Stop-Modus, X auf etwa 10ms/Div).

Zähler hat auf allen Phasen Saft. Das Kabel ist knapp 50 cm lang und abgeschirmt. Nich abgeschirmt sind an jeder Seite ca. 5cm, wo das Kabel in die Schraubklemmen geht. Ich habe 2 Kabelpaare eines Patchkabels über Kreuz geschaltet (blau+grün/weiß und grün+blau/weiß). An den Enden sind Adernendhülsen. Auf dem Modul ist ein Abschlusswiderstand.

Mit einem ESP32 und GPIO16 und GPIO17 für den seriellen Port blinken jetzt beide LED auf dem Adapter. Aber das ist auch schon die einzige Änderung. Daten kommen immer noch nicht an.

Thomas

Ich habe es geschafft, mich wieder mit dem Stromzähler zu beschäftigen. Anstelle eines ESP mit ESPHome drauf, habe ich einen eifachen USB-TTL-Wandler dranghangen und bin Laptop und der Software des Herstellers dran. Und sie da, ich bekomme alle Daten ausgelesen. Es liegt also weder an der Verkabelung, noch am Wandler. Der Schuldige muss das ESPHome-Script sein.
Ich habe mir vorsichtshalber aus der Windowssoftware die gesendeten und empfangenen Byte-Folgen gespeichert, inkl. der dazugehörigen Texte.
Wenn ich mir jetzt die Bytefolgen und den Text ansehe, dann kann ich die Bytes in der Reihenfolge drehen und wenden, wie ich will. Ich komme niemals auf die dekodierten Werte.
Die gesendeten Codes passen zu dem, was im ESPHome-Script steht. Zumindest steht der Code, der im Script übergeben wird im 3. und 4. Byte im gesendeten Code der Herstellersoftware.
Im Script steht: address: 0x041A
Die Herstellersoftware sendet: 01 04 04 1A 00 02 51 3C

Es geht. Auf einer anderen Seite hatte jemand das gleiche Problem. Die Ursache ist die Beschaltung des RX-Pin auf den Platinen. D5 und D6 an stelle D1 und D3 und das Problem war Geschichte.
Jetzt muss ich nur noch die MUltiplikatoren richtig setzen. 239919,00V ist ein bisschen viel.

ddfadb7175e2e62ad81007ae3354ba31ca287d96_2_690x237

Hallo, der Post ist zwar schon einen Weile her, aber könntest Du mir die Liste mit den Parametern zukommen lassen, oder den Link einstellen wo Du das gefunden hast? Ich schon mehrfach danach gesucht aber genau diese Parameterliste nicht gefunden.
Vielen Dank
Gruß Carsten

Modbus Dateien.txt (2,6 MB)

Die Dateiendung auf .zip ändern.

Hallo,
vielen Dank für die Datei
VG

Schön, dass es nun funzt.
Das GPIO0 = D3 Probleme bereiten kann wurde ja schon oft diskutiert.
Ich hatte bisher aber gedacht, dass dann der ESP nicht bootet. Aber der lief ja anscheinend, konnte nur den Modbus nicht lesen …
Bin verwundert, aber wieder was gelernt.

Das scheint mit der Beschaltung des Pins am D1 mini zu tun zu haben. Vermutlich würde ien nackter ESP8266 keine Probleme machen, da man dort in der Regel weder eine LED noch einen Widerstand anlötet. PullUps und PullDowns werden an anderen Pins benötigt, zum stabilen Booten. GPIO3 ist automatisch auf InPut und GPIO1 ist automatisch auf OutPut beim Booten. Das sind die Regeln, die man beim Beschalten dieser beiden Pins bachten muss, sonst droht der Kurzschlusstod, wenn man nicht selber passende Widerstände verlötet.

Hallo Zusammen!

Wahnsinnig gut, dass ihr das Thema bereits diskutiert.
@Solarix: Du hast zu meiner allgemeinen Verwirrung sogar etwas mehr beigetragen, insbesondere weil du viele Dinge klarstellst (was sehr gut ist)

Kind asks:
Mag mal jemand eine funktionierende ESPHome config hier einstellen?

Das wäre total klasse. :slight_smile:

Grüße aus dem Münsterland

Hallo autox,

erst mal Dank für die Blumen!
Meine ESPHome config tut zwar seit vielen Monaten genau das, was sie tun soll. Aber ist halt immer spezifisch (bei mir werden beispielsweise inzwischen 5 Zähler verschiedener Typen (Lesekopf, S0, ModBus) abgefragt und etliche Pins sind noch für Erweiterungen (Gaszähler,…) freigehalten). Insofern kann ich Dir sinnvollerweise nur einen Ausschnitt ‘liefern’, sonst wird die Verwirrung noch größer … :zany_face:
Ich habe versucht, die bei jedem Zähler wiederkehrenden Dinge jeweils in ein Package (also separate Datei) auszulagern. Das klappte an manchen Stellen auf Anhieb, an anderen Stellen nicht (da habe ich es dann aus Zeitgründen halt gelassen).
Das Beispiel ist abgespeckt auf zwei Zähler, einen SML und einen mit ModBus.
Den Modbus-Zähler frage ich mit verschiedenen Häufigkeiten ab. Die momentane Last brauche ich recht zügig (zwecks Ansteuerung Solaranlage mit Akku), wird derzeit alle 10s abgefragt. (da werde ich aber die Abfragefrequenz noch erhöhen). Außerdem ist der Zähler falsch rum eingebaut (war wegen der Kabelführung sinnvoll), deshalb per Software korrigiert (filters: - multiply: -1.0 und Bezug und Einspeisung getauscht)

Insgesamt also keine Lösung für ein einfaches Copy&Paste ….

uart:  #uart in package geht nicht (Compilerfehler??), deshalb hier
  - id: uartsmle     # UART fuer Zaehler Eltern
    tx_pin: GPIO1    # TX = RXD0 Standard Hardware-UART des Boards
    rx_pin: GPIO3    # RX = TXD0 Standard Hardware-UART des Boards
    baud_rate: 9600
    data_bits: 8 
    parity: NONE
    stop_bits: 1

  - id: uartmodbus   # UART fuer Zaehler Haustechnik an Kinder
    tx_pin: GPIO14   # D5 (Software-UART)
    rx_pin: GPIO12   # D6 Software-UART kann evtl. Fehler verursachen,
    baud_rate: 9600  # diese Schnittstelle nur zum Auslesen von Zaehlerständen verwenden                      
    data_bits: 8 
    parity: NONE     
    stop_bits: 1
sml:   #sml in package geht nicht (Compilerfehler??), deshalb hier
  - id: smle          # SML fuer Zaehler Eltern
    uart_id: uartsmle
packages: #Quelltext von sml ausgelagert
  kzaehlersml: !include 
    file: elt_sml.yaml
    vars:
      name_sml: e     # SML-Einbindung fuer Zaehler Eltern
modbus:
  id: modbuszaehler
  uart_id: uartmodbus
  flow_control_pin: D1    #todo=anderes GPIO?  GPIO5
  
modbus_controller:
- id: modbus_ds100_technik
  address: 90            # Adresse des Modbus-Slaves 
  modbus_id: modbuszaehler
  setup_priority: -10  
  update_interval: 300s
  
- id: modbus_ds100_technik_fast
  address: 90            # Adresse des Modbus-Slaves 
  modbus_id: modbuszaehler
  setup_priority: -10  
  update_interval: 10s  
sensor:
- platform: modbus_controller
  modbus_controller_id: modbus_ds100_technik_fast
  name: "K Technik Last momentan"
  register_type: read
  address: 0x0420           
  value_type: S_DWORD
  accuracy_decimals: 0
  unit_of_measurement: "W"
  state_class: measurement
  device_class: power
  filters:
    - multiply: -1.0     # Zaehler falsch gepolt Last <-> Bezug getauscht

- platform: modbus_controller
  modbus_controller_id: modbus_ds100_technik
  name: "K Technik Bezug Total"
  register_type: read
  address: 0x0118 # Zaehler falsch gepolt Last <-> Bezug getauscht
  value_type: S_DWORD
  accuracy_decimals: 2
  unit_of_measurement: "kWh"
  state_class: measurement
  device_class: energy
  filters:
    - multiply: 0.01

- platform: modbus_controller
  modbus_controller_id: modbus_ds100_technik
  name: "K Technik Einspeisung Total"
  register_type: read
  address: 0x010E # Zaehler falsch gepolt Last <-> Bezug getauscht
  value_type: S_DWORD
  accuracy_decimals: 2
  unit_of_measurement: "kWh"
  state_class: measurement
  device_class: energy
  filters:
    - multiply: 0.01
# in separatem file: elt_s0.yaml
sensor:  
  #Zaehler mit S0-Ausgang
  #beim Anschluss die Polaritaet beachten
  #Anschluss -S0 an GND
  #Anschluss +S0 an ein GPIO des ESP8266 mit internem PullUp-Widerstand/index  
  - platform: pulse_counter
    pin: 
      number: ${pinnumbers0}
      mode: INPUT_PULLUP   
    id: ${nameid_s0}_zaehler_pulse
    #keine Vergabe eines Namens: in HomeAssistant nicht sichtbar
    #15ms Filter gegen Spikes
    # vgl. Dokumentation S0 Impulsdauer >= 30 ms
    internal_filter: 15ms
    #minuetlich wird ein neuer Wert berechnet
    update_interval: 60s 
    count_mode: 
        rising_edge: DISABLE
        falling_edge: INCREMENT
        
    #Umrechnung der Impulse in momentane Leistung
    #S0 liefert keine Information, ob momentan Einspeisung oder Last!! 
  - platform: copy
    source_id: ${nameid_s0}_zaehler_pulse
    unit_of_measurement: 'W'
    #Vergabe eines Namens: in HomeAssistant sichtbar
    name: '${namefriendly_s0} Last momentan'
    accuracy_decimals: 0
    filters:
      - multiply: ${mult_s0}  # (Elt: 60s/1000 Pulse pro kWh)
                      # (60s/10  100 Pulse pro m³  ca. 10kWh/m³ --> 10 Pulse/kWh
# in separatem file elt_sml.yaml
sensor:  
  - platform: sml
    name: "${name_sml} Bezug Total"
    sml_id: sml${name_sml}
    obis_code: "1-0:1.8.0"
    unit_of_measurement: kWh
    accuracy_decimals: 4
    device_class: energy
    state_class: total_increasing
    filters:
      - multiply: 0.0001
      
  - platform: sml
    name: "${name_sml} Einspeisung Total"
    sml_id: sml${name_sml}
    obis_code: "1-0:2.8.0"
    unit_of_measurement: kWh
    accuracy_decimals: 4
    device_class: energy
    state_class: total_increasing
    filters:
      - multiply: 0.0001

  - platform: sml
    name: "${name_sml} Last momentan"
    sml_id: sml${name_sml}
    obis_code: "1-0:16.7.0"
    unit_of_measurement: W
    accuracy_decimals: 0
    device_class: energy
    filters:
      - multiply: 1