Compare commits

...

2 Commits

Author SHA1 Message Date
Ard Kuijpers
1732181fbb Added docs 2023-02-12 14:26:37 +01:00
Ard Kuijpers
521881a81a Add possibility to read from remote port 2023-02-12 14:13:02 +01:00
4 changed files with 47 additions and 4 deletions

1
.gitignore vendored
View File

@@ -5,5 +5,6 @@ __pycache__/
*.log *.log
# local files # local files
env
.env .env
.vscode .vscode

View File

@@ -1,6 +1,6 @@
# For more information, please refer to https://aka.ms/vscode-docker-python # For more information, please refer to https://aka.ms/vscode-docker-python
FROM python:3.9-slim as base FROM python:3.11-slim as base
FROM base as builder FROM base as builder
RUN apt-get update \ RUN apt-get update \

33
README.md Normal file
View File

@@ -0,0 +1,33 @@
# DSMR 2 MQTT bridge
## Introduction
This bridigng component reads Dutch Smart Meter Requirements (DSMR) telegrams and sends them to a MQTT broker using the [Homie convention](https://homieiot.github.io/). The component is written in Python and is based on the execelent work of others:
* [DSMR Parser](https://github.com/ndokter/dsmr_parser)
* [Homie4](https://github.com/mjcumming/homie4)
![Works with Homie](https://homieiot.github.io/img/works-with-homie.png).
## Configuration
Create some environment variables (e.g. with a .env file) to specify the required settings:
```bash
PYTHONPATH="."
MQTT_HOST=mqtt.local
DSMR_PORT=/dev/ttyUSB0
```
If you have forwared the raw serial signal through ser2net, you should use `DSMR_PORT=remote://<hostname>:<port>`, e.g.:
```bash
DSMR_PORT=remote://forwarding-pi.local:3333
```
If you use credentials to access the MQTT broker, then alsp specify:
```bash
MQTT_USERNAME=<mqtt-user>
MQTT_PASSWORD=<mqtt_passwrd>
```

15
app.py
View File

@@ -1,10 +1,11 @@
import os import os
import time import time
import re
import sys import sys
import threading import threading
import _thread import _thread
from dsmr_parser import telegram_specifications from dsmr_parser import telegram_specifications
from dsmr_parser.clients import SerialReader, SERIAL_SETTINGS_V2_2, SERIAL_SETTINGS_V4, SERIAL_SETTINGS_V5 from dsmr_parser.clients import SerialReader, SocketReader, SERIAL_SETTINGS_V2_2, SERIAL_SETTINGS_V4, SERIAL_SETTINGS_V5
from app_settings import Settings from app_settings import Settings
from device_dsmr import Device_DSMR from device_dsmr import Device_DSMR
@@ -41,10 +42,18 @@ def main():
spec = telegram_specifications.V5 spec = telegram_specifications.V5
device = Device_DSMR("dsmr", name="Digitale Slimme Meter") device = Device_DSMR("dsmr", name="Digitale Slimme Meter")
serial_reader = SerialReader(cfg.dsmr_port, serial_setup, spec) if "remote:" not in cfg.dsmr_port:
logger.info(f"using serial port {cfg.dsmr_port}")
reader = SerialReader(cfg.dsmr_port, serial_setup, spec)
else:
result = re.search(r"remote://([^:]+):(.+)", cfg.dsmr_port)
host = result.group(1)
port = int(result.group(2))
logger.info(f"reading from remote host {host} on port {port}")
reader = SocketReader(host, port, spec)
def handle_next_telegram(): def handle_next_telegram():
telegram = next(serial_reader.read_as_object()) telegram = next(reader.read_as_object())
device.update(telegram) device.update(telegram)
logger.info(f"New telegram at {telegram.P1_MESSAGE_TIMESTAMP.value}") logger.info(f"New telegram at {telegram.P1_MESSAGE_TIMESTAMP.value}")