xirixiz / dsmr-reader-docker

DSMR Reader in Docker.
https://hub.docker.com/r/xirixiz/dsmr-reader-docker
112 stars 33 forks source link

ENV DSMRREADER_REMOTE_DATALOGGER_INPUT_METHOD not working #329

Closed bsmeding closed 1 year ago

bsmeding commented 1 year ago

Support guidelines

I've found an issue and checked that ...

Description

I try to automate the setup of my DSMR environment en test. I use a remote logger on IP socket.

See issue 303 with the same question only not solved in this issue.

I want to automatically set the correct logger, so not manual after the deployment but with the environment variables that are made for this configuration part only they doesn't apply, when settings this environment vars:

- DSMRREADER_REMOTE_DATALOGGER_MODE=standalone
- DSMRREADER_REMOTE_DATALOGGER_INPUT_METHOD=ipv4
- DSMRREADER_REMOTE_DATALOGGER_NETWORK_HOST=192.168.123.10
- DSMRREADER_REMOTE_DATALOGGER_NETWORK_PORT=23

The DSMR still configured as Standalone -> Serial -> '/dev/ttyUSB0'

Expected behaviour

IPv4 socket used with IP address and port configured in the ENV

Actual behaviour

Default configuration of serial and /dev/ttyUSB0

Steps to reproduce

  1. Set environment vars as listed above or in documentation
  2. Deploy container
  3. Check Datalogger section

Docker info

Client:
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.10.4
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.17.2
    Path:     /usr/libexec/docker/cli-plugins/docker-compose
  scan: Docker Scan (Docker Inc.)
    Version:  v0.23.0
    Path:     /usr/libexec/docker/cli-plugins/docker-scan

Server:
 Containers: 2
  Running: 2
  Paused: 0
  Stopped: 0
 Images: 2
 Server Version: 23.0.2
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 1e1ea6e986c6c86565bc33d52e34b81b3e2bc71f
 runc version: v1.1.4-0-g5fd4c4d
 init version: de40ad0
 Security Options:
  apparmor
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 5.15.0-67-generic
 Operating System: Ubuntu 22.04.2 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 3.799GiB
 Name: ubuntubase
 ID: d0dfa9b3-7b25-4966-8ca7-8442ed34e716
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

### Version

* Docker compose version (type `docker-compose --version`): `Docker version 23.0.2, build 569dd73`
* System info (type `uname -a`): `Linux ubuntubase 5.15.0-67-generic #74-Ubuntu SMP Wed Feb 22 14:14:39 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux`

### Docker compose

