dsmrreader / dsmr-reader

DSMR-telegram reader & data visualizer for hobbyists. Free for non-commercial use.
https://dsmr-reader.readthedocs.io
Other
463 stars 95 forks source link

Read telegrams from network socket (DSMRloggerWS) #1057

Closed digiater closed 4 years ago

digiater commented 4 years ago

dsmr reader ziet er heel fijn uit om data te vergaren, alleen heb ik alles onder vmware in virtuele machines draaien. Voor de data logging gebruik ik dsmr logger (https://mrwheel.github.io/DSMRloggerWS/hardware_V4.5/) gekoppeld aan home assistant waardoor ik de data gewoon van het netwerk af kan halen.

Het lijkt er op dat dsmr reader hier niet mee kan omgaan wat de functionalieteit tekort doet. Ik ben vooral geinteresseerd in long term opslag van de data. Is het mogelijk om hier wat aanpassingen voor te doen zodat dit mogelijk wordt?

Ik kan het zelf doen als ik wat hints krijg omdat ik er niet al te veel tijd voor heb ((heb veel programmeer ervaring, alleen niet in python, ben meer C/C++ man) .

Jur.

dennissiemensma commented 4 years ago

Bedankt voor je vraag. In #677 is dit destijds eerder behandeld, maar ik weet niet of degene daar uiteindelijk uit is gekomen.

Ik zie dat DSMRloggerWS meerdere integraties heeft. Je zou kunnen vragen of er ook een integratie kan komen voor DSMR-reader. Deze is nog simpeler dan die voor MinderGas, gezien alleen het volgende nodig is:

De rest doet DSMR-reader verder. Voor een voorbeeld, zie de huidige HTTP request in de remote datalogger.

Het is dat ik zelf die DSMRloggerWS niet ergens kan draaien, anders had ik het wellicht wel voor je kunnen doen.


Als alternatief kun je kijken naar de (inmiddels in het voorjaar toegevoegde) nieuwe API's van die tool: https://willem.aandewiel.nl/index.php/2020/02/28/restapis-zijn-hip-nieuwe-firmware-voor-de-dsmr-logger/

Ik zie een endpoint die exact de informatie ophaalt die DSMR-reader nodig heeft: Onbewerkt telegram uit de Slimme Meter (onderaan pagina).

Daarmee kun je dus een scriptje maken die, in een taal naar jouw wens, data van de ene API ophaalt en in de andere wegschrijft.


Tot slot kan ik nog kijken of ik een DSMR-reader 'plugin' kan maken die wellicht die DSMRloggerWS API uitleest. Het nadeel van plugins zijn wel dat ze foutgevoelig zijn en geen onderdeel van de codebase. Het is dan puur iets wat je zelf toevoegt aan je eigen installatie.

Ik kan er altijd een opzetje voor je maken en als het werkt mooi. Zo niet dan kun je het zo weer uitschakelen.

dennissiemensma commented 4 years ago

Je kunt deze plugin proberen. Ik kon het endpoint zelf niet testen, maar als je de juiste URL instelt, zou het moeten werken:

Pas de DSMRLOGGERWS_ENDPOINT hieronder aan

Probeer het vooral even met wget op je Pi.

Nieuw bestand: dsmr_plugins/modules/poll_dsmrloggerws_api.py

"""
Enable this plugin in your settings.py by defining:

DSMRREADER_PLUGINS = [
    'dsmr_plugins.modules.poll_dsmrloggerws_api',
]
"""
import requests

from django.dispatch import receiver

from dsmr_backend.signals import backend_called
import dsmr_datalogger.services.datalogger

# Preverve a low timeout to prevent the entire backend process from hanging too long.
DSMRLOGGERWS_ENDPOINT = 'http://localhost/api/v1/sm/telegram'
DSMRLOGGERWS_TIMEOUT = 5

@receiver(backend_called)
def handle_backend_called(**kwargs):
    response = requests.get(DSMRLOGGERWS_ENDPOINT, timeout=DSMRLOGGERWS_TIMEOUT)

    if response.status_code != 200:
        print(' [!] DSMRloggerWS plugin: Telegram endpoint failed (HTTP {}): {}'.format(
            response.status_code,
            response.text
        ))
        return

    dsmr_datalogger.services.datalogger.telegram_to_reading(data=response.text)

Regels toevoegen aan: dsmrreader/settings.py

DSMRREADER_PLUGINS = [
    'dsmr_plugins.modules.poll_dsmrloggerws_api',
]

Herstart DSMR-reader backend process

sudo supervisorctl restart dsmr_backend
digiater commented 4 years ago

Dennis,

Heel hartelijk dank voor de code, het werkt uitstekend.

Ik moest nog wel wat moeite doen om het aan de gang te krijgen. In eerste instantie leek het te werken, echter na een paar minuten kwam er geen data meer binnen. Vervolgens heb ik debugging aangezet wat in elk geval geen activiteit in de logfiles tot gevolg had. Ik kwam er wel achter wat er mis was met dit commando:

(dsmrreader) dsmr@dsmr:~/dsmr-reader$ ./manage.py dsmr_backend [2020-07-25 09:45:39,303] DEBUG dsmr_backend.management.commands.dsmr_backend: Starting infinite command loop... [2020-07-25 09:45:39,305] DEBUG SP: 0 backend service(s) ready to run [!] DSMRloggerWS plugin: Telegram endpoint failed (HTTP 500): 500: internal server error (low heap)

wget gaf dezefde error:

(dsmrreader) dsmr@dsmr:~/dsmr-reader/logs$ wget http://xxxxxxxxxx/api/v1/sm/telegram --2020-07-25 09:51:00-- http://xxxxxxxxxxxx/api/v1/sm/telegram Resolving xxxxxxxxxxxxxx (xxxxxxxxxxxxxxxxx)... 192.168.14.15 Connecting to xxxxxxxxxxxxxxxxx (xxxxxxxxxxxxxx)|192.168.14.15|:80... connected. HTTP request sent, awaiting response... 500 Internal Server Error 2020-07-25 09:51:00 ERROR 500: Internal Server Error.

En op het console van de reader zag ik dit:

[09:51:12][ 8160| 7856] processAPI ( 50): from[192.168.13.42] URI[/api/v1/sm/telegram] method[GET] [09:51:12][ 6816| 6560] processAPI ( 61): ==> Bailout due to low heap (6816 bytes))

Het probleem zat dus duidelijk in de P1 reader. Het lijkt er op dat als er elke seconde een request gedaan wordt dit na enige tijd een heap overflow in die software tot gevolg heeft, met bovenstaande errors als gevolg. Ik heb in dsmr reader de backend config aangepast om niet elke seconde maar elke 5 seconden te draaien, en dat lijkt om het probleem heen te werken. Sinds die tijd loopt het goed.

Ik zal later kijken of ik kan achterhalen wat er met dat ding mis is, maar het lijkt dus op een memory leak als de requests te snel binnenkomen.

Voor nu ben ik heel tevreden, het draait in een aparte virtuele machine binnen vmware ESXi onder Linux mint.

Bedankt!

Jur.

zuidwijk commented 4 years ago

Hey Dennis, ik ben een zeer grote fan van je werk, dsmr-reader is echt een mooi stukje werk! Ik, en vele anderen, maken er veel gebruik van.

Toch zou ook ik graag zien dat er ipv een usb kabel, ook een netwerk socket gebruik kan worden. Ik heb een paar netwerk modules gemaakt om de data van de P1 meter via het netwerk naar een ander gedeelte in huis te versturen.

Doormiddel van ser2net of socat kan je dat mappen aan een pseudo tty, welke vervolgens aan dsmr-reader gekoppeld kan worden. Maar op sommige systemen waar men gebruik maakt van docker (op een Synology, of op Hassio) daar kan men dit niet gebruiken. Het zou een mooie aanvulling zijn als er direct een netwerk socket gebruikt kan worden als bijvoorbeeld telnet (welke ik gebruik met esp-link).

Zie hier een paar van mijn creaties: 4005954 4119630

dennissiemensma commented 4 years ago

@digiater bedankt voor de update, fijn om te horen!

dennissiemensma commented 4 years ago

@zuidwijk bedankt voor je verzoek. In principe kan ik daar wel wat voor maken, maar ik heb dan wel veel meer specs nodig. En daarnaast kan ik het zelf ook niet testen en dat helpt niet bij ontwikkelen.

Specs zoals:


Als workaround zou je ook nog de rauwe telegram data via de API van DSMR-reader kunnen pushen, zonder ser2net via zo'n netwerkmodule. Dat is per telegram een POST-request.

zuidwijk commented 4 years ago

Inprincipe kan je het beschouwen als een gewone tty zoals de usb kabel. De telegrams die je ziet binnenkomen via USB zijn exact hetzelfde als via de telnet sessie.

Als ik met socat een pseudo tty aanmaak, dan kan je deze vervolges gewoon als tty doorgeven aan dsmr:

$ cat /etc/systemd/system/socat.service 
[Unit]
Description=Socat

[Service]
Type=simple
ExecStart=/usr/bin/socat -U pty,link=/dev/virtualcom0,raw tcp:10.0.0.10:23&
User=root
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Onderstaand screenshot, laat zien wat de output is, het zijn exact dezelfde telegrammen als wat een usb-kabel geeft, alleen dan over het netwerk:

P1-reading-over-network

Ik heb een kort videotje gemaakt om te laten zien wat de werking/output is: P1-reading-recording.mp4.zip

Als je een netwerk-module nodig hebt, kan ik je er 1 opsturen om te ontwikkelen ;)

