Using remote via tcp
This commit is contained in:
24
README.md
24
README.md
@@ -7,7 +7,7 @@ This bridigng component reads Dutch Smart Meter Requirements (DSMR) telegrams an
|
|||||||
* [DSMR Parser](https://github.com/ndokter/dsmr_parser)
|
* [DSMR Parser](https://github.com/ndokter/dsmr_parser)
|
||||||
* [Homie4](https://github.com/mjcumming/homie4)
|
* [Homie4](https://github.com/mjcumming/homie4)
|
||||||
|
|
||||||
## Configuration
|
## Configuring the bridge
|
||||||
|
|
||||||
Create some environment variables (e.g. with a .env file) to specify the required settings:
|
Create some environment variables (e.g. with a .env file) to specify the required settings:
|
||||||
|
|
||||||
@@ -18,10 +18,10 @@ DSMR_PORT=/dev/ttyUSB0
|
|||||||
DSMR_PROTOCOL=V5
|
DSMR_PROTOCOL=V5
|
||||||
```
|
```
|
||||||
|
|
||||||
If you have forwared the raw serial signal through ser2net, you should use `DSMR_PORT=remote://<hostname>:<port>`, e.g.:
|
If you have forwared the raw serial signal through ser2net, you should use `DSMR_PORT=tcp://<hostname>:<port>`, e.g.:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
DSMR_PORT=remote://forwarding-pi.local:3333
|
DSMR_PORT=tcp://forwarding-pi.local:3334
|
||||||
```
|
```
|
||||||
|
|
||||||
If you use credentials to access the MQTT broker, then alsp specify:
|
If you use credentials to access the MQTT broker, then alsp specify:
|
||||||
@@ -33,4 +33,22 @@ MQTT_PASSWORD=<mqtt-password>
|
|||||||
|
|
||||||
Inspect the source [`app_settings.py`](app_settings.py) to find out about the other less frequently used settings.
|
Inspect the source [`app_settings.py`](app_settings.py) to find out about the other less frequently used settings.
|
||||||
|
|
||||||
|
## Configuring ser2net
|
||||||
|
|
||||||
|
On the forwarding computer (e.g a Raspberry Pi) you need to install ser2net:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt upgrade && sudo apt install ser2net
|
||||||
|
```
|
||||||
|
|
||||||
|
Then edit the configurion file `/etc/ser2net.yaml` and add
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
connection: &Dsmr
|
||||||
|
accepter: tcp,3334
|
||||||
|
connector: serialdev,
|
||||||
|
/dev/ttyUSB0,
|
||||||
|
115200n81, local
|
||||||
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
31
app.py
31
app.py
@@ -9,24 +9,24 @@ from dsmr_parser.clients import SerialReader, SocketReader, SERIAL_SETTINGS_V2_2
|
|||||||
|
|
||||||
from app_settings import Settings
|
from app_settings import Settings
|
||||||
from device_dsmr import Device_DSMR
|
from device_dsmr import Device_DSMR
|
||||||
from serial import SerialException
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
cfg = Settings()
|
||||||
|
|
||||||
logfmt = "%(asctime)s [%(levelname)-5.5s] [%(name)s] %(message)s"
|
logfmt = "%(asctime)s [%(levelname)-5.5s] [%(name)s] %(message)s"
|
||||||
logging.basicConfig(level=logging.INFO, format=logfmt, filename="dsmr2mqtt.log")
|
logging.basicConfig(level=cfg.loglevel, format=logfmt, filename="dsmr2mqtt.log")
|
||||||
# set up logging to console
|
# set up logging to console
|
||||||
consolelog = logging.StreamHandler(sys.stdout)
|
consolelog = logging.StreamHandler(sys.stdout)
|
||||||
consolelog.setLevel(logging.INFO)
|
consolelog.setLevel(cfg.loglevel)
|
||||||
# set a format which is simpler for console use
|
# set a format which is simpler for console use
|
||||||
formatter = logging.Formatter(logfmt)
|
formatter = logging.Formatter(logfmt)
|
||||||
consolelog.setFormatter(formatter)
|
consolelog.setFormatter(formatter)
|
||||||
logging.getLogger("").addHandler(consolelog)
|
logging.getLogger("").addHandler(consolelog)
|
||||||
|
|
||||||
cfg = Settings()
|
|
||||||
protocol_version: str = str(cfg.dsmr_protocol)
|
protocol_version: str = str(cfg.dsmr_protocol)
|
||||||
if 'V2' in protocol_version:
|
if 'V2' in protocol_version:
|
||||||
serial_setup = SERIAL_SETTINGS_V2_2
|
serial_setup = SERIAL_SETTINGS_V2_2
|
||||||
@@ -42,34 +42,35 @@ 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")
|
||||||
if "remote:" not in cfg.dsmr_port:
|
if "tcp:" in cfg.dsmr_port:
|
||||||
logger.info(f"using serial port {cfg.dsmr_port}")
|
result = re.search(r"tcp://([^:]+):(.+)", cfg.dsmr_port)
|
||||||
reader = SerialReader(cfg.dsmr_port, serial_setup, spec)
|
|
||||||
else:
|
|
||||||
result = re.search(r"remote://([^:]+):(.+)", cfg.dsmr_port)
|
|
||||||
host = result.group(1)
|
host = result.group(1)
|
||||||
port = int(result.group(2))
|
port = int(result.group(2))
|
||||||
logger.info(f"reading from remote host {host} on port {port}")
|
logger.info(f"reading from remote host {host} on port {port}")
|
||||||
reader = SocketReader(host, port, spec)
|
reader = SocketReader(host, port, spec)
|
||||||
|
else:
|
||||||
|
logger.info(f"using serial port {cfg.dsmr_port}")
|
||||||
|
reader = SerialReader(cfg.dsmr_port, serial_setup, spec)
|
||||||
|
|
||||||
def handle_next_telegram():
|
def handle_next_telegram():
|
||||||
telegram = next(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}")
|
||||||
|
|
||||||
def startTimer():
|
def start_timer():
|
||||||
threading.Timer(cfg.dsmr_update_interval, startTimer).start()
|
threading.Timer(cfg.dsmr_update_interval, start_timer).start()
|
||||||
try:
|
try:
|
||||||
handle_next_telegram()
|
handle_next_telegram()
|
||||||
except:
|
except UnicodeDecodeError:
|
||||||
|
logger.warning("Cannot decode telegram")
|
||||||
|
except Exception as ex:
|
||||||
_thread.interrupt_main()
|
_thread.interrupt_main()
|
||||||
|
|
||||||
|
start_timer.has_decode_error = False
|
||||||
|
|
||||||
startTimer()
|
start_timer()
|
||||||
# for telegram in serial_reader.read_as_object():
|
# for telegram in serial_reader.read_as_object():
|
||||||
# device.update(telegram)
|
# device.update(telegram)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import logging
|
import logging
|
||||||
import datetime
|
|
||||||
|
|
||||||
from homie.device_base import Device_Base
|
from homie.device_base import Device_Base
|
||||||
from homie.node.node_base import Node_Base
|
from homie.node.node_base import Node_Base
|
||||||
|
|||||||
Reference in New Issue
Block a user