Compare commits
2 Commits
24f736218e
...
1732181fbb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1732181fbb | ||
|
|
521881a81a |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,5 +5,6 @@ __pycache__/
|
|||||||
*.log
|
*.log
|
||||||
|
|
||||||
# local files
|
# local files
|
||||||
|
env
|
||||||
.env
|
.env
|
||||||
.vscode
|
.vscode
|
||||||
|
|||||||
@@ -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
33
README.md
Normal 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)
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
## 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
15
app.py
@@ -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}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user