```yaml
Don't use docker-compose

Container logs

LOGS:

Traceback (most recent call last):
  File "/app/dsmr_datalogger/scripts/dsmr_datalogger_api_client.py", line 39, in read_telegram
    serial_handle = serial.serial_for_url(
                    ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/serial/__init__.py", line 90, in serial_for_url
    instance.open()
  File "/usr/local/lib/python3.11/site-packages/serial/serialposix.py", line 325, in open
    raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
serial.serialutil.SerialException: [Errno 2] could not open port /dev/ttyUSB0: [Errno 2] No such file or directory: '/dev/ttyUSB0'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/app/dsmr_backend/mixins.py", line 96, in run_once
    self.run(data=self.data, **options)
  File "/app/dsmr_datalogger/management/commands/dsmr_datalogger.py", line 29, in run
    telegram = next(self.telegram_generator)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/dsmr_datalogger/scripts/dsmr_datalogger_api_client.py", line 43, in read_telegram
    raise RuntimeError("Failed to connect: {}", error) from error
RuntimeError: ('Failed to connect: {}', SerialException(2, "could not open port /dev/ttyUSB0: [Errno 2] No such file or directory: '/dev/ttyUSB0'"))

Starting DSMR Reader - datalogger...
Current logging level set to "WARNING". More information can be found here: https://dsmr-reader.readthedocs.io/en/latest/how-to/troubleshooting/enabling-debug-logging.html
2023-03-30 19:35:31,565 ERROR    mixins       run_once                        107 | dsmr_datalogger.management.commands.dsmr_datalogger: [!] Exception raised. Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/serial/serialposix.py", line 322, in open
    self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/dev/ttyUSB0'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/app/dsmr_datalogger/scripts/dsmr_datalogger_api_client.py", line 39, in read_telegram
    serial_handle = serial.serial_for_url(
                    ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/serial/__init__.py", line 90, in serial_for_url
    instance.open()
  File "/usr/local/lib/python3.11/site-packages/serial/serialposix.py", line 325, in open
    raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
serial.serialutil.SerialException: [Errno 2] could not open port /dev/ttyUSB0: [Errno 2] No such file or directory: '/dev/ttyUSB0'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/app/dsmr_backend/mixins.py", line 96, in run_once
    self.run(data=self.data, **options)
  File "/app/dsmr_datalogger/management/commands/dsmr_datalogger.py", line 29, in run
    telegram = next(self.telegram_generator)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/dsmr_datalogger/scripts/dsmr_datalogger_api_client.py", line 43, in read_telegram
    raise RuntimeError("Failed to connect: {}", error) from error
RuntimeError: ('Failed to connect: {}', SerialException(2, "could not open port /dev/ttyUSB0: [Errno 2] No such file or directory: '/dev/ttyUSB0'"))

Docker inspect - CONFIG:

       "Config": {
            "Hostname": "bf7237aa4bb6",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "ExposedPorts": {
                "443/tcp": {},
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "TZ=Europe/Paris",
                "PUID=1040",
                "GUID=1001",
                "DJANGO_TIME_ZONE=Europe/Paris",
                "VIRTUAL_HOST=localhost",
                "DUID=1040",
                "DGID=1001",
                "DISABLE_NGINX_ACCESS_LOGS=true",
                "DSMRREADER_ADMIN_USER=admin",
                "DSMRREADER_ADMIN_PASSWORD=admin",
                "DSMRREADER_LOGLEVEL=WARNING",
                "DJANGO_SECRET_KEY=dsmrreader",
                "DSMRREADER_SUPPRESS_STORAGE_SIZE_WARNINGS=True",
                "ENABLE_IFRAME=False",
                "VACUUM_DB_ON_STARTUP=true",
                "DJANGO_DATABASE_ENGINE=django.db.backends.postgresql",
                "DJANGO_DATABASE_NAME=dsmrreader",
                "DJANGO_DATABASE_USER=dsmrreader",
                "DJANGO_DATABASE_PASSWORD=dsmrreader",
                "DJANGO_DATABASE_HOST=dsmr_db",
                "DJANGO_DATABASE_PORT=5432",
                "DJANGO_DATABASE_CONN_MAX_AGE=60",
                "DSMRREADER_REMOTE_DATALOGGER_INPUT_METHOD=ipv4",
                "DSMRREADER_REMOTE_DATALOGGER_NETWORK_HOST=192.168.10.10",
                "DSMRREADER_REMOTE_DATALOGGER_NETWORK_PORT=23",
                "PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "LANG=C.UTF-8",
                "GPG_KEY=A035C8C19219BA821ECEA86B64E628F8D684696D",
                "PYTHON_VERSION=3.11.2",
                "PYTHON_PIP_VERSION=22.3.1",
                "PYTHON_SETUPTOOLS_VERSION=65.5.1",
                "PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/d5cb0afaf23b8520f1bbcfed521017b4a95f5c01/public/get-pip.py",
                "PYTHON_GET_PIP_SHA256=394be00f13fa1b9aaa47e911bdb59a09c3b2986472130f30aa0bfaf7f3980637",
                "PS1=$(whoami)@dsmr_reader_docker:$(pwd)\\$ ",
                "TERM=xterm",
                "QEMU_ARCH=x86_64",
                "S6_BEHAVIOUR_IF_STAGE2_FAILS=2",
                "DSMR_VERSION=5.10.3",
                "DOCKER_TARGET_RELEASE=2023.03.02",
                "DSMRREADER_OPERATION_MODE=standalone",
                "DSMRREADER_REMOTE_DATALOGGER_SERIAL_PORT=/dev/ttyUSB0",
                "DSMRREADER_REMOTE_DATALOGGER_SERIAL_BAUDRATE=115200",
                "DSMRREADER_REMOTE_DATALOGGER_SERIAL_BYTESIZE=8",
                "DSMRREADER_REMOTE_DATALOGGER_SERIAL_PARITY=N"
            ],
            "Cmd": null,
            "Healthcheck": {
                "Test": [
                    "CMD",
                    "curl",
                    "-Lsf",
                    "http://127.0.0.1/about",
                    "-o",
                    "/dev/null",
                    "-w",
                    "HTTP_%{http_code}"
                ],
                "Interval": 10000000000,
                "Timeout": 5000000000,
                "Retries": 10
            },
            "Image": "xirixiz/dsmr-reader-docker",
            "Volumes": null,
            "WorkingDir": "/app",
            "Entrypoint": [
                "/init"
            ],
            "OnBuild": null,
            "Labels": {
                "org.opencontainers.image.created": "2023-03-20T13:59:16.701Z",
                "org.opencontainers.image.description": "DSMR Reader in Docker.",
                "org.opencontainers.image.licenses": "",
                "org.opencontainers.image.revision": "a3888dd10c41e395a3450f22c9b2dd34d232a5b0",
                "org.opencontainers.image.source": "https://github.com/xirixiz/dsmr-reader-docker",
                "org.opencontainers.image.title": "dsmr-reader-docker",
                "org.opencontainers.image.url": "https://github.com/xirixiz/dsmr-reader-docker",
                "org.opencontainers.image.version": "5.10.3-2023.03.02"
            }
        }

Additional info

No response

bsmeding commented 1 year ago

I searched trough the code and see that the settings must be saved in .env, when checking that file that is correct

root@dsmr_reader_docker:/app# cat .env
DSMRREADER_REMOTE_DATALOGGER_INPUT_METHOD=ipv4
DSMRREADER_REMOTE_DATALOGGER_NETWORK_HOST=192.168.10.10
DSMRREADER_REMOTE_DATALOGGER_NETWORK_PORT=23
DSMRREADER_LOGLEVEL=WARNING
root@dsmr_reader_docker:/app#
xirixiz commented 1 year ago

Hi @bsmeding, we kunnen het ook in het Nederlands over hebben volgens mij. Omdat het opgelost werd met handmatig instellen heb ik er geen tijd meer aan besteed. Ik heb wel de code destijds aangepast voor de verschillende modi waarin DSMR Reader gestart kan worden.

Wellicht heeft @dennissiemensma een aanvulling waarom de settings uit de .env file niet gezet worden in de app settings zelf.

bsmeding commented 1 year ago

Ja dat kan inderdaad ben zo gewend het in Engels te doen ging automatisch 🙂

Vreemd is dat ze inderdaad wel juist worden geladen als env, maar niks mee wordt gedaan verder in de app

Wacht verdere reactie van @dennissiemensma af

dennissiemensma commented 1 year ago

Als ik de aanname mag doen dat je de hele DSMR-reader applicatie draait en daarbij DSMRREADER_REMOTE_DATALOGGER_INPUT_METHOD gebruikt, dan gaat die combinatie niet werken.

De envvars voor de remote datalogger zijn alleen voor wanneer het datalogger script zonder DSMR-reader draait. Dit omdat er dan dus ook geen database-instelling is die gebruikt kan worden.

Eerdere versies van het remote datalogger script vereisten nog dat iemand in de eigen kopie instellingen moest aanpassen, zoals in v3:

Later is dat veranderd naar envvars, maar dus puur voor bovenstaande use-case.


Als je DSMR-reader gebruikt zul je het via de database of GUI moeten instellen. Alleen staat dat wellicht niet expliciet in de docs:

Het is wellicht wat verwarrend omdat het script zowel los werkend uit de repo te downloaden is:

Als ook door DSMR-reader zelf gebruikt wordt, bij een volledige installatie:


Echter wordt alles qua envvars in dat script niet gebruikt door DSMR-reader, alleen als het direct via de command-line als individueel script gedraaid wordt met letterlijk: python3 dsmr_datalogger_api_client.py:

dennissiemensma commented 1 year ago

Overigens kun je uiteraard ook zonder GUI de instellingen wijzigen, direct in de database, alleen zul je moeten opletten dat je geen ongeldige waardes invoert, omdat er dan geen validatie van de GUI op zit.

De datalogger instellingen staan in dsmr_datalogger_dataloggersettings:

select * from dsmr_datalogger_dataloggersettings;
 id | serial_port  | dsmr_version | process_sleep | input_method | network_socket_address | network_socket_port | restart_required | override_telegram_timestamp | dsmr_extra_device_channel 
----+--------------+--------------+---------------+--------------+------------------------+---------------------+------------------+-----------------------------+---------------------------
  1 | /dev/ttyUSB0 |            4 |           0.5 | serial       | localhost              |                4000 | f                | f                           |                          
(1 row)
bsmeding commented 1 year ago

Hi @dennissiemensma ik gebruik inderdaad de hele applicatie zoals in deze repo in Docker. Gezien ik alle applicaties die ik draai via automatisch (Ansible) uitrol op mijn servers wil ik ook de configuratie hiervan automatisch instellen zodat ik een Test en Productie omgeving heb en hiermee beter versie upgrades kan doen.

Vandaar dat ik probeer om een kant en klaar pakket (Ansible Role) te maken waarin zonder manuele handelingen in de GUI alles weer werkt. En het liefst ook niet direct in een Database werken.

De ENV vars lijken te doen wat ik nodig had, maar ik lees dat dit alleen is als de logger en reader apart worden gebruikt? Als ik er twee aparte containers van maak zou het wel moeten werken? Een voor Logger en een voor de Reader?

dennissiemensma commented 1 year ago

Bedankt voor je aanvulling! Technisch gezien kun je het proberen, alleen is het dus niet op die manier ervoor gemaakt, dus je kunt alsnog tegen dingen aanlopen die je niet op die manier kan configueren. Plus dat een remote datalogger complexiteit toevoegt als je hem niet nodig hebt. Verder zullen er misschien meer instellingen zijn in DSMR-reader die je wellicht wilt provisionen naar je eigen defaults bij een re-install/upgrade, maar dus ook in de database staan.

Mijn advies is om (als je eigen probeersel niet werkt), UPDATE-queries te gebruiken door dergelijke instellingen, zodat je het vooral simpel en onderhoudbaar voor jezelf houdt. Omdat het update-queries zijn voor instellingen, zijn ze tevens idempotent en kun je ze zonder gevolgen vaker uitvoeren, wat meestal wel wenselijk is bij playbooks.

bsmeding commented 1 year ago

Ok dank je duidelijk, jammer dat het niet met de ENV werkt of een config file.

Ik zal zelf nog beide scenario's testen kijken of het op een gedegen manier lukt om dit te automatiseren. Rechtstreeks in de DB ben ik niet zo een voorstander van, maar wellicht de oplossing.

beide bedankt voor de feedback!

xirixiz commented 1 year ago

Heldere en waardevolle info heren, bedankt! Zou het mogelijk zijn om dit soort zaken middels een API te configureren? Het is maar iets dat mij te binnen schiet. Ik heb geen idee of het veel werk is iets dergelijks toe te voegen.

wimleers commented 8 months ago

Ik ben hier zonet ook tegen aan gelopen. En eerder ook https://github.com/xirixiz/dsmr-reader-docker/issues/303#issuecomment-1345186020.

~Waarom is dit gesloten? 🤔~ Zou het mogelijk zijn om dit alsnog configureerbaar te maken via een environment variable? If not, zouden de docs dan kunnen verduidelijkt worden, zodat gebruikers van "seriële poort via ethernet" ook de juiste richting uitgeduwd worden?

Voor context: in België is het níet zo dat de meter in je appartement staat! Die staat in de "gemeenschappelijke delen". Een P1-kabel van daar tot in je appartement is quasi nooit mogelijk. Blijft over: WiFi of Ethernet!

dennissiemensma commented 8 months ago

@wimleers helpt dit je niet verder? https://github.com/xirixiz/dsmr-reader-docker/issues/303#issuecomment-1345268194

Afhankelijk van wat je exact dichtbij je slimme meter hebt staan, kun je het daar laten forwarden naar de DSMR-installatie binnen je netwerk binnen. Of je kunt iets draaien wat de meter serieel uitleest en het via je netwerk beschikbaar maakt via ser2net, waardoor DSMR-reader er ook bij kan (mits op hetzelfde netwerk uiteraard).