zuidwijk commented 4 years ago

Ik vergeet te reageren over de API, dat zou alleen kunnen met de WiFi modules, omdat daar een ESP op zit waar je code op kunt plaatsen. Echter de ethernet modules zijn niks anders dan "domme" doorgeefluiken. Ze sturen de ontvangen seriële data door via het netwerk. Daar kan ik geen eigen code opzetten.

dennissiemensma commented 4 years ago

Bedankt voor de toelichting! In dat geval lijkt het inderdaad niet heel spannend. Ik zal kijken of ik iets kan maken voor een 4.x release.

Ik neem aan dat je momenteel ook Docker gebruikt of heb je de handmatige DSMR-reader installatie draaien? Dit ivm testen.

zuidwijk commented 4 years ago

Ik maak momenteel gebruik van de docker variant van xirixiz (Bram), momenteel versie 3.11. Zover ik weet is hij momenteel met vakantie, maar gaat ie wel kijken naar release 4. Dus ik ben benieuwd :)

dennissiemensma commented 4 years ago

Staat klaar voor de v4.1 release. Flinke refactoring:

Configuratie voor standaard-installatie kan gewoon via admin:

Selection_002

Getest met ser2net lokaal.

dennissiemensma commented 4 years ago

Uitgebracht in v4.1

