Smart Meter des Netzbetreibers auslesen KAIFA MA309M
Für ein sinnvolles Optimieren des Stromverbrauchs hilft das Wissen über die aktuellen Verbrauchsdaten. Dazu kann ein zusätzlichen Smart Meter verbaut werden, oder noch besser: Der Smart Meter des Netzbetreibers ausgelesen werden. Als Beispiel kann der Smart Meter meines Netzbetreibers, der Salzburg AG über die M-Bus-Kundenschnittstelle abgefragt und die Daten dadurch in anderen Systemen verwendet werden. Die ausgelesenen Werte umfassen den Energieverbrauch und bei Einsatz einer PV-Anlage die Einspeiseleistung, sowie die Spannung und den Strom jeder einzelnen Phase, alles live, im 5-Sekunden-Takt. Für das Auslesen des Kaifa MA309M reicht ein MBUS-to UART-Board und ein ESP32-Mikrocontroller. Programmiert habe ich den Mikrocontroller in ESP-Home mithilfe eines Open-Source-Projekts von Github: https://github.com/DomiStyle/esphome-dlms-meter. Nach dem Aufspielen des Projekts auf den ESP32 liefert dieser, beim Anschluss an den Smart Meter, die Daten an Home Assistant, wodurch diese ausgewertet und für bestimmte Automatisierungen verwendet werden können.
Eine Voraussetzung für die Kommunikation mit dem Smart Meter ist das Aktivieren der Kundenschnittstelle im Webportal des Netzbetreibers:
Kundenschnittstelle freigeben
Für das Aktivieren der Kundenschnittstelle bietet mein Netzbetreiber im Portal einen Menüpunkt für dessen Freigabe:
Der dadurch bereitgestellte Schlüssel kann für das Auslesen der Daten mittels M-Bus über einen RJ12-Stecker verwendet werden.
Benötigte Hardware
Als Hardware wird dazu folgendes benötigt:
- RJ11 oder RJ12 Kabel
- ESP32:
- m-bus-slave-click TSS721A (MBus -to UART-Board): at.rs-online.com/web/p/entwicklungstools-kommunikation-und-drahtlos/2167484
- 5V-Netzteil oder Ladegerät als Spannungsversorgung für den ESP32
- Kabel:
benötigte Software
Wie bereits an anderen Stellen dieser Seite erwähnt, verwende ich ausschließlich Docker-Container für mein Smart-Home-Setup:
- Home Assistant
- ESP Home (Verbindung zu Home Assistant mittels API-Key)
- Alternativ zur ESP-Home API: MQTT - Broker und Heimassistent MQTT - Integration
Verkabelung
Den TSS721A habe ich wie folgt mit dem ESP32 verbunden:
Stromversorgung über die PINs:
- 5V und
- GND
vom ESP32 auf das M-Bus Board:
- ESP32-Pin35 <-> M-Bus Board Pin TX
- ESP32-Pin16 <-> M-Bus Board Pin RX
- ESP32-GND <-> M-Bus Board GND
- ESP32-3V3 <-> M-Bus Board 3V3
Vom M-Bus-Board auf den RJ12-Stecker
- M-Bus Board MBUS1 auf RJ12-3
- M-Bus Board MBUS2 auf RJ12-4
Vom TSS721A geht es mittels RJ-12 Stecker in den Anschluss des Smart Meter:
Hier nochmal ein Einzelfoto der beiden Boards:
ESPHome-Projekt
Als Voraussetzung für das ESPHome-Projekt wird ein zusätzlicher Ordner vom Git-Hub-Projekt benötigt, welcher in einen Unterordner in ESP-Home kopiert oder mittels git clone heruntergeladen werden kann.
Die Volumes in der Docker-Compose-Datei von ESP-Home mounten bei mir den /config-Ordner auf ./esphome:
..
volumes:
- ./esphome:/config:rw
..
docker-compose.yml, siehe auch: Home-Assistant + DIY Mikrocontroller + ESP Home (Docker)
Die Dateien des esphome-dlms-meter-Projekts habe ich mittels git clone in einem Unterordner abgelegt:
cd OrdnerDesESPHome-Projekts
git clone git@github.com:DomiStyle/esphome-dlms-meter.git
Der Ordner befindet sich bei mir innerhalb von ./esphome, also im Container als Unterordner von /config : /config/esphome-dlms-meter
Damit Wifi und der API-Key des ESP-Home-Projekts richtig angelegt werden, sollte der ESP32 in ESP-Home zunächst als neues Gerät hinzugefügt werden:
Im Anschluss kann die Konfig des ESP32 wie folgt angepasst werden:
esphome:
name: smartmeter
includes:
- ./esphome-dlms-meter
esp32:
board: esp32dev
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "??"
ota:
password: "??"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Smartmeter Fallback Hotspot"
password: "??"
captive_portal:
uart:
tx_pin: GPIO16
rx_pin: GPIO35
baud_rate: 2400
rx_buffer_size: 2048
id: mbus
sensor:
- platform: template
id: meter01_voltage_l1
name: meter01_voltage_l1
unit_of_measurement: V
accuracy_decimals: 1
device_class: "voltage"
state_class: "measurement"
- platform: template
id: meter01_voltage_l2
name: meter01_voltage_l2
unit_of_measurement: V
accuracy_decimals: 1
device_class: "voltage"
state_class: "measurement"
- platform: template
id: meter01_voltage_l3
name: meter01_voltage_l3
unit_of_measurement: V
accuracy_decimals: 1
device_class: "voltage"
state_class: "measurement"
- platform: template
id: meter01_current_l1
name: meter01_current_l1
unit_of_measurement: A
accuracy_decimals: 2
device_class: "current"
state_class: "measurement"
- platform: template
id: meter01_current_l2
name: meter01_current_l2
unit_of_measurement: A
accuracy_decimals: 2
device_class: "current"
state_class: "measurement"
- platform: template
id: meter01_current_l3
name: meter01_current_l3
unit_of_measurement: A
accuracy_decimals: 2
device_class: "current"
state_class: "measurement"
- platform: template
id: meter01_active_power_plus
name: meter01_active_power_plus
unit_of_measurement: W
accuracy_decimals: 0
device_class: "power"
state_class: "measurement"
- platform: template
id: meter01_active_power_minus
name: meter01_active_power_minus
unit_of_measurement: W
accuracy_decimals: 0
device_class: "power"
state_class: "measurement"
- platform: template
id: meter01_active_energy_plus
name: meter01_active_energy_plus
unit_of_measurement: Wh
accuracy_decimals: 0
device_class: "energy"
state_class: "total_increasing"
- platform: template
id: meter01_active_energy_minus
name: meter01_active_energy_minus
unit_of_measurement: Wh
accuracy_decimals: 0
device_class: "energy"
state_class: "total_increasing"
- platform: template
id: meter01_reactive_energy_plus
name: meter01_reactive_energy_plus
unit_of_measurement: Wh
accuracy_decimals: 0
device_class: "energy"
state_class: "total_increasing"
- platform: template
id: meter01_reactive_energy_minus
name: meter01_reactive_energy_minus
unit_of_measurement: Wh
accuracy_decimals: 0
device_class: "energy"
state_class: "total_increasing"
text_sensor:
- platform: template
id: meter01_timestamp
name: meter01_timestamp
mqtt:
broker: "192.168.1.5"
port: "1883"
username: "mqtt"
password: "??"
id: mqtt_broker
discovery: true
custom_component:
- lambda: |-
auto dlms_meter = new esphome::espdm::DlmsMeter(id(mbus));
uint8_t key[] = {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??};
dlms_meter->set_key(key, 16);
dlms_meter->set_voltage_sensors(id(meter01_voltage_l1), id(meter01_voltage_l2), id(meter01_voltage_l3));
dlms_meter->set_current_sensors(id(meter01_current_l1), id(meter01_current_l2), id(meter01_current_l3));
dlms_meter->set_active_power_sensors(id(meter01_active_power_plus), id(meter01_active_power_minus));
dlms_meter->set_active_energy_sensors(id(meter01_active_energy_plus), id(meter01_active_energy_minus));
dlms_meter->set_reactive_energy_sensors(id(meter01_reactive_energy_plus), id(meter01_reactive_energy_minus));
dlms_meter->set_timestamp_sensor(id(meter01_timestamp)); // Set sensor to use for timestamp (optional)
dlms_meter->enable_mqtt(id(mqtt_broker), "meter01/data");
return {dlms_meter};
Der Parameter "includes" verweist auf den zuvor kopierten Ordner des Github-Projektes. Der unit8_t key muss mit dem zuvor erstellten Schlüssel der Kundenschnittstelle (Netzbetreiberportal) befüllt werden. Die Verbindung des ESP32 mit Home Assistant kann über den ESP-Home und dessen API-Key erfolgen - der Bereich "mqtt:" ist dann nicht notwendig. Wer für die Verbindung MQTT als Protokoll bevorzugt, kann alternativ die Daten für den MQTT-Broker anpassen. (IP, Username und Password).
Falsche Werte in Home Assistant
Zu Beginn habe ich für die Verbindung des TSS721A den im Projekt empfohlenen Pin 36 verwendet, was immer wieder mal komplett falsche Werte erzeugt hat:
Die falschen Werte habe ich zunächst händisch korrigiert, siehe auch: www.libe.net/home-assistant-statistic
Fehlerhafte Werte können per Filter in ESP-Home vermieden werden, siehe folgendes Beispiel:
...
- platform: template
id: meter01_active_power_plus
name: meter01_active_power_plus
unit_of_measurement: W
accuracy_decimals: 0
device_class: "power"
state_class: "measurement"
filters:
- lambda: |-
float MAX_DIFFERENCE = 1500.0;
static float last_value_t = NAN;
static int count_missed_t = 0;
if (count_missed_t == 5) last_value_t = x;
if (isnan(last_value_t) || std::abs(x - last_value_t) < MAX_DIFFERENCE) {
count_missed_t = 0;
return last_value_t = x;
} else {
count_missed_t += 1;
ESP_LOGW("main", "Missed Data active_power_plus %d", count_missed_t);
return last_value_t;
}
Besser ist es aber, wenn die fehlerhaften Werte gar nicht entstehen. Bei mir konnte ich das Problem lösen, indem ich den RX Pin von 36 auf 35 geändert habe. Ein entsprechender Hinweis ist auch in dem Github-Projekt zu finden: https://github.com/DomiStyle/esphome-dlms-meter/issues/16
ESP-Home Update: MBUS: Frame too big for received data
Mit der ursprünglichen ESP-Home-Version 2022.11.3 habe ich als Wert für die uart - rx_buffer_size: 1024 verwendet, was nach einem ESP-Home-Update auf 2023.4.3 beim Auslesen der Daten folgenden Fehler verursacht hat:
[20:44:29][E][espdm:064]: MBUS: Frame too big for received data
[20:44:30][E][espdm:048]: MBUS: Start bytes do not match
[20:44:30][E][espdm:104]: DLMS: Unsupported system title length
Nachdem ich rx_buffer_size auf 2048 geändert habe, konnte ich den ESP32 auch mit der neuen ESPHome-Version verwenden:
uart:
tx_pin: GPIO16
rx_pin: GPIO35
baud_rate: 2400
rx_buffer_size: 2048
id: mbus
siehe auch: https://github.com/DomiStyle/esphome-dlms-meter/issues/19
Fazit
Wenn der Netzbetreiber ein Auslesen des Smartmeters erlaubt, liefert dieser die exakte Bezugs- und Einspeiseleistung. Zudem können die Daten für das Steuern einer Smarthome-Lösung wie Home-Assistant verwendet werden. Der exakte Einspeisewert kann speziell für Betreiber von Photovoltaikanlagen interessant sein. Denkbar wäre als Beispiel auf den Überschuss einer PV-Anlage zu reagieren, ganz ohne der Notwendigkeit den Wechselrichter abzufragen und ohne einen zusätzlichen Smartmeter verbauen zu müssen. Als Beispiel: Heizung mit Home Assistant steuern.
{{percentage}} % positiv
DANKE für deine Bewertung!
Fragen / Kommentare
(sortiert nach Bewertung / Datum) [alle Kommentare(neueste zuerst)]
Hey Sag wäre es auch möglich das so zu programmieren das es auch für die EVN in Niederösterreich funktioniert? Hab da auch einen Kaifa Smartmeter am Start. LG Markus
Hy Läuft bei dir im Netz der EVN? LG Thomas
Beitrag erstellt von anonym
Hallo, dank der super Anleitung läuft mein ESP und schickt auch Daten. Habe im Log was gesehen was ich nicht verstehe. Evtl. kann jemand was sagen dazu. Es geht um die Einträge [W] 10:47:33 [W] [component:204] Component <unknown> took a long time for an operation (0.06 s). 10:47:33 [W] [component:205] Components should block for at most 20-30ms. 10:47:38 [W] [component:204] Component <unknown> took a long time for an operation (3.76 s). 10:47:38 [W] [component:205] Components should block for at most 20-30ms. 10:47:38 [D] [text_sensor:064] 'meter01_timestamp': Sending state '2023-08-26T10:47:35Z' 10:47:38 [D] [text_sensor:064] 'meter01_timestamp': Sending state '2023-08-26T10:47:35Z' 10:47:38 [D] [sensor:094] 'meter01_voltage_l2': Sending state 237.30000 V with 1 decimals of accuracy 10:47:38 [D] [sensor:094] 'meter01_active_power_plus': Sending state 6.00000 W with 0 decimals of accuracy 10:47:38 [I] [espdm:393] Received valid data 10:47:38 [W] [component:204] Component <unknown> took a long time for an operation (0.05 s). 10:47:38 [W] [component:205] Components should block for at most 20-30ms. 10:47:43 [W] [component:204] Component <unknown> took a long time for an operation (3.76 s). 10:47:43 [W] [component:205] Components should block for at most 20-30ms. 10:47:43 [W] [component:205] Components should block for at most 20-30ms. 10:47:43 [D] [text_sensor:064] 'meter01_timestamp': Sending state '2023-08-26T10:47:40Z' 10:47:43 [D] [sensor:094] 'meter01_voltage_l2': Sending state 237.50000 V with 1 decimals of accuracy 10:47:43 [D] [sensor:094] 'meter01_voltage_l3': Sending state 236.89999 V with 1 decimals of accuracy 10:47:43 [D] [sensor:094] 'meter01_active_power_plus': Sending state 5.00000 W with 0 decimals of accuracy 10:47:43 [I] [espdm:393] Received valid data 10:47:43 [W] [component:204] Component <unknown> took a long time for an operation (0.07 s). 10:47:43 [W] [component:205] Components should block for at most 20-30ms. 10:47:48 [W] [component:204] Component <unknown> took a long time for an operation (3.76 s). 10:47:48 [W] [component:205] Components should block for at most 20-30ms. 10:47:48 [D] [text_sensor:064] 'meter01_timestamp': Sending state '2023-08-26T10:47:45Z' Hat aber wie es aussieht keinen Einfluss auf die Funktion. LG Obmar
Hi! Vielen Dank für die tolle Anleitung. Leider scheitere ich daran, dass ich Daten vom Zähler empfange. Ich hatte versucht exakt deine Komponenten nachzukaufen und auch dann die Verkabelung gleich vorzunehmen. Unterschiede: RJ11 Kabel, aber auch hier habe ich die mittleren 2 Kabel verwendet ... ich hoffe das habe ich so richtig verstanden. Dann habe ich noch GPIO 17 und 16 für TX bzw RX verwendet, da das so für UART1 im Pinout des AZDelivery ESP32 gestanden ist. Aber wenn ich das richtig verstehe sollten auch andere Pins funktionieren wenn man sie benennt. Ist leider mein ersters ESP32-Projekt. Egal wie ich die Konfiguration ändere bzw. andere PINs verbinde, ich bekomme ich keine Daten zu sehen. Die Freischaltung von TINETZ habe ich erhalten (hoffe die kann nicht ablaufen, da das sicherlich länger her ist). Hast du ev. einen Tip, wie man das weiter debuggen kann? Ich habe schon mit dem Debug-Level gespielt bzw. auch veruscht die UART Kommunikation zu loggen. Aber ich sehe weder einen Versuch der Kommunikation bzw. ob z.B. der Key nicht passt. Die letzte Meldung im Log ist die erfolgreiche Verbindung mit Home Assistant, aber ich sehe dort keine Daten. Auch wenn ich mich mit dem ESP32 verbinde sehe ich keine Daten. debug: direction: BOTH dummy_receiver: false after: delimiter: "\n" sequence: - lambda: UARTDebug::log_string(direction, bytes); Gibt es einen guten Weg das zu debuggen? Wie kann ich loggen, ob die MBUS-Verbindung versucht wird herzustellen? Bin für jeden Tipp dankbar. Gruß, Andreas
m-bus-slave-click TSS721A Bestellung nur über Firma giebt Möglichkeit ohne Firma bestellen
https://www.tme.eu/at/details/mikroe-3880/erweiterungsboards/mikroe/m-bus-master-click/ Da hab ich es bestellt. War am nächsten Tag da.
Beitrag erstellt von anonym
Danke für die Anleitung! Wir haben hier in Vorarlberg ebenfalls KAIFA MA309M im EInsatz. Dazu habe ich Home Assistent auf meiner Synology NAS in einer virtuellen Umgebung laufen und dort die Add-ons "ESPHome" und "Mosquitto broker" installiert. Wie muss ich hier vorgehen, wenn ich nicht Docker verwende? Wäre nett, wenn du mir weiterhelfen könntest. Danke im Voraus und LG, Kurt
Hallo Kurt, habe ich leider noch nicht gemacht, aber ich denke, du musst dann die zugehörigen Integrationen für MQTT und ESPHome hinzufügen und konfigurieren. Die benötigten Files (includes) für ESPHome würde ich über External Components versuchen?
Beitrag erstellt von Bernhard
Vielen Dank für die tolle Anleitung! Ich versuche gerade den Nachbau mit den gleichen Komponenten, jedoch sehe ich in der Log-Ausgabe außer Info MQTT verbunden keine Ausgabe mehr. Es werden auch keine Messwerte ausgegeben. In anderen Projekten werden auch andere Pins belegt, daher bin ich mir nicht sicher, ob das so alles passt. Verstehe auch nicht, warum hier nicht RX und TX am NodeMCU verwendet wird, sondern ein Pin 35. Bin um jeden Hinweis dankbar, finde das Projekt sehr interessant. LG Daniel Logausgabe: INFO Waiting for result... INFO OTA successful INFO Successfully uploaded program. INFO Starting log output from meter01/debug INFO Connected to MQTT broker!
Danke, hat sich erübrigt! Funktioniert perfekt! Habe api: vergessen - offensichtlich funktioniert bei mir die mqtt-verbindung nicht, aber als esphome in homeassistant wird das Smartmeter korrekt angezeigt! Danke für die Anleitung! LG Daniel
Beitrag erstellt von anonym
Danke für den Hinweis: Ja das sind zwei verschiedene Varianten: ESP-Home API oder MQTT. Ich passe den Artikel bei Gelegenheit an, damit das etwas verständlicher wird.
Beitrag erstellt von Bernhard
Hallo. Seit ein paar Tagen habe ich nun auch den neuen Zähler MA309 und den Aktivierungscode. Leider kommt mir beim Compilieren des ESP32 schon ein Fehler: /config/esphome/esphome-web-29c708.yaml: In lambda function: /config/esphome/esphome-web-29c708.yaml:149:29: error: expected type-specifier before 'DlmsMeter' auto dlms_meter = new DlmsMeter(id(mbus)); ^~~~~~~~~ /config/esphome/esphome-web-29c708.yaml:158:25: error: could not convert '{dlms_meter}' from '<brace-enclosed initializer list>' to 'std::vector<esphome::Component*>' return {dlms_meter}; ^ Hast du eine Idee woran es liegen könnte? Besten Dank für jede Hilfe. lg Wolfgang
hallo. Den Fehler konnte ich inzwischen lösen. Es war ein ESP32 Problem. Leider bekomme ich totzdem keine Daten aus dem Zähler. Zuerst bekam ich die Fehlermeldung MBUS code falsch. Den habe ich aber von meinem Netzbetreiber erhalten. Habe den auch mehrfach kontrolliert. Jetzt ist der Fehler weg (ohne mein Zutun). Leider aber immer noch keine Daten. Kann ich den MQTT nicht abschalten oder aus dem Programm entfernen? Vielen Dank für jede Hilfe Wolfgang
Beitrag erstellt von anonym
hallo, ja MQTT wird nicht benötigt, da die Daten auch über den ESPHome API Key in Home Assistant verfügbar sein sollen. Bei Problemen könntest du ev. auch andere PINs versuchen..
Beitrag erstellt von Bernhard
Hallo Bernhard. Inzwischen bekomme ich auch Werte angezeigt ;-) Dafür habe ich auch einen MQTT Server aufgesetzt. So funktioniert es auch. Da ich aber keinen API Code im ESP32 verwende sind die Daten wieder weg sobald der MQTT abgeschaltet wird obwohl ich auch von Homeassistant auf den ESP32 zugreifen kann. Ich mach nun nochmals einen neuen ESP32 mit API Code und teste. Mir ist vorallem wichtig, dass auch die hardware soweit funktioniert. Besten Dank für deine Unterstützung. lg Wolfgang
Beitrag erstellt von anonym
Hallo Bernhard. Nun habe ich den ESP32 mit API in Betrieb genommen und es funktioniert bestens (auch ohne MQTT). Vielen Dank für deine Anleitung. Laut Zähler werden aber noch weitere Werte (Hochtarif, Niedertarif für Bezug und Einspeisung ausgegeben) werden diese von deinen "includes" nicht ausgewertet bzw. ausgegeben? Da mich vorallem auch diese Werte interessieren wäre eine Erweiterung super. Besten Dank im Voraus für deine Unterstützung. lg Wolfgang
Beitrag erstellt von anonym
Hi, zuerst mal genial - Danke vielmals!!! Frage wir haben bei uns eine sogenannte halbe Wandlermessung - also der Strom wird mit einem Faktor (in unserem Fall mal 40) multipliziert - die Spannung nicht, die Leistung bzw die Arbeit muss dann auch natürlich richtig gerechnet werden (eben mit dem gemessenen Strom mal 40....) Gibt es die Möglichkeit, diesen Faktor gleich in den Code einzubauen, damit würde ich mir einen Helfer im HA sparen und der esp spuckt gleich von Beginn an der richtigen Wert aus? liebe Grüße Heli
Hallo Heli, ich denke, das sollte über den Templatesensor möglich sein: https://esphome.io/components/sensor/template.html. Ich habe aber nicht ausprobiert, ob die Lambda-Funktion in die bestehenden Templatesensoren eingebaut werden kann, oder dazu eigene Templatesensoren mit Verweis auf die ID der bestehenden Sensoren benötigt werden.
Beitrag erstellt von Bernhard
Hallo und vielen Dank für die schöne Anleitung! Leider kann ich Sie leider nicht testen. Ich wohne im 4 Stock und mein "smart" Zähler ist im Keller. Ausserdem gibt es im Kasten auch keine Steckdose, um ein Auslesegerät zu versorgen. Ich stelle mir sowieso die Frage warum man 2024 noch soetwas basteln muss und nicht der Anbieter die Daten online zu Verfügung stellen kann. Vielen Dank an die TIWAG Tinetz... Das ist ja ein smarter Verein! LOL