dennissiemensma commented 4 years ago

Ik kom er trouwens net achter dat de pyserial library voor de seriele poort uitlezen, ook ondersteuning heeft voor netwerk sockets. Ik zal kijken of ik dat in een latere versie ga refactoren.

zuidwijk commented 4 years ago

Nice! Ik wacht nu met smart op Bram z'n terugkomst van z'n vakantie 😁👍🏼

digiater commented 4 years ago

Zojuist een upgrade gedaan naar v4.1.1, maar ik krijg de logger niet meer aan de gang.

dit is ingevuld bij network socket address:

http://dsmrlogger.xxxx.nl/api/v1/sm/telegram

port staat op 80. logging is aangezet, DSMRREADER_LOGLEVEL=DEBUG in .env gezet.

Ik kan geen logfile ontdekken, in ~dsmr/logs staan alleen oude logs.

Wat te doen?

dennissiemensma commented 4 years ago

Je kunt het beste even de Supervisor logs zoals genoemd in de docs bekijken: https://dsmr-reader.readthedocs.io/nl/latest/troubleshooting.html

Wat betreft de datalogger, de URL die je aanroept lijkt me geen socket maar een HTTP API. De netwerksockets die ondersteund worden zijn zaken zoals ser2net en vergelijkbare tools, waarvoor DSMR-reader geen protocol hoeft te kennen.

Ik denk dat je het beste bij de eerdere plugin kunt blijven.

digiater commented 4 years ago

ok ik heb de plugin er weer ingehangen en dat werkt weer. de nieuwe socket interface is in mijn geval dus niet bruikbaar. voor de rest lijkt alles weer goed te werken.

voor wat de logging betreft had ik op een verkeerde plek gekeken.

Bedankt.