From 1e728d793785f6630753c48578676721261cbb66 Mon Sep 17 00:00:00 2001
From: Basti <89860334+Xerolux@users.noreply.github.com>
Date: Sun, 3 May 2026 16:33:31 +0200
Subject: [PATCH 1/2] Big openWB Update 2026
---
.github/workflows/github-actions-python.yml | 8 +-
.gitignore | 3 +-
.htaccess | 11 -
README.md | 9 +-
data/config/apache/000-default.conf | 45 --
data/config/apache/apache-openwb-ssl.conf | 149 ------
data/config/apache/apache-proplus.conf | 12 -
data/config/apache/apache-redirect-ssl.conf | 29 --
data/config/apache/http-api-ssl.conf | 141 ------
data/config/apache/localhost.conf | 47 --
data/config/caddy/Caddyfile | 212 +++++++++
data/config/chrony/chrony.conf | 32 ++
.../mosquitto/public/openwb-default-acl.conf | 2 +-
.../public/openwb-user-management.conf | 2 +-
data/config/openwb-simpleAPI.service | 4 +-
data/config/openwb2.service | 4 +-
data/config/openwbRemoteSupport.service | 4 +-
data/config/php/fpm/20-uploadlimit.ini | 2 +
data/config/profile.d/99-openwb-motd.sh | 45 ++
data/config/sudoers/apache2 | 2 -
data/config/sudoers/caddy | 2 +
.../sample_modbus/sample_modbus/bat.py | 6 +-
.../sample_modbus/sample_modbus/counter.py | 4 +-
.../sample_modbus/sample_modbus/inverter.py | 4 +-
openwb-install.sh | 62 ++-
packages/control/ocpp.py | 22 +-
packages/helpermodules/broker.py | 4 +-
packages/helpermodules/create_debug.py | 7 +-
packages/modbus_control_tester.py | 18 +-
.../chargepoint_module.py | 8 +-
packages/modules/common/b23.py | 16 +-
packages/modules/common/evse.py | 18 +-
packages/modules/common/lovato.py | 10 +-
packages/modules/common/modbus.py | 24 +-
packages/modules/common/mpm3pm.py | 18 +-
packages/modules/common/pymodbus_compat.py | 118 +++++
packages/modules/common/sdm.py | 36 +-
packages/modules/conftest.py | 12 +-
.../modules/devices/algodue/algodue/bat.py | 4 +-
.../devices/algodue/algodue/counter.py | 16 +-
.../devices/algodue/algodue/inverter.py | 4 +-
.../devices/alpha_ess/alpha_ess/bat.py | 16 +-
.../devices/alpha_ess/alpha_ess/counter.py | 14 +-
.../devices/alpha_ess/alpha_ess/inverter.py | 2 +-
packages/modules/devices/ampere/ampere/bat.py | 4 +-
.../modules/devices/ampere/ampere/counter.py | 4 +-
.../modules/devices/ampere/ampere/inverter.py | 4 +-
.../devices/azzurro_zcs/azzurro_zcs/bat.py | 8 +-
.../azzurro_zcs/azzurro_zcs/counter.py | 10 +-
.../azzurro_zcs/azzurro_zcs/inverter.py | 12 +-
.../azzurro_zcs/azzurro_zcs_3p/pv_inverter.py | 10 +-
.../carlo_gavazzi/carlo_gavazzi/counter.py | 10 +-
.../modules/devices/chint/chint/counter.py | 20 +-
packages/modules/devices/deye/deye/bat.py | 14 +-
packages/modules/devices/deye/deye/counter.py | 16 +-
.../modules/devices/deye/deye/inverter.py | 6 +-
packages/modules/devices/e3dc/e3dc/bat.py | 4 +-
packages/modules/devices/e3dc/e3dc/counter.py | 2 +-
.../devices/e3dc/e3dc/external_inverter.py | 2 +-
.../modules/devices/e3dc/e3dc/inverter.py | 2 +-
.../modules/devices/fox_ess/fox_ess/bat.py | 8 +-
.../devices/fox_ess/fox_ess/counter.py | 8 +-
.../devices/fox_ess/fox_ess/inverter.py | 4 +-
.../modules/devices/good_we/good_we/bat.py | 30 +-
.../devices/good_we/good_we/counter.py | 16 +-
.../devices/good_we/good_we/inverter.py | 4 +-
.../modules/devices/growatt/growatt/bat.py | 20 +-
.../devices/growatt/growatt/counter.py | 28 +-
.../devices/growatt/growatt/inverter.py | 8 +-
packages/modules/devices/huawei/huawei/bat.py | 4 +-
.../modules/devices/huawei/huawei/counter.py | 4 +-
.../modules/devices/huawei/huawei/inverter.py | 2 +-
.../modules/devices/huawei/huawei_emma/bat.py | 4 +-
.../devices/huawei/huawei_emma/counter.py | 4 +-
.../devices/huawei/huawei_emma/inverter.py | 4 +-
.../devices/huawei/huawei_smartlogger/bat.py | 4 +-
.../huawei/huawei_smartlogger/counter.py | 8 +-
.../huawei/huawei_smartlogger/inverter.py | 4 +-
packages/modules/devices/idm/idm/counter.py | 4 +-
.../modules/devices/janitza/janitza/bat.py | 2 +-
.../devices/janitza/janitza/counter.py | 12 +-
.../devices/janitza/janitza/inverter.py | 2 +-
.../modules/devices/kaco/kaco_tx/scale.py | 2 +-
.../devices/kostal/kostal_piko_ci/counter.py | 6 +-
.../devices/kostal/kostal_piko_ci/inverter.py | 6 +-
.../devices/kostal/kostal_plenticore/bat.py | 14 +-
.../kostal/kostal_plenticore/counter.py | 14 +-
.../kostal/kostal_plenticore/device.py | 4 +-
.../kostal/kostal_plenticore/inverter.py | 8 +-
.../devices/kostal/kostal_sem/counter.py | 14 +-
.../modules/devices/marstek/venus_c_e/bat.py | 4 +-
packages/modules/devices/mtec/mtec/bat.py | 8 +-
packages/modules/devices/mtec/mtec/counter.py | 4 +-
.../modules/devices/mtec/mtec/inverter.py | 2 +-
packages/modules/devices/nibe/nibe/counter.py | 4 +-
packages/modules/devices/orno/orno/counter.py | 4 +-
packages/modules/devices/orno/orno/device.py | 4 +-
.../devices/powerdog/powerdog/counter.py | 6 +-
.../devices/powerdog/powerdog/inverter.py | 2 +-
packages/modules/devices/qcells/qcells/bat.py | 8 +-
.../modules/devices/qcells/qcells/counter.py | 16 +-
.../modules/devices/qcells/qcells/inverter.py | 12 +-
.../modules/devices/saxpower/saxpower/bat.py | 2 +-
.../devices/saxpower/saxpower/counter.py | 2 +-
.../modules/devices/siemens/siemens/bat.py | 4 +-
.../devices/siemens/siemens/counter.py | 2 +-
.../devices/siemens/siemens/inverter.py | 2 +-
.../devices/siemens/siemens_sentron/bat.py | 6 +-
.../siemens/siemens_sentron/counter.py | 16 +-
.../siemens/siemens_sentron/inverter.py | 4 +-
.../devices/sigenergy/sigenergy/bat.py | 8 +-
.../devices/sigenergy/sigenergy/counter.py | 4 +-
.../devices/sigenergy/sigenergy/inverter.py | 2 +-
.../modules/devices/sma/sma_sunny_boy/bat.py | 10 +-
.../sma/sma_sunny_boy/bat_smart_energy.py | 4 +-
.../devices/sma/sma_sunny_boy/bat_tesvolt.py | 4 +-
.../devices/sma/sma_sunny_boy/counter.py | 4 +-
.../devices/sma/sma_sunny_boy/inverter.py | 26 +-
.../devices/sma/sma_sunny_island/bat.py | 6 +-
packages/modules/devices/sofar/sofar/bat.py | 10 +-
.../modules/devices/sofar/sofar/counter.py | 14 +-
.../modules/devices/sofar/sofar/inverter.py | 4 +-
.../devices/solakon/solakon_one/bat.py | 8 +-
.../devices/solakon/solakon_one/inverter.py | 4 +-
.../devices/solaredge/solaredge/bat.py | 10 +-
.../devices/solaredge/solaredge/counter.py | 2 +-
.../solaredge/solaredge/external_inverter.py | 2 +-
.../devices/solaredge/solaredge/inverter.py | 2 +-
.../devices/solaredge/solaredge/meter.py | 6 +-
.../modules/devices/solarmax/solarmax/bat.py | 20 +-
.../solarmax/solarmax/counter_maxstorage.py | 4 +-
.../devices/solarmax/solarmax/inverter.py | 2 +-
.../solarmax/solarmax/inverter_maxstorage.py | 4 +-
packages/modules/devices/solax/solax/bat.py | 4 +-
.../modules/devices/solax/solax/counter.py | 24 +-
.../modules/devices/solax/solax/inverter.py | 14 +-
packages/modules/devices/solis/solis/bat.py | 8 +-
.../modules/devices/solis/solis/counter.py | 10 +-
.../modules/devices/solis/solis/inverter.py | 8 +-
packages/modules/devices/studer/studer/bat.py | 8 +-
.../modules/devices/studer/studer/inverter.py | 4 +-
.../devices/sungrow/sungrow_ihm/bat.py | 24 +-
.../devices/sungrow/sungrow_ihm/counter.py | 8 +-
.../devices/sungrow/sungrow_ihm/inverter.py | 2 +-
.../devices/sungrow/sungrow_micro/inverter.py | 2 +-
.../devices/sungrow/sungrow_sg/counter.py | 10 +-
.../devices/sungrow/sungrow_sg/inverter.py | 6 +-
.../modules/devices/sungrow/sungrow_sh/bat.py | 48 +-
.../devices/sungrow/sungrow_sh/counter.py | 12 +-
.../devices/sungrow/sungrow_sh/inverter.py | 6 +-
.../devices/thermia/thermia/counter.py | 10 +-
packages/modules/devices/upower/upower/bat.py | 12 +-
.../modules/devices/upower/upower/counter.py | 16 +-
.../modules/devices/upower/upower/inverter.py | 8 +-
.../modules/devices/varta/varta/bat_modbus.py | 4 +-
.../modules/devices/varta/varta/counter.py | 2 +-
.../modules/devices/varta/varta/inverter.py | 2 +-
.../modules/devices/victron/victron/bat.py | 30 +-
.../devices/victron/victron/counter.py | 8 +-
.../devices/victron/victron/inverter.py | 6 +-
.../devices/victron/victron_3p75ct/counter.py | 14 +-
.../internal_chargepoint_handler.py | 2 +-
.../internal_chargepoint_handler_config.py | 2 +-
.../internal_chargepoint_handler/rfid.py | 255 +++++------
packages/modules/io_devices/dimm_kit/api.py | 10 +-
packages/modules/smarthome/acthor/watt.py | 8 +-
packages/modules/smarthome/askoheat/watt.py | 8 +-
packages/modules/smarthome/elwa/watt.py | 8 +-
packages/modules/smarthome/idm/watt.py | 16 +-
packages/modules/smarthome/lambda_/off.py | 4 +-
packages/modules/smarthome/lambda_/on.py | 4 +-
packages/modules/smarthome/lambda_/watt.py | 10 +-
packages/modules/smarthome/mqtt/off.py | 2 +-
packages/modules/smarthome/mqtt/on.py | 2 +-
packages/modules/smarthome/mqtt/watt.py | 2 +-
packages/modules/smarthome/nibe/watt.py | 6 +-
packages/modules/smarthome/nxdacxx/off.py | 4 +-
packages/modules/smarthome/nxdacxx/on.py | 4 +-
packages/modules/smarthome/nxdacxx/watt.py | 10 +-
packages/modules/smarthome/ratiotherm/watt.py | 6 +-
packages/modules/smarthome/stiebel/off.py | 4 +-
packages/modules/smarthome/stiebel/on.py | 4 +-
packages/modules/smarthome/vampair/off.py | 4 +-
packages/modules/smarthome/vampair/on.py | 4 +-
packages/modules/smarthome/vampair/watt.py | 6 +-
packages/modules/smarthome/viessmann/off.py | 4 +-
packages/modules/smarthome/viessmann/on.py | 4 +-
packages/modules/smarthome/we514/watt.py | 10 +-
packages/modules/vehicles/ovms/api.py | 4 +-
packages/modules/vehicles/tronity/api.py | 4 +-
packages/modules/vehicles/vwgroup/vwgroup.py | 4 +-
packages/smarthome/smartcommon.py | 6 +-
packages/tools/modbus_finder.py | 10 +-
packages/tools/modbus_tester.py | 8 +-
requirements-dev.txt | 2 +
requirements.txt | 50 +-
runs/atreboot.sh | 109 +++--
runs/backup.sh | 2 +-
runs/evse_read_modbus.py | 2 +-
runs/evse_write_modbus.py | 2 +-
runs/evsewritembusdev.py | 6 +-
runs/install_packages.sh | 50 +-
runs/platform_detect.sh | 99 ++++
runs/readmodbus.py | 6 +-
runs/remoteSupport/remoteSupport.py | 2 +-
runs/setup_apache2.sh | 156 -------
runs/setup_caddy.sh | 212 +++++++++
runs/setup_mosquitto.sh | 13 +-
runs/setup_network.sh | 13 +-
runs/upgrade_stack.sh | 429 ++++++++++++++++++
simpleAPI/simpleAPI_mqtt.py | 2 +-
211 files changed, 2185 insertions(+), 1579 deletions(-)
delete mode 100644 .htaccess
delete mode 100644 data/config/apache/000-default.conf
delete mode 100644 data/config/apache/apache-openwb-ssl.conf
delete mode 100644 data/config/apache/apache-proplus.conf
delete mode 100644 data/config/apache/apache-redirect-ssl.conf
delete mode 100644 data/config/apache/http-api-ssl.conf
delete mode 100644 data/config/apache/localhost.conf
create mode 100644 data/config/caddy/Caddyfile
create mode 100644 data/config/chrony/chrony.conf
create mode 100644 data/config/php/fpm/20-uploadlimit.ini
create mode 100644 data/config/profile.d/99-openwb-motd.sh
delete mode 100644 data/config/sudoers/apache2
create mode 100644 data/config/sudoers/caddy
create mode 100644 packages/modules/common/pymodbus_compat.py
create mode 100644 requirements-dev.txt
create mode 100644 runs/platform_detect.sh
delete mode 100755 runs/setup_apache2.sh
create mode 100644 runs/setup_caddy.sh
create mode 100644 runs/upgrade_stack.sh
diff --git a/.github/workflows/github-actions-python.yml b/.github/workflows/github-actions-python.yml
index e942a8e893..0ca01ff4c0 100644
--- a/.github/workflows/github-actions-python.yml
+++ b/.github/workflows/github-actions-python.yml
@@ -5,15 +5,19 @@ on: pull_request
jobs:
build:
runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: ["3.10", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- - name: Set up Python 3.9
+ - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
- python-version: "3.9.12"
+ python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip3 install -r "/home/runner/work/core/core/requirements.txt"
+ pip3 install -r "/home/runner/work/core/core/requirements-dev.txt"
- name: Flake8 with annotations in packages folder
uses: TrueBrain/actions-flake8@v2.1
with:
diff --git a/.gitignore b/.gitignore
index 57189a06cb..5e006c7f24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,4 +21,5 @@ data/restore/*.tar.gz
data/data_migration/*.tar.gz
ramdisk/*
web/lastcommit
-!.gitignore
+.stack-version
+!.gitignore
diff --git a/.htaccess b/.htaccess
deleted file mode 100644
index 6b43667dee..0000000000
--- a/.htaccess
+++ /dev/null
@@ -1,11 +0,0 @@
-
- Header set Cache-Control "no-cache, no-store, must-revalidate"
- Header set Pragma "no-cache"
- Header set Expires 0
-
-
-RedirectMatch 404 \.conf$
-RedirectMatch 404 \.ini$
-RedirectMatch 404 \.py$
-RedirectMatch 404 \.sh$
-ErrorDocument 404 /openWB/web/error.html
diff --git a/README.md b/README.md
index 14b32635c5..4db6999995 100644
--- a/README.md
+++ b/README.md
@@ -33,11 +33,10 @@ Bei fertig erworbenen openWB ist die Software bereits vorinstalliert.
Software:
- Installiertes Raspberry Pi OS auf einem Raspberry Pi 3b oder besser.
-- Raspberry Pi OS Lite installieren. Aktuell wird in der Version 2.1 nur **Debian 11 "Bullseye"** (derzeit "oldstable") unterstützt.
-
-- alternativ kann auch ein x86_64 System (Hardware oder als VM) mit installiertem **Debian 11 "Bullseye"** als Basis verwendet werden.
-- Eine Installation unter **Debian 12 "Bookworm"** wird noch nicht unterstützt!
-- Bitte beachten das **Debian 11 "Bullseye"** nur mit erheblichem Aufwand mit einem Raspberry Pi 5 kompatibel ist. Wir empfehlen die Nutzung von einem Raspberry Pi 3b.
+- Raspberry Pi OS Lite installieren. Unterstützt werden **Debian 12 "Bookworm"** und **Debian 13 "Trixie"**.
+- alternativ kann auch ein x86_64 System (Hardware oder als VM) mit installiertem **Debian 12 "Bookworm"** oder **Debian 13 "Trixie"** als Basis verwendet werden.
+- **Python 3.10 oder neuer** wird benötigt (Python 3.13 empfohlen).
+- Die Installation richtet automatisch ein Python Virtual Environment unter `/opt/openwb-venv` ein.
In der Shell folgendes eingeben:
diff --git a/data/config/apache/000-default.conf b/data/config/apache/000-default.conf
deleted file mode 100644
index 4a16b41bec..0000000000
--- a/data/config/apache/000-default.conf
+++ /dev/null
@@ -1,45 +0,0 @@
-# openwb-version:6
-
- # The ServerName directive sets the request scheme, hostname and port that
- # the server uses to identify itself. This is used when creating
- # redirection URLs. In the context of virtual hosts, the ServerName
- # specifies what hostname must appear in the request's Host: header to
- # match this virtual host. For the default virtual host (this file) this
- # value is not decisive as it is used as a last resort host regardless.
- # However, you must set it for any further virtual host explicitly.
- #ServerName www.example.com
-
- ServerAdmin webmaster@localhost
- DocumentRoot /var/www/html
- # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
- # error, crit, alert, emerg.
- # It is also possible to configure the loglevel for particular
- # modules, e.g.
- #LogLevel info ssl:warn
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- #CustomLog ${APACHE_LOG_DIR}/access.log combined
-
- AllowOverride All
- Require all granted
- Options -Indexes
-
-
- Options +Indexes
-
-
- Options +Indexes
-
- # For most configuration files from conf-available/, which are
- # enabled or disabled at a global level, it is possible to
- # include a line for only one particular virtual host. For example the
- # following line enables the CGI configuration for this host only
- # after it has been globally disabled with "a2disconf".
- #Include conf-available/serve-cgi-bin.conf
-
- # Proxy WebSocket and MQTT connections to Mosquitto
- # ToDo: remove /mqtt target once all clients use /ws
- ProxyPassMatch "^/(ws|mqtt)(/|$)" "ws://127.0.0.1:9003/"
-
-
-# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
diff --git a/data/config/apache/apache-openwb-ssl.conf b/data/config/apache/apache-openwb-ssl.conf
deleted file mode 100644
index ddd95d2a1f..0000000000
--- a/data/config/apache/apache-openwb-ssl.conf
+++ /dev/null
@@ -1,149 +0,0 @@
-# openwb-version:8
-
-
- ServerAdmin webmaster@localhost
-
- DocumentRoot /var/www/html
-
- # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
- # error, crit, alert, emerg.
- # It is also possible to configure the loglevel for particular
- # modules, e.g.
- #LogLevel info ssl:warn
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
- # For most configuration files from conf-available/, which are
- # enabled or disabled at a global level, it is possible to
- # include a line for only one particular virtual host. For example the
- # following line enables the CGI configuration for this host only
- # after it has been globally disabled with "a2disconf".
- #Include conf-available/serve-cgi-bin.conf
-
- # SSL Engine Switch:
- # Enable/Disable SSL for this virtual host.
- SSLEngine on
-
- # A self-signed (snakeoil) certificate can be created by installing
- # the ssl-cert package. See
- # /usr/share/doc/apache2/README.Debian.gz for more info.
- # If both key and certificate are stored in the same file, only the
- # SSLCertificateFile directive is needed.
- SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
- SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
-
- # Server Certificate Chain:
- # Point SSLCertificateChainFile at a file containing the
- # concatenation of PEM encoded CA certificates which form the
- # certificate chain for the server certificate. Alternatively
- # the referenced file can be the same as SSLCertificateFile
- # when the CA certificates are directly appended to the server
- # certificate for convinience.
- #SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
-
- # Certificate Authority (CA):
- # Set the CA certificate verification path where to find CA
- # certificates for client authentication or alternatively one
- # huge file containing all of them (file must be PEM encoded)
- # Note: Inside SSLCACertificatePath you need hash symlinks
- # to point to the certificate files. Use the provided
- # Makefile to update the hash symlinks after changes.
- #SSLCACertificatePath /etc/ssl/certs/
- #SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt
-
- # Certificate Revocation Lists (CRL):
- # Set the CA revocation path where to find CA CRLs for client
- # authentication or alternatively one huge file containing all
- # of them (file must be PEM encoded)
- # Note: Inside SSLCARevocationPath you need hash symlinks
- # to point to the certificate files. Use the provided
- # Makefile to update the hash symlinks after changes.
- #SSLCARevocationPath /etc/apache2/ssl.crl/
- #SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl
-
- # Client Authentication (Type):
- # Client certificate verification type and depth. Types are
- # none, optional, require and optional_no_ca. Depth is a
- # number which specifies how deeply to verify the certificate
- # issuer chain before deciding the certificate is not valid.
- #SSLVerifyClient require
- #SSLVerifyDepth 10
-
- # SSL Engine Options:
- # Set various options for the SSL engine.
- # o FakeBasicAuth:
- # Translate the client X.509 into a Basic Authorisation. This means that
- # the standard Auth/DBMAuth methods can be used for access control. The
- # user name is the `one line' version of the client's X.509 certificate.
- # Note that no password is obtained from the user. Every entry in the user
- # file needs this password: `xxj31ZMTZzkVA'.
- # o ExportCertData:
- # This exports two additional environment variables: SSL_CLIENT_CERT and
- # SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
- # server (always existing) and the client (only existing when client
- # authentication is used). This can be used to import the certificates
- # into CGI scripts.
- # o StdEnvVars:
- # This exports the standard SSL/TLS related `SSL_*' environment variables.
- # Per default this exportation is switched off for performance reasons,
- # because the extraction step is an expensive operation and is usually
- # useless for serving static content. So one usually enables the
- # exportation for CGI and SSI requests only.
- # o OptRenegotiate:
- # This enables optimized SSL connection renegotiation handling when SSL
- # directives are used in per-directory context.
- #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
-
- SSLOptions +StdEnvVars
-
-
- SSLOptions +StdEnvVars
-
-
- AllowOverride All
- Require all granted
- Options -Indexes
-
-
- Options +Indexes
-
-
- Options +Indexes
-
- # SSL Protocol Adjustments:
- # The safe and default but still SSL/TLS standard compliant shutdown
- # approach is that mod_ssl sends the close notify alert but doesn't wait for
- # the close notify alert from client. When you need a different shutdown
- # approach you can use one of the following variables:
- # o ssl-unclean-shutdown:
- # This forces an unclean shutdown when the connection is closed, i.e. no
- # SSL close notify alert is send or allowed to received. This violates
- # the SSL/TLS standard but is needed for some brain-dead browsers. Use
- # this when you receive I/O errors because of the standard approach where
- # mod_ssl sends the close notify alert.
- # o ssl-accurate-shutdown:
- # This forces an accurate shutdown when the connection is closed, i.e. a
- # SSL close notify alert is send and mod_ssl waits for the close notify
- # alert of the client. This is 100% SSL/TLS standard compliant, but in
- # practice often causes hanging connections with brain-dead browsers. Use
- # this only for browsers where you know that their SSL implementation
- # works correctly.
- # Notice: Most problems of broken clients are also related to the HTTP
- # keep-alive facility, so you usually additionally want to disable
- # keep-alive for those clients, too. Use variable "nokeepalive" for this.
- # Similarly, one has to force some clients to use HTTP/1.0 to workaround
- # their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
- # "force-response-1.0" for this.
- # BrowserMatch "MSIE [2-6]" \
- # nokeepalive ssl-unclean-shutdown \
- # downgrade-1.0 force-response-1.0
-
- # Proxy WebSocket and MQTT connections to Mosquitto
- # ToDo: remove /mqtt target once all clients use /ws
- ProxyPassMatch "^/(ws|mqtt)(/|$)" "ws://127.0.0.1:9003/"
-
-
-
-
-# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
diff --git a/data/config/apache/apache-proplus.conf b/data/config/apache/apache-proplus.conf
deleted file mode 100644
index c20f2b6a35..0000000000
--- a/data/config/apache/apache-proplus.conf
+++ /dev/null
@@ -1,12 +0,0 @@
-# openwb-version:1
-Listen 8080
-
-
- ProxyPreserveHost On
-
- # Proxy for Pro:
- ProxyPass / http://192.168.192.50:80/
- ProxyPassReverse / http://192.168.192.50:80/
-
- ServerName localhost
-
diff --git a/data/config/apache/apache-redirect-ssl.conf b/data/config/apache/apache-redirect-ssl.conf
deleted file mode 100644
index 8ee4d9c539..0000000000
--- a/data/config/apache/apache-redirect-ssl.conf
+++ /dev/null
@@ -1,29 +0,0 @@
-# openwb-version:1
-
- # The ServerName directive sets the request scheme, hostname and port that
- # the server uses to identify itself. This is used when creating
- # redirection URLs. In the context of virtual hosts, the ServerName
- # specifies what hostname must appear in the request's Host: header to
- # match this virtual host. For the default virtual host (this file) this
- # value is not decisive as it is used as a last resort host regardless.
- # However, you must set it for any further virtual host explicitly.
- #ServerName www.example.com
-
- ServerAdmin webmaster@localhost
- DocumentRoot /var/www/html
- # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
- # error, crit, alert, emerg.
- # It is also possible to configure the loglevel for particular
- # modules, e.g.
- #LogLevel info ssl:warn
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- #CustomLog ${APACHE_LOG_DIR}/access.log combined
-
- # redirect all HTTP traffic to HTTPS
- RewriteEngine On
- RewriteCond %{HTTPS} off
- RewriteRule ^/?(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
-
-
-# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
diff --git a/data/config/apache/http-api-ssl.conf b/data/config/apache/http-api-ssl.conf
deleted file mode 100644
index 2a2546da76..0000000000
--- a/data/config/apache/http-api-ssl.conf
+++ /dev/null
@@ -1,141 +0,0 @@
-# openwb-version:1
-
- Listen 8443
-
-
- ServerAdmin webmaster@localhost
-
- DocumentRoot /var/www/html/openWB/runs/http-api
-
- # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
- # error, crit, alert, emerg.
- # It is also possible to configure the loglevel for particular
- # modules, e.g.
- #LogLevel info ssl:warn
-
- ErrorLog ${APACHE_LOG_DIR}/api-ssl-error.log
- CustomLog ${APACHE_LOG_DIR}/api-ssl-access.log combined
-
- # For most configuration files from conf-available/, which are
- # enabled or disabled at a global level, it is possible to
- # include a line for only one particular virtual host. For example the
- # following line enables the CGI configuration for this host only
- # after it has been globally disabled with "a2disconf".
- #Include conf-available/serve-cgi-bin.conf
-
- # SSL Engine Switch:
- # Enable/Disable SSL for this virtual host.
- SSLEngine on
-
- # A self-signed (snakeoil) certificate can be created by installing
- # the ssl-cert package. See
- # /usr/share/doc/apache2/README.Debian.gz for more info.
- # If both key and certificate are stored in the same file, only the
- # SSLCertificateFile directive is needed.
- SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
- SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
-
- # Server Certificate Chain:
- # Point SSLCertificateChainFile at a file containing the
- # concatenation of PEM encoded CA certificates which form the
- # certificate chain for the server certificate. Alternatively
- # the referenced file can be the same as SSLCertificateFile
- # when the CA certificates are directly appended to the server
- # certificate for convinience.
- #SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
-
- # Certificate Authority (CA):
- # Set the CA certificate verification path where to find CA
- # certificates for client authentication or alternatively one
- # huge file containing all of them (file must be PEM encoded)
- # Note: Inside SSLCACertificatePath you need hash symlinks
- # to point to the certificate files. Use the provided
- # Makefile to update the hash symlinks after changes.
- #SSLCACertificatePath /etc/ssl/certs/
- #SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt
-
- # Certificate Revocation Lists (CRL):
- # Set the CA revocation path where to find CA CRLs for client
- # authentication or alternatively one huge file containing all
- # of them (file must be PEM encoded)
- # Note: Inside SSLCARevocationPath you need hash symlinks
- # to point to the certificate files. Use the provided
- # Makefile to update the hash symlinks after changes.
- #SSLCARevocationPath /etc/apache2/ssl.crl/
- #SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl
-
- # Client Authentication (Type):
- # Client certificate verification type and depth. Types are
- # none, optional, require and optional_no_ca. Depth is a
- # number which specifies how deeply to verify the certificate
- # issuer chain before deciding the certificate is not valid.
- #SSLVerifyClient require
- #SSLVerifyDepth 10
-
- # SSL Engine Options:
- # Set various options for the SSL engine.
- # o FakeBasicAuth:
- # Translate the client X.509 into a Basic Authorisation. This means that
- # the standard Auth/DBMAuth methods can be used for access control. The
- # user name is the `one line' version of the client's X.509 certificate.
- # Note that no password is obtained from the user. Every entry in the user
- # file needs this password: `xxj31ZMTZzkVA'.
- # o ExportCertData:
- # This exports two additional environment variables: SSL_CLIENT_CERT and
- # SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
- # server (always existing) and the client (only existing when client
- # authentication is used). This can be used to import the certificates
- # into CGI scripts.
- # o StdEnvVars:
- # This exports the standard SSL/TLS related `SSL_*' environment variables.
- # Per default this exportation is switched off for performance reasons,
- # because the extraction step is an expensive operation and is usually
- # useless for serving static content. So one usually enables the
- # exportation for CGI and SSI requests only.
- # o OptRenegotiate:
- # This enables optimized SSL connection renegotiation handling when SSL
- # directives are used in per-directory context.
- #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
-
- SSLOptions +StdEnvVars
-
-
- SSLOptions +StdEnvVars
-
-
- AllowOverride All
- Require all granted
- Options -Indexes
-
- # SSL Protocol Adjustments:
- # The safe and default but still SSL/TLS standard compliant shutdown
- # approach is that mod_ssl sends the close notify alert but doesn't wait for
- # the close notify alert from client. When you need a different shutdown
- # approach you can use one of the following variables:
- # o ssl-unclean-shutdown:
- # This forces an unclean shutdown when the connection is closed, i.e. no
- # SSL close notify alert is send or allowed to received. This violates
- # the SSL/TLS standard but is needed for some brain-dead browsers. Use
- # this when you receive I/O errors because of the standard approach where
- # mod_ssl sends the close notify alert.
- # o ssl-accurate-shutdown:
- # This forces an accurate shutdown when the connection is closed, i.e. a
- # SSL close notify alert is send and mod_ssl waits for the close notify
- # alert of the client. This is 100% SSL/TLS standard compliant, but in
- # practice often causes hanging connections with brain-dead browsers. Use
- # this only for browsers where you know that their SSL implementation
- # works correctly.
- # Notice: Most problems of broken clients are also related to the HTTP
- # keep-alive facility, so you usually additionally want to disable
- # keep-alive for those clients, too. Use variable "nokeepalive" for this.
- # Similarly, one has to force some clients to use HTTP/1.0 to workaround
- # their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
- # "force-response-1.0" for this.
- # BrowserMatch "MSIE [2-6]" \
- # nokeepalive ssl-unclean-shutdown \
- # downgrade-1.0 force-response-1.0
-
-
-
-
-# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
diff --git a/data/config/apache/localhost.conf b/data/config/apache/localhost.conf
deleted file mode 100644
index 4d809119de..0000000000
--- a/data/config/apache/localhost.conf
+++ /dev/null
@@ -1,47 +0,0 @@
-# openwb-version:2
-Listen 127.0.0.1:81
-
-
- # The ServerName directive sets the request scheme, hostname and port that
- # the server uses to identify itself. This is used when creating
- # redirection URLs. In the context of virtual hosts, the ServerName
- # specifies what hostname must appear in the request's Host: header to
- # match this virtual host. For the default virtual host (this file) this
- # value is not decisive as it is used as a last resort host regardless.
- # However, you must set it for any further virtual host explicitly.
- #ServerName www.example.com
-
- ServerAdmin webmaster@localhost
- DocumentRoot /var/www/html
- # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
- # error, crit, alert, emerg.
- # It is also possible to configure the loglevel for particular
- # modules, e.g.
- #LogLevel info ssl:warn
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- #CustomLog ${APACHE_LOG_DIR}/access.log combined
-
- AllowOverride All
- Require all granted
- Options -Indexes
-
-
- Options +Indexes
-
-
- Options +Indexes
-
- # For most configuration files from conf-available/, which are
- # enabled or disabled at a global level, it is possible to
- # include a line for only one particular virtual host. For example the
- # following line enables the CGI configuration for this host only
- # after it has been globally disabled with "a2disconf".
- #Include conf-available/serve-cgi-bin.conf
-
- # Proxy WebSocket and MQTT connections to Mosquitto
- # ToDo: remove /mqtt target once all clients use /ws
- ProxyPassMatch "^/(ws|mqtt)(/|$)" "ws://127.0.0.1:9003/"
-
-
-# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
diff --git a/data/config/caddy/Caddyfile b/data/config/caddy/Caddyfile
new file mode 100644
index 0000000000..adacf01e27
--- /dev/null
+++ b/data/config/caddy/Caddyfile
@@ -0,0 +1,212 @@
+# openwb-version:1
+# openWB Caddy configuration
+# Replaces all Apache vhosts + .htaccess files
+
+# Global options
+{
+ # Use snakeoil certs for HTTPS (LAN device, no public domain)
+ # Caddy auto-HTTPS needs to be disabled for internal IPs
+ auto_https off
+}
+
+# PHP-FPM upstream
+# Detect PHP version dynamically via php-fpm socket symlink
+{$PHP_FPM_SOCK:unix//run/php/php-fpm.sock}
+
+# --- Main site: HTTP (:80) ---
+# openwb-version:http-unencrypted:1
+:80 {
+ root * /var/www/html
+
+ php_fastcgi {$PHP_FPM_SOCK:unix//run/php/php-fpm.sock}
+
+ file_server {
+ index index.php index.html
+ }
+
+ # ramdisk and backup allow directory listing
+ @ramdisk path /openWB/ramdisk/*
+ handle_path @ramdisk {
+ root * /var/www/html/openWB/ramdisk
+ file_server browse
+ }
+ @backup path /openWB/data/backup/*
+ handle_path @backup {
+ root * /var/www/html/openWB/data/backup
+ file_server browse
+ }
+
+ # WebSocket/MQTT proxy to mosquitto
+ # TODO: remove /mqtt target once all clients use /ws
+ handle_path /ws/* {
+ reverse_proxy 127.0.0.1:9003
+ }
+ handle_path /mqtt/* {
+ reverse_proxy 127.0.0.1:9003
+ }
+
+ # .htaccess: no-cache headers
+ header {
+ Cache-Control "no-cache, no-store, must-revalidate"
+ Pragma "no-cache"
+ Expires 0
+ }
+
+ # .htaccess: block sensitive file types
+ @blocked {
+ path *.conf
+ path *.ini
+ path *.py
+ path *.sh
+ }
+ respond @blocked 404
+
+ # Custom 404
+ handle_errors {
+ @404 expression {http.error.status_code} == 404
+ handle @404 {
+ rewrite * /openWB/web/error.html
+ file_server
+ }
+ }
+
+ log {
+ output file /var/log/caddy/access.log
+ }
+}
+
+# --- Main site: HTTPS (:443) ---
+# openwb-version:https-main:1
+:443 {
+ root * /var/www/html
+
+ tls /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/private/ssl-cert-snakeoil.key
+
+ php_fastcgi {$PHP_FPM_SOCK:unix//run/php/php-fpm.sock}
+
+ file_server {
+ index index.php index.html
+ }
+
+ @ramdisk path /openWB/ramdisk/*
+ handle_path @ramdisk {
+ root * /var/www/html/openWB/ramdisk
+ file_server browse
+ }
+ @backup path /openWB/data/backup/*
+ handle_path @backup {
+ root * /var/www/html/openWB/data/backup
+ file_server browse
+ }
+
+ handle_path /ws/* {
+ reverse_proxy 127.0.0.1:9003
+ }
+ handle_path /mqtt/* {
+ reverse_proxy 127.0.0.1:9003
+ }
+
+ header {
+ Cache-Control "no-cache, no-store, must-revalidate"
+ Pragma "no-cache"
+ Expires 0
+ }
+
+ @blocked {
+ path *.conf
+ path *.ini
+ path *.py
+ path *.sh
+ }
+ respond @blocked 404
+
+ handle_errors {
+ @404 expression {http.error.status_code} == 404
+ handle @404 {
+ rewrite * /openWB/web/error.html
+ file_server
+ }
+ }
+
+ log {
+ output file /var/log/caddy/ssl-access.log
+ }
+}
+
+# --- HTTP redirect to HTTPS (enabled when unencrypted access is disabled) ---
+# This block is only activated by setup_caddy.sh based on MQTT config
+# When active, :80 is replaced by the redirect block above
+# openwb-version:http-redirect:1
+# Uncommented by setup_caddy.sh when allow_unencrypted_access != "true"
+#:80 {
+# redir https://{host}{uri} permanent
+#}
+
+# --- Localhost internal (:81) ---
+# openwb-version:localhost:1
+127.0.0.1:81 {
+ root * /var/www/html
+
+ php_fastcgi {$PHP_FPM_SOCK:unix//run/php/php-fpm.sock}
+
+ file_server {
+ index index.php index.html
+ }
+
+ @ramdisk path /openWB/ramdisk/*
+ handle_path @ramdisk {
+ root * /var/www/html/openWB/ramdisk
+ file_server browse
+ }
+ @backup path /openWB/data/backup/*
+ handle_path @backup {
+ root * /var/www/html/openWB/data/backup
+ file_server browse
+ }
+
+ handle_path /ws/* {
+ reverse_proxy 127.0.0.1:9003
+ }
+ handle_path /mqtt/* {
+ reverse_proxy 127.0.0.1:9003
+ }
+
+ header {
+ Cache-Control "no-cache, no-store, must-revalidate"
+ Pragma "no-cache"
+ Expires 0
+ }
+
+ @blocked {
+ path *.conf
+ path *.ini
+ path *.py
+ path *.sh
+ }
+ respond @blocked 404
+}
+
+# --- HTTP API over HTTPS (:8443) ---
+# openwb-version:http-api:1
+:8443 {
+ root * /var/www/html/openWB/runs/http-api
+
+ tls /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/private/ssl-cert-snakeoil.key
+
+ php_fastcgi {$PHP_FPM_SOCK:unix//run/php/php-fpm.sock}
+
+ file_server {
+ index index.php index.html
+ }
+
+ log {
+ output file /var/log/caddy/api-access.log
+ }
+}
+
+# --- Pro+ reverse proxy (:8080) ---
+# Enabled only when USB network adapter is detected
+# openwb-version:proplus:1
+#:8080 {
+# reverse_proxy 192.168.192.50:80
+#}
diff --git a/data/config/chrony/chrony.conf b/data/config/chrony/chrony.conf
new file mode 100644
index 0000000000..508e6f6622
--- /dev/null
+++ b/data/config/chrony/chrony.conf
@@ -0,0 +1,32 @@
+# openwb-version:1
+# Chrony NTP configuration for openWB
+# PTB Braunschweig (primary, Germany's national metrology institute)
+server ptbtime1.ptb.de iburst prefer
+server ptbtime2.ptb.de iburst
+
+# NTP Pool (Germany)
+pool 0.de.pool.ntp.org iburst
+
+# Ubuntu NTP pools (reliable fallback)
+pool ntp.ubuntu.com iburst maxsources 4
+pool 0.ubuntu.pool.ntp.org iburst maxsources 1
+pool 1.ubuntu.pool.ntp.org iburst maxsources 1
+pool 2.ubuntu.pool.ntp.org iburst maxsources 2
+
+# Allow local network to query this server (useful for LAN charge points)
+allow 192.168.0.0/16
+allow 10.0.0.0/8
+allow 172.16.0.0/12
+
+# Drift file
+driftfile /var/lib/chrony/chrony.drift
+
+# Log
+logdir /var/log/chrony
+maxupdateskew 100.0
+
+# Allow step on first sync
+makestep 1 -1
+
+# RTC sync
+rtconutc
diff --git a/data/config/mosquitto/public/openwb-default-acl.conf b/data/config/mosquitto/public/openwb-default-acl.conf
index 75503da260..f11ee93f71 100644
--- a/data/config/mosquitto/public/openwb-default-acl.conf
+++ b/data/config/mosquitto/public/openwb-default-acl.conf
@@ -1,7 +1,7 @@
# openwb-version:1
# localhost websocket listener
-# used for internal connections only (apache2 reverse proxy)
+# used for internal connections only (caddy reverse proxy)
listener 9003 127.0.0.1
protocol websockets
allow_anonymous true
diff --git a/data/config/mosquitto/public/openwb-user-management.conf b/data/config/mosquitto/public/openwb-user-management.conf
index eceb6fc774..43f71bf078 100644
--- a/data/config/mosquitto/public/openwb-user-management.conf
+++ b/data/config/mosquitto/public/openwb-user-management.conf
@@ -1,7 +1,7 @@
# openwb-version:1
# localhost websocket listener
-# used for internal connections only (apache2 reverse proxy)
+# used for internal connections only (caddy reverse proxy)
listener 9003 127.0.0.1
protocol websockets
allow_anonymous true
diff --git a/data/config/openwb-simpleAPI.service b/data/config/openwb-simpleAPI.service
index b549c9223b..54f1668dc5 100644
--- a/data/config/openwb-simpleAPI.service
+++ b/data/config/openwb-simpleAPI.service
@@ -1,4 +1,4 @@
-# openwb-version:1
+# openwb-version:2
[Unit]
Description="openWB mqtt simpleAPI"
After=mosquitto.service
@@ -6,7 +6,7 @@ After=mosquitto.service
[Service]
User=openwb
WorkingDirectory=/var/www/html/openWB
-ExecStart=/var/www/html/openWB/simpleAPI/simpleAPI_mqtt.py
+ExecStart=/opt/openwb-venv/bin/python3 /var/www/html/openWB/simpleAPI/simpleAPI_mqtt.py
Restart=always
# extend timeout to 15min for long running atreboot
TimeoutStartSec=900
diff --git a/data/config/openwb2.service b/data/config/openwb2.service
index 6b0c007a7b..e31239e887 100644
--- a/data/config/openwb2.service
+++ b/data/config/openwb2.service
@@ -1,4 +1,4 @@
-# openwb-version:4
+# openwb-version:5
[Unit]
Description="Regelung openWB 2.0"
After=mosquitto_local.service
@@ -7,7 +7,7 @@ After=mosquitto_local.service
User=openwb
WorkingDirectory=/var/www/html/openWB
ExecStartPre=-/var/www/html/openWB/runs/atreboot.sh
-ExecStart=/var/www/html/openWB/packages/main.py
+ExecStart=/opt/openwb-venv/bin/python3 /var/www/html/openWB/packages/main.py
Restart=always
# extend timeout to 15min for long running atreboot
TimeoutStartSec=900
diff --git a/data/config/openwbRemoteSupport.service b/data/config/openwbRemoteSupport.service
index 0b49f1f0fc..8dec8bf320 100644
--- a/data/config/openwbRemoteSupport.service
+++ b/data/config/openwbRemoteSupport.service
@@ -1,4 +1,4 @@
-# openwb-version:3
+# openwb-version:4
[Unit]
Description="Remote Support Handler openWB 2.0"
After=mosquitto_local.service
@@ -6,7 +6,7 @@ After=mosquitto_local.service
[Service]
User=openwb
WorkingDirectory=/var/www/html/openWB
-ExecStart=/var/www/html/openWB/runs/remoteSupport/remoteSupport.py
+ExecStart=/opt/openwb-venv/bin/python3 /var/www/html/openWB/runs/remoteSupport/remoteSupport.py
Restart=always
[Install]
diff --git a/data/config/php/fpm/20-uploadlimit.ini b/data/config/php/fpm/20-uploadlimit.ini
new file mode 100644
index 0000000000..c604d90e76
--- /dev/null
+++ b/data/config/php/fpm/20-uploadlimit.ini
@@ -0,0 +1,2 @@
+upload_max_filesize = 300M
+post_max_size = 300M
diff --git a/data/config/profile.d/99-openwb-motd.sh b/data/config/profile.d/99-openwb-motd.sh
new file mode 100644
index 0000000000..cb8a0e9b3c
--- /dev/null
+++ b/data/config/profile.d/99-openwb-motd.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+OPENWBBASEDIR="/var/www/html/openWB"
+
+IP=$(hostname -I 2>/dev/null | awk '{print $1}')
+if [ -z "$IP" ]; then
+ IP="unknown"
+fi
+
+# Get openWB version
+OWB_VERSION="unknown"
+OWB_GIT="unknown"
+if [ -d "$OPENWBBASEDIR/.git" ]; then
+ OWB_GIT=$(cd "$OPENWBBASEDIR" && git rev-parse --short HEAD 2>/dev/null || echo "unknown")
+ OWB_BRANCH=$(cd "$OPENWBBASEDIR" && git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
+fi
+
+# Check service status
+OWB_STATUS=$(systemctl is-active openwb2.service 2>/dev/null || echo "unknown")
+
+# Get Debian version
+. /etc/os-release 2>/dev/null
+DEBIAN_VER="${PRETTY_NAME:-unknown}"
+
+# Get uptime
+UPTIME=$(uptime -p 2>/dev/null || echo "unknown")
+
+# Get memory
+MEM=$(free -h 2>/dev/null | awk '/^Mem:/{print $3 "/" $2}' || echo "unknown")
+
+# Get load
+LOAD=$(cat /proc/loadavg 2>/dev/null | awk '{print $1 " " $2 " " $3}' || echo "unknown")
+
+printf "${GREEN}╔══════════════════════════════════════════════════════════╗
+║ openWB 2.0 ║
+╚══════════════════════════════════════════════════════════╝${RESET}
+ Web UI: ${BOLD}http://${IP}/openWB/${RESET}
+ Status: $([ "$OWB_STATUS" = "active" ] && echo "$GREEN" || echo "$RED")${OWB_STATUS}${RESET}
+ Git: ${OWB_BRANCH} @ ${OWB_GIT}
+ OS: ${DEBIAN_VER}
+ Uptime: ${UPTIME}
+ Load: ${LOAD}
+ Memory: ${MEM}
+
+ ${DIM}Logs: journalctl -u openwb2 -f${RESET}
+"
diff --git a/data/config/sudoers/apache2 b/data/config/sudoers/apache2
deleted file mode 100644
index 7d077feec1..0000000000
--- a/data/config/sudoers/apache2
+++ /dev/null
@@ -1,2 +0,0 @@
-# openwb-version:1
-www-data ALL=NOPASSWD: /bin/systemctl restart openwb2.service, /bin/systemctl restart openwbRemoteSupport.service, /bin/systemctl restart mosquitto.service, /bin/systemctl restart mosquitto_local.service
diff --git a/data/config/sudoers/caddy b/data/config/sudoers/caddy
new file mode 100644
index 0000000000..5364ab7885
--- /dev/null
+++ b/data/config/sudoers/caddy
@@ -0,0 +1,2 @@
+# openwb-version:1
+caddy ALL=NOPASSWD: /bin/systemctl restart openwb2.service, /bin/systemctl restart openwbRemoteSupport.service, /bin/systemctl restart mosquitto.service, /bin/systemctl restart mosquitto_local.service
diff --git a/docs/samples/sample_modbus/sample_modbus/bat.py b/docs/samples/sample_modbus/sample_modbus/bat.py
index e13e03bfab..9c52d26f69 100644
--- a/docs/samples/sample_modbus/sample_modbus/bat.py
+++ b/docs/samples/sample_modbus/sample_modbus/bat.py
@@ -53,7 +53,7 @@ def update(self) -> None:
# read_input_registers_bulk benötigit als Parameter das Startregister, die Anzahl der Register,
# Register-Mapping und die Modbus-ID
resp = self.client.read_input_registers_bulk(
- Register.CURRENT_L1, 70, mapping=self.REG_MAPPING, unit=self.id)
+ Register.CURRENT_L1, 70, mapping=self.REG_MAPPING, device_id=self.id)
imported, exported = self.peak_filter.check_values(resp[Register.POWER],
resp[Register.IMPORTED],
resp[Register.EXPORTED])
@@ -66,8 +66,8 @@ def update(self) -> None:
self.store.set(bat_state)
# Einzelregister lesen (dauert länger, bei sehr weit >100 auseinanderliegenden Registern sinnvoll)
- power = self.client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit)
- soc = self.client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit)
+ power = self.client.read_holding_registers(reg, ModbusDataType.INT_32, device_id=unit)
+ soc = self.client.read_holding_registers(reg, ModbusDataType.INT_32, device_id=unit)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/docs/samples/sample_modbus/sample_modbus/counter.py b/docs/samples/sample_modbus/sample_modbus/counter.py
index 8bf7d3b8b1..2e8f45de32 100644
--- a/docs/samples/sample_modbus/sample_modbus/counter.py
+++ b/docs/samples/sample_modbus/sample_modbus/counter.py
@@ -57,7 +57,7 @@ def update(self):
# read_input_registers_bulk benötigit als Parameter das Startregister, die Anzahl der Register,
# Register-Mapping und die Modbus-ID
resp = self.client.read_input_registers_bulk(
- Register.VOLTAGE_L1, 76, mapping=self.REG_MAPPING, unit=self.id)
+ Register.VOLTAGE_L1, 76, mapping=self.REG_MAPPING, device_id=self.id)
imported, exported = self.peak_filter.check_values(sum(resp[Register.POWER_L1]),
resp[Register.IMPORTED],
resp[Register.EXPORTED])
@@ -74,7 +74,7 @@ def update(self):
self.store.set(counter_state)
# Einzelregister lesen (dauert länger, bei sehr weit >100 auseinanderliegenden Registern sinnvoll)
- power = self.client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit)
+ power = self.client.read_holding_registers(reg, ModbusDataType.INT_32, device_id=unit)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/docs/samples/sample_modbus/sample_modbus/inverter.py b/docs/samples/sample_modbus/sample_modbus/inverter.py
index a46530a18c..cde8eee54a 100644
--- a/docs/samples/sample_modbus/sample_modbus/inverter.py
+++ b/docs/samples/sample_modbus/sample_modbus/inverter.py
@@ -51,7 +51,7 @@ def update(self) -> None:
# read_input_registers_bulk benötigit als Parameter das Startregister, die Anzahl der Register,
# Register-Mapping und die Modbus-ID
resp = self.client.read_input_registers_bulk(
- Register.CURRENT_L1, 70, mapping=self.REG_MAPPING, unit=self.id)
+ Register.CURRENT_L1, 70, mapping=self.REG_MAPPING, device_id=self.id)
_, exported = self.peak_filter.check_values(resp[Register.POWER], None, resp[Register.EXPORTED])
inverter_state = InverterState(
power=resp[Register.POWER],
@@ -62,7 +62,7 @@ def update(self) -> None:
self.store.set(inverter_state)
# Einzelregister lesen (dauert länger, bei sehr weit >100 auseinanderliegenden Registern sinnvoll)
- power = self.client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit)
+ power = self.client.read_holding_registers(reg, ModbusDataType.INT_32, device_id=unit)
self.peak_filter.check_values(power)
exported = self.sim_counter.sim_count(power)[1]
diff --git a/openwb-install.sh b/openwb-install.sh
index 5665357839..5bcb4c4a32 100755
--- a/openwb-install.sh
+++ b/openwb-install.sh
@@ -92,34 +92,50 @@ cp -a "${SRC}/openwb_local.conf" /etc/mosquitto/conf_local.d/
systemctl start mosquitto_local
echo "mosquitto done"
-# apache
-echo -n "replacing apache default page..."
-cp "${OPENWBBASEDIR}/data/config/apache/000-default.conf" "/etc/apache2/sites-available/"
+# caddy + php-fpm
+echo -n "configuring caddy web server..."
cp "${OPENWBBASEDIR}/index.html" /var/www/html/index.html
-echo "done"
-echo -n "fix upload limit..."
-if [ -d "/etc/php/7.3/" ]; then
- echo "upload_max_filesize = 300M" > /etc/php/7.3/apache2/conf.d/20-uploadlimit.ini
- echo "post_max_size = 300M" >> /etc/php/7.3/apache2/conf.d/20-uploadlimit.ini
- echo "done (OS Buster)"
-elif [ -d "/etc/php/7.4/" ]; then
- echo "upload_max_filesize = 300M" > /etc/php/7.4/apache2/conf.d/20-uploadlimit.ini
- echo "post_max_size = 300M" >> /etc/php/7.4/apache2/conf.d/20-uploadlimit.ini
- echo "done (OS Bullseye)"
+# ensure caddy can read webroot without changing file ownership
+chmod -R a+rX /var/www/html
+# fix php-fpm upload limit
+php_dir=""
+for dir in /etc/php/*/fpm/conf.d; do
+ if [ -d "$dir" ]; then
+ php_dir="$dir"
+ break
+ fi
+done
+if [ -n "$php_dir" ]; then
+ cp "${OPENWBBASEDIR}/data/config/php/fpm/20-uploadlimit.ini" "${php_dir}/20-uploadlimit.ini"
+ echo "PHP upload limit set ($(basename $(dirname $(dirname "$php_dir"))))"
+else
+ echo "no PHP-FPM config directory found, skipping upload limit"
fi
-echo -n "enabling apache ssl module..."
-a2enmod ssl
-a2enmod proxy_wstunnel
-sudo a2dissite default-ssl
-sudo cp "${OPENWBBASEDIR}/data/config/apache/apache-openwb-ssl.conf" /etc/apache2/sites-available/
-sudo a2ensite apache-openwb-ssl
+# start php-fpm
+systemctl enable php*-fpm 2>/dev/null
+systemctl start php*-fpm 2>/dev/null
+# generate and install caddyfile
+"${OPENWBBASEDIR}/runs/setup_caddy.sh"
echo "done"
-echo -n "restarting apache..."
-systemctl restart apache2
+
+echo "installing python requirements into venv..."
+python3 -m venv /opt/openwb-venv
+chown -R "$OPENWB_USER:$OPENWB_GROUP" /opt/openwb-venv
+sudo -u "$OPENWB_USER" /opt/openwb-venv/bin/python3 -m pip install --upgrade pip
+sudo -u "$OPENWB_USER" /opt/openwb-venv/bin/python3 -m pip install -r "${OPENWBBASEDIR}/requirements.txt"
+
+echo "configuring chrony NTP..."
+systemctl stop systemd-timesyncd 2>/dev/null || true
+systemctl disable systemd-timesyncd 2>/dev/null || true
+cp "${OPENWBBASEDIR}/data/config/chrony/chrony.conf" /etc/chrony/chrony.conf
+systemctl enable chrony
+systemctl restart chrony
echo "done"
-echo "installing python requirements..."
-sudo -u "$OPENWB_USER" pip install -r "${OPENWBBASEDIR}/requirements.txt"
+echo "installing MOTD..."
+cp "${OPENWBBASEDIR}/data/config/profile.d/99-openwb-motd.sh" /etc/profile.d/99-openwb-motd.sh
+chmod 755 /etc/profile.d/99-openwb-motd.sh
+echo "done"
echo "installing openwb2 system service..."
ln -s "${OPENWBBASEDIR}/data/config/openwb2.service" /etc/systemd/system/openwb2.service
diff --git a/packages/control/ocpp.py b/packages/control/ocpp.py
index 352357cffd..1a5f5f3b2c 100644
--- a/packages/control/ocpp.py
+++ b/packages/control/ocpp.py
@@ -1,5 +1,4 @@
from datetime import datetime, timezone
-import json
import logging
from helpermodules.utils.error_handling import ImportErrorContext
@@ -25,22 +24,22 @@ def _get_formatted_time(self: OptionalProtocol) -> str:
def _process_call(self: OptionalProtocol,
chargebox_id: str,
fault_state: FaultState,
- func: Callable) -> Optional[websockets.WebSocketClientProtocol]:
- async def make_call() -> websockets.WebSocketClientProtocol:
+ func: Callable) -> Optional[tuple]:
+ async def make_call():
url = self.data.ocpp.config.url
async with websockets.connect(f"{url}{'' if url.endswith('/') else '/'}{chargebox_id}",
subprotocols=[self.data.ocpp.config.version]) as ws:
+ response = None
try:
cp = OcppChargepoint(chargebox_id, ws, 2)
- await cp.call(func)
+ response = await cp.call(func)
except asyncio.exceptions.TimeoutError:
- # log.exception("Erwarteter TimeOut StartTransaction")
pass
- return ws
+ return ws, response
try:
if self.data.ocpp.config.active and chargebox_id:
return asyncio.run(make_call())
- except websockets.exceptions.InvalidStatusCode:
+ except websockets.exceptions.InvalidStatus:
fault_state.warning(f"Chargebox ID {chargebox_id} konnte nicht im OCPP-Backend gefunden werden oder "
"URL des Backends ist falsch.")
return None
@@ -68,14 +67,17 @@ def start_transaction(self: OptionalProtocol,
id_tag: str,
imported: int) -> Optional[int]:
try:
- ws = self._process_call(chargebox_id, fault_state, call.StartTransaction(
+ result = self._process_call(chargebox_id, fault_state, call.StartTransaction(
connector_id=connector_id,
id_tag=id_tag if id_tag else "",
meter_start=int(imported),
timestamp=self._get_formatted_time()
))
- if ws:
- transaction_id = json.loads(ws.messages[0])[2]["transactionId"]
+ if result:
+ _ws, response = result
+ if response is None:
+ return None
+ transaction_id = response.transaction_id
log.debug(f"Transaction ID: {transaction_id} für Chargebox ID: {chargebox_id} mit Tag: {id_tag} "
f"und Zählerstand: {imported} erhalten.")
return transaction_id
diff --git a/packages/helpermodules/broker.py b/packages/helpermodules/broker.py
index c9b6940c6f..d41cf45606 100644
--- a/packages/helpermodules/broker.py
+++ b/packages/helpermodules/broker.py
@@ -25,7 +25,7 @@ def __init__(self,
port: int = 1886) -> None:
try:
self.name = f"openWB-{name}-{get_name_suffix()}"
- self.client = mqtt.Client(self.name)
+ self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, client_id=self.name)
self.client.on_connect = on_connect
self.client.on_message = on_message
self.client.connect(host, port)
@@ -48,7 +48,7 @@ def disconnect(self) -> None:
class InternalBrokerPublisher:
def __init__(self) -> None:
try:
- self.client = mqtt.Client(f"openWB-python-bulk-publisher-{get_name_suffix()}")
+ self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, client_id=f"openWB-python-bulk-publisher-{get_name_suffix()}")
self.client.connect("localhost", 1886)
except Exception:
log.exception("Fehler beim Verbindungsaufbau zum Bulk-Publisher")
diff --git a/packages/helpermodules/create_debug.py b/packages/helpermodules/create_debug.py
index 28f82085d0..69f8bbbc96 100644
--- a/packages/helpermodules/create_debug.py
+++ b/packages/helpermodules/create_debug.py
@@ -63,8 +63,11 @@ def get_common_data():
def get_hardware_data():
parsed_data = ""
- temp = run_shell_command(["vcgencmd measure_temp"]).removeprefix("temp=").removesuffix("\n")
- throttled = int(run_shell_command("vcgencmd get_throttled").removeprefix("throttled="), 16)
+ try:
+ temp = run_shell_command(["vcgencmd", "measure_temp"]).removeprefix("temp=").removesuffix("\n")
+ throttled = int(run_shell_command(["vcgencmd", "get_throttled"]).removeprefix("throttled="), 16)
+ except Exception:
+ return "Hardware data not available (vcgencmd not found or not a Raspberry Pi)\n"
parsed_data += f"Temperature_C: {temp}"
mask_undervoltage = 0b0001
mask_temp_limit = 0b1000
diff --git a/packages/modbus_control_tester.py b/packages/modbus_control_tester.py
index f11ccbba5e..9588005d26 100755
--- a/packages/modbus_control_tester.py
+++ b/packages/modbus_control_tester.py
@@ -4,7 +4,7 @@
import logging
import struct
from typing import Optional
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import time
from modules.common import modbus
from modules.common.modbus import ModbusDataType
@@ -54,7 +54,7 @@ class ReadMode(Enum):
def heartbeat_read():
- read_client.read_input_registers(10104, modbus.ModbusDataType.INT_16, unit=slave_id)
+ read_client.read_input_registers(10104, modbus.ModbusDataType.INT_16, device_id=slave_id)
def read_reg(register: int,
@@ -66,28 +66,28 @@ def read_reg(register: int,
if action == Actions.READ_NUMBER:
if read_mode == ReadMode.READ_INPUT_REG:
if length > 1:
- resp = read_client.read_input_registers(register, [data_type]*length, unit=slave_id)
+ resp = read_client.read_input_registers(register, [data_type]*length, device_id=slave_id)
else:
- resp = read_client.read_input_registers(register, data_type, unit=slave_id)
+ resp = read_client.read_input_registers(register, data_type, device_id=slave_id)
elif read_mode == ReadMode.READ_HOLDING_REG:
if length > 1:
- resp = read_client.read_holding_registers(register, [data_type]*length, unit=slave_id)
+ resp = read_client.read_holding_registers(register, [data_type]*length, device_id=slave_id)
else:
- resp = read_client.read_holding_registers(register, data_type, unit=slave_id)
+ resp = read_client.read_holding_registers(register, data_type, device_id=slave_id)
return resp
elif action == Actions.READ_STR:
if read_mode == ReadMode.READ_INPUT_REG:
- resp = read_client.read_input_registers(register, [modbus.ModbusDataType.INT_16]*length, unit=slave_id)
+ resp = read_client.read_input_registers(register, [modbus.ModbusDataType.INT_16]*length, device_id=slave_id)
elif read_mode == ReadMode.READ_HOLDING_REG:
resp = read_client.read_holding_registers(
- register, [modbus.ModbusDataType.INT_16]*length, unit=slave_id)
+ register, [modbus.ModbusDataType.INT_16]*length, device_id=slave_id)
string = ""
for word in resp:
string += struct.pack(">h", word).decode("utf-8")
return resp
elif action == Actions.WRITE_VALUE:
client = ModbusTcpClient(host, port=port)
- client.write_registers(register, write_value, unit=slave_id)
+ client.write_registers(register, write_value, device_id=slave_id)
return None
except Exception:
log.exception("Fehler")
diff --git a/packages/modules/chargepoints/openwb_series2_satellit/chargepoint_module.py b/packages/modules/chargepoints/openwb_series2_satellit/chargepoint_module.py
index 3a6b63979d..1272fb8660 100644
--- a/packages/modules/chargepoints/openwb_series2_satellit/chargepoint_module.py
+++ b/packages/modules/chargepoints/openwb_series2_satellit/chargepoint_module.py
@@ -148,16 +148,16 @@ def switch_phases(self, phases_to_use: int) -> None:
time.sleep(5)
if phases_to_use == 1:
self._client.client.delegate.write_register(
- 0x0001, 256, unit=self.ID_PHASE_SWITCH_UNIT)
+ 0x0001, 256, device_id=self.ID_PHASE_SWITCH_UNIT)
time.sleep(1)
self._client.client.delegate.write_register(
- 0x0001, 512, unit=self.ID_PHASE_SWITCH_UNIT)
+ 0x0001, 512, device_id=self.ID_PHASE_SWITCH_UNIT)
else:
self._client.client.delegate.write_register(
- 0x0002, 512, unit=self.ID_PHASE_SWITCH_UNIT)
+ 0x0002, 512, device_id=self.ID_PHASE_SWITCH_UNIT)
time.sleep(1)
self._client.client.delegate.write_register(
- 0x0002, 256, unit=self.ID_PHASE_SWITCH_UNIT)
+ 0x0002, 256, device_id=self.ID_PHASE_SWITCH_UNIT)
except AttributeError:
self._create_client()
self._validate_version()
diff --git a/packages/modules/common/b23.py b/packages/modules/common/b23.py
index affebbd9d0..b123c52e2e 100644
--- a/packages/modules/common/b23.py
+++ b/packages/modules/common/b23.py
@@ -46,7 +46,7 @@ def get_serial_number(self) -> str:
# Modbus mapping version: 0x8910, 1 Register, only 2 bytes
data_type = ModbusDataType.UINT_32
time.sleep(0.1)
- value = self.client.read_holding_registers(0x8900, data_type, unit=self.id)
+ value = self.client.read_holding_registers(0x8900, data_type, device_id=self.id)
return str(self.check_nan(value, value, data_type))
def get_currents(self) -> List[float]:
@@ -55,14 +55,14 @@ def get_currents(self) -> List[float]:
data_type = ModbusDataType.UINT_32
time.sleep(0.1)
return [self.check_nan(val, val / 100, data_type)
- for val in self.client.read_holding_registers(0x5B0C, [data_type]*3, unit=self.id)]
+ for val in self.client.read_holding_registers(0x5B0C, [data_type]*3, device_id=self.id)]
def get_frequency(self) -> float:
"""Returns frequency in Hz.
"""
data_type = ModbusDataType.UINT_16
time.sleep(0.1)
- raw_value = self.client.read_holding_registers(0x5B2C, data_type, unit=self.id)
+ raw_value = self.client.read_holding_registers(0x5B2C, data_type, device_id=self.id)
return self.check_nan(raw_value, raw_value / 100, data_type)
def get_imported(self) -> float:
@@ -70,12 +70,12 @@ def get_imported(self) -> float:
"""
data_type = ModbusDataType.UINT_64
time.sleep(0.1)
- raw_value = self.client.read_holding_registers(0x5000, data_type, unit=self.id)
+ raw_value = self.client.read_holding_registers(0x5000, data_type, device_id=self.id)
return self.check_nan(raw_value, raw_value * 10, data_type)
def get_exported(self) -> float:
time.sleep(0.1)
- return self.client.read_holding_registers(0x5004, ModbusDataType.UINT_64, unit=self.id) * 10
+ return self.client.read_holding_registers(0x5004, ModbusDataType.UINT_64, device_id=self.id) * 10
def get_power(self) -> Tuple[List[float], float]:
"""Returns power per phase and total power.
@@ -84,7 +84,7 @@ def get_power(self) -> Tuple[List[float], float]:
time.sleep(0.1)
# reading of total power and power per phase in one call
powers = [self.check_nan(val, val / 100, data_type)
- for val in self.client.read_holding_registers(0x5B14, [data_type]*4, unit=self.id)]
+ for val in self.client.read_holding_registers(0x5B14, [data_type]*4, device_id=self.id)]
return powers[1:4], powers[0]
def get_power_factors(self) -> List[float]:
@@ -95,7 +95,7 @@ def get_power_factors(self) -> List[float]:
data_type = ModbusDataType.INT_16
time.sleep(0.1)
return [self.check_nan(val, val / 1000, data_type)
- for val in self.client.read_holding_registers(0x5B3B, [data_type]*3, unit=self.id)]
+ for val in self.client.read_holding_registers(0x5B3B, [data_type]*3, device_id=self.id)]
def get_voltages(self) -> List[float]:
"""Returns voltages for all 3 phases.
@@ -103,7 +103,7 @@ def get_voltages(self) -> List[float]:
data_type = ModbusDataType.UINT_32
time.sleep(0.1)
values = [self.check_nan(val, val / 10, data_type)
- for val in self.client.read_holding_registers(0x5B00, [data_type]*3, unit=self.id)]
+ for val in self.client.read_holding_registers(0x5B00, [data_type]*3, device_id=self.id)]
return values
def get_counter_state(self) -> CounterState:
diff --git a/packages/modules/common/evse.py b/packages/modules/common/evse.py
index dba788746b..d8642f05a9 100644
--- a/packages/modules/common/evse.py
+++ b/packages/modules/common/evse.py
@@ -35,9 +35,9 @@ def __init__(self, modbus_id: int, client: modbus.ModbusSerialClient_) -> None:
self.id = modbus_id
with client:
time.sleep(0.1)
- self.version = self.client.read_holding_registers(1005, ModbusDataType.UINT_16, unit=self.id)
+ self.version = self.client.read_holding_registers(1005, ModbusDataType.UINT_16, device_id=self.id)
time.sleep(0.1)
- self.max_current = self.client.read_holding_registers(2007, ModbusDataType.UINT_16, unit=self.id)
+ self.max_current = self.client.read_holding_registers(2007, ModbusDataType.UINT_16, device_id=self.id)
with ModifyLoglevelContext(log, logging.DEBUG):
log.debug(f"Firmware-Version der EVSE: {self.version}")
if self.version < 17:
@@ -50,7 +50,7 @@ def __init__(self, modbus_id: int, client: modbus.ModbusSerialClient_) -> None:
def get_plug_charge_state(self) -> Tuple[bool, bool, float]:
time.sleep(0.1)
raw_set_current, _, state_number = self.client.read_holding_registers(
- 1000, [ModbusDataType.UINT_16]*3, unit=self.id)
+ 1000, [ModbusDataType.UINT_16]*3, device_id=self.id)
# remove leading zeros
self.evse_current = int(raw_set_current)
log.debug("Gesetzte Stromstärke EVSE: "+str(self.evse_current) +
@@ -78,7 +78,7 @@ def get_evse_state(self) -> EvseState:
def is_precise_current_active(self) -> bool:
time.sleep(0.1)
- value = self.client.read_holding_registers(2005, ModbusDataType.UINT_16, unit=self.id)
+ value = self.client.read_holding_registers(2005, ModbusDataType.UINT_16, device_id=self.id)
with ModifyLoglevelContext(log, logging.DEBUG):
if value & self.PRECISE_CURRENT_BIT:
log.debug("Angabe der Ströme in 0,01A-Schritten ist aktiviert.")
@@ -89,23 +89,23 @@ def is_precise_current_active(self) -> bool:
def activate_precise_current(self) -> None:
time.sleep(0.1)
- value = self.client.read_holding_registers(2005, ModbusDataType.UINT_16, unit=self.id)
+ value = self.client.read_holding_registers(2005, ModbusDataType.UINT_16, device_id=self.id)
if value & self.PRECISE_CURRENT_BIT:
return
else:
with ModifyLoglevelContext(log, logging.DEBUG):
log.debug("Bit zur Angabe der Ströme in 0,1A-Schritten wird gesetzt.")
- self.client.write_register(2005, value ^ self.PRECISE_CURRENT_BIT, unit=self.id)
+ self.client.write_register(2005, value ^ self.PRECISE_CURRENT_BIT, device_id=self.id)
# Zeit zum Verarbeiten geben
time.sleep(1)
def deactivate_precise_current(self) -> None:
time.sleep(0.1)
- value = self.client.read_holding_registers(2005, ModbusDataType.UINT_16, unit=self.id)
+ value = self.client.read_holding_registers(2005, ModbusDataType.UINT_16, device_id=self.id)
if value & self.PRECISE_CURRENT_BIT:
with ModifyLoglevelContext(log, logging.DEBUG):
log.debug("Bit zur Angabe der Ströme in 0,1A-Schritten wird zurueckgesetzt.")
- self.client.write_register(2005, value ^ self.PRECISE_CURRENT_BIT, unit=self.id)
+ self.client.write_register(2005, value ^ self.PRECISE_CURRENT_BIT, device_id=self.id)
else:
return
@@ -118,4 +118,4 @@ def set_current(self, current: int, phases_in_use: Optional[int] = None) -> None
current = 16
formatted_current = round(current*100) if self._precise_current else round(current)
if self.evse_current != formatted_current:
- self.client.write_register(1000, formatted_current, unit=self.id)
+ self.client.write_register(1000, formatted_current, device_id=self.id)
diff --git a/packages/modules/common/lovato.py b/packages/modules/common/lovato.py
index cb8a0b596e..3c7375cb5b 100644
--- a/packages/modules/common/lovato.py
+++ b/packages/modules/common/lovato.py
@@ -17,21 +17,21 @@ def __init__(self, modbus_id: int, client: modbus.ModbusTcpClient_, fault_state:
def get_voltages(self) -> List[float]:
return [val / 100 for val in self.client.read_input_registers(
- 0x0001, [ModbusDataType.INT_32]*3, unit=self.id)]
+ 0x0001, [ModbusDataType.INT_32]*3, device_id=self.id)]
def get_power(self) -> Tuple[List[float], float]:
powers = [val / 100 for val in self.client.read_input_registers(
- 0x0013, [ModbusDataType.INT_32]*3, unit=self.id
+ 0x0013, [ModbusDataType.INT_32]*3, device_id=self.id
)]
power = sum(powers)
return powers, power
def get_power_factors(self) -> List[float]:
return [val / 10000 for val in self.client.read_input_registers(
- 0x0025, [ModbusDataType.INT_32]*3, unit=self.id)]
+ 0x0025, [ModbusDataType.INT_32]*3, device_id=self.id)]
def get_frequency(self) -> float:
- frequency = self.client.read_input_registers(0x0031, ModbusDataType.INT_32, unit=self.id) / 100
+ frequency = self.client.read_input_registers(0x0031, ModbusDataType.INT_32, device_id=self.id) / 100
if frequency > 100:
# needed if external measurement clamps connected
frequency = frequency / 10
@@ -39,7 +39,7 @@ def get_frequency(self) -> float:
def get_currents(self) -> List[float]:
return [val / 10000 for val in self.client.read_input_registers(
- 0x0007, [ModbusDataType.INT_32]*3, unit=self.id)]
+ 0x0007, [ModbusDataType.INT_32]*3, device_id=self.id)]
def get_counter_state(self) -> CounterState:
powers, power = self.get_power()
diff --git a/packages/modules/common/modbus.py b/packages/modules/common/modbus.py
index 9f5fc13e50..65cec6db4f 100644
--- a/packages/modules/common/modbus.py
+++ b/packages/modules/common/modbus.py
@@ -11,10 +11,10 @@
from typing import Any, Callable, Iterable, Optional, Union, overload, List
import pymodbus
-from pymodbus.client.sync import ModbusTcpClient, ModbusUdpClient, ModbusSerialClient
-from pymodbus.constants import Endian
-from pymodbus.payload import BinaryPayloadBuilder, BinaryPayloadDecoder
-from pymodbus.transaction import ModbusSocketFramer
+from pymodbus.client import ModbusTcpClient, ModbusUdpClient, ModbusSerialClient
+from modules.common.pymodbus_compat import Endian
+from modules.common.pymodbus_compat import BinaryPayloadBuilder, BinaryPayloadDecoder
+from pymodbus.framer import FramerType
from urllib3.util import parse_url
log = logging.getLogger(__name__)
@@ -103,7 +103,7 @@ def divide_rounding_up(numerator: int, denominator: int):
number_of_addresses = sum(divide_rounding_up(
t.bits, _MODBUS_HOLDING_REGISTER_SIZE) for t in types)
response = read_register_method(
- address, number_of_addresses, **kwargs)
+ address, count=number_of_addresses, **kwargs)
if response.isError():
raise Exception(__name__+" "+str(response))
decoder = BinaryPayloadDecoder.fromRegisters(response.registers, byteorder, wordorder)
@@ -176,7 +176,7 @@ def read_coils(self, address: int, count: int, **kwargs) -> bool:
def read_coils(self, address: int, count: int, **kwargs):
try:
- response = self._delegate.read_coils(address, count, **kwargs)
+ response = self._delegate.read_coils(address, count=count, **kwargs)
if response.isError():
raise Exception(__name__+" "+str(response))
return response.bits[0] if count == 1 else response.bits[:count]
@@ -235,7 +235,7 @@ def __read_bulk(self,
if self.is_socket_open() is False:
self.connect()
try:
- response = read_register_method(start_address, count, **kwargs)
+ response = read_register_method(start_address, count=count, **kwargs)
if response.isError():
raise Exception(__name__+" "+str(response))
decoder = BinaryPayloadDecoder.fromRegisters(response.registers, byteorder, wordorder)
@@ -299,13 +299,13 @@ def __init__(self,
address: str,
port: int = 502,
sleep_after_connect: Optional[int] = 0,
- framer: type[ModbusSocketFramer] = ModbusSocketFramer,
+ framer=FramerType.SOCKET,
**kwargs):
parsed_url = parse_url(address)
host = parsed_url.host
if parsed_url.port is not None:
port = parsed_url.port
- super().__init__(ModbusTcpClient(host, port, framer, **kwargs), address, port, sleep_after_connect)
+ super().__init__(ModbusTcpClient(host, port=port, framer=framer, **kwargs), address, port, sleep_after_connect)
class ModbusUdpClient_(ModbusClient):
@@ -318,7 +318,7 @@ def __init__(self,
host = parsed_url.host
if parsed_url.port is not None:
port = parsed_url.port
- super().__init__(ModbusUdpClient(host, port, **kwargs), address, port, sleep_after_connect)
+ super().__init__(ModbusUdpClient(host, port=port, **kwargs), address, port, sleep_after_connect)
class ModbusSerialClient_(ModbusClient):
@@ -326,8 +326,8 @@ def __init__(self,
port: int,
sleep_after_connect: Optional[int] = 0,
**kwargs):
- super().__init__(ModbusSerialClient(method="rtu",
- port=port,
+ super().__init__(ModbusSerialClient(port,
+ framer=FramerType.RTU,
baudrate=9600,
stopbits=1,
bytesize=8,
diff --git a/packages/modules/common/mpm3pm.py b/packages/modules/common/mpm3pm.py
index 4791398dc7..59844a00f7 100644
--- a/packages/modules/common/mpm3pm.py
+++ b/packages/modules/common/mpm3pm.py
@@ -17,40 +17,40 @@ def __init__(self, modbus_id: int, client: modbus.ModbusTcpClient_, fault_state:
def get_voltages(self) -> List[float]:
return [val / 10 for val in self.client.read_input_registers(
- 0x08, [ModbusDataType.UINT_32]*3, unit=self.id)]
+ 0x08, [ModbusDataType.UINT_32]*3, device_id=self.id)]
def get_imported(self) -> float:
# Faktorisierung anders als in der Dokumentation angegeben
- return self.client.read_input_registers(0x0002, ModbusDataType.UINT_32, unit=self.id) * 10
+ return self.client.read_input_registers(0x0002, ModbusDataType.UINT_32, device_id=self.id) * 10
def get_power(self) -> Tuple[List[float], float]:
powers = [val / 100 for val in self.client.read_input_registers(
- 0x14, [ModbusDataType.INT_32]*3, unit=self.id)]
- power = self.client.read_input_registers(0x26, ModbusDataType.INT_32, unit=self.id) / 100
+ 0x14, [ModbusDataType.INT_32]*3, device_id=self.id)]
+ power = self.client.read_input_registers(0x26, ModbusDataType.INT_32, device_id=self.id) / 100
return powers, power
def get_exported(self) -> float:
# Faktorisierung anders als in der Dokumentation angegeben
- return self.client.read_input_registers(0x0004, ModbusDataType.UINT_32, unit=self.id) * 10
+ return self.client.read_input_registers(0x0004, ModbusDataType.UINT_32, device_id=self.id) * 10
def get_power_factors(self) -> List[float]:
# Faktorisierung anders als in der Dokumentation angegeben?
factors = [val / 10 for val in self.client.read_input_registers(
- 0x20, [ModbusDataType.UINT_32]*3, unit=self.id)]
+ 0x20, [ModbusDataType.UINT_32]*3, device_id=self.id)]
# check if the absolute value of an entry in factors is greater 1
if any([abs(factor) > 1 for factor in factors]):
factors = [factor / 100 for factor in factors]
return factors
def get_frequency(self) -> float:
- return self.client.read_input_registers(0x2c, ModbusDataType.UINT_32, unit=self.id) / 100
+ return self.client.read_input_registers(0x2c, ModbusDataType.UINT_32, device_id=self.id) / 100
def get_currents(self) -> List[float]:
return [val / 100 for val in self.client.read_input_registers(
- 0x0E, [ModbusDataType.UINT_32]*3, unit=self.id)]
+ 0x0E, [ModbusDataType.UINT_32]*3, device_id=self.id)]
def get_serial_number(self) -> str:
- return str(self.client.read_input_registers(0x33, ModbusDataType.UINT_32, unit=self.id))
+ return str(self.client.read_input_registers(0x33, ModbusDataType.UINT_32, device_id=self.id))
def get_counter_state(self) -> CounterState:
powers, power = self.get_power()
diff --git a/packages/modules/common/pymodbus_compat.py b/packages/modules/common/pymodbus_compat.py
new file mode 100644
index 0000000000..910fef810a
--- /dev/null
+++ b/packages/modules/common/pymodbus_compat.py
@@ -0,0 +1,118 @@
+import struct
+
+
+class Endian:
+ Big = "big"
+ Little = "little"
+
+
+class BinaryPayloadDecoder:
+ def __init__(self, payload, byteorder="big", wordorder="big"):
+ self._payload = payload
+ self._bo = byteorder
+ self._wo = wordorder
+ self._ptr = 0
+
+ @classmethod
+ def fromRegisters(cls, registers, byteorder="big", wordorder="big"):
+ if wordorder == "little":
+ registers = list(reversed(registers))
+ raw = b""
+ for r in registers:
+ raw += struct.pack(">H", r)
+ return cls(raw, byteorder, wordorder)
+
+ def reset(self):
+ self._ptr = 0
+
+ def skip_bytes(self, n):
+ self._ptr += n
+
+ def _decode(self, fmt):
+ sz = struct.calcsize(fmt)
+ data = self._payload[self._ptr:self._ptr + sz]
+ self._ptr += sz
+ if ">" not in fmt and "<" not in fmt:
+ fmt = ">" + fmt
+ return struct.unpack(fmt, data)[0]
+
+ def decode_8bit_uint(self):
+ return self._decode("B")
+
+ def decode_16bit_uint(self):
+ return self._decode(">H")
+
+ def decode_16bit_int(self):
+ return self._decode(">h")
+
+ def decode_32bit_uint(self):
+ return self._decode(">I")
+
+ def decode_32bit_int(self):
+ return self._decode(">i")
+
+ def decode_64bit_uint(self):
+ return self._decode(">Q")
+
+ def decode_64bit_int(self):
+ return self._decode(">q")
+
+ def decode_32bit_float(self):
+ return self._decode(">f")
+
+ def decode_64bit_float(self):
+ return self._decode(">d")
+
+
+class BinaryPayloadBuilder:
+ def __init__(self, byteorder="big", wordorder="big"):
+ self._bo = byteorder
+ self._wo = wordorder
+ self._regs = []
+
+ def reset(self):
+ self._regs = []
+
+ def _add(self, value, fmt):
+ if ">" not in fmt and "<" not in fmt:
+ fmt = ">" + fmt
+ data = struct.pack(fmt, value)
+ regs = []
+ for i in range(0, len(data), 2):
+ chunk = data[i:i+2]
+ if len(chunk) == 1:
+ chunk = b"\x00" + chunk
+ regs.append(struct.unpack(">H", chunk)[0])
+ if self._wo == "little":
+ regs.reverse()
+ self._regs.extend(regs)
+
+ def add_8bit_uint(self, v):
+ self._add(v, "B")
+
+ def add_16bit_uint(self, v):
+ self._add(v, ">H")
+
+ def add_16bit_int(self, v):
+ self._add(v, ">h")
+
+ def add_32bit_uint(self, v):
+ self._add(v, ">I")
+
+ def add_32bit_int(self, v):
+ self._add(v, ">i")
+
+ def add_64bit_uint(self, v):
+ self._add(v, ">Q")
+
+ def add_64bit_int(self, v):
+ self._add(v, ">q")
+
+ def add_32bit_float(self, v):
+ self._add(v, ">f")
+
+ def add_64bit_float(self, v):
+ self._add(v, ">d")
+
+ def to_registers(self):
+ return list(self._regs)
diff --git a/packages/modules/common/sdm.py b/packages/modules/common/sdm.py
index 6fe1cd62ed..0d6d53d321 100644
--- a/packages/modules/common/sdm.py
+++ b/packages/modules/common/sdm.py
@@ -20,12 +20,12 @@ def __init__(self, modbus_id: int, client: modbus.ModbusTcpClient_) -> None:
self.id = modbus_id
self.fast_mode = True
with client:
- self.serial_number = str(self.client.read_holding_registers(0xFC00, ModbusDataType.UINT_32, unit=self.id))
+ self.serial_number = str(self.client.read_holding_registers(0xFC00, ModbusDataType.UINT_32, device_id=self.id))
def get_imported(self) -> float:
# smarthome legacy
time.sleep(0.1)
- return self.client.read_input_registers(0x0048, ModbusDataType.FLOAT_32, unit=self.id) * 1000
+ return self.client.read_input_registers(0x0048, ModbusDataType.FLOAT_32, device_id=self.id) * 1000
class SdmRegister(IntEnum):
@@ -57,14 +57,14 @@ def __init__(self, modbus_id: int, client: modbus.ModbusTcpClient_, fault_state:
def get_power(self) -> Tuple[List[float], float]:
# smarthome legacy
time.sleep(0.1)
- powers = self.client.read_input_registers(0x0C, [ModbusDataType.FLOAT_32]*3, unit=self.id)
+ powers = self.client.read_input_registers(0x0C, [ModbusDataType.FLOAT_32]*3, device_id=self.id)
power = sum(powers)
return powers, power
def get_voltages(self) -> Tuple[List[float], float]:
# client handler
time.sleep(0.1)
- return self.client.read_input_registers(0x00, [ModbusDataType.FLOAT_32]*3, unit=self.id)
+ return self.client.read_input_registers(0x00, [ModbusDataType.FLOAT_32]*3, device_id=self.id)
def get_counter_state(self) -> CounterState:
# entgegen der Doku können nicht bei allen SDM72 80 Register auf einmal gelesen werden,
@@ -73,18 +73,18 @@ def get_counter_state(self) -> CounterState:
try:
time.sleep(0.1)
bulk_1 = self.client.read_input_registers_bulk(
- SdmRegister.VOLTAGE_L1, 18, mapping=self.REG_MAPPING_BULK_1, unit=self.id)
+ SdmRegister.VOLTAGE_L1, 18, mapping=self.REG_MAPPING_BULK_1, device_id=self.id)
time.sleep(0.1)
power_factors = self.client.read_input_registers(
- SdmRegister.POWER_FACTOR_L1, [ModbusDataType.FLOAT_32]*3, unit=self.id)
+ SdmRegister.POWER_FACTOR_L1, [ModbusDataType.FLOAT_32]*3, device_id=self.id)
time.sleep(0.1)
bulk_2 = self.client.read_input_registers_bulk(
- SdmRegister.FREQUENCY, 6, mapping=self.REG_MAPPING_BULK_2, unit=self.id)
+ SdmRegister.FREQUENCY, 6, mapping=self.REG_MAPPING_BULK_2, device_id=self.id)
resp = {**bulk_1, **bulk_2}
except Exception:
log.exception("Fehler beim Auslesen des Zählers")
self.client.read_input_registers(
- SdmRegister.VOLTAGE_L1, [ModbusDataType.FLOAT_32]*3, unit=self.id)
+ SdmRegister.VOLTAGE_L1, [ModbusDataType.FLOAT_32]*3, device_id=self.id)
self.fast_mode = False
if self.fast_mode is False:
# im gleichen Durchlauf noch im slow mode versuchen, sonst schlägt der Hardware-Check fehl
@@ -92,23 +92,23 @@ def get_counter_state(self) -> CounterState:
resp = {}
time.sleep(0.1)
resp[SdmRegister.VOLTAGE_L1] = self.client.read_input_registers(
- SdmRegister.VOLTAGE_L1, [ModbusDataType.FLOAT_32]*3, unit=self.id)
+ SdmRegister.VOLTAGE_L1, [ModbusDataType.FLOAT_32]*3, device_id=self.id)
time.sleep(0.1)
resp[SdmRegister.CURRENT_L1] = self.client.read_input_registers(
- SdmRegister.CURRENT_L1, [ModbusDataType.FLOAT_32]*3, unit=self.id)
+ SdmRegister.CURRENT_L1, [ModbusDataType.FLOAT_32]*3, device_id=self.id)
time.sleep(0.1)
resp[SdmRegister.POWER_L1] = self.client.read_input_registers(
- SdmRegister.POWER_L1, [ModbusDataType.FLOAT_32]*3, unit=self.id)
+ SdmRegister.POWER_L1, [ModbusDataType.FLOAT_32]*3, device_id=self.id)
time.sleep(0.1)
power_factors = self.client.read_input_registers(
- SdmRegister.POWER_FACTOR_L1, [ModbusDataType.FLOAT_32]*3, unit=self.id)
+ SdmRegister.POWER_FACTOR_L1, [ModbusDataType.FLOAT_32]*3, device_id=self.id)
time.sleep(0.1)
# frequency noch mit auslesen klappt nicht
resp[SdmRegister.IMPORTED], resp[SdmRegister.EXPORTED] = self.client.read_input_registers(
- SdmRegister.IMPORTED, [ModbusDataType.FLOAT_32]*2, unit=self.id)
+ SdmRegister.IMPORTED, [ModbusDataType.FLOAT_32]*2, device_id=self.id)
time.sleep(0.1)
resp[SdmRegister.FREQUENCY] = self.client.read_input_registers(
- SdmRegister.FREQUENCY, ModbusDataType.FLOAT_32, unit=self.id)
+ SdmRegister.FREQUENCY, ModbusDataType.FLOAT_32, device_id=self.id)
frequency = resp[SdmRegister.FREQUENCY]
if frequency > 100:
@@ -147,19 +147,19 @@ def __init__(self, modbus_id: int, client: modbus.ModbusTcpClient_, fault_state:
def get_power(self) -> Tuple[List[float], float]:
# smarthome legacy
time.sleep(0.1)
- power = self.client.read_input_registers(0x0C, ModbusDataType.FLOAT_32, unit=self.id)
+ power = self.client.read_input_registers(0x0C, ModbusDataType.FLOAT_32, device_id=self.id)
return [power, 0, 0], power
def get_counter_state(self) -> CounterState:
# beim SDM120 steht nichts von Bulk-Reads in der Doku, daher auch auf 20 Register limitiert
time.sleep(0.1)
bulk_1 = self.client.read_input_registers_bulk(
- SdmRegister.VOLTAGE_L1, 14, mapping=self.REG_MAPPING_BULK_1, unit=self.id)
+ SdmRegister.VOLTAGE_L1, 14, mapping=self.REG_MAPPING_BULK_1, device_id=self.id)
time.sleep(0.1)
- power_factor = self.client.read_input_registers(0x1E, ModbusDataType.FLOAT_32, unit=self.id)
+ power_factor = self.client.read_input_registers(0x1E, ModbusDataType.FLOAT_32, device_id=self.id)
time.sleep(0.1)
bulk_2 = self.client.read_input_registers_bulk(
- SdmRegister.FREQUENCY, 6, mapping=self.REG_MAPPING_BULK_2, unit=self.id)
+ SdmRegister.FREQUENCY, 6, mapping=self.REG_MAPPING_BULK_2, device_id=self.id)
resp = {**bulk_1, **bulk_2}
frequency = resp[SdmRegister.FREQUENCY]
if frequency > 100:
diff --git a/packages/modules/conftest.py b/packages/modules/conftest.py
index 9733696c81..e88978c896 100644
--- a/packages/modules/conftest.py
+++ b/packages/modules/conftest.py
@@ -20,11 +20,17 @@
# sys.modules['telnetlib3'] = type(sys)('telnetlib3')
-module = type(sys)('pymodbus.client.sync')
+module = type(sys)('pymodbus.client')
module.ModbusSerialClient = Mock()
module.ModbusTcpClient = Mock()
module.ModbusUdpClient = Mock()
-sys.modules['pymodbus.client.sync'] = module
+sys.modules['pymodbus.client'] = module
+
+module = type(sys)('pymodbus.framer')
+module.FramerType = Mock()
+module.FramerType.SOCKET = 'socket'
+module.FramerType.RTU = 'rtu'
+sys.modules['pymodbus.framer'] = module
module = type(sys)('pymodbus.constants')
module.Endian = Mock()
@@ -35,8 +41,6 @@
sys.modules['pymodbus.payload'] = module
module = type(sys)('pymodbus.transaction')
-module.ModbusSocketFramer = Mock()
-module.ModbusRtuFramer = Mock()
sys.modules['pymodbus.transaction'] = module
module = type(sys)('socketserver')
diff --git a/packages/modules/devices/algodue/algodue/bat.py b/packages/modules/devices/algodue/algodue/bat.py
index 5ceee007e5..70c1478aa1 100644
--- a/packages/modules/devices/algodue/algodue/bat.py
+++ b/packages/modules/devices/algodue/algodue/bat.py
@@ -36,8 +36,8 @@ def initialize(self) -> None:
def update(self):
currents = self.__tcp_client.read_input_registers(
- 0x100E, [ModbusDataType.FLOAT_32]*3, unit=self.__modbus_id)
- powers = self.__tcp_client.read_input_registers(0x1020, [ModbusDataType.FLOAT_32]*3, unit=self.__modbus_id)
+ 0x100E, [ModbusDataType.FLOAT_32]*3, device_id=self.__modbus_id)
+ powers = self.__tcp_client.read_input_registers(0x1020, [ModbusDataType.FLOAT_32]*3, device_id=self.__modbus_id)
power = sum(powers)
self.peak_filter.check_values(power)
diff --git a/packages/modules/devices/algodue/algodue/counter.py b/packages/modules/devices/algodue/algodue/counter.py
index 805410400f..7d46d7bba0 100644
--- a/packages/modules/devices/algodue/algodue/counter.py
+++ b/packages/modules/devices/algodue/algodue/counter.py
@@ -35,15 +35,15 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.COUNTER, self.component_config.id, self.fault_state)
def update(self):
- frequency = self.__tcp_client.read_input_registers(0x1038, ModbusDataType.FLOAT_32, unit=self.__modbus_id)
+ frequency = self.__tcp_client.read_input_registers(0x1038, ModbusDataType.FLOAT_32, device_id=self.__modbus_id)
currents = self.__tcp_client.read_input_registers(
- 0x100E, [ModbusDataType.FLOAT_32]*3, unit=self.__modbus_id)
- powers = self.__tcp_client.read_input_registers(0x1020, [ModbusDataType.FLOAT_32]*3, unit=self.__modbus_id)
+ 0x100E, [ModbusDataType.FLOAT_32]*3, device_id=self.__modbus_id)
+ powers = self.__tcp_client.read_input_registers(0x1020, [ModbusDataType.FLOAT_32]*3, device_id=self.__modbus_id)
power = sum(powers)
voltages = self.__tcp_client.read_input_registers(
- 0x1000, [ModbusDataType.FLOAT_32]*3, unit=self.__modbus_id)
+ 0x1000, [ModbusDataType.FLOAT_32]*3, device_id=self.__modbus_id)
power_factors = self.__tcp_client.read_input_registers(
- 0x1018, [ModbusDataType.FLOAT_32]*3, unit=self.__modbus_id)
+ 0x1018, [ModbusDataType.FLOAT_32]*3, device_id=self.__modbus_id)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
@@ -63,8 +63,8 @@ def update(self):
component_descriptor = ComponentDescriptor(configuration_factory=AlgodueCounterSetup)
-# serial_chars = self.client.read_holding_registers(0x500, [ModbusDataType.UINT_8]*10, unit=self.id)
-# model_id = self.client.read_holding_registers(0x505, ModbusDataType.UINT_16, unit=self.id)
+# serial_chars = self.client.read_holding_registers(0x500, [ModbusDataType.UINT_8]*10, device_id=self.id)
+# model_id = self.client.read_holding_registers(0x505, ModbusDataType.UINT_16, device_id=self.id)
# model_string = "unknown"
# if model_id == 0x03:
# model_string = "6 A, 3 phases, 4 wires"
@@ -77,7 +77,7 @@ def update(self):
# elif model_id == 0x12:
# model_string = "63 A, 3 phases, 4 wires"
-# type_id = self.client.read_holding_registers(0x506, ModbusDataType.UINT_16, unit=self.id)
+# type_id = self.client.read_holding_registers(0x506, ModbusDataType.UINT_16, device_id=self.id)
# type_string = "unknown"
# if type_id == 0x00:
# type_string = "NO MID, RESET"
diff --git a/packages/modules/devices/algodue/algodue/inverter.py b/packages/modules/devices/algodue/algodue/inverter.py
index b8cd036822..2d30d731d5 100644
--- a/packages/modules/devices/algodue/algodue/inverter.py
+++ b/packages/modules/devices/algodue/algodue/inverter.py
@@ -36,8 +36,8 @@ def initialize(self) -> None:
def update(self):
currents = self.__tcp_client.read_input_registers(
- 0x100E, [ModbusDataType.FLOAT_32]*3, unit=self.__modbus_id)
- powers = self.__tcp_client.read_input_registers(0x1020, [ModbusDataType.FLOAT_32]*3, unit=self.__modbus_id)
+ 0x100E, [ModbusDataType.FLOAT_32]*3, device_id=self.__modbus_id)
+ powers = self.__tcp_client.read_input_registers(0x1020, [ModbusDataType.FLOAT_32]*3, device_id=self.__modbus_id)
power = sum(powers)
self.peak_filter.check_values(power)
diff --git a/packages/modules/devices/alpha_ess/alpha_ess/bat.py b/packages/modules/devices/alpha_ess/alpha_ess/bat.py
index 8663913cc5..c72c0228ba 100644
--- a/packages/modules/devices/alpha_ess/alpha_ess/bat.py
+++ b/packages/modules/devices/alpha_ess/alpha_ess/bat.py
@@ -39,9 +39,9 @@ def update(self) -> None:
# keine Unterschiede zwischen den Versionen
time.sleep(0.1)
- voltage = self.__tcp_client.read_holding_registers(0x0100, ModbusDataType.INT_16, unit=self.__modbus_id)
+ voltage = self.__tcp_client.read_holding_registers(0x0100, ModbusDataType.INT_16, device_id=self.__modbus_id)
time.sleep(0.1)
- current = self.__tcp_client.read_holding_registers(0x0101, ModbusDataType.INT_16, unit=self.__modbus_id)
+ current = self.__tcp_client.read_holding_registers(0x0101, ModbusDataType.INT_16, device_id=self.__modbus_id)
power = voltage * current * -1 / 100
log.debug(
@@ -49,7 +49,7 @@ def update(self) -> None:
(power, voltage, current)
)
time.sleep(0.1)
- soc_reg = self.__tcp_client.read_holding_registers(0x0102, ModbusDataType.INT_16, unit=self.__modbus_id)
+ soc_reg = self.__tcp_client.read_holding_registers(0x0102, ModbusDataType.INT_16, device_id=self.__modbus_id)
soc = int(soc_reg * 0.1)
self.peak_filter.check_values(power)
@@ -69,7 +69,7 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
# Kein Powerlimit gefordert, externe Steuerung deaktivieren
log.debug("Keine Batteriesteuerung gefordert, deaktiviere externe Steuerung.")
if self.last_mode is not None:
- self.__tcp_client.write_register(2127, 0, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(2127, 0, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = None
elif power_limit <= 0:
# AlphaESS kann die Entladung nur über den SoC verhindern (komplette Entladesperre)
@@ -77,15 +77,15 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
# Zeiten für Netzladung müssen im Wechselrichter aktiviert werden
log.debug("Aktive Batteriesteuerung angestoßen. Setze Entladesperre.")
if self.last_mode != 'stop':
- self.__tcp_client.write_register(2127, 1, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(2133, 10, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(2127, 1, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(2133, 10, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'stop'
else:
# Aktive Ladung
log.debug("Aktive Batteriesteuerung angestoßen. Setze aktive Ladung.")
if self.last_mode != 'charge':
- self.__tcp_client.write_register(2127, 1, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(2133, 100, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(2127, 1, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(2133, 100, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'charge'
def power_limit_controllable(self) -> bool:
diff --git a/packages/modules/devices/alpha_ess/alpha_ess/counter.py b/packages/modules/devices/alpha_ess/alpha_ess/counter.py
index ea184ee888..11cec1561c 100644
--- a/packages/modules/devices/alpha_ess/alpha_ess/counter.py
+++ b/packages/modules/devices/alpha_ess/alpha_ess/counter.py
@@ -37,12 +37,12 @@ def update(self):
time.sleep(0.1)
if self.__device_config.source == 0 and self.__device_config.version == 0:
power, exported, imported = self.__tcp_client.read_holding_registers(
- 0x6, [modbus.ModbusDataType.INT_32] * 3, unit=self.__modbus_id)
+ 0x6, [modbus.ModbusDataType.INT_32] * 3, device_id=self.__modbus_id)
exported *= 10
imported *= 10
imported, exported = self.peak_filter.check_values(power, imported, exported)
currents = [val / 230 for val in self.__tcp_client.read_holding_registers(
- 0x0000, [ModbusDataType.INT_32]*3, unit=self.__modbus_id)]
+ 0x0000, [ModbusDataType.INT_32]*3, device_id=self.__modbus_id)]
counter_state = CounterState(
currents=currents,
imported=imported,
@@ -50,18 +50,18 @@ def update(self):
power=power
)
else:
- power = self.__tcp_client.read_holding_registers(0x0021, ModbusDataType.INT_32, unit=self.__modbus_id)
+ power = self.__tcp_client.read_holding_registers(0x0021, ModbusDataType.INT_32, device_id=self.__modbus_id)
exported, imported = [
val * 10 for val in self.__tcp_client.read_holding_registers(
- 0x0010, [ModbusDataType.INT_32] * 2, unit=self.__modbus_id
+ 0x0010, [ModbusDataType.INT_32] * 2, device_id=self.__modbus_id
)]
imported, exported = self.peak_filter.check_values(power, imported, exported)
frequency = self.__tcp_client.read_holding_registers(
- 0x001A, ModbusDataType.UINT_16, unit=self.__modbus_id) / 100
+ 0x001A, ModbusDataType.UINT_16, device_id=self.__modbus_id) / 100
currents = self.__tcp_client.read_holding_registers(
- 0x0017, [ModbusDataType.INT_16]*3, unit=self.__modbus_id)
+ 0x0017, [ModbusDataType.INT_16]*3, device_id=self.__modbus_id)
powers = self.__tcp_client.read_holding_registers(
- 0x001b, [ModbusDataType.INT_32]*3, unit=self.__modbus_id)
+ 0x001b, [ModbusDataType.INT_32]*3, device_id=self.__modbus_id)
currents = scale_currents(currents, powers)
counter_state = CounterState(
currents=currents,
diff --git a/packages/modules/devices/alpha_ess/alpha_ess/inverter.py b/packages/modules/devices/alpha_ess/alpha_ess/inverter.py
index d38a28bdda..512d234918 100644
--- a/packages/modules/devices/alpha_ess/alpha_ess/inverter.py
+++ b/packages/modules/devices/alpha_ess/alpha_ess/inverter.py
@@ -56,7 +56,7 @@ def __version_factory(self) -> int:
def __get_power(self, reg_p: int) -> Number:
powers = [
- self.__tcp_client.read_holding_registers(address, ModbusDataType.INT_32, unit=self.__modbus_id)
+ self.__tcp_client.read_holding_registers(address, ModbusDataType.INT_32, device_id=self.__modbus_id)
for address in [reg_p, 0x041F, 0x0423, 0x0427]
]
powers[0] = abs(powers[0])
diff --git a/packages/modules/devices/ampere/ampere/bat.py b/packages/modules/devices/ampere/ampere/bat.py
index 1ee8a9269c..8cf0c878fb 100644
--- a/packages/modules/devices/ampere/ampere/bat.py
+++ b/packages/modules/devices/ampere/ampere/bat.py
@@ -36,8 +36,8 @@ def initialize(self) -> None:
self.client = self.kwargs['client']
def update(self) -> None:
- power = self.client.read_input_registers(535, ModbusDataType.INT_16, unit=self.modbus_id) * -1
- soc = self.client.read_input_registers(1339, ModbusDataType.UINT_16, unit=self.modbus_id)
+ power = self.client.read_input_registers(535, ModbusDataType.INT_16, device_id=self.modbus_id) * -1
+ soc = self.client.read_input_registers(1339, ModbusDataType.UINT_16, device_id=self.modbus_id)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/ampere/ampere/counter.py b/packages/modules/devices/ampere/ampere/counter.py
index 5ecc06f901..ec377b593b 100644
--- a/packages/modules/devices/ampere/ampere/counter.py
+++ b/packages/modules/devices/ampere/ampere/counter.py
@@ -36,8 +36,8 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.COUNTER, self.component_config.id, self.fault_state)
def update(self):
- powers = self.client.read_input_registers(1349, [ModbusDataType.INT_16]*3, unit=self.modbus_id)
- power = self.client.read_input_registers(1348, ModbusDataType.INT_16, unit=self.modbus_id)
+ powers = self.client.read_input_registers(1349, [ModbusDataType.INT_16]*3, device_id=self.modbus_id)
+ power = self.client.read_input_registers(1348, ModbusDataType.INT_16, device_id=self.modbus_id)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/ampere/ampere/inverter.py b/packages/modules/devices/ampere/ampere/inverter.py
index 8fcbc47ed0..daed698483 100644
--- a/packages/modules/devices/ampere/ampere/inverter.py
+++ b/packages/modules/devices/ampere/ampere/inverter.py
@@ -36,8 +36,8 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.INVERTER, self.component_config.id, self.fault_state)
def update(self) -> None:
- pv1_power = self.client.read_holding_registers(519, ModbusDataType.INT_16, unit=self.modbus_id) * -1
- pv2_power = self.client.read_holding_registers(522, ModbusDataType.INT_16, unit=self.modbus_id) * -1
+ pv1_power = self.client.read_holding_registers(519, ModbusDataType.INT_16, device_id=self.modbus_id) * -1
+ pv2_power = self.client.read_holding_registers(522, ModbusDataType.INT_16, device_id=self.modbus_id) * -1
power = pv1_power + pv2_power
diff --git a/packages/modules/devices/azzurro_zcs/azzurro_zcs/bat.py b/packages/modules/devices/azzurro_zcs/azzurro_zcs/bat.py
index f13cd5b59a..d595bd90ec 100644
--- a/packages/modules/devices/azzurro_zcs/azzurro_zcs/bat.py
+++ b/packages/modules/devices/azzurro_zcs/azzurro_zcs/bat.py
@@ -33,15 +33,15 @@ def update(self) -> None:
# 0x020D Battery charge-discharge power Int16 -10-10 kW accuracy 0,01 kW pos charge, neg discharge
# 0x020E Battery voltage Cell UInt16 0-100 V accuracy 0,1 V
# 0x020F Battery charge-discharge current Int -100-100 A accuracy 0,01A
- power = self.client.read_input_registers(0x020D, ModbusDataType.INT_16, unit=self.__modbus_id)
+ power = self.client.read_input_registers(0x020D, ModbusDataType.INT_16, device_id=self.__modbus_id)
# 0x0210 SoC UInt16 0-100 %
- soc = self.client.read_input_registers(0x0210, ModbusDataType.UINT_16, unit=self.__modbus_id)
+ soc = self.client.read_input_registers(0x0210, ModbusDataType.UINT_16, device_id=self.__modbus_id)
# 0x0227 Total energy charging battery low UInt16 in kWh LSB
imported = self.client.read_input_registers(
- 0x0227, ModbusDataType.UINT_16, unit=self.__modbus_id) * 100
+ 0x0227, ModbusDataType.UINT_16, device_id=self.__modbus_id) * 100
# 0x0229 Total energy discharging battery low UInt16 in kWh LSB
exported = self.client.read_input_registers(
- 0x0229, ModbusDataType.UINT_16, unit=self.__modbus_id) * 100
+ 0x0229, ModbusDataType.UINT_16, device_id=self.__modbus_id) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
bat_state = BatState(
diff --git a/packages/modules/devices/azzurro_zcs/azzurro_zcs/counter.py b/packages/modules/devices/azzurro_zcs/azzurro_zcs/counter.py
index 25ab9f48e8..10e6672d01 100644
--- a/packages/modules/devices/azzurro_zcs/azzurro_zcs/counter.py
+++ b/packages/modules/devices/azzurro_zcs/azzurro_zcs/counter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from typing import TypedDict, Any
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractCounter
from modules.common.component_state import CounterState
@@ -36,22 +36,22 @@ def update(self) -> None:
# 0x0212 Grid Power Int16 -10-10 kW Unit 0,01kW Feed in/out power
# 0x0214 Input/Output power Int16 -10-10kW 0,01kW Energy storage power inverter
power = self.client.read_input_registers(0x0212, ModbusDataType.INT_16, wordorder=Endian.Little,
- unit=self.__modbus_id) * -1
+ device_id=self.__modbus_id) * -1
# 0x020C Grid frequency UInt 0-100 Hz Unit 0,01 Hz
frequency = self.client.read_input_registers(
- 0x020C, ModbusDataType.UINT_16, unit=self.__modbus_id) / 100
+ 0x020C, ModbusDataType.UINT_16, device_id=self.__modbus_id) / 100
exported = [value * 10
for value in self.client.read_input_registers(
# 0x021E Total energy injected into the grid UInt16 Unit 1kWh high
# 0x021F Total energy injected into the grid UInt16 Unit 1kWh low
0x021E, [ModbusDataType.UINT_16] * 10,
- wordorder=Endian.Little, unit=self.__modbus_id)]
+ wordorder=Endian.Little, device_id=self.__modbus_id)]
imported = [value * 10
for value in self.client.read_input_registers(
# 0x0220 Total energy taken from the grid UInt16 Unit 1kWh high
# 0x0221 Total energy taken from the grid UInt16 Unit 1kWh low
0x0220, [ModbusDataType.UINT_16] * 10,
- wordorder=Endian.Little, unit=self.__modbus_id)]
+ wordorder=Endian.Little, device_id=self.__modbus_id)]
imported, exported = self.peak_filter.check_values(power, imported, exported)
counter_state = CounterState(
diff --git a/packages/modules/devices/azzurro_zcs/azzurro_zcs/inverter.py b/packages/modules/devices/azzurro_zcs/azzurro_zcs/inverter.py
index 2d7b7de42d..4c80155db4 100644
--- a/packages/modules/devices/azzurro_zcs/azzurro_zcs/inverter.py
+++ b/packages/modules/devices/azzurro_zcs/azzurro_zcs/inverter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from typing import TypedDict, Any
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractInverter
from modules.common.component_state import InverterState
@@ -35,18 +35,18 @@ def update(self) -> None:
# 0x0250 PV1 Voltage UInt16 0-1000V Unit 0,1V
# 0x0251 PV1 current Int16 0-100A Unit 0,01A
power_string1 = (self.client.read_input_registers(
- 0x0250, ModbusDataType.UINT_16, unit=self.__modbus_id) / 10) * \
- (self.client.read_input_registers(0x0251, ModbusDataType.INT_16, unit=self.__modbus_id) / 10)
+ 0x0250, ModbusDataType.UINT_16, device_id=self.__modbus_id) / 10) * \
+ (self.client.read_input_registers(0x0251, ModbusDataType.INT_16, device_id=self.__modbus_id) / 10)
# 0x0255 PV2 Power UInt16 0-100 kW Unit 0,01kW
# 0x0253 PV2 Voltage UInt16 0-1000V Unit 0,1V
# 0x0254 PV2 current Int16 0-100A Unit 0,01A
power_string2 = (self.client.read_input_registers(
- 0x0253, ModbusDataType.INT_16, unit=self.__modbus_id) / 10) * \
- (self.client.read_input_registers(0x0254, ModbusDataType.INT_16, unit=self.__modbus_id) / 10)
+ 0x0253, ModbusDataType.INT_16, device_id=self.__modbus_id) / 10) * \
+ (self.client.read_input_registers(0x0254, ModbusDataType.INT_16, device_id=self.__modbus_id) / 10)
power = (power_string1 + power_string2) * -1
# 0x0215 PV Power generation UInt16 0 -10 kW Unit 0,01kW
exported = self.client.read_input_registers(0x0215, ModbusDataType.UINT_16, wordorder=Endian.Little,
- unit=self.__modbus_id) * 100
+ device_id=self.__modbus_id) * 100
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/azzurro_zcs/azzurro_zcs_3p/pv_inverter.py b/packages/modules/devices/azzurro_zcs/azzurro_zcs_3p/pv_inverter.py
index cb792c7dc4..d74e7a6c24 100644
--- a/packages/modules/devices/azzurro_zcs/azzurro_zcs_3p/pv_inverter.py
+++ b/packages/modules/devices/azzurro_zcs/azzurro_zcs_3p/pv_inverter.py
@@ -35,12 +35,12 @@ def update(self) -> None:
power = exported = 0
currents = None
try:
- power = self.client.read_holding_registers(0x0485, ModbusDataType.INT_16, unit=self.__modbus_id)*10
- exported = self.client.read_holding_registers(0x0684, ModbusDataType.UINT_32, unit=self.__modbus_id)*10
+ power = self.client.read_holding_registers(0x0485, ModbusDataType.INT_16, device_id=self.__modbus_id)*10
+ exported = self.client.read_holding_registers(0x0684, ModbusDataType.UINT_32, device_id=self.__modbus_id)*10
currents = [
- self.client.read_holding_registers(0x48E, ModbusDataType.INT_16, unit=self.__modbus_id)*0.01,
- self.client.read_holding_registers(0x499, ModbusDataType.INT_16, unit=self.__modbus_id)*0.01,
- self.client.read_holding_registers(0x4A4, ModbusDataType.INT_16, unit=self.__modbus_id)*0.01
+ self.client.read_holding_registers(0x48E, ModbusDataType.INT_16, device_id=self.__modbus_id)*0.01,
+ self.client.read_holding_registers(0x499, ModbusDataType.INT_16, device_id=self.__modbus_id)*0.01,
+ self.client.read_holding_registers(0x4A4, ModbusDataType.INT_16, device_id=self.__modbus_id)*0.01
]
except Exception:
log.debug("Modbus could not be read.")
diff --git a/packages/modules/devices/carlo_gavazzi/carlo_gavazzi/counter.py b/packages/modules/devices/carlo_gavazzi/carlo_gavazzi/counter.py
index 18ff88a5f4..fecec94504 100644
--- a/packages/modules/devices/carlo_gavazzi/carlo_gavazzi/counter.py
+++ b/packages/modules/devices/carlo_gavazzi/carlo_gavazzi/counter.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
from typing import Any, TypedDict
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.devices.carlo_gavazzi.carlo_gavazzi.config import CarloGavazziCounterSetup
from modules.common import modbus
@@ -39,13 +39,13 @@ def initialize(self) -> None:
def update(self):
with self.__tcp_client:
voltages = [val / 10 for val in self.__tcp_client.read_input_registers(
- 0x00, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, unit=self.__modbus_id)]
+ 0x00, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, device_id=self.__modbus_id)]
powers = [val / 10 for val in self.__tcp_client.read_input_registers(
- 0x12, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, unit=self.__modbus_id)]
+ 0x12, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, device_id=self.__modbus_id)]
power = sum(powers)
currents = [(val / 1000) for val in self.__tcp_client.read_input_registers(
- 0x0C, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, unit=self.__modbus_id)]
- frequency = self.__tcp_client.read_input_registers(0x33, ModbusDataType.INT_16, unit=self.__modbus_id) / 10
+ 0x0C, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, device_id=self.__modbus_id)]
+ frequency = self.__tcp_client.read_input_registers(0x33, ModbusDataType.INT_16, device_id=self.__modbus_id) / 10
if frequency > 100:
frequency = frequency / 10
diff --git a/packages/modules/devices/chint/chint/counter.py b/packages/modules/devices/chint/chint/counter.py
index 9654cdfb2a..a9708834d9 100644
--- a/packages/modules/devices/chint/chint/counter.py
+++ b/packages/modules/devices/chint/chint/counter.py
@@ -33,30 +33,30 @@ def initialize(self) -> None:
def update(self):
powers = voltages = currents = power_factors = None
imported_ep = exported_ep = power = frequency = 0
- irat = self.client.read_holding_registers(0x0006, ModbusDataType.INT_16, unit=self.__modbus_id)
- urat = self.client.read_holding_registers(0x0007, ModbusDataType.INT_16, unit=self.__modbus_id)
+ irat = self.client.read_holding_registers(0x0006, ModbusDataType.INT_16, device_id=self.__modbus_id)
+ urat = self.client.read_holding_registers(0x0007, ModbusDataType.INT_16, device_id=self.__modbus_id)
power_ratio = urat*0.1*irat*0.1
- frequency = self.client.read_holding_registers(0x2044, ModbusDataType.FLOAT_32, unit=self.__modbus_id)/100
+ frequency = self.client.read_holding_registers(0x2044, ModbusDataType.FLOAT_32, device_id=self.__modbus_id)/100
power = self.client.read_holding_registers(0x2012,
- ModbusDataType.FLOAT_32, unit=self.__modbus_id) * power_ratio
- powers = [self.client.read_holding_registers(reg, ModbusDataType.FLOAT_32, unit=self.__modbus_id) * power_ratio
+ ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * power_ratio
+ powers = [self.client.read_holding_registers(reg, ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * power_ratio
for reg in [0x2014, 0x2016, 0x2018]]
voltage_ratio = urat*0.1*0.1
voltages = [self.client.read_holding_registers(
- reg, ModbusDataType.FLOAT_32, unit=self.__modbus_id) * voltage_ratio
+ reg, ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * voltage_ratio
for reg in [0x2006, 0x2008, 0x200A]]
current_ratio = irat*0.001
currents = [self.client.read_holding_registers(
- reg, ModbusDataType.FLOAT_32, unit=self.__modbus_id) * current_ratio
+ reg, ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * current_ratio
for reg in [0x200C, 0x200E, 0x2010]]
- power_factors = [self.client.read_holding_registers(reg, ModbusDataType.FLOAT_32, unit=self.__modbus_id) * 0.001
+ power_factors = [self.client.read_holding_registers(reg, ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * 0.001
for reg in [0x202C, 0x202E, 0x2030]]
ep_ratio = irat * urat * 100
imported_ep = self.client.read_holding_registers(0x401E,
- ModbusDataType.FLOAT_32, unit=self.__modbus_id) * ep_ratio
+ ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * ep_ratio
exported_ep = self.client.read_holding_registers(0x4028,
- ModbusDataType.FLOAT_32, unit=self.__modbus_id) * ep_ratio
+ ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * ep_ratio
imported_ep, exported_ep = self.peak_filter.check_values(power, imported_ep, exported_ep)
diff --git a/packages/modules/devices/deye/deye/bat.py b/packages/modules/devices/deye/deye/bat.py
index f6677ce765..920f33a876 100644
--- a/packages/modules/devices/deye/deye/bat.py
+++ b/packages/modules/devices/deye/deye/bat.py
@@ -33,18 +33,18 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.BAT, self.component_config.id, self.fault_state)
self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="speicher")
self.device_type = DeviceType(self.client.read_holding_registers(
- 0, ModbusDataType.INT_16, unit=self.component_config.configuration.modbus_id))
+ 0, ModbusDataType.INT_16, device_id=self.component_config.configuration.modbus_id))
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
if self.device_type == DeviceType.SINGLE_PHASE_STRING or self.device_type == DeviceType.SINGLE_PHASE_HYBRID:
- power = self.client.read_holding_registers(190, ModbusDataType.INT_16, unit=unit) * -1
- soc = self.client.read_holding_registers(184, ModbusDataType.INT_16, unit=unit)
+ power = self.client.read_holding_registers(190, ModbusDataType.INT_16, device_id=unit) * -1
+ soc = self.client.read_holding_registers(184, ModbusDataType.INT_16, device_id=unit)
if self.device_type == DeviceType.SINGLE_PHASE_HYBRID:
- imported = self.client.read_holding_registers(72, ModbusDataType.UINT_16, unit=unit) * 100
- exported = self.client.read_holding_registers(74, ModbusDataType.UINT_16, unit=unit) * 100
+ imported = self.client.read_holding_registers(72, ModbusDataType.UINT_16, device_id=unit) * 100
+ exported = self.client.read_holding_registers(74, ModbusDataType.UINT_16, device_id=unit) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
elif self.device_type == DeviceType.SINGLE_PHASE_STRING:
@@ -52,11 +52,11 @@ def update(self) -> None:
imported, exported = self.sim_counter.sim_count(power)
else: # THREE_PHASE_LV (0x0500, 0x0005), THREE_PHASE_HV (0x0006)
- power = self.client.read_holding_registers(590, ModbusDataType.INT_16, unit=unit) * -1
+ power = self.client.read_holding_registers(590, ModbusDataType.INT_16, device_id=unit) * -1
if self.device_type == DeviceType.THREE_PHASE_HV:
power = power * 10
- soc = self.client.read_holding_registers(588, ModbusDataType.INT_16, unit=unit)
+ soc = self.client.read_holding_registers(588, ModbusDataType.INT_16, device_id=unit)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/deye/deye/counter.py b/packages/modules/devices/deye/deye/counter.py
index cc9c002dc9..1d2be5ea52 100644
--- a/packages/modules/devices/deye/deye/counter.py
+++ b/packages/modules/devices/deye/deye/counter.py
@@ -32,13 +32,13 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.COUNTER, self.component_config.id, self.fault_state)
self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="bezug")
self.device_type = DeviceType(self.client.read_holding_registers(
- 0, ModbusDataType.INT_16, unit=self.component_config.configuration.modbus_id))
+ 0, ModbusDataType.INT_16, device_id=self.component_config.configuration.modbus_id))
def update(self):
unit = self.component_config.configuration.modbus_id
if self.device_type == DeviceType.SINGLE_PHASE_STRING or self.device_type == DeviceType.SINGLE_PHASE_HYBRID:
- frequency = self.client.read_holding_registers(79, ModbusDataType.INT_16, unit=unit) / 100
+ frequency = self.client.read_holding_registers(79, ModbusDataType.INT_16, device_id=unit) / 100
if self.device_type == DeviceType.SINGLE_PHASE_HYBRID:
powers = [0]*3
@@ -48,18 +48,18 @@ def update(self):
elif self.device_type == DeviceType.SINGLE_PHASE_STRING:
currents = [
- c / 100 for c in self.client.read_holding_registers(76, [ModbusDataType.INT_16]*3, unit=unit)]
+ c / 100 for c in self.client.read_holding_registers(76, [ModbusDataType.INT_16]*3, device_id=unit)]
voltages = [
- v / 10 for v in self.client.read_holding_registers(70, [ModbusDataType.INT_16]*3, unit=unit)]
+ v / 10 for v in self.client.read_holding_registers(70, [ModbusDataType.INT_16]*3, device_id=unit)]
powers = [currents[i] * voltages[i] for i in range(0, 3)]
power = sum(powers)
else: # THREE_PHASE_LV (0x0500, 0x0005), THREE_PHASE_HV (0x0006)
- currents = [c / 100 for c in self.client.read_holding_registers(613, [ModbusDataType.INT_16]*3, unit=unit)]
- voltages = [v / 10 for v in self.client.read_holding_registers(644, [ModbusDataType.INT_16]*3, unit=unit)]
- powers = self.client.read_holding_registers(616, [ModbusDataType.INT_16]*3, unit=unit)
+ currents = [c / 100 for c in self.client.read_holding_registers(613, [ModbusDataType.INT_16]*3, device_id=unit)]
+ voltages = [v / 10 for v in self.client.read_holding_registers(644, [ModbusDataType.INT_16]*3, device_id=unit)]
+ powers = self.client.read_holding_registers(616, [ModbusDataType.INT_16]*3, device_id=unit)
power = sum(powers)
- frequency = self.client.read_holding_registers(609, ModbusDataType.INT_16, unit=unit) / 100
+ frequency = self.client.read_holding_registers(609, ModbusDataType.INT_16, device_id=unit) / 100
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/deye/deye/inverter.py b/packages/modules/devices/deye/deye/inverter.py
index 13eeb467be..e9dee5b5e3 100644
--- a/packages/modules/devices/deye/deye/inverter.py
+++ b/packages/modules/devices/deye/deye/inverter.py
@@ -32,16 +32,16 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.INVERTER, self.component_config.id, self.fault_state)
self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="pv")
self.device_type = DeviceType(self.client.read_holding_registers(
- 0, ModbusDataType.INT_16, unit=self.component_config.configuration.modbus_id))
+ 0, ModbusDataType.INT_16, device_id=self.component_config.configuration.modbus_id))
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
if self.device_type == DeviceType.SINGLE_PHASE_STRING or self.device_type == DeviceType.SINGLE_PHASE_HYBRID:
- power = sum(self.client.read_holding_registers(186, [ModbusDataType.INT_16]*4, unit=unit)) * -1
+ power = sum(self.client.read_holding_registers(186, [ModbusDataType.INT_16]*4, device_id=unit)) * -1
else: # THREE_PHASE_LV (0x0500, 0x0005), THREE_PHASE_HV (0x0006)
- power = sum(self.client.read_holding_registers(672, [ModbusDataType.INT_16]*2, unit=unit)) * -1
+ power = sum(self.client.read_holding_registers(672, [ModbusDataType.INT_16]*2, device_id=unit)) * -1
if self.device_type == DeviceType.THREE_PHASE_HV:
power = power * 10
diff --git a/packages/modules/devices/e3dc/e3dc/bat.py b/packages/modules/devices/e3dc/e3dc/bat.py
index 18d290671c..86e5497e2e 100644
--- a/packages/modules/devices/e3dc/e3dc/bat.py
+++ b/packages/modules/devices/e3dc/e3dc/bat.py
@@ -18,9 +18,9 @@
def read_bat(client: modbus.ModbusTcpClient_, modbus_id: int) -> Tuple[int, int]:
# 40082 SoC
- soc = client.read_holding_registers(40082, ModbusDataType.INT_16, unit=modbus_id)
+ soc = client.read_holding_registers(40082, ModbusDataType.INT_16, device_id=modbus_id)
# 40069 Speicherleistung
- power = client.read_holding_registers(40069, ModbusDataType.INT_32, wordorder=Endian.Little, unit=modbus_id)
+ power = client.read_holding_registers(40069, ModbusDataType.INT_32, wordorder=Endian.Little, device_id=modbus_id)
return soc, power
diff --git a/packages/modules/devices/e3dc/e3dc/counter.py b/packages/modules/devices/e3dc/e3dc/counter.py
index f58ff196dd..4744c301a1 100644
--- a/packages/modules/devices/e3dc/e3dc/counter.py
+++ b/packages/modules/devices/e3dc/e3dc/counter.py
@@ -29,7 +29,7 @@ def read_counter(client: modbus.ModbusTcpClient_, modbus_id: int) -> Tuple[int,
# bei den meisten e3dc auf 40128
# farm haben typ 5, normale e3dc haben nur typ 1 und keinen typ 5
# bei farm ist typ 1 vorhanden aber liefert immer 0
- meters = list(map(int, client.read_holding_registers(40104, [ModbusDataType.INT_16] * 28, unit=modbus_id)))
+ meters = list(map(int, client.read_holding_registers(40104, [ModbusDataType.INT_16] * 28, device_id=modbus_id)))
log.debug("meters: %s", meters)
try:
powers = get_meter_phases(5, meters)
diff --git a/packages/modules/devices/e3dc/e3dc/external_inverter.py b/packages/modules/devices/e3dc/e3dc/external_inverter.py
index 93c8955271..49c1205c46 100644
--- a/packages/modules/devices/e3dc/e3dc/external_inverter.py
+++ b/packages/modules/devices/e3dc/e3dc/external_inverter.py
@@ -19,7 +19,7 @@
def read_external_inverter(client: modbus.ModbusTcpClient_, modbus_id: int) -> int:
pv_external = int(client.read_holding_registers(
- 40075, ModbusDataType.INT_32, wordorder=Endian.Little, unit=modbus_id))
+ 40075, ModbusDataType.INT_32, wordorder=Endian.Little, device_id=modbus_id))
return pv_external
diff --git a/packages/modules/devices/e3dc/e3dc/inverter.py b/packages/modules/devices/e3dc/e3dc/inverter.py
index 25249f49ca..f88b373a07 100644
--- a/packages/modules/devices/e3dc/e3dc/inverter.py
+++ b/packages/modules/devices/e3dc/e3dc/inverter.py
@@ -18,7 +18,7 @@
def read_inverter(client: modbus.ModbusTcpClient_, modbus_id: int) -> int:
- pv = int(client.read_holding_registers(40067, ModbusDataType.INT_32, wordorder=Endian.Little, unit=modbus_id) * -1)
+ pv = int(client.read_holding_registers(40067, ModbusDataType.INT_32, wordorder=Endian.Little, device_id=modbus_id) * -1)
return pv
diff --git a/packages/modules/devices/fox_ess/fox_ess/bat.py b/packages/modules/devices/fox_ess/fox_ess/bat.py
index 408fa44e44..9cd186e146 100644
--- a/packages/modules/devices/fox_ess/fox_ess/bat.py
+++ b/packages/modules/devices/fox_ess/fox_ess/bat.py
@@ -32,12 +32,12 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_holding_registers(31036, ModbusDataType.INT_16, unit=unit) * -1
- soc = self.client.read_holding_registers(31038, ModbusDataType.UINT_16, unit=unit)
+ power = self.client.read_holding_registers(31036, ModbusDataType.INT_16, device_id=unit) * -1
+ soc = self.client.read_holding_registers(31038, ModbusDataType.UINT_16, device_id=unit)
# Geladen in kWh * 0,1
- imported = self.client.read_holding_registers(32003, ModbusDataType.UINT_32, unit=unit) * 100
+ imported = self.client.read_holding_registers(32003, ModbusDataType.UINT_32, device_id=unit) * 100
# Entladen in kWh * 0,1
- exported = self.client.read_holding_registers(32006, ModbusDataType.UINT_32, unit=unit) * 100
+ exported = self.client.read_holding_registers(32006, ModbusDataType.UINT_32, device_id=unit) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
bat_state = BatState(
diff --git a/packages/modules/devices/fox_ess/fox_ess/counter.py b/packages/modules/devices/fox_ess/fox_ess/counter.py
index e600ce8f13..3c2da2c6a5 100644
--- a/packages/modules/devices/fox_ess/fox_ess/counter.py
+++ b/packages/modules/devices/fox_ess/fox_ess/counter.py
@@ -29,11 +29,11 @@ def update(self) -> None:
unit = self.component_config.configuration.modbus_id
powers = [val * -1 for val in
- self.client.read_holding_registers(31026, [ModbusDataType.INT_16]*3, unit=unit)]
+ self.client.read_holding_registers(31026, [ModbusDataType.INT_16]*3, device_id=unit)]
power = sum(powers)
- frequency = self.client.read_holding_registers(31015, ModbusDataType.UINT_16, unit=unit) / 100
- imported = self.client.read_holding_registers(32018, ModbusDataType.UINT_32, unit=unit) * 100
- exported = self.client.read_holding_registers(32015, ModbusDataType.UINT_32, unit=unit) * 100
+ frequency = self.client.read_holding_registers(31015, ModbusDataType.UINT_16, device_id=unit) / 100
+ imported = self.client.read_holding_registers(32018, ModbusDataType.UINT_32, device_id=unit) * 100
+ exported = self.client.read_holding_registers(32015, ModbusDataType.UINT_32, device_id=unit) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
counter_state = CounterState(
diff --git a/packages/modules/devices/fox_ess/fox_ess/inverter.py b/packages/modules/devices/fox_ess/fox_ess/inverter.py
index d64265aed4..862b6568fd 100644
--- a/packages/modules/devices/fox_ess/fox_ess/inverter.py
+++ b/packages/modules/devices/fox_ess/fox_ess/inverter.py
@@ -31,10 +31,10 @@ def update(self) -> None:
unit = self.component_config.configuration.modbus_id
# PV1 + PV2 Power
power = sum([self.client.read_holding_registers(
- reg, ModbusDataType.INT_16, unit=unit)
+ reg, ModbusDataType.INT_16, device_id=unit)
for reg in [31002, 31005]]) * -1
# Gesamt Produktion Wechselrichter unsigned integer in kWh * 0,1
- exported = self.client.read_holding_registers(32000, ModbusDataType.UINT_32, unit=unit) * 100
+ exported = self.client.read_holding_registers(32000, ModbusDataType.UINT_32, device_id=unit) * 100
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/good_we/good_we/bat.py b/packages/modules/devices/good_we/good_we/bat.py
index de31002305..19ec9b7da9 100644
--- a/packages/modules/devices/good_we/good_we/bat.py
+++ b/packages/modules/devices/good_we/good_we/bat.py
@@ -49,19 +49,19 @@ def update(self) -> None:
if battery_index == 1:
if self.version == GoodWeVersion.V_1_7:
power = self.__tcp_client.read_holding_registers(
- 35183, ModbusDataType.INT_16, unit=self.__modbus_id)*-1
+ 35183, ModbusDataType.INT_16, device_id=self.__modbus_id)*-1
else:
power = self.__tcp_client.read_holding_registers(
- 35182, ModbusDataType.INT_32, unit=self.__modbus_id)*-1
- soc = self.__tcp_client.read_holding_registers(37007, ModbusDataType.UINT_16, unit=self.__modbus_id)
+ 35182, ModbusDataType.INT_32, device_id=self.__modbus_id)*-1
+ soc = self.__tcp_client.read_holding_registers(37007, ModbusDataType.UINT_16, device_id=self.__modbus_id)
imported = self.__tcp_client.read_holding_registers(
- 35206, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 35206, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
exported = self.__tcp_client.read_holding_registers(
- 35209, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 35209, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
else:
- power = self.__tcp_client.read_holding_registers(35264, ModbusDataType.INT_32, unit=self.__modbus_id)*-1
- soc = self.__tcp_client.read_holding_registers(39005, ModbusDataType.UINT_16, unit=self.__modbus_id)
+ power = self.__tcp_client.read_holding_registers(35264, ModbusDataType.INT_32, device_id=self.__modbus_id)*-1
+ soc = self.__tcp_client.read_holding_registers(39005, ModbusDataType.UINT_16, device_id=self.__modbus_id)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
@@ -80,31 +80,31 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
if power_limit is None:
log.debug("Keine Batteriesteuerung, Selbstregelung durch Wechselrichter")
if self.last_mode is not None:
- self.__tcp_client.write_register(47511, 1, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(47512, 0, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(47511, 1, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(47512, 0, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = None
elif power_limit == 0:
log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht entladen")
if self.last_mode != 'stop':
- self.__tcp_client.write_register(47511, 2, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(47512, 0, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(47511, 2, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(47512, 0, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'stop'
elif power_limit < 0:
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W entladen für den Hausverbrauch")
if self.last_mode != 'discharge':
- self.__tcp_client.write_register(47511, 3, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(47511, 3, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'discharge'
# Die maximale Entladeleistung begrenzen auf 5000W, maximaler Wertebereich Modbusregister.
power_value = int(min(abs(power_limit), 10000))
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W entladen für den Hausverbrauch")
- self.__tcp_client.write_register(47512, power_value, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(47512, power_value, data_type=ModbusDataType.UINT_16, device_id=unit)
elif power_limit > 0:
if self.last_mode != 'charge':
- self.__tcp_client.write_register(47511, 2, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(47511, 2, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'charge'
power_value = int(min(abs(power_limit), 10000))
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W entladen für den Hausverbrauch")
- self.__tcp_client.write_register(47512, power_value, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(47512, power_value, data_type=ModbusDataType.UINT_16, device_id=unit)
def power_limit_controllable(self) -> bool:
return True
diff --git a/packages/modules/devices/good_we/good_we/counter.py b/packages/modules/devices/good_we/good_we/counter.py
index f8fa2f4691..15cff34bf3 100644
--- a/packages/modules/devices/good_we/good_we/counter.py
+++ b/packages/modules/devices/good_we/good_we/counter.py
@@ -42,28 +42,28 @@ def update(self) -> None:
with self.__tcp_client:
if self.firmware < 9:
power = self.__tcp_client.read_holding_registers(
- 36008, ModbusDataType.INT_16, unit=self.__modbus_id) * -1
+ 36008, ModbusDataType.INT_16, device_id=self.__modbus_id) * -1
powers = [
val * -1 for val in self.__tcp_client.read_holding_registers(
- 36005, [ModbusDataType.INT_16]*3, unit=self.__modbus_id)]
+ 36005, [ModbusDataType.INT_16]*3, device_id=self.__modbus_id)]
else:
power = self.__tcp_client.read_holding_registers(
- 36025, ModbusDataType.INT_32, unit=self.__modbus_id) * -1
+ 36025, ModbusDataType.INT_32, device_id=self.__modbus_id) * -1
powers = [
val * -1 for val in self.__tcp_client.read_holding_registers(
- 36019, [ModbusDataType.INT_32]*3, unit=self.__modbus_id)]
+ 36019, [ModbusDataType.INT_32]*3, device_id=self.__modbus_id)]
power_factors = [
val / 1000 for val in self.__tcp_client.read_holding_registers(
- 36010, [ModbusDataType.INT_16]*3, unit=self.__modbus_id)]
+ 36010, [ModbusDataType.INT_16]*3, device_id=self.__modbus_id)]
frequency = self.__tcp_client.read_holding_registers(
- 36014, ModbusDataType.UINT_16, unit=self.__modbus_id) / 100
+ 36014, ModbusDataType.UINT_16, device_id=self.__modbus_id) / 100
if self.version == GoodWeVersion.V_1_7:
exported = self.__tcp_client.read_holding_registers(
- 36015, ModbusDataType.FLOAT_32, unit=self.__modbus_id)
+ 36015, ModbusDataType.FLOAT_32, device_id=self.__modbus_id)
imported = self.__tcp_client.read_holding_registers(
- 36017, ModbusDataType.FLOAT_32, unit=self.__modbus_id)
+ 36017, ModbusDataType.FLOAT_32, device_id=self.__modbus_id)
imported, exported = self.peak_filter.check_values(power, imported, exported)
else:
# v1.0 und v1.1 liefern keine Werte zurueck obwohl Register laut Doku gleich
diff --git a/packages/modules/devices/good_we/good_we/inverter.py b/packages/modules/devices/good_we/good_we/inverter.py
index 2f77bc943c..b5b008502d 100644
--- a/packages/modules/devices/good_we/good_we/inverter.py
+++ b/packages/modules/devices/good_we/good_we/inverter.py
@@ -38,10 +38,10 @@ def initialize(self) -> None:
def update(self) -> None:
with self.__tcp_client:
power = sum([self.__tcp_client.read_holding_registers(
- reg, ModbusDataType.INT_32, unit=self.__modbus_id)
+ reg, ModbusDataType.INT_32, device_id=self.__modbus_id)
for reg in [35105, 35109, 35113, 35117]]) * -1
exported = self.__tcp_client.read_holding_registers(
- 35191, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 35191, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/growatt/growatt/bat.py b/packages/modules/devices/growatt/growatt/bat.py
index 6bbf5530ac..ac60df7fb8 100644
--- a/packages/modules/devices/growatt/growatt/bat.py
+++ b/packages/modules/devices/growatt/growatt/bat.py
@@ -35,28 +35,28 @@ def initialize(self) -> None:
def update(self) -> None:
if self.version == GrowattVersion.max_series:
power_in = self.client.read_input_registers(
- 1011, ModbusDataType.UINT_32, unit=self.__modbus_id) * 0.1
+ 1011, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 0.1
power_out = self.client.read_input_registers(
- 1009, ModbusDataType.UINT_32, unit=self.__modbus_id) * -0.1
+ 1009, ModbusDataType.UINT_32, device_id=self.__modbus_id) * -0.1
power = power_in + power_out
- soc = self.client.read_input_registers(1014, ModbusDataType.UINT_16, unit=self.__modbus_id)
+ soc = self.client.read_input_registers(1014, ModbusDataType.UINT_16, device_id=self.__modbus_id)
imported = self.client.read_input_registers(
- 1058, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 1058, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
exported = self.client.read_input_registers(
- 1054, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 1054, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
else:
power_in = self.client.read_input_registers(
- 3180, ModbusDataType.UINT_32, unit=self.__modbus_id) * -0.1
+ 3180, ModbusDataType.UINT_32, device_id=self.__modbus_id) * -0.1
power_out = self.client.read_input_registers(
- 3178, ModbusDataType.UINT_32, unit=self.__modbus_id) * 0.1
+ 3178, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 0.1
power = power_in + power_out
- soc = self.client.read_input_registers(3171, ModbusDataType.UINT_16, unit=self.__modbus_id)
+ soc = self.client.read_input_registers(3171, ModbusDataType.UINT_16, device_id=self.__modbus_id)
imported = self.client.read_input_registers(
- 3131, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 3131, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
exported = self.client.read_input_registers(
- 3127, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 3127, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
bat_state = BatState(
diff --git a/packages/modules/devices/growatt/growatt/counter.py b/packages/modules/devices/growatt/growatt/counter.py
index ea18aef915..2f0a0d7506 100644
--- a/packages/modules/devices/growatt/growatt/counter.py
+++ b/packages/modules/devices/growatt/growatt/counter.py
@@ -34,40 +34,40 @@ def initialize(self) -> None:
def update(self) -> None:
if self.version == GrowattVersion.max_series:
- power_in = self.client.read_input_registers(1021, ModbusDataType.UINT_32, unit=self.__modbus_id) * 0.1
- power_out = self.client.read_input_registers(1029, ModbusDataType.UINT_32, unit=self.__modbus_id) * -0.1
+ power_in = self.client.read_input_registers(1021, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 0.1
+ power_out = self.client.read_input_registers(1029, ModbusDataType.UINT_32, device_id=self.__modbus_id) * -0.1
power = power_in + power_out
powers = [
self.client.read_input_registers(
- 40, ModbusDataType.INT_32, unit=self.__modbus_id) / 10,
+ 40, ModbusDataType.INT_32, device_id=self.__modbus_id) / 10,
self.client.read_input_registers(
- 44, ModbusDataType.INT_32, unit=self.__modbus_id) / 10,
+ 44, ModbusDataType.INT_32, device_id=self.__modbus_id) / 10,
self.client.read_input_registers(
- 48, ModbusDataType.INT_32, unit=self.__modbus_id) / 10]
+ 48, ModbusDataType.INT_32, device_id=self.__modbus_id) / 10]
# Einheit 0.1 kWh
- exported = self.client.read_input_registers(1050, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
- imported = self.client.read_input_registers(1046, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ exported = self.client.read_input_registers(1050, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
+ imported = self.client.read_input_registers(1046, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
# TL-X Dokumentation hat die gleichen Register wie die MAX Serie,
# zusätzlich sind aber auch unten abweichende enthalten
else:
- power_in = self.client.read_input_registers(3041, ModbusDataType.UINT_32, unit=self.__modbus_id) * 0.1
- power_out = self.client.read_input_registers(3043, ModbusDataType.UINT_32, unit=self.__modbus_id) * -0.1
+ power_in = self.client.read_input_registers(3041, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 0.1
+ power_out = self.client.read_input_registers(3043, ModbusDataType.UINT_32, device_id=self.__modbus_id) * -0.1
power = power_in + power_out
powers = [
self.client.read_input_registers(
- 3028, ModbusDataType.INT_32, unit=self.__modbus_id) / 10,
+ 3028, ModbusDataType.INT_32, device_id=self.__modbus_id) / 10,
self.client.read_input_registers(
- 3032, ModbusDataType.INT_32, unit=self.__modbus_id) / 10,
+ 3032, ModbusDataType.INT_32, device_id=self.__modbus_id) / 10,
self.client.read_input_registers(
- 3036, ModbusDataType.INT_32, unit=self.__modbus_id) / 10]
+ 3036, ModbusDataType.INT_32, device_id=self.__modbus_id) / 10]
# Einheit 0.1 kWh
- exported = self.client.read_input_registers(3073, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
- imported = self.client.read_input_registers(3069, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ exported = self.client.read_input_registers(3073, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
+ imported = self.client.read_input_registers(3069, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
counter_state = CounterState(
diff --git a/packages/modules/devices/growatt/growatt/inverter.py b/packages/modules/devices/growatt/growatt/inverter.py
index bc6da22ace..ec05fe9990 100644
--- a/packages/modules/devices/growatt/growatt/inverter.py
+++ b/packages/modules/devices/growatt/growatt/inverter.py
@@ -35,14 +35,14 @@ def initialize(self) -> None:
def update(self) -> None:
if self.version == GrowattVersion.max_series:
power = self.client.read_input_registers(
- 1, ModbusDataType.UINT_32, unit=self.__modbus_id) / -10
+ 1, ModbusDataType.UINT_32, device_id=self.__modbus_id) / -10
exported = self.client.read_input_registers(
- 91, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 91, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
else:
power = self.client.read_input_registers(
- 3001, ModbusDataType.UINT_32, unit=self.__modbus_id) / -10
+ 3001, ModbusDataType.UINT_32, device_id=self.__modbus_id) / -10
exported = self.client.read_input_registers(
- 3053, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 3053, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/huawei/huawei/bat.py b/packages/modules/devices/huawei/huawei/bat.py
index 9de263ec72..f3e29f1337 100644
--- a/packages/modules/devices/huawei/huawei/bat.py
+++ b/packages/modules/devices/huawei/huawei/bat.py
@@ -40,10 +40,10 @@ def initialize(self) -> None:
def update(self) -> None:
if self.type == HuaweiType.SDongle:
time.sleep(1)
- power = self.client.read_holding_registers(37765, ModbusDataType.INT_32, unit=self.modbus_id)
+ power = self.client.read_holding_registers(37765, ModbusDataType.INT_32, device_id=self.modbus_id)
if self.type == HuaweiType.SDongle:
time.sleep(1)
- soc = self.client.read_holding_registers(37760, ModbusDataType.INT_16, unit=self.modbus_id) / 10
+ soc = self.client.read_holding_registers(37760, ModbusDataType.INT_16, device_id=self.modbus_id) / 10
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/huawei/huawei/counter.py b/packages/modules/devices/huawei/huawei/counter.py
index 6b6196c9bf..a4a4821052 100644
--- a/packages/modules/devices/huawei/huawei/counter.py
+++ b/packages/modules/devices/huawei/huawei/counter.py
@@ -40,11 +40,11 @@ def initialize(self) -> None:
def update(self) -> None:
if self.type == HuaweiType.SDongle:
time.sleep(1)
- currents = self.client.read_holding_registers(37107, [ModbusDataType.INT_32]*3, unit=self.modbus_id)
+ currents = self.client.read_holding_registers(37107, [ModbusDataType.INT_32]*3, device_id=self.modbus_id)
currents = [val / -100 for val in currents]
if self.type == HuaweiType.SDongle:
time.sleep(1)
- power = self.client.read_holding_registers(37113, ModbusDataType.INT_32, unit=self.modbus_id) * -1
+ power = self.client.read_holding_registers(37113, ModbusDataType.INT_32, device_id=self.modbus_id) * -1
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/huawei/huawei/inverter.py b/packages/modules/devices/huawei/huawei/inverter.py
index d788b50397..16eef04eb7 100644
--- a/packages/modules/devices/huawei/huawei/inverter.py
+++ b/packages/modules/devices/huawei/huawei/inverter.py
@@ -40,7 +40,7 @@ def initialize(self) -> None:
def update(self) -> None:
if self.type == HuaweiType.SDongle:
time.sleep(1)
- power = self.client.read_holding_registers(32064, ModbusDataType.INT_32, unit=self.modbus_id) * -1
+ power = self.client.read_holding_registers(32064, ModbusDataType.INT_32, device_id=self.modbus_id) * -1
self.peak_filter.check_values(power)
_, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/huawei/huawei_emma/bat.py b/packages/modules/devices/huawei/huawei_emma/bat.py
index 9f98c8e6bd..fd5d78ae15 100644
--- a/packages/modules/devices/huawei/huawei_emma/bat.py
+++ b/packages/modules/devices/huawei/huawei_emma/bat.py
@@ -34,8 +34,8 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.BAT, self.component_config.id, self.fault_state)
def update(self) -> None:
- power = self.client.read_holding_registers(30360, ModbusDataType.INT_32, unit=self.modbus_id)
- soc = self.client.read_holding_registers(30368, ModbusDataType.UINT_16, unit=self.modbus_id) * 0.01
+ power = self.client.read_holding_registers(30360, ModbusDataType.INT_32, device_id=self.modbus_id)
+ soc = self.client.read_holding_registers(30368, ModbusDataType.UINT_16, device_id=self.modbus_id) * 0.01
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/huawei/huawei_emma/counter.py b/packages/modules/devices/huawei/huawei_emma/counter.py
index f7f3e6bd40..3aaa1fef6c 100644
--- a/packages/modules/devices/huawei/huawei_emma/counter.py
+++ b/packages/modules/devices/huawei/huawei_emma/counter.py
@@ -34,9 +34,9 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.COUNTER, self.component_config.id, self.fault_state)
def update(self) -> None:
- currents = self.client.read_holding_registers(31651, [ModbusDataType.INT_32]*3, unit=self.modbus_id)
+ currents = self.client.read_holding_registers(31651, [ModbusDataType.INT_32]*3, device_id=self.modbus_id)
currents = [val * 0.1 for val in currents]
- power = self.client.read_holding_registers(31657, ModbusDataType.INT_32, unit=self.modbus_id)
+ power = self.client.read_holding_registers(31657, ModbusDataType.INT_32, device_id=self.modbus_id)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/huawei/huawei_emma/inverter.py b/packages/modules/devices/huawei/huawei_emma/inverter.py
index 11324f7dc5..6e3b3c2424 100644
--- a/packages/modules/devices/huawei/huawei_emma/inverter.py
+++ b/packages/modules/devices/huawei/huawei_emma/inverter.py
@@ -32,8 +32,8 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.INVERTER, self.component_config.id, self.fault_state)
def update(self) -> None:
- power = self.client.read_holding_registers(30354, ModbusDataType.INT_32, unit=self.modbus_id) * -1
- exported = self.client.read_holding_registers(30348, ModbusDataType.UINT_64, unit=self.modbus_id) * 10
+ power = self.client.read_holding_registers(30354, ModbusDataType.INT_32, device_id=self.modbus_id) * -1
+ exported = self.client.read_holding_registers(30348, ModbusDataType.UINT_64, device_id=self.modbus_id) * 10
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
power=power,
diff --git a/packages/modules/devices/huawei/huawei_smartlogger/bat.py b/packages/modules/devices/huawei/huawei_smartlogger/bat.py
index 4d82b598cf..6585e9a16e 100644
--- a/packages/modules/devices/huawei/huawei_smartlogger/bat.py
+++ b/packages/modules/devices/huawei/huawei_smartlogger/bat.py
@@ -34,8 +34,8 @@ def initialize(self) -> None:
def update(self) -> None:
modbus_id = self.component_config.configuration.modbus_id
- power = self.__tcp_client.read_holding_registers(37765, ModbusDataType.INT_32, unit=modbus_id)
- soc = self.__tcp_client.read_holding_registers(37760, ModbusDataType.INT_16, unit=modbus_id) / 10
+ power = self.__tcp_client.read_holding_registers(37765, ModbusDataType.INT_32, device_id=modbus_id)
+ soc = self.__tcp_client.read_holding_registers(37760, ModbusDataType.INT_16, device_id=modbus_id) / 10
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/huawei/huawei_smartlogger/counter.py b/packages/modules/devices/huawei/huawei_smartlogger/counter.py
index 80b7ae5a53..161a64394f 100644
--- a/packages/modules/devices/huawei/huawei_smartlogger/counter.py
+++ b/packages/modules/devices/huawei/huawei_smartlogger/counter.py
@@ -33,12 +33,12 @@ def initialize(self) -> None:
def update(self) -> None:
modbus_id = self.component_config.configuration.modbus_id
- power = self.client.read_holding_registers(32278, ModbusDataType.INT_32, unit=modbus_id)
+ power = self.client.read_holding_registers(32278, ModbusDataType.INT_32, device_id=modbus_id)
currents = [val / 10 for val in self.client.read_holding_registers(
- 32272, [ModbusDataType.INT_32] * 3, unit=modbus_id)]
+ 32272, [ModbusDataType.INT_32] * 3, device_id=modbus_id)]
voltages = [val / 100 for val in self.client.read_holding_registers(
- 32260, [ModbusDataType.INT_32] * 3, unit=modbus_id)]
- powers = self.client.read_holding_registers(32335, [ModbusDataType.INT_32] * 3, unit=modbus_id)
+ 32260, [ModbusDataType.INT_32] * 3, device_id=modbus_id)]
+ powers = self.client.read_holding_registers(32335, [ModbusDataType.INT_32] * 3, device_id=modbus_id)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/huawei/huawei_smartlogger/inverter.py b/packages/modules/devices/huawei/huawei_smartlogger/inverter.py
index efe5604051..500a7208ab 100644
--- a/packages/modules/devices/huawei/huawei_smartlogger/inverter.py
+++ b/packages/modules/devices/huawei/huawei_smartlogger/inverter.py
@@ -37,8 +37,8 @@ def initialize(self) -> None:
def update(self) -> None:
modbus_id = self.component_config.configuration.modbus_id
- power = self.client.read_holding_registers(32080, ModbusDataType.INT_32, unit=modbus_id) * -1
- exported = self.client.read_holding_registers(32106, ModbusDataType.INT_32, unit=modbus_id) * 10
+ power = self.client.read_holding_registers(32080, ModbusDataType.INT_32, device_id=modbus_id) * -1
+ exported = self.client.read_holding_registers(32106, ModbusDataType.INT_32, device_id=modbus_id) * 10
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/idm/idm/counter.py b/packages/modules/devices/idm/idm/counter.py
index 6712dc1580..b7899b43fb 100644
--- a/packages/modules/devices/idm/idm/counter.py
+++ b/packages/modules/devices/idm/idm/counter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from typing import TypedDict, Any
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractCounter
from modules.common.component_state import CounterState
@@ -37,7 +37,7 @@ def initialize(self) -> None:
def update(self):
unit = self.modbus_id
power = self.client.read_input_registers(4122, ModbusDataType.FLOAT_32,
- wordorder=Endian.Little, unit=unit) * 1000
+ wordorder=Endian.Little, device_id=unit) * 1000
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/janitza/janitza/bat.py b/packages/modules/devices/janitza/janitza/bat.py
index 73d927a81d..4b3a06c8a5 100644
--- a/packages/modules/devices/janitza/janitza/bat.py
+++ b/packages/modules/devices/janitza/janitza/bat.py
@@ -34,7 +34,7 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.BAT, self.component_config.id, self.fault_state)
def update(self):
- power = self.__tcp_client.read_holding_registers(19026, ModbusDataType.FLOAT_32, unit=self.__modbus_id) * -1
+ power = self.__tcp_client.read_holding_registers(19026, ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * -1
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/janitza/janitza/counter.py b/packages/modules/devices/janitza/janitza/counter.py
index 72e054cd23..3d8ea1e6ec 100644
--- a/packages/modules/devices/janitza/janitza/counter.py
+++ b/packages/modules/devices/janitza/janitza/counter.py
@@ -36,16 +36,16 @@ def initialize(self) -> None:
def update(self) -> None:
with self.__tcp_client:
- power = self.__tcp_client.read_holding_registers(19026, ModbusDataType.FLOAT_32, unit=self.__modbus_id)
+ power = self.__tcp_client.read_holding_registers(19026, ModbusDataType.FLOAT_32, device_id=self.__modbus_id)
powers = self.__tcp_client.read_holding_registers(
- 19020, [ModbusDataType.FLOAT_32] * 3, unit=self.__modbus_id)
+ 19020, [ModbusDataType.FLOAT_32] * 3, device_id=self.__modbus_id)
currents = self.__tcp_client.read_holding_registers(
- 19012, [ModbusDataType.FLOAT_32] * 3, unit=self.__modbus_id)
+ 19012, [ModbusDataType.FLOAT_32] * 3, device_id=self.__modbus_id)
voltages = self.__tcp_client.read_holding_registers(
- 19000, [ModbusDataType.FLOAT_32] * 3, unit=self.__modbus_id)
+ 19000, [ModbusDataType.FLOAT_32] * 3, device_id=self.__modbus_id)
power_factors = self.__tcp_client.read_holding_registers(
- 19044, [ModbusDataType.FLOAT_32] * 3, unit=self.__modbus_id)
- frequency = self.__tcp_client.read_holding_registers(19050, ModbusDataType.FLOAT_32, unit=self.__modbus_id)
+ 19044, [ModbusDataType.FLOAT_32] * 3, device_id=self.__modbus_id)
+ frequency = self.__tcp_client.read_holding_registers(19050, ModbusDataType.FLOAT_32, device_id=self.__modbus_id)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/janitza/janitza/inverter.py b/packages/modules/devices/janitza/janitza/inverter.py
index d3637eaed7..598e45166f 100644
--- a/packages/modules/devices/janitza/janitza/inverter.py
+++ b/packages/modules/devices/janitza/janitza/inverter.py
@@ -34,7 +34,7 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.INVERTER, self.component_config.id, self.fault_state)
def update(self):
- power = self.__tcp_client.read_holding_registers(19026, ModbusDataType.FLOAT_32, unit=self.__modbus_id) * -1
+ power = self.__tcp_client.read_holding_registers(19026, ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * -1
self.peak_filter.check_values(power)
_, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/kaco/kaco_tx/scale.py b/packages/modules/devices/kaco/kaco_tx/scale.py
index bfe78d2ddd..b54d14385c 100644
--- a/packages/modules/devices/kaco/kaco_tx/scale.py
+++ b/packages/modules/devices/kaco/kaco_tx/scale.py
@@ -21,7 +21,7 @@ def scale_registers(registers: List[Number]) -> List[float]:
def create_scaled_reader(client: ModbusTcpClient_, modbus_id: int, type: ModbusDataType):
def scaled_reader(address: int, count: int):
return scale_registers(
- client.read_holding_registers(address, [type] * count + [ModbusDataType.INT_16], unit=modbus_id)
+ client.read_holding_registers(address, [type] * count + [ModbusDataType.INT_16], device_id=modbus_id)
)
return scaled_reader
diff --git a/packages/modules/devices/kostal/kostal_piko_ci/counter.py b/packages/modules/devices/kostal/kostal_piko_ci/counter.py
index d8003c2c29..1b5343da82 100644
--- a/packages/modules/devices/kostal/kostal_piko_ci/counter.py
+++ b/packages/modules/devices/kostal/kostal_piko_ci/counter.py
@@ -34,10 +34,10 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_holding_registers(252, ModbusDataType.FLOAT_32, unit=unit)
+ power = self.client.read_holding_registers(252, ModbusDataType.FLOAT_32, device_id=unit)
powers = [self.client.read_holding_registers(
- reg, ModbusDataType.FLOAT_32, unit=unit) for reg in [224, 234, 244]]
- frequency = self.client.read_holding_registers(220, ModbusDataType.FLOAT_32, unit=unit)
+ reg, ModbusDataType.FLOAT_32, device_id=unit) for reg in [224, 234, 244]]
+ frequency = self.client.read_holding_registers(220, ModbusDataType.FLOAT_32, device_id=unit)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/kostal/kostal_piko_ci/inverter.py b/packages/modules/devices/kostal/kostal_piko_ci/inverter.py
index a9851ac454..34a40d9088 100644
--- a/packages/modules/devices/kostal/kostal_piko_ci/inverter.py
+++ b/packages/modules/devices/kostal/kostal_piko_ci/inverter.py
@@ -32,10 +32,10 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_holding_registers(172, ModbusDataType.FLOAT_32, unit=unit) * -1
+ power = self.client.read_holding_registers(172, ModbusDataType.FLOAT_32, device_id=unit) * -1
currents = [self.client.read_holding_registers(
- reg, ModbusDataType.FLOAT_32, unit=unit) for reg in [154, 160, 166]]
- exported = self.client.read_holding_registers(320, ModbusDataType.FLOAT_32, unit=unit)
+ reg, ModbusDataType.FLOAT_32, device_id=unit) for reg in [154, 160, 166]]
+ exported = self.client.read_holding_registers(320, ModbusDataType.FLOAT_32, device_id=unit)
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
power=power,
diff --git a/packages/modules/devices/kostal/kostal_plenticore/bat.py b/packages/modules/devices/kostal/kostal_plenticore/bat.py
index 4c10ce66cc..d787e315bf 100644
--- a/packages/modules/devices/kostal/kostal_plenticore/bat.py
+++ b/packages/modules/devices/kostal/kostal_plenticore/bat.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
import logging
from typing import TypedDict, Any, Optional
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractBat
from modules.common.component_state import BatState
@@ -41,12 +41,12 @@ def initialize(self) -> None:
def update(self) -> None:
power = self.client.read_holding_registers(
- 582, ModbusDataType.INT_16, unit=self.modbus_id, wordorder=self.endianess) * -1
+ 582, ModbusDataType.INT_16, device_id=self.modbus_id, wordorder=self.endianess) * -1
soc = self.client.read_holding_registers(
- 514, ModbusDataType.INT_16, unit=self.modbus_id, wordorder=self.endianess)
+ 514, ModbusDataType.INT_16, device_id=self.modbus_id, wordorder=self.endianess)
if power < 0:
power = self.client.read_holding_registers(
- 106, ModbusDataType.FLOAT_32, unit=self.modbus_id, wordorder=self.endianess) * -1
+ 106, ModbusDataType.FLOAT_32, device_id=self.modbus_id, wordorder=self.endianess) * -1
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
@@ -73,21 +73,21 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
# wiederholt auf Stop setzen damit sich Register nicht zurücksetzt
log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht entladen")
self.client.write_register(1034, 0.0, data_type=ModbusDataType.FLOAT_32,
- wordorder=self.endianess, unit=unit)
+ wordorder=self.endianess, device_id=unit)
elif power_limit < 0:
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W entladen für den Hausverbrauch")
# Die maximale Entladeleistung begrenzen auf 7000W
power_value = float(min(abs(power_limit), 7000))
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W entladen für den Hausverbrauch")
self.client.write_register(1034, power_value, data_type=ModbusDataType.FLOAT_32,
- wordorder=self.endianess, unit=unit)
+ wordorder=self.endianess, device_id=unit)
elif power_limit > 0:
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W geladen")
# Die maximale Ladeleistung begrenzen auf 7000W
power_value = float(min(abs(power_limit), 7000)) * -1
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W geladen")
self.client.write_register(1034, power_value, data_type=ModbusDataType.FLOAT_32,
- wordorder=self.endianess, unit=unit)
+ wordorder=self.endianess, device_id=unit)
def power_limit_controllable(self) -> bool:
return True
diff --git a/packages/modules/devices/kostal/kostal_plenticore/counter.py b/packages/modules/devices/kostal/kostal_plenticore/counter.py
index d12db3eecf..9652da6995 100644
--- a/packages/modules/devices/kostal/kostal_plenticore/counter.py
+++ b/packages/modules/devices/kostal/kostal_plenticore/counter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from typing import TypedDict, Any
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractCounter
from modules.common.component_state import CounterState
@@ -38,17 +38,17 @@ def initialize(self) -> None:
def update(self) -> None:
power = self.client.read_holding_registers(
- 252, ModbusDataType.FLOAT_32, unit=self.modbus_id, wordorder=self.endianess)
+ 252, ModbusDataType.FLOAT_32, device_id=self.modbus_id, wordorder=self.endianess)
power_factor = self.client.read_holding_registers(
- 150, ModbusDataType.FLOAT_32, unit=self.modbus_id, wordorder=self.endianess)
+ 150, ModbusDataType.FLOAT_32, device_id=self.modbus_id, wordorder=self.endianess)
currents = [self.client.read_holding_registers(
- reg, ModbusDataType.FLOAT_32, unit=self.modbus_id, wordorder=self.endianess) for reg in [222, 232, 242]]
+ reg, ModbusDataType.FLOAT_32, device_id=self.modbus_id, wordorder=self.endianess) for reg in [222, 232, 242]]
voltages = [self.client.read_holding_registers(
- reg, ModbusDataType.FLOAT_32, unit=self.modbus_id, wordorder=self.endianess) for reg in [230, 240, 250]]
+ reg, ModbusDataType.FLOAT_32, device_id=self.modbus_id, wordorder=self.endianess) for reg in [230, 240, 250]]
powers = [self.client.read_holding_registers(
- reg, ModbusDataType.FLOAT_32, unit=self.modbus_id, wordorder=self.endianess) for reg in [224, 234, 244]]
+ reg, ModbusDataType.FLOAT_32, device_id=self.modbus_id, wordorder=self.endianess) for reg in [224, 234, 244]]
frequency = self.client.read_holding_registers(
- 220, ModbusDataType.FLOAT_32, unit=self.modbus_id, wordorder=self.endianess)
+ 220, ModbusDataType.FLOAT_32, device_id=self.modbus_id, wordorder=self.endianess)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/kostal/kostal_plenticore/device.py b/packages/modules/devices/kostal/kostal_plenticore/device.py
index e911c90a4d..120364091f 100644
--- a/packages/modules/devices/kostal/kostal_plenticore/device.py
+++ b/packages/modules/devices/kostal/kostal_plenticore/device.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
import logging
from typing import Iterable, Union
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import DeviceDescriptor
from modules.common.configurable_device import ConfigurableDevice, ComponentFactoryByType, MultiComponentUpdater
@@ -54,7 +54,7 @@ def initializer():
nonlocal client, endianess
client = ModbusTcpClient_(device_config.configuration.ip_address, device_config.configuration.port)
endianess = Endian.Big if client.read_holding_registers(
- 5, ModbusDataType.UINT_16, unit=device_config.configuration.modbus_id) else Endian.Little
+ 5, ModbusDataType.UINT_16, device_id=device_config.configuration.modbus_id) else Endian.Little
return ConfigurableDevice(
device_config=device_config,
diff --git a/packages/modules/devices/kostal/kostal_plenticore/inverter.py b/packages/modules/devices/kostal/kostal_plenticore/inverter.py
index 8712ba8ba2..6f51c226ca 100644
--- a/packages/modules/devices/kostal/kostal_plenticore/inverter.py
+++ b/packages/modules/devices/kostal/kostal_plenticore/inverter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from typing import TypedDict, Any
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractInverter
from modules.common.component_state import InverterState
@@ -42,13 +42,13 @@ def initialize(self) -> None:
def update(self) -> None:
power = self.client.read_holding_registers(
- 575, ModbusDataType.INT_16, unit=self.modbus_id, wordorder=self.endianess) * -1
+ 575, ModbusDataType.INT_16, device_id=self.modbus_id, wordorder=self.endianess) * -1
exported = self.client.read_holding_registers(
- 320, ModbusDataType.FLOAT_32, unit=self.modbus_id, wordorder=self.endianess)
+ 320, ModbusDataType.FLOAT_32, device_id=self.modbus_id, wordorder=self.endianess)
# Try to read dc_power, if it fails just skip it and set to None
try:
dc_power = self.client.read_holding_registers(
- 1066, ModbusDataType.FLOAT_32, unit=self.modbus_id, wordorder=self.endianess) * -1
+ 1066, ModbusDataType.FLOAT_32, device_id=self.modbus_id, wordorder=self.endianess) * -1
self.fault_state.no_error()
except Exception:
dc_power = None
diff --git a/packages/modules/devices/kostal/kostal_sem/counter.py b/packages/modules/devices/kostal/kostal_sem/counter.py
index a14fa66820..db2f061429 100644
--- a/packages/modules/devices/kostal/kostal_sem/counter.py
+++ b/packages/modules/devices/kostal/kostal_sem/counter.py
@@ -32,23 +32,23 @@ def initialize(self) -> None:
def update(self):
with self.__tcp_client:
voltages = [self.__tcp_client.read_holding_registers(
- reg, ModbusDataType.UINT_32, unit=self.__modbus_id) * 0.001 for reg in [62, 102, 142]]
+ reg, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 0.001 for reg in [62, 102, 142]]
currents = [self.__tcp_client.read_holding_registers(
- reg, ModbusDataType.UINT_32, unit=self.__modbus_id) * 0.001 for reg in [60, 100, 140]]
+ reg, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 0.001 for reg in [60, 100, 140]]
power_factors = [self.__tcp_client.read_holding_registers(
- reg, ModbusDataType.INT_32, unit=self.__modbus_id) * 0.001 for reg in [64, 104, 144]]
+ reg, ModbusDataType.INT_32, device_id=self.__modbus_id) * 0.001 for reg in [64, 104, 144]]
imported, exported = [val * 0.1 for val in self.__tcp_client.read_holding_registers(
- 512, [ModbusDataType.UINT_64]*2, unit=self.__modbus_id)]
+ 512, [ModbusDataType.UINT_64]*2, device_id=self.__modbus_id)]
frequency = self.__tcp_client.read_holding_registers(
- 26, ModbusDataType.UINT_32, unit=self.__modbus_id) * 0.001
+ 26, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 0.001
powers = []
for reg in [40, 80, 120]:
powers_temp = self.__tcp_client.read_holding_registers(
- reg, [ModbusDataType.UINT_32]*2, unit=self.__modbus_id)
+ reg, [ModbusDataType.UINT_32]*2, device_id=self.__modbus_id)
powers.append((powers_temp[0] if powers_temp[0] >= powers_temp[1] else -powers_temp[1]) * 0.1)
- power_temp = self.__tcp_client.read_holding_registers(0, [ModbusDataType.UINT_32]*2, unit=self.__modbus_id)
+ power_temp = self.__tcp_client.read_holding_registers(0, [ModbusDataType.UINT_32]*2, device_id=self.__modbus_id)
power = (power_temp[0] if power_temp[0] >= power_temp[1] else -power_temp[1]) * 0.1
imported, exported = self.peak_filter.check_values(power, imported, exported)
counter_state = CounterState(
diff --git a/packages/modules/devices/marstek/venus_c_e/bat.py b/packages/modules/devices/marstek/venus_c_e/bat.py
index 2c848e23a1..f2c3f13c54 100644
--- a/packages/modules/devices/marstek/venus_c_e/bat.py
+++ b/packages/modules/devices/marstek/venus_c_e/bat.py
@@ -31,11 +31,11 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.BAT, self.component_config.id, self.fault_state)
def _read_reg(self, addr: int, type_: ModbusDataType) -> Union[int, float]:
- return self.client.read_holding_registers(addr, type_, unit=self.component_config.configuration.modbus_id)
+ return self.client.read_holding_registers(addr, type_, device_id=self.component_config.configuration.modbus_id)
def _write_reg(self, addr: int, val: int) -> None:
# Marstek Venus does not work with write_registers!
- self.client._delegate.write_register(addr, val, unit=self.component_config.configuration.modbus_id)
+ self.client._delegate.write_register(addr, val, device_id=self.component_config.configuration.modbus_id)
def update(self) -> None:
power = -self._read_reg(32202, ModbusDataType.INT_32)
diff --git a/packages/modules/devices/mtec/mtec/bat.py b/packages/modules/devices/mtec/mtec/bat.py
index ffe652a905..bfbcd0e9fb 100644
--- a/packages/modules/devices/mtec/mtec/bat.py
+++ b/packages/modules/devices/mtec/mtec/bat.py
@@ -39,12 +39,12 @@ def update(self) -> None:
generation = self.component_config.configuration.generation
if generation == 2:
- power = self.client.read_holding_registers(40258, ModbusDataType.INT_32, unit=unit) * -1
+ power = self.client.read_holding_registers(40258, ModbusDataType.INT_32, device_id=unit) * -1
# soc unit 0.01%
- soc = self.client.read_holding_registers(43000, ModbusDataType.UINT_16, unit=unit) / 100
+ soc = self.client.read_holding_registers(43000, ModbusDataType.UINT_16, device_id=unit) / 100
else:
- power = self.client.read_holding_registers(30258, ModbusDataType.INT_32, unit=unit) * -1
- soc = self.client.read_holding_registers(33000, ModbusDataType.UINT_16, unit=unit) / 100
+ power = self.client.read_holding_registers(30258, ModbusDataType.INT_32, device_id=unit) * -1
+ soc = self.client.read_holding_registers(33000, ModbusDataType.UINT_16, device_id=unit) / 100
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/mtec/mtec/counter.py b/packages/modules/devices/mtec/mtec/counter.py
index cdbec9fb68..7a499f5460 100644
--- a/packages/modules/devices/mtec/mtec/counter.py
+++ b/packages/modules/devices/mtec/mtec/counter.py
@@ -34,8 +34,8 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_holding_registers(11000, ModbusDataType.INT_32, unit=unit) * -1
- powers = self.client.read_holding_registers(10994, [ModbusDataType.INT_32]*3, unit=unit)
+ power = self.client.read_holding_registers(11000, ModbusDataType.INT_32, device_id=unit) * -1
+ powers = self.client.read_holding_registers(10994, [ModbusDataType.INT_32]*3, device_id=unit)
powers = [value * -1 for value in powers]
self.peak_filter.check_values(power)
diff --git a/packages/modules/devices/mtec/mtec/inverter.py b/packages/modules/devices/mtec/mtec/inverter.py
index fbd5975359..139cff48e7 100644
--- a/packages/modules/devices/mtec/mtec/inverter.py
+++ b/packages/modules/devices/mtec/mtec/inverter.py
@@ -34,7 +34,7 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_holding_registers(11028, ModbusDataType.UINT_32, unit=unit) * -1
+ power = self.client.read_holding_registers(11028, ModbusDataType.UINT_32, device_id=unit) * -1
self.peak_filter.check_values(power)
_, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/nibe/nibe/counter.py b/packages/modules/devices/nibe/nibe/counter.py
index b20830a29c..389df061a7 100644
--- a/packages/modules/devices/nibe/nibe/counter.py
+++ b/packages/modules/devices/nibe/nibe/counter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from typing import TypedDict, Any
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractCounter
from modules.common.component_state import CounterState
@@ -34,7 +34,7 @@ def initialize(self) -> None:
def update(self):
unit = self.component_config.configuration.modbus_id
- power = self.client.read_input_registers(2166, ModbusDataType.UINT_32, wordorder=Endian.Little, unit=unit)
+ power = self.client.read_input_registers(2166, ModbusDataType.UINT_32, wordorder=Endian.Little, device_id=unit)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/orno/orno/counter.py b/packages/modules/devices/orno/orno/counter.py
index 2b5c19ed62..71c7f651be 100644
--- a/packages/modules/devices/orno/orno/counter.py
+++ b/packages/modules/devices/orno/orno/counter.py
@@ -29,9 +29,9 @@ def initialize(self) -> None:
def update(self):
power = self.client.read_holding_registers(
- 0x141, ModbusDataType.INT_32, unit=self.component_config.configuration.modbus_id)
+ 0x141, ModbusDataType.INT_32, device_id=self.component_config.configuration.modbus_id)
imported = self.client.read_holding_registers(
- 0xA001, ModbusDataType.INT_32, unit=self.component_config.configuration.modbus_id) * 10
+ 0xA001, ModbusDataType.INT_32, device_id=self.component_config.configuration.modbus_id) * 10
imported, _ = self.peak_filter.check_values(power, imported, None)
counter_state = CounterState(
imported=imported,
diff --git a/packages/modules/devices/orno/orno/device.py b/packages/modules/devices/orno/orno/device.py
index 169bc971fd..232073123d 100644
--- a/packages/modules/devices/orno/orno/device.py
+++ b/packages/modules/devices/orno/orno/device.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
import logging
-from pymodbus.transaction import ModbusRtuFramer
+from pymodbus.framer import FramerType
from typing import Iterable
from modules.common.abstract_device import DeviceDescriptor
@@ -29,7 +29,7 @@ def update_components(components: Iterable[OrnoCounter]):
def initializer():
nonlocal client
client = ModbusTcpClient_(device_config.configuration.ip_address,
- device_config.configuration.port, framer=ModbusRtuFramer)
+ device_config.configuration.port, framer=FramerType.RTU)
return ConfigurableDevice(
device_config=device_config,
diff --git a/packages/modules/devices/powerdog/powerdog/counter.py b/packages/modules/devices/powerdog/powerdog/counter.py
index 9319da99e3..7e45fc42e0 100644
--- a/packages/modules/devices/powerdog/powerdog/counter.py
+++ b/packages/modules/devices/powerdog/powerdog/counter.py
@@ -41,13 +41,13 @@ def update(self, inverter_power: float) -> None:
with self.__tcp_client:
if self.component_config.configuration.position_evu:
export_power = self.__tcp_client.read_input_registers(
- 40000, ModbusDataType.INT_32, unit=self.__modbus_id) * -1
+ 40000, ModbusDataType.INT_32, device_id=self.__modbus_id) * -1
import_power = self.__tcp_client.read_input_registers(
- 40024, ModbusDataType.INT_32, unit=self.__modbus_id)
+ 40024, ModbusDataType.INT_32, device_id=self.__modbus_id)
power = export_power + import_power
else:
home_consumption = self.__tcp_client.read_input_registers(
- 40026, ModbusDataType.INT_32, unit=self.__modbus_id)
+ 40026, ModbusDataType.INT_32, device_id=self.__modbus_id)
power = home_consumption + inverter_power
log.debug("Powerdog Hausverbrauch[W]: " + str(home_consumption))
diff --git a/packages/modules/devices/powerdog/powerdog/inverter.py b/packages/modules/devices/powerdog/powerdog/inverter.py
index 241cdf01ae..5c98042028 100644
--- a/packages/modules/devices/powerdog/powerdog/inverter.py
+++ b/packages/modules/devices/powerdog/powerdog/inverter.py
@@ -39,7 +39,7 @@ def initialize(self) -> None:
def update(self) -> float:
with self.__tcp_client:
- power = self.__tcp_client.read_input_registers(40002, ModbusDataType.INT_32, unit=self.__modbus_id) * -1
+ power = self.__tcp_client.read_input_registers(40002, ModbusDataType.INT_32, device_id=self.__modbus_id) * -1
self.peak_filter.check_values(power)
_, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/qcells/qcells/bat.py b/packages/modules/devices/qcells/qcells/bat.py
index 3a68bd58cd..b4e2b5d164 100644
--- a/packages/modules/devices/qcells/qcells/bat.py
+++ b/packages/modules/devices/qcells/qcells/bat.py
@@ -30,12 +30,12 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.BAT, self.component_config.id, self.fault_state)
def update(self) -> None:
- power = self.client.read_input_registers(0x0016, ModbusDataType.INT_16, unit=self.__modbus_id)
- soc = self.client.read_input_registers(0x001C, ModbusDataType.UINT_16, unit=self.__modbus_id)
+ power = self.client.read_input_registers(0x0016, ModbusDataType.INT_16, device_id=self.__modbus_id)
+ soc = self.client.read_input_registers(0x001C, ModbusDataType.UINT_16, device_id=self.__modbus_id)
imported = self.client.read_input_registers(
- 0x0021, ModbusDataType.UINT_16, unit=self.__modbus_id) * 100
+ 0x0021, ModbusDataType.UINT_16, device_id=self.__modbus_id) * 100
exported = self.client.read_input_registers(
- 0x001D, ModbusDataType.UINT_16, unit=self.__modbus_id) * 100
+ 0x001D, ModbusDataType.UINT_16, device_id=self.__modbus_id) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
bat_state = BatState(
diff --git a/packages/modules/devices/qcells/qcells/counter.py b/packages/modules/devices/qcells/qcells/counter.py
index 3102cf7f45..d00abe27c0 100644
--- a/packages/modules/devices/qcells/qcells/counter.py
+++ b/packages/modules/devices/qcells/qcells/counter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from typing import TypedDict, Any
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractCounter
from modules.common.component_state import CounterState
@@ -32,22 +32,22 @@ def initialize(self) -> None:
def update(self) -> None:
power = self.client.read_input_registers(0x0046, ModbusDataType.INT_32, wordorder=Endian.Little,
- unit=self.__modbus_id) * -1
+ device_id=self.__modbus_id) * -1
frequency = self.client.read_input_registers(
- 0x0007, ModbusDataType.UINT_16, unit=self.__modbus_id) / 100
+ 0x0007, ModbusDataType.UINT_16, device_id=self.__modbus_id) / 100
try:
powers = [-value for value in self.client.read_input_registers(
- 0x0082, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, unit=self.__modbus_id
+ 0x0082, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, device_id=self.__modbus_id
)]
except Exception:
powers = None
try:
voltages = [self.client.read_input_registers(
- 0x006A, ModbusDataType.UINT_16, unit=self.__modbus_id
+ 0x006A, ModbusDataType.UINT_16, device_id=self.__modbus_id
) / 10, self.client.read_input_registers(
- 0x006E, ModbusDataType.UINT_16, unit=self.__modbus_id
+ 0x006E, ModbusDataType.UINT_16, device_id=self.__modbus_id
) / 10, self.client.read_input_registers(
- 0x0072, ModbusDataType.UINT_16, unit=self.__modbus_id
+ 0x0072, ModbusDataType.UINT_16, device_id=self.__modbus_id
) / 10]
if voltages[0] < 1:
voltages[0] = 230
@@ -60,7 +60,7 @@ def update(self) -> None:
exported, imported = [value * 10
for value in self.client.read_input_registers(
0x0048, [ModbusDataType.UINT_32] * 2,
- wordorder=Endian.Little, unit=self.__modbus_id
+ wordorder=Endian.Little, device_id=self.__modbus_id
)]
imported, exported = self.peak_filter.check_values(power, imported, exported)
diff --git a/packages/modules/devices/qcells/qcells/inverter.py b/packages/modules/devices/qcells/qcells/inverter.py
index 4f147027d4..71ad8a0398 100644
--- a/packages/modules/devices/qcells/qcells/inverter.py
+++ b/packages/modules/devices/qcells/qcells/inverter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from typing import TypedDict, Any
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractInverter
from modules.common.component_state import InverterState
@@ -32,14 +32,14 @@ def initialize(self) -> None:
def update(self) -> None:
power_string1 = (self.client.read_input_registers(
- 0x0003, ModbusDataType.INT_16, unit=self.__modbus_id) / 10) * \
- (self.client.read_input_registers(0x0005, ModbusDataType.INT_16, unit=self.__modbus_id) / 10)
+ 0x0003, ModbusDataType.INT_16, device_id=self.__modbus_id) / 10) * \
+ (self.client.read_input_registers(0x0005, ModbusDataType.INT_16, device_id=self.__modbus_id) / 10)
power_string2 = (self.client.read_input_registers(
- 0x0004, ModbusDataType.INT_16, unit=self.__modbus_id) / 10) * \
- (self.client.read_input_registers(0x0006, ModbusDataType.INT_16, unit=self.__modbus_id) / 10)
+ 0x0004, ModbusDataType.INT_16, device_id=self.__modbus_id) / 10) * \
+ (self.client.read_input_registers(0x0006, ModbusDataType.INT_16, device_id=self.__modbus_id) / 10)
power = (power_string1 + power_string2) * -1
exported = self.client.read_input_registers(0x0094, ModbusDataType.UINT_32, wordorder=Endian.Little,
- unit=self.__modbus_id) * 100
+ device_id=self.__modbus_id) * 100
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/saxpower/saxpower/bat.py b/packages/modules/devices/saxpower/saxpower/bat.py
index 6149d2b52a..41070665d7 100644
--- a/packages/modules/devices/saxpower/saxpower/bat.py
+++ b/packages/modules/devices/saxpower/saxpower/bat.py
@@ -37,7 +37,7 @@ def initialize(self) -> None:
def update(self) -> None:
with self.__tcp_client:
# Die beiden Register müssen zwingend zusammen ausgelesen werden, sonst scheitert die zweite Abfrage.
- soc, power = self.__tcp_client.read_holding_registers(46, [ModbusDataType.INT_16]*2, unit=self.__modbus_id)
+ soc, power = self.__tcp_client.read_holding_registers(46, [ModbusDataType.INT_16]*2, device_id=self.__modbus_id)
power = power * -1 + 16384
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/saxpower/saxpower/counter.py b/packages/modules/devices/saxpower/saxpower/counter.py
index bc6ace7263..a8a4272b4f 100644
--- a/packages/modules/devices/saxpower/saxpower/counter.py
+++ b/packages/modules/devices/saxpower/saxpower/counter.py
@@ -34,7 +34,7 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.COUNTER, self.component_config.id, self.fault_state)
def update(self) -> None:
- power = self.client.read_holding_registers(48, ModbusDataType.INT_16, unit=self.__modbus_id)
+ power = self.client.read_holding_registers(48, ModbusDataType.INT_16, device_id=self.__modbus_id)
power = power - 16384
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/siemens/siemens/bat.py b/packages/modules/devices/siemens/siemens/bat.py
index 3200fffb58..da7a74eb6f 100644
--- a/packages/modules/devices/siemens/siemens/bat.py
+++ b/packages/modules/devices/siemens/siemens/bat.py
@@ -36,8 +36,8 @@ def initialize(self) -> None:
def update(self) -> None:
with self.__tcp_client:
- power = self.__tcp_client.read_holding_registers(6, ModbusDataType.INT_32, unit=self.__modbus_id) * -1
- soc = int(self.__tcp_client.read_holding_registers(8, ModbusDataType.INT_32, unit=self.__modbus_id))
+ power = self.__tcp_client.read_holding_registers(6, ModbusDataType.INT_32, device_id=self.__modbus_id) * -1
+ soc = int(self.__tcp_client.read_holding_registers(8, ModbusDataType.INT_32, device_id=self.__modbus_id))
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/siemens/siemens/counter.py b/packages/modules/devices/siemens/siemens/counter.py
index 6f694febdb..2ef16010d9 100644
--- a/packages/modules/devices/siemens/siemens/counter.py
+++ b/packages/modules/devices/siemens/siemens/counter.py
@@ -36,7 +36,7 @@ def initialize(self) -> None:
def update(self) -> None:
with self.__tcp_client:
- power = self.__tcp_client.read_holding_registers(14, ModbusDataType.INT_32, unit=self.__modbus_id)
+ power = self.__tcp_client.read_holding_registers(14, ModbusDataType.INT_32, device_id=self.__modbus_id)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/siemens/siemens/inverter.py b/packages/modules/devices/siemens/siemens/inverter.py
index c190ee7230..4c452b3177 100644
--- a/packages/modules/devices/siemens/siemens/inverter.py
+++ b/packages/modules/devices/siemens/siemens/inverter.py
@@ -36,7 +36,7 @@ def initialize(self) -> None:
def update(self) -> None:
with self.__tcp_client:
- power = self.__tcp_client.read_holding_registers(16, ModbusDataType.INT_32, unit=self.__modbus_id) * -1
+ power = self.__tcp_client.read_holding_registers(16, ModbusDataType.INT_32, device_id=self.__modbus_id) * -1
self.peak_filter.check_values(power)
_, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/siemens/siemens_sentron/bat.py b/packages/modules/devices/siemens/siemens_sentron/bat.py
index fa25f09b03..5c143a0758 100644
--- a/packages/modules/devices/siemens/siemens_sentron/bat.py
+++ b/packages/modules/devices/siemens/siemens_sentron/bat.py
@@ -32,9 +32,9 @@ def initialize(self) -> None:
def update(self) -> None:
with self.__tcp_client:
- power = self.__tcp_client.read_holding_registers(65, ModbusDataType.FLOAT_32, unit=self.__modbus_id) * -1
- imported = self.__tcp_client.read_holding_registers(801, ModbusDataType.FLOAT_64, unit=self.__modbus_id)
- exported = self.__tcp_client.read_holding_registers(809, ModbusDataType.FLOAT_64, unit=self.__modbus_id)
+ power = self.__tcp_client.read_holding_registers(65, ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * -1
+ imported = self.__tcp_client.read_holding_registers(801, ModbusDataType.FLOAT_64, device_id=self.__modbus_id)
+ exported = self.__tcp_client.read_holding_registers(809, ModbusDataType.FLOAT_64, device_id=self.__modbus_id)
imported, exported = self.peak_filter.check_values(power, imported, exported)
bat_state = BatState(
diff --git a/packages/modules/devices/siemens/siemens_sentron/counter.py b/packages/modules/devices/siemens/siemens_sentron/counter.py
index b3e2e25f52..313cf151e0 100644
--- a/packages/modules/devices/siemens/siemens_sentron/counter.py
+++ b/packages/modules/devices/siemens/siemens_sentron/counter.py
@@ -32,16 +32,16 @@ def initialize(self) -> None:
def update(self) -> None:
with self.__tcp_client:
- imported = self.__tcp_client.read_holding_registers(801, ModbusDataType.FLOAT_64, unit=self.__modbus_id)
- exported = self.__tcp_client.read_holding_registers(809, ModbusDataType.FLOAT_64, unit=self.__modbus_id)
- power = self.__tcp_client.read_holding_registers(65, ModbusDataType.FLOAT_32, unit=self.__modbus_id)
- powers = self.__tcp_client.read_holding_registers(25, [ModbusDataType.FLOAT_32] * 3, unit=self.__modbus_id)
- frequency = self.__tcp_client.read_holding_registers(55, ModbusDataType.FLOAT_32, unit=self.__modbus_id)
+ imported = self.__tcp_client.read_holding_registers(801, ModbusDataType.FLOAT_64, device_id=self.__modbus_id)
+ exported = self.__tcp_client.read_holding_registers(809, ModbusDataType.FLOAT_64, device_id=self.__modbus_id)
+ power = self.__tcp_client.read_holding_registers(65, ModbusDataType.FLOAT_32, device_id=self.__modbus_id)
+ powers = self.__tcp_client.read_holding_registers(25, [ModbusDataType.FLOAT_32] * 3, device_id=self.__modbus_id)
+ frequency = self.__tcp_client.read_holding_registers(55, ModbusDataType.FLOAT_32, device_id=self.__modbus_id)
currents = self.__tcp_client.read_holding_registers(
- 13, [ModbusDataType.FLOAT_32] * 3, unit=self.__modbus_id)
- voltages = self.__tcp_client.read_holding_registers(1, [ModbusDataType.FLOAT_32] * 3, unit=self.__modbus_id)
+ 13, [ModbusDataType.FLOAT_32] * 3, device_id=self.__modbus_id)
+ voltages = self.__tcp_client.read_holding_registers(1, [ModbusDataType.FLOAT_32] * 3, device_id=self.__modbus_id)
power_factors = self.__tcp_client.read_holding_registers(
- 37, [ModbusDataType.FLOAT_32] * 3, unit=self.__modbus_id)
+ 37, [ModbusDataType.FLOAT_32] * 3, device_id=self.__modbus_id)
imported, exported = self.peak_filter.check_values(power, imported, exported)
counter_state = CounterState(
diff --git a/packages/modules/devices/siemens/siemens_sentron/inverter.py b/packages/modules/devices/siemens/siemens_sentron/inverter.py
index 6a54107a25..626a51cff3 100644
--- a/packages/modules/devices/siemens/siemens_sentron/inverter.py
+++ b/packages/modules/devices/siemens/siemens_sentron/inverter.py
@@ -32,8 +32,8 @@ def initialize(self) -> None:
def update(self) -> None:
with self.__tcp_client:
- power = self.__tcp_client.read_holding_registers(65, ModbusDataType.FLOAT_32, unit=self.__modbus_id) * -1
- exported = self.__tcp_client.read_holding_registers(809, ModbusDataType.FLOAT_64, unit=self.__modbus_id)
+ power = self.__tcp_client.read_holding_registers(65, ModbusDataType.FLOAT_32, device_id=self.__modbus_id) * -1
+ exported = self.__tcp_client.read_holding_registers(809, ModbusDataType.FLOAT_64, device_id=self.__modbus_id)
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/sigenergy/sigenergy/bat.py b/packages/modules/devices/sigenergy/sigenergy/bat.py
index 26cb612de7..0abf6015b6 100644
--- a/packages/modules/devices/sigenergy/sigenergy/bat.py
+++ b/packages/modules/devices/sigenergy/sigenergy/bat.py
@@ -37,9 +37,9 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_holding_registers(30037, ModbusDataType.INT_32, unit=unit)
+ power = self.client.read_holding_registers(30037, ModbusDataType.INT_32, device_id=unit)
# soc unit 0.1%
- soc = self.client.read_holding_registers(30014, ModbusDataType.UINT_16, unit=unit) / 10
+ soc = self.client.read_holding_registers(30014, ModbusDataType.UINT_16, device_id=unit) / 10
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
@@ -59,13 +59,13 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
log.debug("Keine Batteriesteuerung, Selbstregelung durch Wechselrichter")
if self.last_mode is not None:
# Entladesperre ab 5%, Ansonsten Eigenregelung
- self.client.write_register(40048, 50, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.client.write_register(40048, 50, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = None
else:
log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht entladen")
if self.last_mode != 'stop':
# Entladesperre auch bei 100% SoC
- self.client.write_register(40048, 1000, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.client.write_register(40048, 1000, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'stop'
def power_limit_controllable(self) -> bool:
diff --git a/packages/modules/devices/sigenergy/sigenergy/counter.py b/packages/modules/devices/sigenergy/sigenergy/counter.py
index f8d4e2b7c7..a861b31774 100644
--- a/packages/modules/devices/sigenergy/sigenergy/counter.py
+++ b/packages/modules/devices/sigenergy/sigenergy/counter.py
@@ -32,8 +32,8 @@ def initialize(self) -> None:
def update(self):
unit = self.component_config.configuration.modbus_id
- powers = self.client.read_holding_registers(30052, [ModbusDataType.INT_32]*3, unit=unit)
- power = self.client.read_holding_registers(30005, ModbusDataType.INT_32, unit=unit)
+ powers = self.client.read_holding_registers(30052, [ModbusDataType.INT_32]*3, device_id=unit)
+ power = self.client.read_holding_registers(30005, ModbusDataType.INT_32, device_id=unit)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/sigenergy/sigenergy/inverter.py b/packages/modules/devices/sigenergy/sigenergy/inverter.py
index 06c1d824d4..3bdb9d0ccc 100644
--- a/packages/modules/devices/sigenergy/sigenergy/inverter.py
+++ b/packages/modules/devices/sigenergy/sigenergy/inverter.py
@@ -33,7 +33,7 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_holding_registers(30035, ModbusDataType.INT_32, unit=unit) * -1
+ power = self.client.read_holding_registers(30035, ModbusDataType.INT_32, device_id=unit) * -1
self.peak_filter.check_values(power)
_, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/sma/sma_sunny_boy/bat.py b/packages/modules/devices/sma/sma_sunny_boy/bat.py
index b405760df1..debf53f961 100644
--- a/packages/modules/devices/sma/sma_sunny_boy/bat.py
+++ b/packages/modules/devices/sma/sma_sunny_boy/bat.py
@@ -35,16 +35,16 @@ def initialize(self) -> None:
def read(self) -> BatState:
unit = self.component_config.configuration.modbus_id
- soc = self.__tcp_client.read_holding_registers(30845, ModbusDataType.UINT_32, unit=unit)
- imp = self.__tcp_client.read_holding_registers(31393, ModbusDataType.INT_32, unit=unit)
- exp = self.__tcp_client.read_holding_registers(31395, ModbusDataType.INT_32, unit=unit)
+ soc = self.__tcp_client.read_holding_registers(30845, ModbusDataType.UINT_32, device_id=unit)
+ imp = self.__tcp_client.read_holding_registers(31393, ModbusDataType.INT_32, device_id=unit)
+ exp = self.__tcp_client.read_holding_registers(31395, ModbusDataType.INT_32, device_id=unit)
if imp > 5:
power = imp
else:
power = exp * -1
- exported = self.__tcp_client.read_holding_registers(31401, ModbusDataType.UINT_64, unit=unit)
- imported = self.__tcp_client.read_holding_registers(31397, ModbusDataType.UINT_64, unit=unit)
+ exported = self.__tcp_client.read_holding_registers(31401, ModbusDataType.UINT_64, device_id=unit)
+ imported = self.__tcp_client.read_holding_registers(31397, ModbusDataType.UINT_64, device_id=unit)
if exported == self.SMA_UINT_64_NAN or imported == self.SMA_UINT_64_NAN:
raise ValueError(f'Batterie lieferte nicht plausible Werte. Export: {exported}, Import: {imported}. ',
diff --git a/packages/modules/devices/sma/sma_sunny_boy/bat_smart_energy.py b/packages/modules/devices/sma/sma_sunny_boy/bat_smart_energy.py
index 8e320ea5be..554d9eb44c 100644
--- a/packages/modules/devices/sma/sma_sunny_boy/bat_smart_energy.py
+++ b/packages/modules/devices/sma/sma_sunny_boy/bat_smart_energy.py
@@ -128,14 +128,14 @@ def _read_registers(self, register_names: list, unit: int) -> Dict[str, Union[in
values = {}
for key in register_names:
address, data_type = self.REGISTERS[key]
- values[key] = self.__tcp_client.read_holding_registers(address, data_type, unit=unit)
+ values[key] = self.__tcp_client.read_holding_registers(address, data_type, device_id=unit)
log.debug(f"Bat raw values {self.__tcp_client.address}: {values}")
return values
def _write_registers(self, values_to_write: Dict[str, Union[int, float]], unit: int) -> None:
for key, value in values_to_write.items():
address, data_type = self.REGISTERS[key]
- self.__tcp_client.write_register(address, value, data_type, unit=unit)
+ self.__tcp_client.write_register(address, value, data_type, device_id=unit)
log.debug(f"Neuer Wert {value} in Register {address} geschrieben.")
def power_limit_controllable(self) -> bool:
diff --git a/packages/modules/devices/sma/sma_sunny_boy/bat_tesvolt.py b/packages/modules/devices/sma/sma_sunny_boy/bat_tesvolt.py
index 166898839e..d5d5b30eb7 100644
--- a/packages/modules/devices/sma/sma_sunny_boy/bat_tesvolt.py
+++ b/packages/modules/devices/sma/sma_sunny_boy/bat_tesvolt.py
@@ -35,8 +35,8 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.BAT, self.component_config.id, self.fault_state)
def update(self) -> None:
- soc = self.__tcp_client.read_input_registers(1056, ModbusDataType.INT_32, unit=25) / 10
- power = self.__tcp_client.read_input_registers(1012, ModbusDataType.INT_32, unit=25) * -1
+ soc = self.__tcp_client.read_input_registers(1056, ModbusDataType.INT_32, device_id=25) / 10
+ power = self.__tcp_client.read_input_registers(1012, ModbusDataType.INT_32, device_id=25) * -1
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/sma/sma_sunny_boy/counter.py b/packages/modules/devices/sma/sma_sunny_boy/counter.py
index 5f14524d63..ffbd31fcba 100644
--- a/packages/modules/devices/sma/sma_sunny_boy/counter.py
+++ b/packages/modules/devices/sma/sma_sunny_boy/counter.py
@@ -35,8 +35,8 @@ def initialize(self) -> None:
def update(self):
unit = self.component_config.configuration.modbus_id
- imp = self.__tcp_client.read_holding_registers(30865, ModbusDataType.UINT_32, unit=unit)
- exp = self.__tcp_client.read_holding_registers(30867, ModbusDataType.UINT_32, unit=unit)
+ imp = self.__tcp_client.read_holding_registers(30865, ModbusDataType.UINT_32, device_id=unit)
+ exp = self.__tcp_client.read_holding_registers(30867, ModbusDataType.UINT_32, device_id=unit)
if imp > 5:
power = imp
else:
diff --git a/packages/modules/devices/sma/sma_sunny_boy/inverter.py b/packages/modules/devices/sma/sma_sunny_boy/inverter.py
index 39db80d84a..45a23ef581 100644
--- a/packages/modules/devices/sma/sma_sunny_boy/inverter.py
+++ b/packages/modules/devices/sma/sma_sunny_boy/inverter.py
@@ -50,39 +50,39 @@ def read(self) -> InverterState:
if self.component_config.configuration.version == SmaInverterVersion.default:
# AC Wirkleistung über alle Phasen (W) [Pac]
- power_total = self.tcp_client.read_holding_registers(30775, ModbusDataType.INT_32, unit=unit)
+ power_total = self.tcp_client.read_holding_registers(30775, ModbusDataType.INT_32, device_id=unit)
# Gesamtertrag (Wh) [E-Total]
- energy = self.tcp_client.read_holding_registers(30529, ModbusDataType.UINT_32, unit=unit)
+ energy = self.tcp_client.read_holding_registers(30529, ModbusDataType.UINT_32, device_id=unit)
# Bei Hybrid Wechselrichtern treten Abweichungen auf, die in der Nacht
# immer wieder Generatorleistung anzeigen (0-50 Watt). Um dies zu verhindern, schauen wir uns
# zunächst an, ob vom DC Teil überhaupt Leistung kommt. Ist dies nicht der Fall, können wir power
# gleich auf 0 setzen.
# Leistung DC an Eingang 1 und 2
- dc_power = (self.tcp_client.read_holding_registers(30773, ModbusDataType.INT_32, unit=unit) +
- self.tcp_client.read_holding_registers(30961, ModbusDataType.INT_32, unit=unit))
+ dc_power = (self.tcp_client.read_holding_registers(30773, ModbusDataType.INT_32, device_id=unit) +
+ self.tcp_client.read_holding_registers(30961, ModbusDataType.INT_32, device_id=unit))
- currents = self.tcp_client.read_holding_registers(30977, [ModbusDataType.INT_32]*3, unit=unit)
+ currents = self.tcp_client.read_holding_registers(30977, [ModbusDataType.INT_32]*3, device_id=unit)
if all(c == self.SMA_INT32_NAN for c in currents):
currents = None
else:
currents = [current / -1000 if current != self.SMA_INT32_NAN else 0 for current in currents]
elif self.component_config.configuration.version == SmaInverterVersion.core2:
# AC Wirkleistung über alle Phasen (W) [Pac]
- power_total = self.tcp_client.read_holding_registers(40084, ModbusDataType.INT_16, unit=unit) * 10
+ power_total = self.tcp_client.read_holding_registers(40084, ModbusDataType.INT_16, device_id=unit) * 10
# Gesamtertrag (Wh) [E-Total] SF=2!
- energy = self.tcp_client.read_holding_registers(40094, ModbusDataType.UINT_32, unit=unit) * 100
+ energy = self.tcp_client.read_holding_registers(40094, ModbusDataType.UINT_32, device_id=unit) * 100
# Power
- dc_power = self.tcp_client.read_holding_registers(40101, ModbusDataType.UINT_32, unit=unit) * 100
+ dc_power = self.tcp_client.read_holding_registers(40101, ModbusDataType.UINT_32, device_id=unit) * 100
# Phasenstöme
- current_L1 = self.tcp_client.read_holding_registers(30977, ModbusDataType.INT_32, unit=unit) * -1
- current_L2 = self.tcp_client.read_holding_registers(30979, ModbusDataType.INT_32, unit=unit) * -1
- current_L3 = self.tcp_client.read_holding_registers(30981, ModbusDataType.INT_32, unit=unit) * -1
+ current_L1 = self.tcp_client.read_holding_registers(30977, ModbusDataType.INT_32, device_id=unit) * -1
+ current_L2 = self.tcp_client.read_holding_registers(30979, ModbusDataType.INT_32, device_id=unit) * -1
+ current_L3 = self.tcp_client.read_holding_registers(30981, ModbusDataType.INT_32, device_id=unit) * -1
currents = [current_L1 / 1000, current_L2 / 1000, current_L3 / 1000]
elif self.component_config.configuration.version == SmaInverterVersion.datamanager:
# AC Wirkleistung über alle Phasen (W) [Pac]
- power_total = self.tcp_client.read_holding_registers(30775, ModbusDataType.INT_32, unit=unit)
+ power_total = self.tcp_client.read_holding_registers(30775, ModbusDataType.INT_32, device_id=unit)
# Total eingespeiste Energie auf allen Außenleitern (Wh) [E-Total]
- energy = self.tcp_client.read_holding_registers(30513, ModbusDataType.UINT_64, unit=unit)
+ energy = self.tcp_client.read_holding_registers(30513, ModbusDataType.UINT_64, device_id=unit)
# DC-Power = power_total - Cluster-Controller gibt in Register 30775 immer korrekte Werte aus,
# daher ist wie bei SmaInverterVersion.default keine Prüfung auf DC-Leistung notwendig.
# Aus kompatibilitätsgründen wird dc_power auf den Wert der AC-Wirkleistung gesetzt.
diff --git a/packages/modules/devices/sma/sma_sunny_island/bat.py b/packages/modules/devices/sma/sma_sunny_island/bat.py
index 7d866b303d..834565129e 100644
--- a/packages/modules/devices/sma/sma_sunny_island/bat.py
+++ b/packages/modules/devices/sma/sma_sunny_island/bat.py
@@ -32,10 +32,10 @@ def read(self) -> BatState:
unit = self.component_config.configuration.modbus_id
with self.__tcp_client:
- soc = self.__tcp_client.read_holding_registers(30845, ModbusDataType.INT_32, unit=unit)
+ soc = self.__tcp_client.read_holding_registers(30845, ModbusDataType.INT_32, device_id=unit)
- power = self.__tcp_client.read_holding_registers(30775, ModbusDataType.INT_32, unit=unit) * -1
- imported, exported = self.__tcp_client.read_holding_registers(30595, [ModbusDataType.INT_32]*2, unit=unit)
+ power = self.__tcp_client.read_holding_registers(30775, ModbusDataType.INT_32, device_id=unit) * -1
+ imported, exported = self.__tcp_client.read_holding_registers(30595, [ModbusDataType.INT_32]*2, device_id=unit)
imported, exported = self.peak_filter.check_values(power, imported, exported)
return BatState(
diff --git a/packages/modules/devices/sofar/sofar/bat.py b/packages/modules/devices/sofar/sofar/bat.py
index c06c9ec0be..13b02f6924 100644
--- a/packages/modules/devices/sofar/sofar/bat.py
+++ b/packages/modules/devices/sofar/sofar/bat.py
@@ -32,21 +32,21 @@ def initialize(self) -> None:
def update(self) -> None:
# 0x900D High 8 bits: the number of battery packs in parallel
# Lower 8 bits: the number of battery strings in the battery pack
- battery_packs = self.client.read_holding_registers(0x900D, ModbusDataType.UINT_16, unit=self.__modbus_id) >> 8
+ battery_packs = self.client.read_holding_registers(0x900D, ModbusDataType.UINT_16, device_id=self.__modbus_id) >> 8
# Power bat1 - bat12: INT_16 in kW accuracy 0,01
power_regs = [0x0606, 0x060D, 0x0614, 0x061B, 0x0622, 0x0629, 0x0630, 0x0637, 0x0646, 0x064D, 0x0654, 0x065B]
- power = sum(self.client.read_holding_registers(power_regs[idx], ModbusDataType.INT_16, unit=self.__modbus_id)
+ power = sum(self.client.read_holding_registers(power_regs[idx], ModbusDataType.INT_16, device_id=self.__modbus_id)
for idx in range(battery_packs)) * 10
- soc = self.client.read_holding_registers(0x9012, ModbusDataType.UINT_16, unit=self.__modbus_id)
+ soc = self.client.read_holding_registers(0x9012, ModbusDataType.UINT_16, device_id=self.__modbus_id)
# 0x0696 Bat_charge_total LSB UInt32 0,1 kWh
# 0x0697 Bat_charge_total UInt32 0,1 kWh
imported = self.client.read_holding_registers(
- 0x0696, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 0x0696, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
# 0x069A Bat_discharge_total LSB UInt32 0,1 kWh
# 0x069B Bat:discharge_total UInt32 0,1 kWh
exported = self.client.read_holding_registers(
- 0x069A, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 0x069A, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
bat_state = BatState(
diff --git a/packages/modules/devices/sofar/sofar/counter.py b/packages/modules/devices/sofar/sofar/counter.py
index bed82dc32c..8ba5810ee6 100644
--- a/packages/modules/devices/sofar/sofar/counter.py
+++ b/packages/modules/devices/sofar/sofar/counter.py
@@ -32,23 +32,23 @@ def initialize(self) -> None:
def update(self):
# 0x0485 ActivePower_output_total Int16 in kW accuracy 0,01 discharge + charge -
# 0x0488 ActivePower_PCC_total Int16 0,01 kW
- power = self.client.read_holding_registers(0x0488, ModbusDataType.INT_16, unit=self.__modbus_id) * -10
+ power = self.client.read_holding_registers(0x0488, ModbusDataType.INT_16, device_id=self.__modbus_id) * -10
# 0x0484 Frequency_Grid UInt16 in Hz accuracy 0,01
frequency = self.client.read_holding_registers(
- 0x0484, ModbusDataType.UINT_16, unit=self.__modbus_id) / 100
+ 0x0484, ModbusDataType.UINT_16, device_id=self.__modbus_id) / 100
try:
powers = [
- self.client.read_holding_registers(0x0493, ModbusDataType.INT_16, unit=self.__modbus_id) * -10,
- self.client.read_holding_registers(0x049E, ModbusDataType.INT_16, unit=self.__modbus_id) * -10,
- self.client.read_holding_registers(0x04A9, ModbusDataType.INT_16, unit=self.__modbus_id) * -10]
+ self.client.read_holding_registers(0x0493, ModbusDataType.INT_16, device_id=self.__modbus_id) * -10,
+ self.client.read_holding_registers(0x049E, ModbusDataType.INT_16, device_id=self.__modbus_id) * -10,
+ self.client.read_holding_registers(0x04A9, ModbusDataType.INT_16, device_id=self.__modbus_id) * -10]
except Exception:
powers = None
# 0x0692 Energy_Selling_Total UInt32 in kwH accuracy 0,01 LSB
# 0x0693 Energy_Selling_Total UInt32 in kwH accuracy 0,01
- exported = self.client.read_holding_registers(0x0692, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ exported = self.client.read_holding_registers(0x0692, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
# 0x068E Energy_Purchase_Total UInt32 in kwH accuracy 0,01 LSB
# 0x068F Energy_Purchase_Total UInt32 in kwH accuracy 0,01
- imported = self.client.read_holding_registers(0x068E, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ imported = self.client.read_holding_registers(0x068E, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
counter_state = CounterState(
diff --git a/packages/modules/devices/sofar/sofar/inverter.py b/packages/modules/devices/sofar/sofar/inverter.py
index 253c066349..9c557be4d4 100644
--- a/packages/modules/devices/sofar/sofar/inverter.py
+++ b/packages/modules/devices/sofar/sofar/inverter.py
@@ -31,8 +31,8 @@ def initialize(self) -> None:
def update(self) -> None:
# 0x05C4 Power_PV_Total UINT16 in kW accuracy 0,1
- power = self.client.read_holding_registers(0x05C4, ModbusDataType.UINT_16, unit=self.__modbus_id) * -100
- exported = self.client.read_holding_registers(0x0686, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ power = self.client.read_holding_registers(0x05C4, ModbusDataType.UINT_16, device_id=self.__modbus_id) * -100
+ exported = self.client.read_holding_registers(0x0686, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/solakon/solakon_one/bat.py b/packages/modules/devices/solakon/solakon_one/bat.py
index 933c0bd339..6a3a52c834 100644
--- a/packages/modules/devices/solakon/solakon_one/bat.py
+++ b/packages/modules/devices/solakon/solakon_one/bat.py
@@ -34,13 +34,13 @@ def update(self) -> None:
# AC Leistung am Stecker, Batterie aus dem Netz aufladen hat positive Werte,
# Leistung aus der Batterie und/oder aus PV ins Netz abgeben hat negative Werte
- power = self.client.read_holding_registers(39134, ModbusDataType.INT_32, unit=unit) * -1
+ power = self.client.read_holding_registers(39134, ModbusDataType.INT_32, device_id=unit) * -1
# SoC Ladezustand der Batterie in %
- soc = self.client.read_holding_registers(39424, ModbusDataType.INT_16, unit=unit)
+ soc = self.client.read_holding_registers(39424, ModbusDataType.INT_16, device_id=unit)
# gesamte DC Ladung der Batterie in Wh
- imported = self.client.read_holding_registers(39605, ModbusDataType.UINT_32, unit=unit) * 10
+ imported = self.client.read_holding_registers(39605, ModbusDataType.UINT_32, device_id=unit) * 10
# gesamte DC Entladung der Batterie in Wh
- exported = self.client.read_holding_registers(39609, ModbusDataType.UINT_32, unit=unit) * 10
+ exported = self.client.read_holding_registers(39609, ModbusDataType.UINT_32, device_id=unit) * 10
imported, exported = self.peak_filter.check_values(power, imported, exported)
bat_state = BatState(
diff --git a/packages/modules/devices/solakon/solakon_one/inverter.py b/packages/modules/devices/solakon/solakon_one/inverter.py
index 035fc35e52..0a9c66fdf2 100644
--- a/packages/modules/devices/solakon/solakon_one/inverter.py
+++ b/packages/modules/devices/solakon/solakon_one/inverter.py
@@ -30,9 +30,9 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
# Gesamte DC PV Leistung aller vier MPPT in W
- power = self.client.read_holding_registers(39118, ModbusDataType.INT_32, unit=unit) * -1
+ power = self.client.read_holding_registers(39118, ModbusDataType.INT_32, device_id=unit) * -1
# Gesamte DC PV Produktion in Wh
- exported = self.client.read_holding_registers(39601, ModbusDataType.UINT_32, unit=unit) * 10
+ exported = self.client.read_holding_registers(39601, ModbusDataType.UINT_32, device_id=unit) * 10
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/solaredge/solaredge/bat.py b/packages/modules/devices/solaredge/solaredge/bat.py
index ec88b4fe96..42db08439e 100644
--- a/packages/modules/devices/solaredge/solaredge/bat.py
+++ b/packages/modules/devices/solaredge/solaredge/bat.py
@@ -4,7 +4,7 @@
from typing import Any, TypedDict, Dict, Union, Optional, Tuple
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
import pymodbus
@@ -99,10 +99,10 @@ def get_values(self) -> Tuple[float, float]:
# Read SoC and Power from the appropriate registers
soc = self.__tcp_client.read_holding_registers(
- soc_reg, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=unit
+ soc_reg, ModbusDataType.FLOAT_32, wordorder=Endian.Little, device_id=unit
)
power = self.__tcp_client.read_holding_registers(
- power_reg, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=unit
+ power_reg, ModbusDataType.FLOAT_32, wordorder=Endian.Little, device_id=unit
)
# Handle unsupported case
@@ -203,7 +203,7 @@ def _read_registers(self, register_names: list, unit: int) -> Dict[str, Union[in
address, data_type = self.REGISTERS[key]
try:
values[key] = self.__tcp_client.read_holding_registers(
- address, data_type, wordorder=Endian.Little, unit=unit
+ address, data_type, wordorder=Endian.Little, device_id=unit
)
except pymodbus.exceptions.ModbusException as e:
log.error(f"Failed to read register {key} at address {address}: {e}")
@@ -217,7 +217,7 @@ def _write_registers(self, values_to_write: Dict[str, Union[int, float]], unit:
for key, value in values_to_write.items():
address, data_type = self.REGISTERS[key]
try:
- self.__tcp_client.write_register(address, value, data_type, wordorder=Endian.Little, unit=unit)
+ self.__tcp_client.write_register(address, value, data_type, wordorder=Endian.Little, device_id=unit)
log.debug(f"Neuer Wert {value} in Register {address} geschrieben.")
except pymodbus.exceptions.ModbusException as e:
log.error(f"Failed to write register {key} at address {address}: {e}")
diff --git a/packages/modules/devices/solaredge/solaredge/counter.py b/packages/modules/devices/solaredge/solaredge/counter.py
index 8ae83e2e33..5a6061199e 100644
--- a/packages/modules/devices/solaredge/solaredge/counter.py
+++ b/packages/modules/devices/solaredge/solaredge/counter.py
@@ -57,7 +57,7 @@ def update(self):
(self.registers.imp_exp_scale, ModbusDataType.INT_16),
)
resp = self.__tcp_client.read_holding_registers_bulk(
- self.registers.currents, 52, mapping=reg_mapping, unit=self.component_config.configuration.modbus_id)
+ self.registers.currents, 52, mapping=reg_mapping, device_id=self.component_config.configuration.modbus_id)
imported = scale_registers(resp[self.registers.imported], resp[self.registers.imp_exp_scale])
exported = scale_registers(resp[self.registers.exported], resp[self.registers.imp_exp_scale])
diff --git a/packages/modules/devices/solaredge/solaredge/external_inverter.py b/packages/modules/devices/solaredge/solaredge/external_inverter.py
index 3fd7deafc9..69394b1f2d 100644
--- a/packages/modules/devices/solaredge/solaredge/external_inverter.py
+++ b/packages/modules/devices/solaredge/solaredge/external_inverter.py
@@ -54,7 +54,7 @@ def read_state(self) -> InverterState:
(self.registers.imp_exp_scale, ModbusDataType.INT_16),
)
resp = self.__tcp_client.read_holding_registers_bulk(
- self.registers.currents, 52, mapping=reg_mapping, unit=self.component_config.configuration.modbus_id)
+ self.registers.currents, 52, mapping=reg_mapping, device_id=self.component_config.configuration.modbus_id)
factor = self.component_config.configuration.factor
diff --git a/packages/modules/devices/solaredge/solaredge/inverter.py b/packages/modules/devices/solaredge/solaredge/inverter.py
index 45170cbc70..acb586cc98 100644
--- a/packages/modules/devices/solaredge/solaredge/inverter.py
+++ b/packages/modules/devices/solaredge/solaredge/inverter.py
@@ -62,7 +62,7 @@ def update(self) -> None:
def read_state(self):
resp = self.__tcp_client.read_holding_registers_bulk(
- Register.CURRENTS, 30, mapping=self.REG_MAPPING, unit=self.component_config.configuration.modbus_id)
+ Register.CURRENTS, 30, mapping=self.REG_MAPPING, device_id=self.component_config.configuration.modbus_id)
power = scale_registers(resp[Register.POWER], resp[Register.POWER_SCALE]) * -1
self.peak_filter.check_values(power)
diff --git a/packages/modules/devices/solaredge/solaredge/meter.py b/packages/modules/devices/solaredge/solaredge/meter.py
index cd127ddce0..26fdb50dad 100644
--- a/packages/modules/devices/solaredge/solaredge/meter.py
+++ b/packages/modules/devices/solaredge/solaredge/meter.py
@@ -31,7 +31,7 @@ def __init__(self, internal_meter_id: int = 1, synergy_units: int = 1):
# 40205: AC Frequency Scale Factor
self.frequency = 40204
self.frequency_scale = 40205
- # 40222/40223/40224: Power factor by phase (unit=%)
+ # 40222/40223/40224: Power factor by phase (device_id=%)
# 40225: AC Power Factor Scale Factor
self.power_factors = 40222
self.power_factors_scale = 40225
@@ -96,14 +96,14 @@ def _get_synergy_units(component_config: Union[SolaredgeBatSetup,
SolaredgeExternalInverterSetup],
client) -> int:
if client.read_holding_registers(40121, ModbusDataType.UINT_16,
- unit=component_config.configuration.modbus_id
+ device_id=component_config.configuration.modbus_id
) == synergy_unit_identifier:
# Snyergy-Units vom Haupt-WR des angeschlossenen Meters ermitteln. Es kann mehrere Haupt-WR mit
# unterschiedlichen Modbus-IDs im Verbund geben.
log.debug("Synergy Units supported")
synergy_units = int(client.read_holding_registers(
40129, ModbusDataType.UINT_16,
- unit=component_config.configuration.modbus_id)) or 1
+ device_id=component_config.configuration.modbus_id)) or 1
log.debug(
f"Synergy Units detected for Modbus ID {component_config.configuration.modbus_id}: {synergy_units}")
else:
diff --git a/packages/modules/devices/solarmax/solarmax/bat.py b/packages/modules/devices/solarmax/solarmax/bat.py
index 0e39869f40..f15b8ddeda 100644
--- a/packages/modules/devices/solarmax/solarmax/bat.py
+++ b/packages/modules/devices/solarmax/solarmax/bat.py
@@ -2,7 +2,7 @@
import logging
from typing import TypedDict, Any, Optional
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractBat
from modules.common.component_state import BatState
from modules.common.component_type import ComponentDescriptor
@@ -37,8 +37,8 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_input_registers(114, ModbusDataType.INT_32, unit=unit, wordorder=Endian.Little)
- soc = self.client.read_input_registers(122, ModbusDataType.INT_16, unit=unit)
+ power = self.client.read_input_registers(114, ModbusDataType.INT_32, device_id=unit, wordorder=Endian.Little)
+ soc = self.client.read_input_registers(122, ModbusDataType.INT_16, device_id=unit)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
@@ -57,24 +57,24 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
if power_limit is None:
log.debug("Keine Batteriesteuerung, Selbstregelung durch Wechselrichter")
if self.last_mode is not None:
- self.client.write_register(142, 0, data_type=ModbusDataType.INT_16, unit=unit)
+ self.client.write_register(142, 0, data_type=ModbusDataType.INT_16, device_id=unit)
self.last_mode = None
elif power_limit >= 0:
# Solarmax kann nicht aktiv laden
log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht entladen")
- self.client.write_register(140, 0, data_type=ModbusDataType.INT_16, unit=unit)
- self.client.write_register(141, 0, data_type=ModbusDataType.INT_16, unit=unit)
- self.client.write_register(142, 1, data_type=ModbusDataType.INT_16, unit=unit)
+ self.client.write_register(140, 0, data_type=ModbusDataType.INT_16, device_id=unit)
+ self.client.write_register(141, 0, data_type=ModbusDataType.INT_16, device_id=unit)
+ self.client.write_register(142, 1, data_type=ModbusDataType.INT_16, device_id=unit)
self.last_mode = 'stop'
elif power_limit < 0:
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W entladen für den Hausverbrauch")
- self.client.write_register(142, 1, data_type=ModbusDataType.INT_16, unit=unit)
+ self.client.write_register(142, 1, data_type=ModbusDataType.INT_16, device_id=unit)
self.last_mode = 'discharge'
# Die maximale Entladeleistung begrenzen auf 5000W, maximaler Wertebereich Modbusregister.
power_value = int(min(abs(power_limit), 7000))
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W entladen für den Hausverbrauch")
- self.client.write_register(140, power_value, data_type=ModbusDataType.INT_16, unit=unit)
- self.client.write_register(141, power_value, data_type=ModbusDataType.INT_16, unit=unit)
+ self.client.write_register(140, power_value, data_type=ModbusDataType.INT_16, device_id=unit)
+ self.client.write_register(141, power_value, data_type=ModbusDataType.INT_16, device_id=unit)
def power_limit_controllable(self) -> bool:
return self.component_config.configuration.power_limit_controllable
diff --git a/packages/modules/devices/solarmax/solarmax/counter_maxstorage.py b/packages/modules/devices/solarmax/solarmax/counter_maxstorage.py
index 58805fef26..063d844f56 100644
--- a/packages/modules/devices/solarmax/solarmax/counter_maxstorage.py
+++ b/packages/modules/devices/solarmax/solarmax/counter_maxstorage.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
from typing import TypedDict, Any
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractCounter
from modules.common.component_state import CounterState
from modules.common.component_type import ComponentDescriptor
@@ -36,7 +36,7 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_input_registers(118, ModbusDataType.INT_32, unit=unit, wordorder=Endian.Little) * -1
+ power = self.client.read_input_registers(118, ModbusDataType.INT_32, device_id=unit, wordorder=Endian.Little) * -1
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/solarmax/solarmax/inverter.py b/packages/modules/devices/solarmax/solarmax/inverter.py
index a77c2766fe..d7567521d9 100644
--- a/packages/modules/devices/solarmax/solarmax/inverter.py
+++ b/packages/modules/devices/solarmax/solarmax/inverter.py
@@ -35,7 +35,7 @@ def initialize(self) -> None:
def update(self) -> None:
power = self.client.read_holding_registers(4151, ModbusDataType.UINT_32,
- unit=self.component_config.configuration.modbus_id) * -1
+ device_id=self.component_config.configuration.modbus_id) * -1
power = power / 10
self.peak_filter.check_values(power)
_, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/solarmax/solarmax/inverter_maxstorage.py b/packages/modules/devices/solarmax/solarmax/inverter_maxstorage.py
index d380ade120..b38cf26c2c 100644
--- a/packages/modules/devices/solarmax/solarmax/inverter_maxstorage.py
+++ b/packages/modules/devices/solarmax/solarmax/inverter_maxstorage.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
from typing import TypedDict, Any
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.abstract_device import AbstractInverter
from modules.common.component_state import InverterState
from modules.common.component_type import ComponentDescriptor
@@ -36,7 +36,7 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_input_registers(120, ModbusDataType.INT_32, unit=unit, wordorder=Endian.Little) * -1
+ power = self.client.read_input_registers(120, ModbusDataType.INT_32, device_id=unit, wordorder=Endian.Little) * -1
self.peak_filter.check_values(power)
_, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/solax/solax/bat.py b/packages/modules/devices/solax/solax/bat.py
index c1cd62a371..100465aaf4 100644
--- a/packages/modules/devices/solax/solax/bat.py
+++ b/packages/modules/devices/solax/solax/bat.py
@@ -36,8 +36,8 @@ def update(self) -> None:
unit = self.device_config.configuration.modbus_id
# kein Speicher für Versionen G2 und G4
- power = self.__tcp_client.read_input_registers(0x0016, ModbusDataType.INT_16, unit=unit)
- soc = self.__tcp_client.read_input_registers(0x001C, ModbusDataType.UINT_16, unit=unit)
+ power = self.__tcp_client.read_input_registers(0x0016, ModbusDataType.INT_16, device_id=unit)
+ soc = self.__tcp_client.read_input_registers(0x001C, ModbusDataType.UINT_16, device_id=unit)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
bat_state = BatState(
diff --git a/packages/modules/devices/solax/solax/counter.py b/packages/modules/devices/solax/solax/counter.py
index f42f6d2fc5..7ce3d1c163 100644
--- a/packages/modules/devices/solax/solax/counter.py
+++ b/packages/modules/devices/solax/solax/counter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from typing import Any, TypedDict
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common import modbus
from modules.common.abstract_device import AbstractCounter
@@ -37,32 +37,32 @@ def update(self):
if SolaxVersion(self.device_config.configuration.version) == SolaxVersion.G2:
power = self.__tcp_client.read_input_registers(
- 0x043B, ModbusDataType.INT_32, wordorder=Endian.Little, unit=unit) * -1
- frequency = self.__tcp_client.read_input_registers(0x0407, ModbusDataType.UINT_16, unit=unit) / 100
+ 0x043B, ModbusDataType.INT_32, wordorder=Endian.Little, device_id=unit) * -1
+ frequency = self.__tcp_client.read_input_registers(0x0407, ModbusDataType.UINT_16, device_id=unit) / 100
powers = [-value for value in self.__tcp_client.read_input_registers(
- 0x0704, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, unit=unit)]
+ 0x0704, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, device_id=unit)]
exported, imported = [value * 10 for value in self.__tcp_client.read_input_registers(
- 0x043D, [ModbusDataType.UINT_32] * 2, wordorder=Endian.Little, unit=unit)]
+ 0x043D, [ModbusDataType.UINT_32] * 2, wordorder=Endian.Little, device_id=unit)]
elif SolaxVersion(self.device_config.configuration.version) == SolaxVersion.G3:
power = self.__tcp_client.read_input_registers(
- 0x0046, ModbusDataType.INT_32, wordorder=Endian.Little, unit=unit) * -1
- frequency = self.__tcp_client.read_input_registers(0x0007, ModbusDataType.UINT_16, unit=unit) / 100
+ 0x0046, ModbusDataType.INT_32, wordorder=Endian.Little, device_id=unit) * -1
+ frequency = self.__tcp_client.read_input_registers(0x0007, ModbusDataType.UINT_16, device_id=unit) / 100
try:
powers = [-value for value in self.__tcp_client.read_input_registers(
- 0x0082, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, unit=unit)]
+ 0x0082, [ModbusDataType.INT_32] * 3, wordorder=Endian.Little, device_id=unit)]
except Exception:
powers = None
exported, imported = [value * 10 for value in self.__tcp_client.read_input_registers(
- 0x0048, [ModbusDataType.UINT_32] * 2, wordorder=Endian.Little, unit=unit)]
+ 0x0048, [ModbusDataType.UINT_32] * 2, wordorder=Endian.Little, device_id=unit)]
else:
power = self.__tcp_client.read_input_registers(
- 0x0409, ModbusDataType.INT_32, wordorder=Endian.Little, unit=unit) * -1
- frequency = self.__tcp_client.read_input_registers(0x0406, ModbusDataType.UINT_16, unit=unit) / 100
+ 0x0409, ModbusDataType.INT_32, wordorder=Endian.Little, device_id=unit) * -1
+ frequency = self.__tcp_client.read_input_registers(0x0406, ModbusDataType.UINT_16, device_id=unit) / 100
powers = None
exported, imported = [value * 100 for value in self.__tcp_client.read_input_registers(
- 0x042F, [ModbusDataType.UINT_32] * 2, wordorder=Endian.Little, unit=unit)]
+ 0x042F, [ModbusDataType.UINT_32] * 2, wordorder=Endian.Little, device_id=unit)]
imported, exported = self.peak_filter.check_values(power, imported, exported)
counter_state = CounterState(
imported=imported,
diff --git a/packages/modules/devices/solax/solax/inverter.py b/packages/modules/devices/solax/solax/inverter.py
index b84abce03c..5b08e0a56c 100644
--- a/packages/modules/devices/solax/solax/inverter.py
+++ b/packages/modules/devices/solax/solax/inverter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from typing import Any, TypedDict
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common import modbus
from modules.common.abstract_device import AbstractInverter
@@ -36,19 +36,19 @@ def update(self) -> None:
unit = self.device_config.configuration.modbus_id
if SolaxVersion(self.device_config.configuration.version) == SolaxVersion.G2:
- power = self.__tcp_client.read_input_registers(0x0413, ModbusDataType.UINT_16, unit=unit) * -1
+ power = self.__tcp_client.read_input_registers(0x0413, ModbusDataType.UINT_16, device_id=unit) * -1
exported = self.__tcp_client.read_input_registers(
- 0x0423, ModbusDataType.UINT_32, wordorder=Endian.Little, unit=unit) * 100
+ 0x0423, ModbusDataType.UINT_32, wordorder=Endian.Little, device_id=unit) * 100
elif SolaxVersion(self.device_config.configuration.version) == SolaxVersion.G3:
- power_temp = self.__tcp_client.read_input_registers(0x000A, [ModbusDataType.UINT_16] * 2, unit=unit)
+ power_temp = self.__tcp_client.read_input_registers(0x000A, [ModbusDataType.UINT_16] * 2, device_id=unit)
power = sum(power_temp) * -1
exported = self.__tcp_client.read_input_registers(
- 0x0052, ModbusDataType.UINT_32, wordorder=Endian.Little, unit=unit) * 100
+ 0x0052, ModbusDataType.UINT_32, wordorder=Endian.Little, device_id=unit) * 100
else:
- power_temp = self.__tcp_client.read_input_registers(0x0410, [ModbusDataType.UINT_16] * 2, unit=unit)
+ power_temp = self.__tcp_client.read_input_registers(0x0410, [ModbusDataType.UINT_16] * 2, device_id=unit)
power = sum(power_temp) * -1
exported = self.__tcp_client.read_input_registers(
- 0x042B, ModbusDataType.UINT_32, wordorder=Endian.Little, unit=unit) * 100
+ 0x042B, ModbusDataType.UINT_32, wordorder=Endian.Little, device_id=unit) * 100
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/solis/solis/bat.py b/packages/modules/devices/solis/solis/bat.py
index 490fc6a8f5..5229a634dd 100644
--- a/packages/modules/devices/solis/solis/bat.py
+++ b/packages/modules/devices/solis/solis/bat.py
@@ -33,12 +33,12 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.component_config.configuration.modbus_id
- power = self.client.read_input_registers(33149, ModbusDataType.INT_32, unit=unit)
- soc = self.client.read_input_registers(33139, ModbusDataType.UINT_16, unit=unit)
+ power = self.client.read_input_registers(33149, ModbusDataType.INT_32, device_id=unit)
+ soc = self.client.read_input_registers(33139, ModbusDataType.UINT_16, device_id=unit)
# Geladen in kWh
- imported = self.client.read_input_registers(33161, ModbusDataType.UINT_32, unit=unit) * 1000
+ imported = self.client.read_input_registers(33161, ModbusDataType.UINT_32, device_id=unit) * 1000
# Entladen in kWh
- exported = self.client.read_input_registers(33165, ModbusDataType.UINT_32, unit=unit) * 1000
+ exported = self.client.read_input_registers(33165, ModbusDataType.UINT_32, device_id=unit) * 1000
imported, exported = self.peak_filter.check_values(power, imported, exported)
bat_state = BatState(
diff --git a/packages/modules/devices/solis/solis/counter.py b/packages/modules/devices/solis/solis/counter.py
index e5a17bf559..cce9b6942c 100644
--- a/packages/modules/devices/solis/solis/counter.py
+++ b/packages/modules/devices/solis/solis/counter.py
@@ -37,11 +37,11 @@ def update(self):
if self.version == SolisVersion.inverter:
register_offset = -1
- power = self.client.read_input_registers(3263 + register_offset, ModbusDataType.INT_32, unit=unit) * -1
- powers = self.client.read_input_registers(3257 + register_offset, [ModbusDataType.INT_32]*3, unit=unit)
- frequency = self.client.read_input_registers(3282 + register_offset, ModbusDataType.UINT_16, unit=unit) / 100
- imported = self.client.read_input_registers(3283 + register_offset, ModbusDataType.UINT_32, unit=unit) * 10
- exported = self.client.read_input_registers(3285 + register_offset, ModbusDataType.UINT_32, unit=unit) * 10
+ power = self.client.read_input_registers(3263 + register_offset, ModbusDataType.INT_32, device_id=unit) * -1
+ powers = self.client.read_input_registers(3257 + register_offset, [ModbusDataType.INT_32]*3, device_id=unit)
+ frequency = self.client.read_input_registers(3282 + register_offset, ModbusDataType.UINT_16, device_id=unit) / 100
+ imported = self.client.read_input_registers(3283 + register_offset, ModbusDataType.UINT_32, device_id=unit) * 10
+ exported = self.client.read_input_registers(3285 + register_offset, ModbusDataType.UINT_32, device_id=unit) * 10
imported, exported = self.peak_filter.check_values(power, imported, exported)
counter_state = CounterState(
diff --git a/packages/modules/devices/solis/solis/inverter.py b/packages/modules/devices/solis/solis/inverter.py
index 749829a57f..0d95234353 100644
--- a/packages/modules/devices/solis/solis/inverter.py
+++ b/packages/modules/devices/solis/solis/inverter.py
@@ -33,11 +33,11 @@ def update(self) -> None:
unit = self.component_config.configuration.modbus_id
if self.version == SolisVersion.inverter:
- power = self.client.read_input_registers(3004, ModbusDataType.UINT_32, unit=unit) * -1
- exported = self.client.read_input_registers(3008, ModbusDataType.UINT_32, unit=unit) * 1000
+ power = self.client.read_input_registers(3004, ModbusDataType.UINT_32, device_id=unit) * -1
+ exported = self.client.read_input_registers(3008, ModbusDataType.UINT_32, device_id=unit) * 1000
elif self.version == SolisVersion.hybrid:
- power = self.client.read_input_registers(33057, ModbusDataType.UINT_32, unit=unit) * -1
- exported = self.client.read_input_registers(33029, ModbusDataType.UINT_32, unit=unit) * 1000
+ power = self.client.read_input_registers(33057, ModbusDataType.UINT_32, device_id=unit) * -1
+ exported = self.client.read_input_registers(33029, ModbusDataType.UINT_32, device_id=unit) * 1000
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/studer/studer/bat.py b/packages/modules/devices/studer/studer/bat.py
index a49cf4e1a9..0bf9f5ccce 100644
--- a/packages/modules/devices/studer/studer/bat.py
+++ b/packages/modules/devices/studer/studer/bat.py
@@ -32,10 +32,10 @@ def update(self) -> None:
unit = self.component_config.configuration.modbus_id
with self.__tcp_client:
- power = self.__tcp_client.read_input_registers(6, ModbusDataType.FLOAT_32, unit=unit)
- imported = self.__tcp_client.read_input_registers(14, ModbusDataType.FLOAT_32, unit=unit) * 48
- exported = self.__tcp_client.read_input_registers(16, ModbusDataType.FLOAT_32, unit=unit) * 48
- soc = self.__tcp_client.read_input_registers(4, ModbusDataType.FLOAT_32, unit=unit)
+ power = self.__tcp_client.read_input_registers(6, ModbusDataType.FLOAT_32, device_id=unit)
+ imported = self.__tcp_client.read_input_registers(14, ModbusDataType.FLOAT_32, device_id=unit) * 48
+ exported = self.__tcp_client.read_input_registers(16, ModbusDataType.FLOAT_32, device_id=unit) * 48
+ soc = self.__tcp_client.read_input_registers(4, ModbusDataType.FLOAT_32, device_id=unit)
imported, exported = self.peak_filter.check_values(power, imported, exported)
bat_state = BatState(
diff --git a/packages/modules/devices/studer/studer/inverter.py b/packages/modules/devices/studer/studer/inverter.py
index 131b9f0a97..fa0699ff45 100644
--- a/packages/modules/devices/studer/studer/inverter.py
+++ b/packages/modules/devices/studer/studer/inverter.py
@@ -43,7 +43,7 @@ def update(self) -> None:
power = 0
for i in range(1, vc_count+1):
mb_unit_dev = mb_unit+i
- power += self.__tcp_client.read_input_registers(mb_register, ModbusDataType.FLOAT_32, unit=mb_unit_dev)
+ power += self.__tcp_client.read_input_registers(mb_register, ModbusDataType.FLOAT_32, device_id=mb_unit_dev)
power = power * -1000
if vc_type == 'VS':
@@ -54,7 +54,7 @@ def update(self) -> None:
for i in range(1, vc_count + 1):
mb_unit_dev = mb_unit + i
exported += self.__tcp_client.read_input_registers(mb_register, ModbusDataType.FLOAT_32,
- unit=mb_unit_dev)
+ device_id=mb_unit_dev)
exported = exported * 1000000
_, exported = self.peak_filter.check_values(power, None, exported)
diff --git a/packages/modules/devices/sungrow/sungrow_ihm/bat.py b/packages/modules/devices/sungrow/sungrow_ihm/bat.py
index 2aa86da15b..85f9196efa 100644
--- a/packages/modules/devices/sungrow/sungrow_ihm/bat.py
+++ b/packages/modules/devices/sungrow/sungrow_ihm/bat.py
@@ -37,10 +37,10 @@ def initialize(self) -> None:
def update(self) -> None:
unit = self.device_config.configuration.modbus_id
- soc = int(self.__tcp_client.read_input_registers(8162, ModbusDataType.UINT_16, unit=unit) / 10)
+ soc = int(self.__tcp_client.read_input_registers(8162, ModbusDataType.UINT_16, device_id=unit) / 10)
bat_power = self.__tcp_client.read_input_registers(8160, ModbusDataType.INT_32,
- wordorder=Endian.Little, unit=unit) * -10
+ wordorder=Endian.Little, device_id=unit) * -10
self.peak_filter.check_values(bat_power)
imported, exported = self.sim_counter.sim_count(bat_power)
@@ -59,35 +59,35 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
if power_limit is None:
log.debug("Keine Batteriesteuerung, Selbstregelung durch Wechselrichter")
if self.last_mode is not None:
- self.__tcp_client.write_register(8023, 1, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(8024, 0xCC, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(8023, 1, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(8024, 0xCC, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = None
elif power_limit == 0:
log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht entladen")
if self.last_mode != 'stop':
- self.__tcp_client.write_register(8023, 5, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(8024, 0xCC, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(8023, 5, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(8024, 0xCC, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'stop'
elif power_limit < 0:
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W entladen für den Hausverbrauch")
if self.last_mode != 'discharge':
- self.__tcp_client.write_register(8023, 5, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(8024, 0xBB, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(8023, 5, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(8024, 0xBB, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'discharge'
power_value = int(power_limit / 100)
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W entladen für den Hausverbrauch")
self.__tcp_client.write_register(8025, power_value, data_type=ModbusDataType.UINT_32,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
elif power_limit > 0:
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W geladen")
if self.last_mode != 'charge':
- self.__tcp_client.write_register(8023, 5, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(8025, 0xAA, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(8023, 5, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(8025, 0xAA, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'charge'
power_value = int(power_limit / 100)
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W geladen")
self.__tcp_client.write_register(8025, power_value, data_type=ModbusDataType.UINT_32,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
def power_limit_controllable(self) -> bool:
return True
diff --git a/packages/modules/devices/sungrow/sungrow_ihm/counter.py b/packages/modules/devices/sungrow/sungrow_ihm/counter.py
index 7a2289dade..2d5e747559 100644
--- a/packages/modules/devices/sungrow/sungrow_ihm/counter.py
+++ b/packages/modules/devices/sungrow/sungrow_ihm/counter.py
@@ -34,15 +34,15 @@ def initialize(self) -> None:
def update(self):
unit = self.device_config.configuration.modbus_id
power = self.__tcp_client.read_input_registers(8156, ModbusDataType.INT_32,
- wordorder=Endian.Little, unit=unit) * -10
+ wordorder=Endian.Little, device_id=unit) * -10
powers = self.__tcp_client.read_input_registers(8558, [ModbusDataType.UINT_32] * 3,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
- frequency = self.__tcp_client.read_input_registers(8557, ModbusDataType.UINT_16, unit=unit) / 10
+ frequency = self.__tcp_client.read_input_registers(8557, ModbusDataType.UINT_16, device_id=unit) / 10
voltages = self.__tcp_client.read_input_registers(8554, [ModbusDataType.UINT_16] * 3,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
voltages = [value / 10 for value in voltages]
diff --git a/packages/modules/devices/sungrow/sungrow_ihm/inverter.py b/packages/modules/devices/sungrow/sungrow_ihm/inverter.py
index 2b12ad5cd3..c898b4507d 100644
--- a/packages/modules/devices/sungrow/sungrow_ihm/inverter.py
+++ b/packages/modules/devices/sungrow/sungrow_ihm/inverter.py
@@ -35,7 +35,7 @@ def update(self) -> float:
unit = self.device_config.configuration.modbus_id
power = self.__tcp_client.read_input_registers(8154, ModbusDataType.INT_32,
- wordorder=Endian.Little, unit=unit) * -10
+ wordorder=Endian.Little, device_id=unit) * -10
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/sungrow/sungrow_micro/inverter.py b/packages/modules/devices/sungrow/sungrow_micro/inverter.py
index b189c73f7a..363b40e704 100644
--- a/packages/modules/devices/sungrow/sungrow_micro/inverter.py
+++ b/packages/modules/devices/sungrow/sungrow_micro/inverter.py
@@ -35,7 +35,7 @@ def update(self) -> float:
unit = self.device_config.configuration.modbus_id
power = self.__tcp_client.read_input_registers(32213, ModbusDataType.UINT_32,
- wordorder=Endian.Little, unit=unit) * -1
+ wordorder=Endian.Little, device_id=unit) * -1
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/sungrow/sungrow_sg/counter.py b/packages/modules/devices/sungrow/sungrow_sg/counter.py
index e03c581109..4dc838d50a 100644
--- a/packages/modules/devices/sungrow/sungrow_sg/counter.py
+++ b/packages/modules/devices/sungrow/sungrow_sg/counter.py
@@ -37,21 +37,21 @@ def initialize(self) -> None:
def update(self):
unit = self.device_config.configuration.modbus_id
power = self.__tcp_client.read_input_registers(5082, ModbusDataType.INT_32,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
try:
powers = self.__tcp_client.read_input_registers(5084, [ModbusDataType.INT_32] * 3,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
except Exception:
powers = None
self.fault_state.no_error(self.fault_text)
- frequency = self.__tcp_client.read_input_registers(5035, ModbusDataType.UINT_16, unit=unit) / 10
+ frequency = self.__tcp_client.read_input_registers(5035, ModbusDataType.UINT_16, device_id=unit) / 10
- power_factor = self.__tcp_client.read_input_registers(5034, ModbusDataType.INT_16, unit=unit) / 1000
+ power_factor = self.__tcp_client.read_input_registers(5034, ModbusDataType.INT_16, device_id=unit) / 1000
voltages = self.__tcp_client.read_input_registers(5018, [ModbusDataType.UINT_16] * 3,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
voltages = [value / 10 for value in voltages]
diff --git a/packages/modules/devices/sungrow/sungrow_sg/inverter.py b/packages/modules/devices/sungrow/sungrow_sg/inverter.py
index 33e479f9df..d52ef8f6e8 100644
--- a/packages/modules/devices/sungrow/sungrow_sg/inverter.py
+++ b/packages/modules/devices/sungrow/sungrow_sg/inverter.py
@@ -35,11 +35,11 @@ def update(self) -> float:
unit = self.device_config.configuration.modbus_id
power = self.__tcp_client.read_input_registers(5030, ModbusDataType.INT_32,
- wordorder=Endian.Little, unit=unit) * -1
+ wordorder=Endian.Little, device_id=unit) * -1
dc_power = self.__tcp_client.read_input_registers(5016, ModbusDataType.UINT_32,
- wordorder=Endian.Little, unit=unit) * -1
+ wordorder=Endian.Little, device_id=unit) * -1
- currents = self.__tcp_client.read_input_registers(5021, [ModbusDataType.INT_16]*3, unit=unit)
+ currents = self.__tcp_client.read_input_registers(5021, [ModbusDataType.INT_16]*3, device_id=unit)
currents = [value * -0.1 for value in currents]
diff --git a/packages/modules/devices/sungrow/sungrow_sh/bat.py b/packages/modules/devices/sungrow/sungrow_sh/bat.py
index c04eaefdde..737fed9be1 100644
--- a/packages/modules/devices/sungrow/sungrow_sh/bat.py
+++ b/packages/modules/devices/sungrow/sungrow_sh/bat.py
@@ -43,19 +43,19 @@ def detect_register_check(self) -> RegMode:
try:
self.__tcp_client.read_input_registers(5213, ModbusDataType.INT_32,
- wordorder=Endian.Little, unit=unit)
- self.__tcp_client.read_input_registers(5630, ModbusDataType.INT_16, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
+ self.__tcp_client.read_input_registers(5630, ModbusDataType.INT_16, device_id=unit)
log.debug("Battery register check: using new_registers (5213/5630).")
return RegMode.NEW_REGISTERS
except Exception:
pass
# register 13000 is always available, if unused it contains zero
# register type can only be determined if battery power is not zero
- if self.__tcp_client.read_input_registers(13021, ModbusDataType.UINT_16, unit=unit) == 0:
+ if self.__tcp_client.read_input_registers(13021, ModbusDataType.UINT_16, device_id=unit) == 0:
raise ValueError("Speicherleistung aktuell 0kW. Registertyp wird gesetzt sobald "
"Speicher Leistungswerte liefert.")
try:
- if self.__tcp_client.read_input_registers(13000, ModbusDataType.UINT_16, unit=unit) != 0:
+ if self.__tcp_client.read_input_registers(13000, ModbusDataType.UINT_16, device_id=unit) != 0:
# if battery power is not zero and register 13000 shows status bits, old registers are used
log.debug("Battery register check: using old_registers (13021 + 13000 bits for sign).")
return RegMode.OLD_REGISTERS
@@ -67,20 +67,20 @@ def detect_register_check(self) -> RegMode:
def update(self) -> None:
unit = self.device_config.configuration.modbus_id
- soc = int(self.__tcp_client.read_input_registers(13022, ModbusDataType.UINT_16, unit=unit) / 10)
+ soc = int(self.__tcp_client.read_input_registers(13022, ModbusDataType.UINT_16, device_id=unit) / 10)
# === Mode 1: new_registers ===
if self.register_check == RegMode.NEW_REGISTERS:
- bat_current = self.__tcp_client.read_input_registers(5630, ModbusDataType.INT_16, unit=unit) * -0.1
+ bat_current = self.__tcp_client.read_input_registers(5630, ModbusDataType.INT_16, device_id=unit) * -0.1
bat_power = self.__tcp_client.read_input_registers(5213, ModbusDataType.INT_32,
- wordorder=Endian.Little, unit=unit) * -1
+ wordorder=Endian.Little, device_id=unit) * -1
# === Mode 2: old_registers ===
elif self.register_check == RegMode.OLD_REGISTERS:
- bat_current = self.__tcp_client.read_input_registers(13020, ModbusDataType.INT_16, unit=unit) * -0.1
- bat_power = self.__tcp_client.read_input_registers(13021, ModbusDataType.UINT_16, unit=unit)
+ bat_current = self.__tcp_client.read_input_registers(13020, ModbusDataType.INT_16, device_id=unit) * -0.1
+ bat_power = self.__tcp_client.read_input_registers(13021, ModbusDataType.UINT_16, device_id=unit)
- resp = self.__tcp_client._delegate.read_input_registers(13000, 1, unit=unit)
+ resp = self.__tcp_client._delegate.read_input_registers(13000, 1, device_id=unit)
running_state = resp.registers[0]
is_charging = (running_state & 0x02) != 0
is_discharging = (running_state & 0x04) != 0
@@ -92,13 +92,13 @@ def update(self) -> None:
# === Mode 3: fallback ===
else:
- bat_current = self.__tcp_client.read_input_registers(13020, ModbusDataType.INT_16, unit=unit) * -0.1
- bat_power = self.__tcp_client.read_input_registers(13021, ModbusDataType.UINT_16, unit=unit)
+ bat_current = self.__tcp_client.read_input_registers(13020, ModbusDataType.INT_16, device_id=unit) * -0.1
+ bat_power = self.__tcp_client.read_input_registers(13021, ModbusDataType.UINT_16, device_id=unit)
total_power = self.__tcp_client.read_input_registers(13033, ModbusDataType.INT_32,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
pv_power = self.__tcp_client.read_input_registers(5016, ModbusDataType.UINT_32,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
if total_power > pv_power:
bat_power = -abs(bat_power)
@@ -125,35 +125,35 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
if power_limit is None:
log.debug("Keine Batteriesteuerung, Selbstregelung durch Wechselrichter")
if self.last_mode is not None:
- self.__tcp_client.write_register(13049, 0, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(13050, 0xCC, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(13049, 0, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(13050, 0xCC, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = None
elif power_limit == 0:
log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht entladen")
if self.last_mode != 'stop':
- self.__tcp_client.write_register(13049, 2, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(13050, 0xCC, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(13049, 2, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(13050, 0xCC, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'stop'
elif power_limit < 0:
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W entladen für den Hausverbrauch")
if self.last_mode != 'discharge':
- self.__tcp_client.write_register(13049, 2, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(13050, 0xBB, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(13049, 2, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(13050, 0xBB, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'discharge'
# Die maximale Entladeleistung begrenzen auf 5000W, maximaler Wertebereich Modbusregister.
power_value = int(min(abs(power_limit), 5000))
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W entladen für den Hausverbrauch")
- self.__tcp_client.write_register(13051, power_value, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(13051, power_value, data_type=ModbusDataType.UINT_16, device_id=unit)
elif power_limit > 0:
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W geladen")
if self.last_mode != 'charge':
- self.__tcp_client.write_register(13049, 2, data_type=ModbusDataType.UINT_16, unit=unit)
- self.__tcp_client.write_register(13050, 0xAA, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(13049, 2, data_type=ModbusDataType.UINT_16, device_id=unit)
+ self.__tcp_client.write_register(13050, 0xAA, data_type=ModbusDataType.UINT_16, device_id=unit)
self.last_mode = 'charge'
# Die maximale Entladeleistung begrenzen auf 5000W, maximaler Wertebereich Modbusregister.
power_value = int(min(power_limit, 5000))
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W geladen")
- self.__tcp_client.write_register(13051, power_value, data_type=ModbusDataType.UINT_16, unit=unit)
+ self.__tcp_client.write_register(13051, power_value, data_type=ModbusDataType.UINT_16, device_id=unit)
def power_limit_controllable(self) -> bool:
return True
diff --git a/packages/modules/devices/sungrow/sungrow_sh/counter.py b/packages/modules/devices/sungrow/sungrow_sh/counter.py
index f7b37254a3..871a54ea6f 100644
--- a/packages/modules/devices/sungrow/sungrow_sh/counter.py
+++ b/packages/modules/devices/sungrow/sungrow_sh/counter.py
@@ -38,29 +38,29 @@ def initialize(self) -> None:
def update(self):
unit = self.device_config.configuration.modbus_id
power = self.__tcp_client.read_input_registers(13009, ModbusDataType.INT_32,
- wordorder=Endian.Little, unit=unit) * -1
+ wordorder=Endian.Little, device_id=unit) * -1
try:
powers = self.__tcp_client.read_input_registers(5602, [ModbusDataType.INT_32] * 3,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
except Exception:
powers = None
self.fault_state.no_error(self.fault_text)
- frequency = self.__tcp_client.read_input_registers(5035, ModbusDataType.UINT_16, unit=unit) / 10
+ frequency = self.__tcp_client.read_input_registers(5035, ModbusDataType.UINT_16, device_id=unit) / 10
if self.device_config.configuration.version == Version.SH_winet_dongle:
# On WiNet-S, the frequency accuracy is higher by one place
frequency /= 10
- power_factor = self.__tcp_client.read_input_registers(5034, ModbusDataType.INT_16, unit=unit) / 1000
+ power_factor = self.__tcp_client.read_input_registers(5034, ModbusDataType.INT_16, device_id=unit) / 1000
if self.device_config.configuration.version == Version.SH:
# SH (LAN) provides accurate values from meter
voltages = self.__tcp_client.read_input_registers(5740, [ModbusDataType.UINT_16] * 3,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
else:
# These are actually output voltages of the inverter:
voltages = self.__tcp_client.read_input_registers(5018, [ModbusDataType.UINT_16] * 3,
- wordorder=Endian.Little, unit=unit)
+ wordorder=Endian.Little, device_id=unit)
voltages = [value / 10 for value in voltages]
diff --git a/packages/modules/devices/sungrow/sungrow_sh/inverter.py b/packages/modules/devices/sungrow/sungrow_sh/inverter.py
index fcb56c56ad..7004361bc2 100644
--- a/packages/modules/devices/sungrow/sungrow_sh/inverter.py
+++ b/packages/modules/devices/sungrow/sungrow_sh/inverter.py
@@ -35,11 +35,11 @@ def update(self) -> float:
unit = self.device_config.configuration.modbus_id
power = self.__tcp_client.read_input_registers(13033, ModbusDataType.INT_32,
- wordorder=Endian.Little, unit=unit) * -1
+ wordorder=Endian.Little, device_id=unit) * -1
dc_power = self.__tcp_client.read_input_registers(5016, ModbusDataType.UINT_32,
- wordorder=Endian.Little, unit=unit) * -1
+ wordorder=Endian.Little, device_id=unit) * -1
- currents = self.__tcp_client.read_input_registers(13030, [ModbusDataType.INT_16]*3, unit=unit)
+ currents = self.__tcp_client.read_input_registers(13030, [ModbusDataType.INT_16]*3, device_id=unit)
currents = [value * -0.1 for value in currents]
diff --git a/packages/modules/devices/thermia/thermia/counter.py b/packages/modules/devices/thermia/thermia/counter.py
index 47dbf6cc56..3488502eea 100644
--- a/packages/modules/devices/thermia/thermia/counter.py
+++ b/packages/modules/devices/thermia/thermia/counter.py
@@ -8,7 +8,7 @@
from modules.common.simcount import SimCounter
from modules.common.store import get_counter_value_store
from modules.devices.thermia.thermia.config import ThermiaCounterSetup
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
from modules.common.utils.peak_filter import PeakFilter
from modules.common.component_type import ComponentType
@@ -36,15 +36,15 @@ def initialize(self) -> None:
def update(self):
with self.client:
voltages = [val / 100 for val in self.client.read_input_registers(
- 72, [ModbusDataType.INT_16] * 3, unit=self.modbus_id)]
+ 72, [ModbusDataType.INT_16] * 3, device_id=self.modbus_id)]
powers = [val / 1 for val in self.client.read_input_registers(
- 78, [ModbusDataType.INT_16] * 3, unit=self.modbus_id)]
+ 78, [ModbusDataType.INT_16] * 3, device_id=self.modbus_id)]
power = sum(powers)
currents = [(val / 100) for val in self.client.read_input_registers(
- 69, [ModbusDataType.INT_16] * 3, unit=self.modbus_id)]
+ 69, [ModbusDataType.INT_16] * 3, device_id=self.modbus_id)]
imported = self.client.read_input_registers(
83, ModbusDataType.INT_32, wordorder=Endian.Little,
- unit=self.modbus_id) * 100
+ device_id=self.modbus_id) * 100
exported = 0
imported, _ = self.peak_filter.check_values(power, imported, None)
diff --git a/packages/modules/devices/upower/upower/bat.py b/packages/modules/devices/upower/upower/bat.py
index 304cbf7bd9..1af2ee4c1c 100644
--- a/packages/modules/devices/upower/upower/bat.py
+++ b/packages/modules/devices/upower/upower/bat.py
@@ -33,19 +33,19 @@ def __init__(self,
def update(self) -> None:
if self.version == UPowerVersion.GEN_1:
- power = self.client.read_input_registers(30258, ModbusDataType.INT_32, unit=self.__modbus_id) * -1
- soc = self.client.read_input_registers(33000, ModbusDataType.UINT_16, unit=self.__modbus_id)
+ power = self.client.read_input_registers(30258, ModbusDataType.INT_32, device_id=self.__modbus_id) * -1
+ soc = self.client.read_input_registers(33000, ModbusDataType.UINT_16, device_id=self.__modbus_id)
imported = self.client.read_input_registers(
- 31108, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 31108, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
exported = self.client.read_input_registers(
- 31110, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 31110, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
else:
# 1221 Total Bat Power
# 1427 Battery 1 current power
# Bat 1 (additional batteries offset by 50)
- power = self.client.read_input_registers(1427, ModbusDataType.INT_16, unit=self.__modbus_id)
- soc = self.client.read_input_registers(1402, ModbusDataType.UINT_16, unit=self.__modbus_id) / 10
+ power = self.client.read_input_registers(1427, ModbusDataType.INT_16, device_id=self.__modbus_id)
+ soc = self.client.read_input_registers(1402, ModbusDataType.UINT_16, device_id=self.__modbus_id) / 10
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/upower/upower/counter.py b/packages/modules/devices/upower/upower/counter.py
index 818b62f50a..de4ad21b80 100644
--- a/packages/modules/devices/upower/upower/counter.py
+++ b/packages/modules/devices/upower/upower/counter.py
@@ -33,21 +33,21 @@ def __init__(self,
def update(self):
if self.version == UPowerVersion.GEN_1:
- power = self.client.read_holding_registers(1000, ModbusDataType.INT_32, unit=self.__modbus_id) * -1
- frequency = self.client.read_holding_registers(11015, ModbusDataType.UINT_16, unit=self.__modbus_id)
+ power = self.client.read_holding_registers(1000, ModbusDataType.INT_32, device_id=self.__modbus_id) * -1
+ frequency = self.client.read_holding_registers(11015, ModbusDataType.UINT_16, device_id=self.__modbus_id)
powers = [-value for value in self.client.read_holding_registers(
- 10994, [ModbusDataType.INT_32] * 3, unit=self.__modbus_id)]
- exported = self.client.read_holding_registers(31102, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
- imported = self.client.read_holding_registers(31104, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ 10994, [ModbusDataType.INT_32] * 3, device_id=self.__modbus_id)]
+ exported = self.client.read_holding_registers(31102, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
+ imported = self.client.read_holding_registers(31104, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
imported, exported = self.peak_filter.check_values(power, imported, exported)
else:
- power = self.client.read_holding_registers(1219, ModbusDataType.INT_16, unit=self.__modbus_id) * -10
+ power = self.client.read_holding_registers(1219, ModbusDataType.INT_16, device_id=self.__modbus_id) * -10
frequency = self.client.read_holding_registers(
- 1759, ModbusDataType.UINT_16, unit=self.__modbus_id) / 100
+ 1759, ModbusDataType.UINT_16, device_id=self.__modbus_id) / 100
powers = [-10 * value for value in self.client.read_holding_registers(
- 1750, [ModbusDataType.INT_16] * 3, unit=self.__modbus_id
+ 1750, [ModbusDataType.INT_16] * 3, device_id=self.__modbus_id
)]
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/upower/upower/inverter.py b/packages/modules/devices/upower/upower/inverter.py
index d09ef2fa92..99797c29c6 100644
--- a/packages/modules/devices/upower/upower/inverter.py
+++ b/packages/modules/devices/upower/upower/inverter.py
@@ -30,11 +30,11 @@ def __init__(self,
def update(self) -> None:
if self.version == UPowerVersion.GEN_1:
- power = self.client.read_holding_registers(11028, ModbusDataType.UINT_32, unit=self.__modbus_id) * -1
- exported = self.client.read_holding_registers(11020, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
+ power = self.client.read_holding_registers(11028, ModbusDataType.UINT_32, device_id=self.__modbus_id) * -1
+ exported = self.client.read_holding_registers(11020, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 100
else:
- power = self.client.read_holding_registers(1220, ModbusDataType.UINT_16, unit=self.__modbus_id) * -1
- exported = self.client.read_holding_registers(1006, ModbusDataType.UINT_32, unit=self.__modbus_id) * 10
+ power = self.client.read_holding_registers(1220, ModbusDataType.UINT_16, device_id=self.__modbus_id) * -1
+ exported = self.client.read_holding_registers(1006, ModbusDataType.UINT_32, device_id=self.__modbus_id) * 10
_, exported = self.peak_filter.check_values(power, None, exported)
inverter_state = InverterState(
diff --git a/packages/modules/devices/varta/varta/bat_modbus.py b/packages/modules/devices/varta/varta/bat_modbus.py
index 2ac4cab323..e0cd063f00 100644
--- a/packages/modules/devices/varta/varta/bat_modbus.py
+++ b/packages/modules/devices/varta/varta/bat_modbus.py
@@ -37,8 +37,8 @@ def update(self) -> None:
self.set_state(self.get_state())
def get_state(self) -> BatState:
- soc = self.client.read_holding_registers(1068, ModbusDataType.INT_16, unit=self.__modbus_id)
- power = self.client.read_holding_registers(1066, ModbusDataType.INT_16, unit=self.__modbus_id)
+ soc = self.client.read_holding_registers(1068, ModbusDataType.INT_16, device_id=self.__modbus_id)
+ power = self.client.read_holding_registers(1066, ModbusDataType.INT_16, device_id=self.__modbus_id)
self.peak_filter.check_values(power)
return BatState(
power=power,
diff --git a/packages/modules/devices/varta/varta/counter.py b/packages/modules/devices/varta/varta/counter.py
index 3dd321010a..68e801a303 100644
--- a/packages/modules/devices/varta/varta/counter.py
+++ b/packages/modules/devices/varta/varta/counter.py
@@ -34,7 +34,7 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.COUNTER, self.component_config.id, self.fault_state)
def update(self):
- power = self.client.read_holding_registers(1078, ModbusDataType.INT_16, unit=self.__modbus_id) * -1
+ power = self.client.read_holding_registers(1078, ModbusDataType.INT_16, device_id=self.__modbus_id) * -1
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/varta/varta/inverter.py b/packages/modules/devices/varta/varta/inverter.py
index 5bba140ea2..adeb54b673 100644
--- a/packages/modules/devices/varta/varta/inverter.py
+++ b/packages/modules/devices/varta/varta/inverter.py
@@ -33,7 +33,7 @@ def initialize(self) -> None:
self.peak_filter = PeakFilter(ComponentType.INVERTER, self.component_config.id, self.fault_state)
def update(self):
- power = self.client.read_holding_registers(1102, ModbusDataType.UINT_16, unit=self.__modbus_id) * -1
+ power = self.client.read_holding_registers(1102, ModbusDataType.UINT_16, device_id=self.__modbus_id) * -1
self.peak_filter.check_values(power)
_, exported = self.sim_counter.sim_count(power)
diff --git a/packages/modules/devices/victron/victron/bat.py b/packages/modules/devices/victron/victron/bat.py
index f49dfc4f40..1304b3cab9 100644
--- a/packages/modules/devices/victron/victron/bat.py
+++ b/packages/modules/devices/victron/victron/bat.py
@@ -41,8 +41,8 @@ def initialize(self) -> None:
def update(self) -> None:
modbus_id = self.component_config.configuration.modbus_id
with self.__tcp_client:
- power = self.__tcp_client.read_holding_registers(842, ModbusDataType.INT_16, unit=modbus_id)
- soc = self.__tcp_client.read_holding_registers(843, ModbusDataType.UINT_16, unit=modbus_id)
+ power = self.__tcp_client.read_holding_registers(842, ModbusDataType.INT_16, device_id=modbus_id)
+ soc = self.__tcp_client.read_holding_registers(843, ModbusDataType.UINT_16, device_id=modbus_id)
self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
bat_state = BatState(
@@ -57,7 +57,7 @@ def update(self) -> None:
def set_power_limit(self, power_limit: Optional[int]) -> None:
modbus_id = self.component_config.configuration.modbus_id
# Wenn Victron Dynamic ESS aktiv, erfolgt keine weitere Regelung in openWB
- dynamic_ess_mode = self.__tcp_client.read_holding_registers(5400, ModbusDataType.UINT_16, unit=modbus_id)
+ dynamic_ess_mode = self.__tcp_client.read_holding_registers(5400, ModbusDataType.UINT_16, device_id=modbus_id)
if dynamic_ess_mode == 1:
log.debug("Dynamic ESS Mode ist aktiv, daher erfolgt keine Regelung des Speichers durch openWB")
return
@@ -66,18 +66,18 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
log.debug("Keine Batteriesteuerung, Selbstregelung durch Wechselrichter")
if self.last_mode is not None:
# ESS Mode 2 und Leistung EVU auf 0kW setzen für Selbstregelung
- self.__tcp_client.write_register(2902, 2, data_type=ModbusDataType.UINT_16, unit=modbus_id)
- self.__tcp_client.write_register(2702, 100, data_type=ModbusDataType.UINT_16, unit=modbus_id)
- self.__tcp_client.write_register(2716, 0, data_type=ModbusDataType.INT_32, unit=modbus_id)
+ self.__tcp_client.write_register(2902, 2, data_type=ModbusDataType.UINT_16, device_id=modbus_id)
+ self.__tcp_client.write_register(2702, 100, data_type=ModbusDataType.UINT_16, device_id=modbus_id)
+ self.__tcp_client.write_register(2716, 0, data_type=ModbusDataType.INT_32, device_id=modbus_id)
self.last_mode = None
elif power_limit == 0:
log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht entladen")
if self.last_mode != 'stop':
# ESS Mode 2 und Discharge Power 0% für externe Steuerung und keine Entladung
# Leistung an EVU-Punkt auf 0kW setzen -> Eigenregelung bei laden und Entladen verhindern
- self.__tcp_client.write_register(2902, 2, data_type=ModbusDataType.UINT_16, unit=modbus_id)
- self.__tcp_client.write_register(2702, 0, data_type=ModbusDataType.UINT_16, unit=modbus_id)
- self.__tcp_client.write_register(2716, 0, data_type=ModbusDataType.INT_32, unit=modbus_id)
+ self.__tcp_client.write_register(2902, 2, data_type=ModbusDataType.UINT_16, device_id=modbus_id)
+ self.__tcp_client.write_register(2702, 0, data_type=ModbusDataType.UINT_16, device_id=modbus_id)
+ self.__tcp_client.write_register(2716, 0, data_type=ModbusDataType.INT_32, device_id=modbus_id)
self.last_mode = 'stop'
elif power_limit < 0:
evu_power = data.data.counter_all_data.get_evu_counter().data.get.power
@@ -87,14 +87,14 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
f"Aktuelle Speicherleistung: {self.current_power} W, EVU-Leistung: {evu_power} W "
f"EVU-Leistung um {power_limit - self.current_power} W anpassen auf {set_power} W")
if self.last_mode != 'discharge':
- self.__tcp_client.write_register(2902, 2, data_type=ModbusDataType.UINT_16, unit=modbus_id)
- self.__tcp_client.write_register(2702, 100, data_type=ModbusDataType.UINT_16, unit=modbus_id)
+ self.__tcp_client.write_register(2902, 2, data_type=ModbusDataType.UINT_16, device_id=modbus_id)
+ self.__tcp_client.write_register(2702, 100, data_type=ModbusDataType.UINT_16, device_id=modbus_id)
self.last_mode = 'discharge'
# Setzen der angestrebten EVU-Leistung, Speicher versucht seine Leistung
# anzupassen um den Zielwert zu erreichen
self.__tcp_client.write_register(
- 2716, set_power, data_type=ModbusDataType.INT_32, unit=modbus_id)
+ 2716, set_power, data_type=ModbusDataType.INT_32, device_id=modbus_id)
elif power_limit > 0:
evu_power = data.data.counter_all_data.get_evu_counter().data.get.power
set_power = (power_limit - self.current_power) + evu_power
@@ -103,11 +103,11 @@ def set_power_limit(self, power_limit: Optional[int]) -> None:
f"Aktuelle Speicherleistung: {self.current_power} W, EVU-Leistung: {evu_power} W "
f"EVU-Leistung um {power_limit - self.current_power} W anpassen auf {set_power} W")
if self.last_mode != 'charge':
- self.__tcp_client.write_register(2902, 2, data_type=ModbusDataType.UINT_16, unit=modbus_id)
- self.__tcp_client.write_register(2702, 100, data_type=ModbusDataType.UINT_16, unit=modbus_id)
+ self.__tcp_client.write_register(2902, 2, data_type=ModbusDataType.UINT_16, device_id=modbus_id)
+ self.__tcp_client.write_register(2702, 100, data_type=ModbusDataType.UINT_16, device_id=modbus_id)
self.last_mode = 'charge'
self.__tcp_client.write_register(
- 2716, set_power, data_type=ModbusDataType.INT_32, unit=modbus_id)
+ 2716, set_power, data_type=ModbusDataType.INT_32, device_id=modbus_id)
def power_limit_controllable(self) -> bool:
return True
diff --git a/packages/modules/devices/victron/victron/counter.py b/packages/modules/devices/victron/victron/counter.py
index 11da27e6ce..f67b647437 100644
--- a/packages/modules/devices/victron/victron/counter.py
+++ b/packages/modules/devices/victron/victron/counter.py
@@ -37,16 +37,16 @@ def update(self):
energy_meter = self.component_config.configuration.energy_meter
with self.__tcp_client:
if energy_meter:
- powers = self.__tcp_client.read_holding_registers(2600, [ModbusDataType.INT_16]*3, unit=unit)
+ powers = self.__tcp_client.read_holding_registers(2600, [ModbusDataType.INT_16]*3, device_id=unit)
currents = [
- self.__tcp_client.read_holding_registers(reg, ModbusDataType.INT_16, unit=unit) / 10
+ self.__tcp_client.read_holding_registers(reg, ModbusDataType.INT_16, device_id=unit) / 10
for reg in [2617, 2619, 2621]]
voltages = [
- self.__tcp_client.read_holding_registers(reg, ModbusDataType.UINT_16, unit=unit) / 10
+ self.__tcp_client.read_holding_registers(reg, ModbusDataType.UINT_16, device_id=unit) / 10
for reg in [2616, 2618, 2620]]
power = sum(powers)
else:
- powers = self.__tcp_client.read_holding_registers(820, [ModbusDataType.INT_16]*3, unit=unit)
+ powers = self.__tcp_client.read_holding_registers(820, [ModbusDataType.INT_16]*3, device_id=unit)
power = sum(powers)
self.peak_filter.check_values(power)
diff --git a/packages/modules/devices/victron/victron/inverter.py b/packages/modules/devices/victron/victron/inverter.py
index 2b11b17f81..778b2211e1 100644
--- a/packages/modules/devices/victron/victron/inverter.py
+++ b/packages/modules/devices/victron/victron/inverter.py
@@ -40,7 +40,7 @@ def update(self) -> None:
with self.__tcp_client:
if self.component_config.configuration.mppt:
try:
- power = self.__tcp_client.read_holding_registers(789, ModbusDataType.UINT_16, unit=modbus_id) / -10
+ power = self.__tcp_client.read_holding_registers(789, ModbusDataType.UINT_16, device_id=modbus_id) / -10
except Exception as e:
if "GatewayPathUnavailable" in str(e):
power = 0
@@ -52,8 +52,8 @@ def update(self) -> None:
# Adresse 808-810 ac output connected pv
# Adresse 811-813 ac input connected pv
# Adresse 850 mppt Leistung
- power_temp1 = self.__tcp_client.read_holding_registers(808, [ModbusDataType.UINT_16]*6, unit=100)
- power_temp2 = self.__tcp_client.read_holding_registers(850, ModbusDataType.UINT_16, unit=100)
+ power_temp1 = self.__tcp_client.read_holding_registers(808, [ModbusDataType.UINT_16]*6, device_id=100)
+ power_temp2 = self.__tcp_client.read_holding_registers(850, ModbusDataType.UINT_16, device_id=100)
power = (sum(power_temp1)+power_temp2) * -1
self.peak_filter.check_values(power)
diff --git a/packages/modules/devices/victron/victron_3p75ct/counter.py b/packages/modules/devices/victron/victron_3p75ct/counter.py
index fb7e074022..1c63b0339c 100644
--- a/packages/modules/devices/victron/victron_3p75ct/counter.py
+++ b/packages/modules/devices/victron/victron_3p75ct/counter.py
@@ -33,22 +33,22 @@ def update(self):
unit = 1 # Modbus ID ist immer 1 da Standalone Produkt
with self.__udp_client:
powers = [
- self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit) / 1
+ self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_32, device_id=unit) / 1
for reg in [0x3082, 0x3086, 0x308A]]
currents = [
- self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_16, unit=unit) / 100
+ self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_16, device_id=unit) / 100
for reg in [0x3041, 0x3049, 0x3051]]
voltages = [
- self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_16, unit=unit) / 100
+ self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_16, device_id=unit) / 100
for reg in [0x3040, 0x3048, 0x3050]]
power_factors = [
- self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_16, unit=unit) / 1000
+ self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_16, device_id=unit) / 1000
for reg in [0x3047, 0x304F, 0x3057]]
power = sum(powers)
- frequency = self.__udp_client.read_holding_registers(0x3032, ModbusDataType.UINT_16, unit=unit) / 100
- imported = self.__udp_client.read_holding_registers(0x3034, ModbusDataType.UINT_32, unit=unit) * 10
- exported = self.__udp_client.read_holding_registers(0x3036, ModbusDataType.UINT_32, unit=unit) * 10
+ frequency = self.__udp_client.read_holding_registers(0x3032, ModbusDataType.UINT_16, device_id=unit) / 100
+ imported = self.__udp_client.read_holding_registers(0x3034, ModbusDataType.UINT_32, device_id=unit) * 10
+ exported = self.__udp_client.read_holding_registers(0x3036, ModbusDataType.UINT_32, device_id=unit) * 10
imported, exported = self.peak_filter.check_values(power, imported, exported)
counter_state = CounterState(
diff --git a/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py b/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py
index 30fcf6b12b..c4628b0a58 100644
--- a/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py
+++ b/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
import copy
import logging
from threading import Event, Thread
diff --git a/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler_config.py b/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler_config.py
index 736bf8ec01..2b80baf109 100644
--- a/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler_config.py
+++ b/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler_config.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
from dataclasses import dataclass, field
from typing import List, Optional
diff --git a/packages/modules/internal_chargepoint_handler/rfid.py b/packages/modules/internal_chargepoint_handler/rfid.py
index 46878c99e7..6664dd437f 100644
--- a/packages/modules/internal_chargepoint_handler/rfid.py
+++ b/packages/modules/internal_chargepoint_handler/rfid.py
@@ -1,145 +1,140 @@
import asyncio
import logging
-from evdev import InputDevice, ecodes, list_devices, categorize
from helpermodules.pub import Pub
log = logging.getLogger(__name__)
+try:
+ from evdev import InputDevice, ecodes, list_devices, categorize
+ EVDEV_AVAILABLE = True
+except ImportError:
+ EVDEV_AVAILABLE = False
+ log.info("evdev not available - RFID reader disabled")
-class RfidReader:
- SCAN_CODE_MAP = {
- # function keys
- # 0: None,
- # ecodes.KEY_ESC: u'ESC',
- # ecodes.KEY_BACKSPACE: u'BKSP',
- # ecodes.KEY_TAB: u'TAB',
- # ecodes.KEY_LEFTBRACE: u'[',
- # ecodes.KEY_RIGHTBRACE: u']',
- # ecodes.KEY_ENTER: u'CRLF',
- # ecodes.KEY_LEFTCTRL: u'LCTRL',
- # ecodes.KEY_LEFTSHIFT: u'LSHFT',
- # ecodes.KEY_RIGHTSHIFT: u'RSHFT',
- # ecodes.KEY_LEFTALT: u'LALT',
- # ecodes.KEY_KPENTER: u'CRLF',
- # ecodes.KEY_RIGHTCTRL: u'RCTRL,
- # ecodes.KEY_RIGHTALT: u'RALT'
- # number keys
- ecodes.KEY_1: u'1',
- ecodes.KEY_2: u'2',
- ecodes.KEY_3: u'3',
- ecodes.KEY_4: u'4',
- ecodes.KEY_5: u'5',
- ecodes.KEY_6: u'6',
- ecodes.KEY_7: u'7',
- ecodes.KEY_8: u'8',
- ecodes.KEY_9: u'9',
- ecodes.KEY_0: u'0',
- ecodes.KEY_KP1: u'1',
- ecodes.KEY_KP2: u'2',
- ecodes.KEY_KP3: u'3',
- ecodes.KEY_KP4: u'4',
- ecodes.KEY_KP5: u'5',
- ecodes.KEY_KP6: u'6',
- ecodes.KEY_KP7: u'7',
- ecodes.KEY_KP8: u'8',
- ecodes.KEY_KP9: u'9',
- ecodes.KEY_KP0: u'0',
+if EVDEV_AVAILABLE:
- # latin letters
- ecodes.KEY_A: u'A',
- ecodes.KEY_B: u'B',
- ecodes.KEY_C: u'C',
- ecodes.KEY_D: u'D',
- ecodes.KEY_E: u'E',
- ecodes.KEY_F: u'F',
- ecodes.KEY_G: u'G',
- ecodes.KEY_H: u'H',
- ecodes.KEY_I: u'I',
- ecodes.KEY_J: u'J',
- ecodes.KEY_K: u'K',
- ecodes.KEY_L: u'L',
- ecodes.KEY_M: u'M',
- ecodes.KEY_N: u'N',
- ecodes.KEY_O: u'O',
- ecodes.KEY_P: u'P',
- ecodes.KEY_Q: u'Q',
- ecodes.KEY_R: u'R',
- ecodes.KEY_S: u'S',
- ecodes.KEY_T: u'T',
- ecodes.KEY_U: u'U',
- ecodes.KEY_V: u'V',
- ecodes.KEY_W: u'W',
- ecodes.KEY_X: u'X',
- ecodes.KEY_Y: u'Y',
- ecodes.KEY_Z: u'Z',
+ class RfidReader:
+ SCAN_CODE_MAP = {
+ ecodes.KEY_1: u'1',
+ ecodes.KEY_2: u'2',
+ ecodes.KEY_3: u'3',
+ ecodes.KEY_4: u'4',
+ ecodes.KEY_5: u'5',
+ ecodes.KEY_6: u'6',
+ ecodes.KEY_7: u'7',
+ ecodes.KEY_8: u'8',
+ ecodes.KEY_9: u'9',
+ ecodes.KEY_0: u'0',
+ ecodes.KEY_KP1: u'1',
+ ecodes.KEY_KP2: u'2',
+ ecodes.KEY_KP3: u'3',
+ ecodes.KEY_KP4: u'4',
+ ecodes.KEY_KP5: u'5',
+ ecodes.KEY_KP6: u'6',
+ ecodes.KEY_KP7: u'7',
+ ecodes.KEY_KP8: u'8',
+ ecodes.KEY_KP9: u'9',
+ ecodes.KEY_KP0: u'0',
+ ecodes.KEY_A: u'A',
+ ecodes.KEY_B: u'B',
+ ecodes.KEY_C: u'C',
+ ecodes.KEY_D: u'D',
+ ecodes.KEY_E: u'E',
+ ecodes.KEY_F: u'F',
+ ecodes.KEY_G: u'G',
+ ecodes.KEY_H: u'H',
+ ecodes.KEY_I: u'I',
+ ecodes.KEY_J: u'J',
+ ecodes.KEY_K: u'K',
+ ecodes.KEY_L: u'L',
+ ecodes.KEY_M: u'M',
+ ecodes.KEY_N: u'N',
+ ecodes.KEY_O: u'O',
+ ecodes.KEY_P: u'P',
+ ecodes.KEY_Q: u'Q',
+ ecodes.KEY_R: u'R',
+ ecodes.KEY_S: u'S',
+ ecodes.KEY_T: u'T',
+ ecodes.KEY_U: u'U',
+ ecodes.KEY_V: u'V',
+ ecodes.KEY_W: u'W',
+ ecodes.KEY_X: u'X',
+ ecodes.KEY_Y: u'Y',
+ ecodes.KEY_Z: u'Z',
+ ecodes.KEY_MINUS: u'-',
+ ecodes.KEY_EQUAL: u'=',
+ ecodes.KEY_SEMICOLON: u';',
+ ecodes.KEY_COMMA: u',',
+ ecodes.KEY_DOT: u'.',
+ ecodes.KEY_SLASH: u'/',
+ ecodes.KEY_KPASTERISK: u'*',
+ ecodes.KEY_KPMINUS: u'-',
+ ecodes.KEY_KPPLUS: u'+',
+ ecodes.KEY_KPDOT: u'.',
+ ecodes.KEY_KPSLASH: u'/',
+ }
+ _detected_keyboards: list[InputDevice] = []
- # punctuation marks and other characters
- ecodes.KEY_MINUS: u'-',
- ecodes.KEY_EQUAL: u'=',
- ecodes.KEY_SEMICOLON: u';',
- ecodes.KEY_COMMA: u',',
- ecodes.KEY_DOT: u'.',
- ecodes.KEY_SLASH: u'/',
- ecodes.KEY_KPASTERISK: u'*',
- ecodes.KEY_KPMINUS: u'-',
- ecodes.KEY_KPPLUS: u'+',
- ecodes.KEY_KPDOT: u'.',
- ecodes.KEY_KPSLASH: u'/',
- # ecodes.KEY_APOSTROPHE: u'"',
- # ecodes.KEY_GRAVE: u'`',
- # ecodes.KEY_BACKSLASH: u'\\',
- }
- _detected_keyboards: list[InputDevice] = []
-
- def __init__(self) -> None:
- try:
- devices = [InputDevice(path) for path in list_devices()]
- for device in devices:
- log.debug(f"**** {device.path} {device.name} {device.phys} ****")
- # log.debug(device.capabilities(verbose=True))
- device_capabilities = device.capabilities()
- if ecodes.EV_KEY in device_capabilities:
- log.debug("device emits keyboard events")
- if ecodes.KEY_ENTER in device_capabilities[1]:
- log.debug("detected 'enter' key, device seems to be a keyboard")
- self._detected_keyboards.append(device)
+ def __init__(self) -> None:
+ try:
+ devices = [InputDevice(path) for path in list_devices()]
+ for device in devices:
+ log.debug(f"**** {device.path} {device.name} {device.phys} ****")
+ device_capabilities = device.capabilities()
+ if ecodes.EV_KEY in device_capabilities:
+ log.debug("device emits keyboard events")
+ if ecodes.KEY_ENTER in device_capabilities[1]:
+ log.debug("detected 'enter' key, device seems to be a keyboard")
+ self._detected_keyboards.append(device)
+ else:
+ log.debug("no 'enter' key detected, skipping device")
else:
- log.debug("no 'enter' key detected, skipping device")
- else:
- log.debug("device does not emit keyboard events, skipping")
- log.info("detected keyboard devices:")
+ log.debug("device does not emit keyboard events, skipping")
+ log.info("detected keyboard devices:")
+ for device in self._detected_keyboards:
+ log.info(f"{device.path} {device.name}")
+ except Exception:
+ log.exception("Fehler im Rfid-Modul")
+
+ def keyboards_detected(self) -> bool:
+ return len(self._detected_keyboards) > 0
+
+ async def _read_events(self, device: InputDevice):
+ log.debug(f"reading events from: {device.path}")
+ try:
+ key_string = ""
+ async for event in device.async_read_loop():
+ if event.type == ecodes.EV_KEY:
+ data = categorize(event)
+ if data.keystate == 1:
+ if data.scancode in (ecodes.KEY_ENTER, ecodes.KEY_KPENTER):
+ if len(key_string) > 0:
+ log.debug(f"RFID-String: {key_string}")
+ Pub().pub("openWB/set/internal_chargepoint/last_tag", key_string)
+ key_string = ""
+ else:
+ log.debug(f"new key: {data.scancode} - {ecodes.KEY[data.scancode]}")
+ key_lookup = self.SCAN_CODE_MAP.get(data.scancode) or u''
+ key_string += str(format(key_lookup))
+ except Exception:
+ log.exception("Fehler im Rfid-Modul")
+
+ def run(self):
+ loop = asyncio.new_event_loop()
+ asyncio.set_event_loop(loop)
for device in self._detected_keyboards:
- log.info(f"{device.path} {device.name}")
- except Exception:
- log.exception("Fehler im Rfid-Modul")
+ asyncio.ensure_future(self._read_events(device))
+ loop.run_forever()
- def keyboards_detected(self) -> bool:
- return len(self._detected_keyboards) > 0
+else:
- async def _read_events(self, device: InputDevice):
- log.debug(f"reading events from: {device.path}")
- try:
- key_string = ""
- async for event in device.async_read_loop():
- if event.type == ecodes.EV_KEY:
- data = categorize(event)
- if data.keystate == 1:
- if data.scancode in (ecodes.KEY_ENTER, ecodes.KEY_KPENTER):
- if len(key_string) > 0:
- log.debug(f"RFID-String: {key_string}")
- Pub().pub("openWB/set/internal_chargepoint/last_tag", key_string)
- key_string = ""
- else:
- log.debug(f"new key: {data.scancode} - {ecodes.KEY[data.scancode]}")
- key_lookup = self.SCAN_CODE_MAP.get(data.scancode) or u''
- key_string += str(format(key_lookup))
- except Exception:
- log.exception("Fehler im Rfid-Modul")
+ class RfidReader:
+ def __init__(self) -> None:
+ pass
+
+ def keyboards_detected(self) -> bool:
+ return False
- def run(self):
- loop = asyncio.new_event_loop()
- asyncio.set_event_loop(loop)
- for device in self._detected_keyboards:
- asyncio.ensure_future(self._read_events(device))
- loop.run_forever()
+ def run(self):
+ pass
diff --git a/packages/modules/io_devices/dimm_kit/api.py b/packages/modules/io_devices/dimm_kit/api.py
index 76ed494b4d..ce59b950c9 100644
--- a/packages/modules/io_devices/dimm_kit/api.py
+++ b/packages/modules/io_devices/dimm_kit/api.py
@@ -44,13 +44,13 @@ def read():
# analog inputs are configured as 0-5V (AI1-AI4) and 0-25mA (AI5-AI8) as default
# the values are reported as integers in range of 0-1024
time.sleep(0.1)
- analog_read = client.read_input_registers(0x00, [ModbusDataType.UINT_16]*8, unit=config.configuration.modbus_id)
+ analog_read = client.read_input_registers(0x00, [ModbusDataType.UINT_16]*8, device_id=config.configuration.modbus_id)
analog_input = {getattr(AnalogInputMapping, f'AI{pin+1}').name: analog_read[pin] * 5 for pin in range(8)}
time.sleep(0.1)
- digital_input_read = client.read_coils(0x00, 8, unit=config.configuration.modbus_id)
+ digital_input_read = client.read_coils(0x00, 8, device_id=config.configuration.modbus_id)
digital_input = {getattr(DigitalInputMapping, f'DI{pin+1}').name: digital_input_read[pin] for pin in range(8)}
time.sleep(0.1)
- digital_output_read = client.read_coils(0x10, 8, unit=config.configuration.modbus_id)
+ digital_output_read = client.read_coils(0x10, 8, device_id=config.configuration.modbus_id)
digital_output = {
getattr(DigitalOutputMapping, f'DO{pin+1}').name: digital_output_read[pin] for pin in range(8)}
return IoState(
@@ -63,13 +63,13 @@ def write(analog_output: Optional[Dict[str, int]], digital_output: Optional[Dict
nonlocal client
for i, value in digital_output.items():
client.write_single_coil(DigitalOutputMapping[i].value, 1 if value is True else 0,
- unit=config.configuration.modbus_id)
+ device_id=config.configuration.modbus_id)
def initializer():
nonlocal client
client = ModbusTcpClient_(config.configuration.host, config.configuration.port)
for output, value in config.output["digital"].items():
- client.write_single_coil(DigitalOutputMapping[output].value, value, unit=config.configuration.modbus_id)
+ client.write_single_coil(DigitalOutputMapping[output].value, value, device_id=config.configuration.modbus_id)
return ConfigurableIo(config=config, component_reader=read, component_writer=write, initializer=initializer)
diff --git a/packages/modules/smarthome/acthor/watt.py b/packages/modules/smarthome/acthor/watt.py
index ec32becc8d..418763649e 100644
--- a/packages/modules/smarthome/acthor/watt.py
+++ b/packages/modules/smarthome/acthor/watt.py
@@ -4,7 +4,7 @@
import struct
import codecs
import logging
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
from smarthome.smartret import writeret
log = logging.getLogger("acthor")
@@ -72,10 +72,10 @@
client = ModbusTcpClient(ipadr, port=502)
#
start = 1000
-resp = client.read_holding_registers(start, 35, unit=1)
+resp = client.read_holding_registers(start, count=35, device_id=1)
# Test only
# start = 3524
-# resp = client.read_input_registers(start, 35, unit=1)
+# resp = client.read_input_registers(start, count=35, device_id=1)
value1 = resp.registers[0]
all = format(value1, '04x')
aktpower = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0])
@@ -163,7 +163,7 @@
(devicenumber, ipadr, atype, instpower, faktor))
# modbus write
if modbuswrite == 1:
- rq = client.write_register(1000, neupower, unit=1)
+ rq = client.write_register(1000, neupower, device_id=1)
if count1 < 3:
log.info("watt devicenr %d ipadr %s device written by modbus " %
(devicenumber, ipadr))
diff --git a/packages/modules/smarthome/askoheat/watt.py b/packages/modules/smarthome/askoheat/watt.py
index 6733ae8976..576c9d4984 100644
--- a/packages/modules/smarthome/askoheat/watt.py
+++ b/packages/modules/smarthome/askoheat/watt.py
@@ -3,7 +3,7 @@
import os
import struct
import codecs
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import logging
from smarthome.smartlog import initlog
from smarthome.smartret import writeret
@@ -32,7 +32,7 @@
start = 110
# test
# start = 3522
-resp = client.read_input_registers(start, 1, unit=1)
+resp = client.read_input_registers(start, count=1, device_id=1)
value1 = resp.registers[0]
all = format(value1, '04x')
aktpower = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0])
@@ -40,7 +40,7 @@
start = 638
# test
# start = 3522
-resp = client.read_input_registers(start, 1, unit=1)
+resp = client.read_input_registers(start, count=1, device_id=1)
value1 = resp.registers[0]
all = format(value1, '04x')
temp0 = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0])
@@ -95,7 +95,7 @@
(devicenumber, ipadr, neupower, pvmodus, modbuswrite))
# modbus write
if modbuswrite == 1:
- rq = client.write_register(201, neupower, unit=1)
+ rq = client.write_register(201, neupower, device_id=1)
if count1 < 3:
log.info("watt devicenr %d ipadr %s device written by modbus " %
(devicenumber, ipadr))
diff --git a/packages/modules/smarthome/elwa/watt.py b/packages/modules/smarthome/elwa/watt.py
index 4bfcc40418..7b5d413c85 100644
--- a/packages/modules/smarthome/elwa/watt.py
+++ b/packages/modules/smarthome/elwa/watt.py
@@ -3,7 +3,7 @@
import os
import struct
import codecs
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import logging
from smarthome.smartret import writeret
@@ -31,9 +31,9 @@
client = ModbusTcpClient(ipadr, port=502)
# Test only
# # start = 3524
-# resp=client.read_input_registers(start,20,unit=1)
+# resp=client.read_input_registers(start, count=20, device_id=1)
start = 1000
-resp = client.read_holding_registers(start, 20, unit=1)
+resp = client.read_holding_registers(start, count=20, device_id=1)
value1 = resp.registers[0]
all = format(value1, '04x')
aktpower = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0])
@@ -127,7 +127,7 @@
(devicenumber, ipadr, neupower, pvmodus, modbuswrite))
# modbus write
if modbuswrite == 1:
- rq = client.write_register(1000, neupower, unit=1)
+ rq = client.write_register(1000, neupower, device_id=1)
if count1 < 3:
log.info("watt devicenr %d ipadr %s device written by modbus " %
(devicenumber, ipadr))
diff --git a/packages/modules/smarthome/idm/watt.py b/packages/modules/smarthome/idm/watt.py
index bb4a1c8a01..b61d4fe2e3 100644
--- a/packages/modules/smarthome/idm/watt.py
+++ b/packages/modules/smarthome/idm/watt.py
@@ -3,9 +3,9 @@
import os
import struct
import logging
-from pymodbus.constants import Endian
-from pymodbus.payload import BinaryPayloadBuilder
-from pymodbus.client.sync import ModbusTcpClient
+from modules.common.pymodbus_compat import Endian
+from modules.common.pymodbus_compat import BinaryPayloadBuilder
+from pymodbus.client import ModbusTcpClient
from smarthome.smartlog import initlog
from smarthome.smartret import writeret
devicenumber = int(sys.argv[1])
@@ -47,10 +47,10 @@
# prod
start = 4122
if navvers == "2":
- rr = client.read_input_registers(start, 2, unit=1)
+ rr = client.read_input_registers(start, count=2, device_id=1)
else:
- rr = client.read_holding_registers(start, 2, unit=1)
-raw = struct.pack('>HH', rr.getRegister(1), rr.getRegister(0))
+ rr = client.read_holding_registers(start, count=2, device_id=1)
+raw = struct.pack('>HH', rr.registers[1], rr.registers[0])
lkw = float(struct.unpack('>f', raw)[0])
aktpower = int(lkw*1000)
modbuswrite = 0
@@ -124,11 +124,11 @@
% (devicenumber, ipadr, neupower, pvmodus, modbuswrite))
# modbus write
if modbuswrite == 1:
- client.write_registers(74, regnew, unit=1)
+ client.write_registers(74, regnew, device_id=1)
if count1 < 3:
log.info("devicenr %d ipadr %s device written by modbus " %
(devicenumber, ipadr))
- client.write_registers(78, pvwnew, unit=1)
+ client.write_registers(78, pvwnew, device_id=1)
else:
if pvmodus == 99:
pvmodus = 0
diff --git a/packages/modules/smarthome/lambda_/off.py b/packages/modules/smarthome/lambda_/off.py
index 526317742f..fe3bf75e74 100644
--- a/packages/modules/smarthome/lambda_/off.py
+++ b/packages/modules/smarthome/lambda_/off.py
@@ -5,7 +5,7 @@
import codecs
import logging
from smarthome.smartlog import initlog
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
bp = '/var/www/html/openWB/ramdisk/smarthome_device_'
devicenumber = int(sys.argv[1])
ipadr = str(sys.argv[2])
@@ -22,7 +22,7 @@
% (devicenumber, ipadr, uberschuss))
client = ModbusTcpClient(ipadr, port=502)
start = 103
-resp = client.read_holding_registers(start, 2, unit=1)
+resp = client.read_holding_registers(start, count=2, device_id=1)
value1 = resp.registers[0]
all = format(value1, '04x')
aktpower = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0])
diff --git a/packages/modules/smarthome/lambda_/on.py b/packages/modules/smarthome/lambda_/on.py
index d74abad74a..c50d9e0985 100644
--- a/packages/modules/smarthome/lambda_/on.py
+++ b/packages/modules/smarthome/lambda_/on.py
@@ -4,7 +4,7 @@
import codecs
import logging
from smarthome.smartlog import initlog
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
bp = '/var/www/html/openWB/ramdisk/smarthome_device_'
devicenumber = int(sys.argv[1])
ipadr = str(sys.argv[2])
@@ -23,7 +23,7 @@
% (devicenumber, ipadr, uberschuss))
client = ModbusTcpClient(ipadr, port=502)
start = 103
-resp = client.read_holding_registers(start, 2, unit=1)
+resp = client.read_holding_registers(start, count=2, device_id=1)
value1 = resp.registers[0]
all = format(value1, '04x')
aktpower = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0])
diff --git a/packages/modules/smarthome/lambda_/watt.py b/packages/modules/smarthome/lambda_/watt.py
index a6ad5c641b..9ecd92f431 100644
--- a/packages/modules/smarthome/lambda_/watt.py
+++ b/packages/modules/smarthome/lambda_/watt.py
@@ -5,9 +5,9 @@
import struct
import codecs
import logging
-from pymodbus.payload import Endian
-from pymodbus.payload import BinaryPayloadBuilder
-from pymodbus.client.sync import ModbusTcpClient
+from modules.common.pymodbus_compat import Endian
+from modules.common.pymodbus_compat import BinaryPayloadBuilder
+from pymodbus.client import ModbusTcpClient
from smarthome.smartlog import initlog
from smarthome.smartret import writeret
named_tuple = time.localtime() # getstruct_time
@@ -53,7 +53,7 @@
# aktuelle Leistung lesen
with ModbusTcpClient(ipadr, port=502) as client:
start = 103
- resp = client.read_holding_registers(start, 2, unit=1)
+ resp = client.read_holding_registers(start, count=2, device_id=1)
#
value1 = resp.registers[0]
all = format(value1, '04x')
@@ -104,7 +104,7 @@
builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little)
builder.add_16bit_int(neupower)
pay = builder.to_registers()
- client.write_registers(102, [pay[0]], unit=1)
+ client.write_registers(102, [pay[0]], device_id=1)
if count1 < 3:
log.info(' %d ipadr %s written %6d %#4X' %
(devicenumber, ipadr, pay[0], pay[0]))
diff --git a/packages/modules/smarthome/mqtt/off.py b/packages/modules/smarthome/mqtt/off.py
index edb8cc3953..4faf96844d 100644
--- a/packages/modules/smarthome/mqtt/off.py
+++ b/packages/modules/smarthome/mqtt/off.py
@@ -16,7 +16,7 @@ def on_message(client, userdata, msg) -> None:
devicenumber = str(sys.argv[1])
ipadr = str(sys.argv[2])
uberschuss = int(sys.argv[3])
-client = mqtt.Client("openWB-mqttsmarthomecust")
+client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, client_id="openWB-mqttsmarthomecust")
client.on_connect = on_connect
client.on_message = on_message
startTime = time.time()
diff --git a/packages/modules/smarthome/mqtt/on.py b/packages/modules/smarthome/mqtt/on.py
index aabd8d2299..7794498fbb 100644
--- a/packages/modules/smarthome/mqtt/on.py
+++ b/packages/modules/smarthome/mqtt/on.py
@@ -16,7 +16,7 @@ def on_message(client, userdata, msg) -> None:
devicenumber = str(sys.argv[1])
ipadr = str(sys.argv[2])
uberschuss = int(sys.argv[3])
-client = mqtt.Client("openWB-mqttsmarthomecust")
+client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, client_id="openWB-mqttsmarthomecust")
client.on_connect = on_connect
client.on_message = on_message
startTime = time.time()
diff --git a/packages/modules/smarthome/mqtt/watt.py b/packages/modules/smarthome/mqtt/watt.py
index 304b000423..44fd4eed70 100644
--- a/packages/modules/smarthome/mqtt/watt.py
+++ b/packages/modules/smarthome/mqtt/watt.py
@@ -50,7 +50,7 @@ def on_message(client, userdata, msg) -> None:
devicenumber = int(sys.argv[1])
ipadr = str(sys.argv[2])
uberschuss = int(sys.argv[3])
-client = mqtt.Client("openWB-mqttsmarthomecust" + str(devicenumber))
+client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, client_id="openWB-mqttsmarthomecust" + str(devicenumber))
client.on_connect = on_connect
client.on_message = on_message
startTime = time.time()
diff --git a/packages/modules/smarthome/nibe/watt.py b/packages/modules/smarthome/nibe/watt.py
index d723965d22..75fcff6731 100644
--- a/packages/modules/smarthome/nibe/watt.py
+++ b/packages/modules/smarthome/nibe/watt.py
@@ -1,7 +1,7 @@
#!/usr/bin/python3
import sys
import json
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
# get variables from arguments
devicenumber = str(sys.argv[1]) # SmartHome device number
@@ -18,10 +18,10 @@
CurrentPowerRegisterAddress = 2166 # register for current power reading
# need to specify framer to enable RTUoverTCP
-client = ModbusTcpClient(SERVER_HOST, SERVER_PORT)
+client = ModbusTcpClient(SERVER_HOST, port=SERVER_PORT)
# Aktueller Verbrauch
-resp = client.read_input_registers(CurrentPowerRegisterAddress, 1, unit=1)
+resp = client.read_input_registers(CurrentPowerRegisterAddress, count=1, device_id=1)
if resp and hasattr(resp, "registers"):
CurrentPower = resp.registers[0] # Get the first register value
diff --git a/packages/modules/smarthome/nxdacxx/off.py b/packages/modules/smarthome/nxdacxx/off.py
index e2ef124ac9..dc3b23cffd 100644
--- a/packages/modules/smarthome/nxdacxx/off.py
+++ b/packages/modules/smarthome/nxdacxx/off.py
@@ -2,7 +2,7 @@
import sys
import os
import logging
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
log = logging.getLogger("DAC")
bp = '/var/www/html/openWB/ramdisk/smarthome_device_'
@@ -19,7 +19,7 @@
if dactyp == 2:
client = ModbusTcpClient(ipadr, port=port)
# DO1 ausschalten um SGready zu sperren
- rq = client.write_coil(0, False, unit=1)
+ rq = client.write_coil(0, False, device_id=1)
pvmodus = 0
if os.path.isfile(file_stringpv):
with open(file_stringpv, 'r') as f:
diff --git a/packages/modules/smarthome/nxdacxx/on.py b/packages/modules/smarthome/nxdacxx/on.py
index 2d9318c690..531945040b 100644
--- a/packages/modules/smarthome/nxdacxx/on.py
+++ b/packages/modules/smarthome/nxdacxx/on.py
@@ -1,7 +1,7 @@
#!/usr/bin/python3
import sys
import logging
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
log = logging.getLogger("DAC")
bp = '/var/www/html/openWB/ramdisk/smarthome_device_'
@@ -18,7 +18,7 @@
if dactyp == 2:
client = ModbusTcpClient(ipadr, port=port)
# DO1 einschalten um SGready zu aktivieren
- rq = client.write_coil(0, True, unit=1)
+ rq = client.write_coil(0, True, device_id=1)
pvmodus = 1
with open(file_stringpv, 'w') as f:
f.write(str(pvmodus))
diff --git a/packages/modules/smarthome/nxdacxx/watt.py b/packages/modules/smarthome/nxdacxx/watt.py
index d4fadbb9c7..62a695bbf5 100644
--- a/packages/modules/smarthome/nxdacxx/watt.py
+++ b/packages/modules/smarthome/nxdacxx/watt.py
@@ -1,7 +1,7 @@
#!/usr/bin/python3
import sys
import os
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import logging
from smarthome.smartret import writeret
@@ -86,23 +86,23 @@
if dactyp == 0:
# 10 Volts are 1000
ausgabe = int((neupower * 1000) / maxpower)
- rq = client.write_register(1, ausgabe, unit=1)
+ rq = client.write_register(1, ausgabe, device_id=1)
elif dactyp == 1:
# 10 Volts are 4000
ausgabe = int((neupower * 4000) / maxpower)
- rq = client.write_register(0x01f4, ausgabe, unit=1)
+ rq = client.write_register(0x01f4, ausgabe, device_id=1)
elif dactyp == 2:
ausgabe = int((neupower * 4095) / maxpower)
if ausgabe < 370:
ausgabe = 370
# ausgabe nicht kleiner 0,9V sonst Leistungsregelung der WP aus
- rq = client.write_register(0, ausgabe, unit=1)
+ rq = client.write_register(0, ausgabe, device_id=1)
elif dactyp == 3:
ausgabe = int(((neupower * (4095-820)) / maxpower)+820)
if ausgabe <= 820:
ausgabe = 0
# ausgabe nicht kleiner 4ma sonst Leistungsregelung der WP aus
- rq = client.write_register(0x01f4, ausgabe, unit=1)
+ rq = client.write_register(0x01f4, ausgabe, device_id=1)
else:
pass
if count1 < 3:
diff --git a/packages/modules/smarthome/ratiotherm/watt.py b/packages/modules/smarthome/ratiotherm/watt.py
index e993f7d7bd..018af396a1 100644
--- a/packages/modules/smarthome/ratiotherm/watt.py
+++ b/packages/modules/smarthome/ratiotherm/watt.py
@@ -1,8 +1,8 @@
#!/usr/bin/python3
import sys
import os
-from pymodbus.payload import BinaryPayloadBuilder, Endian
-from pymodbus.client.sync import ModbusTcpClient
+from modules.common.pymodbus_compat import BinaryPayloadBuilder, Endian
+from pymodbus.client import ModbusTcpClient
import logging
from smarthome.smartret import writeret
@@ -82,7 +82,7 @@
builder.add_16bit_int(neupower)
pay = builder.to_registers()
client = ModbusTcpClient(ipadr, port=502)
- client.write_register(100, pay[0], unit=1)
+ client.write_register(100, pay[0], device_id=1)
if count1 < 3:
log.info(" watt devicenr %d ipadr %s written %6d %#4X"
% (devicenumber, ipadr, pay[0], pay[0]))
diff --git a/packages/modules/smarthome/stiebel/off.py b/packages/modules/smarthome/stiebel/off.py
index 2c726b1dec..067b491cf2 100644
--- a/packages/modules/smarthome/stiebel/off.py
+++ b/packages/modules/smarthome/stiebel/off.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
import sys
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import logging
log = logging.getLogger("stiebel")
@@ -12,7 +12,7 @@
log.info('off devicenr %d ipadr %s ueberschuss %6d try to connect (modbus)' % (devicenumber, ipadr, uberschuss))
client = ModbusTcpClient(ipadr, port=502)
# deactivate switch one (manual 4002)
-rq = client.write_register(4001, 0, unit=1)
+rq = client.write_register(4001, 0, device_id=1)
log.info('off devicenr %d ipadr %s ' % (devicenumber, ipadr))
pvmodus = 0
with open(file_stringpv, 'w') as f:
diff --git a/packages/modules/smarthome/stiebel/on.py b/packages/modules/smarthome/stiebel/on.py
index 82c9a9d6d0..65af4d6b75 100644
--- a/packages/modules/smarthome/stiebel/on.py
+++ b/packages/modules/smarthome/stiebel/on.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
import sys
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import logging
log = logging.getLogger("stiebel")
@@ -12,7 +12,7 @@
log.info('on devicenr %d ipadr %s ueberschuss %6d try to connect (modbus)' % (devicenumber, ipadr, uberschuss))
client = ModbusTcpClient(ipadr, port=502)
# activate switch one (manual 4002)
-rq = client.write_register(4001, 1, unit=1)
+rq = client.write_register(4001, 1, device_id=1)
log.info('on devicenr %d ipadr %s ' % (devicenumber, ipadr))
with open(file_stringpv, 'w') as f:
f.write(str(1))
diff --git a/packages/modules/smarthome/vampair/off.py b/packages/modules/smarthome/vampair/off.py
index 3b05b8b520..341b496cce 100644
--- a/packages/modules/smarthome/vampair/off.py
+++ b/packages/modules/smarthome/vampair/off.py
@@ -4,7 +4,7 @@
import time
import struct
import codecs
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import logging
log = logging.getLogger(__name__)
@@ -29,7 +29,7 @@
% (time_string, devicenumber, ipadr, uberschuss), file=f)
client = ModbusTcpClient(ipadr, port=502)
start = 2322
-resp = client.read_input_registers(start, 2, unit=1)
+resp = client.read_input_registers(start, count=2, device_id=1)
value1 = resp.registers[0]
all = format(value1, '04x')
aktpower = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0])
diff --git a/packages/modules/smarthome/vampair/on.py b/packages/modules/smarthome/vampair/on.py
index b9b851342c..f3625c7a6b 100644
--- a/packages/modules/smarthome/vampair/on.py
+++ b/packages/modules/smarthome/vampair/on.py
@@ -4,7 +4,7 @@
import time
import struct
import codecs
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import logging
log = logging.getLogger(__name__)
@@ -31,7 +31,7 @@
% (time_string, devicenumber, ipadr, uberschuss), file=f)
client = ModbusTcpClient(ipadr, port=502)
start = 2322
-resp = client.read_input_registers(start, 2, unit=1)
+resp = client.read_input_registers(start, count=2, device_id=1)
value1 = resp.registers[0]
all = format(value1, '04x')
aktpower = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0])
diff --git a/packages/modules/smarthome/vampair/watt.py b/packages/modules/smarthome/vampair/watt.py
index 9607ec18d8..d2b9effe8d 100644
--- a/packages/modules/smarthome/vampair/watt.py
+++ b/packages/modules/smarthome/vampair/watt.py
@@ -5,7 +5,7 @@
import json
import struct
import codecs
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import logging
log = logging.getLogger(__name__)
@@ -48,7 +48,7 @@
# aktuelle Leistung lesen
client = ModbusTcpClient(ipadr, port=502)
start = 2322
- resp = client.read_input_registers(start, 2, unit=1)
+ resp = client.read_input_registers(start, count=2, device_id=1)
value1 = resp.registers[0]
all = format(value1, '04x')
aktpower = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0])
@@ -91,7 +91,7 @@
modbuswrite), file=f)
# modbus write
if modbuswrite == 1:
- client.write_registers(33409, [neupower], unit=1)
+ client.write_registers(33409, [neupower], device_id=1)
if count1 < 3:
with open(file_string, 'a') as f:
log.debug('%s devicenr %s ipadr %s device written by modbus ' %
diff --git a/packages/modules/smarthome/viessmann/off.py b/packages/modules/smarthome/viessmann/off.py
index 5714df4c39..4f1c447479 100644
--- a/packages/modules/smarthome/viessmann/off.py
+++ b/packages/modules/smarthome/viessmann/off.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
import sys
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import logging
log = logging.getLogger(__name__)
@@ -21,7 +21,7 @@
log.debug(f"[Viessmann {devicenumber}] devicenr {devicenumber} ipadr {ipadr} "
f"ueberschuss {uberschuss:6d} try to connect (modbus)")
client = ModbusTcpClient(ipadr, port=502)
-rq = client.write_coil(16, False, unit=1)
+rq = client.write_coil(16, False, device_id=1)
log.debug(f"[Viessmann {devicenumber}] Modbus write_coil response: {rq}")
client.close()
log.debug(
diff --git a/packages/modules/smarthome/viessmann/on.py b/packages/modules/smarthome/viessmann/on.py
index e44ac8692a..c404333666 100644
--- a/packages/modules/smarthome/viessmann/on.py
+++ b/packages/modules/smarthome/viessmann/on.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
import sys
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client import ModbusTcpClient
import logging
log = logging.getLogger(__name__)
@@ -24,7 +24,7 @@
f"[Viessmann {devicenumber}] devicenr {devicenumber} ipadr {ipadr} "
f"ueberschuss {uberschuss:6d} try to connect (modbus)")
client = ModbusTcpClient(ipadr, port=502)
-rq = client.write_coil(16, True, unit=1)
+rq = client.write_coil(16, True, device_id=1)
log.debug(f"[Viessmann {devicenumber}] Modbus write_coil response: {rq}")
client.close()
log.debug(
diff --git a/packages/modules/smarthome/we514/watt.py b/packages/modules/smarthome/we514/watt.py
index f9d3afe00e..833a8b5005 100644
--- a/packages/modules/smarthome/we514/watt.py
+++ b/packages/modules/smarthome/we514/watt.py
@@ -1,8 +1,8 @@
#!/usr/bin/python3
import sys
import json
-from pymodbus.transaction import ModbusRtuFramer
-from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.framer import FramerType
+from pymodbus.client import ModbusTcpClient
# get variables from arguments
devicenumber = str(sys.argv[1]) # SmartHome device number
@@ -23,14 +23,14 @@
# need to specify framer to enable RTUoverTCP
-client = ModbusTcpClient(SERVER_HOST, SERVER_PORT, framer=ModbusRtuFramer)
+client = ModbusTcpClient(SERVER_HOST, port=SERVER_PORT, framer=FramerType.RTU)
# KWH Total Import
-resp = client.read_holding_registers(TotalEnergyRegisterAddress, 1, unit=MODBUS_DEVICEID)
+resp = client.read_holding_registers(TotalEnergyRegisterAddress, count=1, device_id=MODBUS_DEVICEID)
TotalEnergy = int(resp.registers[0]) * 10 # Value is in 0.01kWh, need to convert to Wh
# Aktueller Verbrauch
-resp = client.read_holding_registers(CurrentPowerRegisterAddress, 1, unit=MODBUS_DEVICEID)
+resp = client.read_holding_registers(CurrentPowerRegisterAddress, count=1, device_id=MODBUS_DEVICEID)
CurrentPower = int(resp.registers[0])
answer = {"power": CurrentPower, "powerc": TotalEnergy}
diff --git a/packages/modules/vehicles/ovms/api.py b/packages/modules/vehicles/ovms/api.py
index cdd530d5c0..ac2c1a80a6 100755
--- a/packages/modules/vehicles/ovms/api.py
+++ b/packages/modules/vehicles/ovms/api.py
@@ -4,7 +4,7 @@
from typing import Union
from asyncio import new_event_loop, set_event_loop
from time import mktime
-from datetime import datetime
+from datetime import datetime, timezone
from json import loads, dumps
from modules.vehicles.ovms.config import OVMS
from helpermodules.pub import Pub
@@ -34,7 +34,7 @@ def write_config(topic: str, config: dict):
def utc2local(utc):
epoch = mktime(utc.timetuple())
- offset = datetime.fromtimestamp(epoch) - datetime.utcfromtimestamp(epoch)
+ offset = datetime.fromtimestamp(epoch) - datetime.fromtimestamp(epoch, tz=timezone.utc).replace(tzinfo=None)
return utc + offset
diff --git a/packages/modules/vehicles/tronity/api.py b/packages/modules/vehicles/tronity/api.py
index 8696a12a05..590bbe478e 100644
--- a/packages/modules/vehicles/tronity/api.py
+++ b/packages/modules/vehicles/tronity/api.py
@@ -8,7 +8,7 @@
from modules.common.abstract_vehicle import VehicleUpdateData
from modules.vehicles.tronity.config import TronityVehicleSocConfiguration, TronityVehicleSoc
from modules.common.component_state import CarState
-from datetime import datetime
+from datetime import datetime, timezone
log = logging.getLogger(__name__)
@@ -29,7 +29,7 @@ def is_token_valid(access_token: str) -> bool:
log.debug("Found Token: %s", access_token)
decoded_data = jwt.decode(jwt=access_token, verify=False, algorithms=['HS256'], options={"verify_signature": False})
- if datetime.utcfromtimestamp(decoded_data['exp']) < datetime.utcnow():
+ if datetime.fromtimestamp(decoded_data['exp'], tz=timezone.utc) < datetime.now(timezone.utc):
log.debug("Token expired: %s", decoded_data)
return False
else:
diff --git a/packages/modules/vehicles/vwgroup/vwgroup.py b/packages/modules/vehicles/vwgroup/vwgroup.py
index 35a92d0d94..d857bceddf 100644
--- a/packages/modules/vehicles/vwgroup/vwgroup.py
+++ b/packages/modules/vehicles/vwgroup/vwgroup.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-from datetime import datetime
+from datetime import datetime, timezone
from json import dumps
import logging
from time import mktime, time
@@ -32,7 +32,7 @@ def __init__(self, conf, vehicle):
# convert utc timestamp to local time
def utc2local(self, utc):
epoch = mktime(utc.timetuple())
- offset = datetime.fromtimestamp(epoch) - datetime.utcfromtimestamp(epoch)
+ offset = datetime.fromtimestamp(epoch) - datetime.fromtimestamp(epoch, tz=timezone.utc).replace(tzinfo=None)
return utc + offset
# async method, called from sync fetch_soc, required because libvwid/libskoda expect async environment
diff --git a/packages/smarthome/smartcommon.py b/packages/smarthome/smartcommon.py
index 7b6d958a41..397e99ac49 100644
--- a/packages/smarthome/smartcommon.py
+++ b/packages/smarthome/smartcommon.py
@@ -205,7 +205,7 @@ def pub(client: mqtt.Client, key: str, value: str) -> None:
def sendmq(mqtt_input: Dict[str, str]) -> None:
global mqtt_cache
- client = mqtt.Client("openWB-SmartHome-bulkpublisher-" + str(os.getpid()))
+ client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, client_id="openWB-SmartHome-bulkpublisher-" + str(os.getpid()))
client.connect("localhost", mqttport)
for key, value in mqtt_input.items():
valueold = mqtt_cache.get(key, 'not in cache')
@@ -233,7 +233,7 @@ def update_devices() -> None:
global parammqtt
global mydevices
global mqtt_cache
- client = mqtt.Client("openWB-SmartHome-bulkpublisher-" + str(os.getpid()))
+ client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, client_id="openWB-SmartHome-bulkpublisher-" + str(os.getpid()))
client.connect("localhost", mqttport)
# statische daten einschaltgruppe
Sbase.ausdevices = 0
@@ -347,7 +347,7 @@ def readmq() -> None:
with open(bp+'/ramdisk/smartparam.sh', 'w') as f:
print('%s' % ('#!/bin/bash'), file=f)
parammqtt = []
- client = mqtt.Client("openWB-mqttsmarthome")
+ client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, client_id="openWB-mqttsmarthome")
client.on_connect = on_connect
client.on_message = on_message
startTime = time.time()
diff --git a/packages/tools/modbus_finder.py b/packages/tools/modbus_finder.py
index a2de5e2016..d167f5634b 100644
--- a/packages/tools/modbus_finder.py
+++ b/packages/tools/modbus_finder.py
@@ -3,7 +3,7 @@
from typing import Callable
import pymodbus
-from pymodbus.constants import Endian
+from modules.common.pymodbus_compat import Endian
import sys
sys.path.append("/var/www/html/openWB/packages")
@@ -53,12 +53,12 @@ def try_read(function: Callable, **kwargs) -> str:
print("Address;INT_16;UINT_16;INT_32;UINT_32")
for address in range(start, end):
- resp_INT_16 = try_read(function, address=address, types=modbus.ModbusDataType.INT_16, unit=slave_id)
- resp_UINT_16 = try_read(function, address=address, types=modbus.ModbusDataType.UINT_16, unit=slave_id)
+ resp_INT_16 = try_read(function, address=address, types=modbus.ModbusDataType.INT_16, device_id=slave_id)
+ resp_UINT_16 = try_read(function, address=address, types=modbus.ModbusDataType.UINT_16, device_id=slave_id)
resp_INT_32 = try_read(function, address=address, types=modbus.ModbusDataType.INT_32, wordorder=Endian.Little,
- unit=slave_id)
+ device_id=slave_id)
resp_UINT_32 = try_read(function, address=address, types=modbus.ModbusDataType.UINT_32, wordorder=Endian.Little,
- unit=slave_id)
+ device_id=slave_id)
print(f"{address};{resp_INT_16};{resp_UINT_16};{resp_INT_32};{resp_UINT_32}")
except Exception as e:
print("Exception " + str(e))
diff --git a/packages/tools/modbus_tester.py b/packages/tools/modbus_tester.py
index f32a993cc2..4cb85e6ef7 100644
--- a/packages/tools/modbus_tester.py
+++ b/packages/tools/modbus_tester.py
@@ -30,14 +30,14 @@
client = modbus.ModbusTcpClient_(host, port=port)
if func == 4:
if length > 1:
- resp = client.read_input_registers(start, [modbus.ModbusDataType[data_type]]*length, unit=slave_id)
+ resp = client.read_input_registers(start, [modbus.ModbusDataType[data_type]]*length, device_id=slave_id)
else:
- resp = client.read_input_registers(start, modbus.ModbusDataType[data_type], unit=slave_id)
+ resp = client.read_input_registers(start, modbus.ModbusDataType[data_type], device_id=slave_id)
elif func == 3:
if length > 1:
- resp = client.read_holding_registers(start, [modbus.ModbusDataType[data_type]]*length, unit=slave_id)
+ resp = client.read_holding_registers(start, [modbus.ModbusDataType[data_type]]*length, device_id=slave_id)
else:
- resp = client.read_holding_registers(start, modbus.ModbusDataType[data_type], unit=slave_id)
+ resp = client.read_holding_registers(start, modbus.ModbusDataType[data_type], device_id=slave_id)
else:
print("unsupported function code: " + str(func))
exit(1)
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 0000000000..68aa87452a
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,2 @@
+pytest>=9.0.3
+requests-mock>=1.12.1
diff --git a/requirements.txt b/requirements.txt
index d3f1163050..dd1619fd4d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,27 +1,23 @@
-# don't update python distribution packages in here
-typing-extensions==4.13.2
-jq==1.1.3
-paho_mqtt==1.6.1
-pymodbus==2.5.2
-pytest==6.2.5
-requests_mock==1.9.3
-lxml==4.9.1
-aiohttp==3.13.4
-schedule==1.1.0
-PyJWT==2.12.0
-bs4==0.0.1
-pkce==1.0.3
-evdev==1.5.0
-cryptography==46.0.6
-msal==1.33.0
-python-dateutil==2.8.2
-umodbus==1.0.4
-pysmb==1.2.9.1
-pytz==2023.3.post1
-grpcio==1.60.1
-protobuf==5.29.6
-ocpp==1.0.0
-websockets==12.0
-pycarwings3==0.7.14
-asyncio==3.4.3
-passlib==1.7.4
+typing-extensions>=4.15.0
+jq>=1.11.0
+paho-mqtt>=2.1.0
+pymodbus>=3.13.0
+lxml>=6.1.0
+aiohttp>=3.13.5
+schedule>=1.2.2
+PyJWT>=2.12.1
+bs4>=0.0.2
+pkce>=1.0.3
+cryptography>=47.0.0
+msal>=1.36.0
+python-dateutil>=2.9.0
+umodbus>=1.0.4
+pysmb>=1.2.13
+pytz>=2026.1
+grpcio>=1.80.0
+protobuf>=7.34.1
+ocpp>=2.1.0
+websockets>=16.0
+pycarwings3>=0.7.14
+passlib>=1.7.4
+evdev>=1.9.3
diff --git a/runs/atreboot.sh b/runs/atreboot.sh
index 8166249e82..dd878c10ef 100755
--- a/runs/atreboot.sh
+++ b/runs/atreboot.sh
@@ -1,5 +1,7 @@
#!/bin/bash
OPENWBBASEDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
+source "${OPENWBBASEDIR}/runs/platform_detect.sh"
+detect_platform
hasInet=0
# setup log file
@@ -8,19 +10,6 @@ touch "$LOGFILE"
chmod 666 "$LOGFILE"
{
- versionMatch() {
- file=$1
- target=$2
- currentVersion=$(grep -o "openwb-version:[0-9]\+" "$file" | grep -o "[0-9]\+$")
- installedVersion=$(sudo grep -o "openwb-version:[0-9]\+" "$target" | grep -o "[0-9]\+$")
- # echo "$currentVersion == $installedVersion ?"
- if ((currentVersion == installedVersion)); then
- return 0
- else
- return 1
- fi
- }
-
if ! id -u openwb >/dev/null 2>&1; then
echo "user 'openwb' missing"
echo "starting upgrade script..."
@@ -72,18 +61,22 @@ chmod 666 "$LOGFILE"
boot_config_source="${OPENWBBASEDIR}/data/config/boot_config.txt"
boot_config_target="/boot/config.txt"
- echo "checking init in $boot_config_target..."
- if versionMatch "$boot_config_source" "$boot_config_target"; then
- echo "already up to date"
+ if [ "$PLATFORM_IS_RPI" = true ]; then
+ echo "checking init in $boot_config_target..."
+ if versionMatch "$boot_config_source" "$boot_config_target"; then
+ echo "already up to date"
+ else
+ echo "openwb section not found or outdated"
+ pattern_begin=$(grep -m 1 '#' "$boot_config_source")
+ pattern_end=$(grep '#' "$boot_config_source" | tail -n 1)
+ sudo sed -i "/$pattern_begin/,/$pattern_end/d" "$boot_config_target"
+ echo "adding init to $boot_config_target..."
+ sudo tee -a "$boot_config_target" <"$boot_config_source" >/dev/null
+ echo "done"
+ sudo reboot now
+ fi
else
- echo "openwb section not found or outdated"
- pattern_begin=$(grep -m 1 '#' "$boot_config_source")
- pattern_end=$(grep '#' "$boot_config_source" | tail -n 1)
- sudo sed -i "/$pattern_begin/,/$pattern_end/d" "$boot_config_target"
- echo "adding init to $boot_config_target..."
- sudo tee -a "$boot_config_target" <"$boot_config_source" >/dev/null
- echo "done"
- sudo reboot now
+ echo "not a Raspberry Pi, skipping boot config"
fi
ramdisk_config_source="${OPENWBBASEDIR}/data/config/ramdisk_config.txt"
@@ -126,14 +119,14 @@ chmod 666 "$LOGFILE"
echo -n "Final group membership: "
groups openwb
- # allow apache to restart some services
- echo "Apache service restart permissions..."
- if versionMatch "${OPENWBBASEDIR}/data/config/sudoers/apache2" "/etc/sudoers.d/apache2"; then
- echo "apache2 sudoers already up to date"
+ # allow caddy to restart some services
+ echo "Caddy service restart permissions..."
+ if versionMatch "${OPENWBBASEDIR}/data/config/sudoers/caddy" "/etc/sudoers.d/caddy"; then
+ echo "caddy sudoers already up to date"
else
- echo "updating apache2 sudoers"
- sudo cp "${OPENWBBASEDIR}/data/config/sudoers/apache2" "/etc/sudoers.d/apache2"
- sudo chmod 440 /etc/sudoers.d/apache2
+ echo "updating caddy sudoers"
+ sudo cp "${OPENWBBASEDIR}/data/config/sudoers/caddy" "/etc/sudoers.d/caddy"
+ sudo chmod 440 /etc/sudoers.d/caddy
fi
# network setup
@@ -148,6 +141,35 @@ chmod 666 "$LOGFILE"
echo "#### continue anyway..."
fi
+ # run stack upgrade (Python, Caddy, PHP-FPM, Chrony, etc.)
+ # idempotent - only changes what's needed
+ echo "Checking for stack upgrades..."
+ if ((hasInet == 1)); then
+ sudo "${OPENWBBASEDIR}/runs/upgrade_stack.sh"
+ else
+ echo "no internet connection, skipping stack upgrade"
+ fi
+
+ # chrony NTP setup
+ echo "NTP time synchronization..."
+ if versionMatch "${OPENWBBASEDIR}/data/config/chrony/chrony.conf" "/etc/chrony/chrony.conf"; then
+ echo "chrony config already up to date"
+ else
+ echo "configuring chrony NTP..."
+ sudo systemctl stop systemd-timesyncd 2>/dev/null || true
+ sudo systemctl disable systemd-timesyncd 2>/dev/null || true
+ sudo cp "${OPENWBBASEDIR}/data/config/chrony/chrony.conf" /etc/chrony/chrony.conf
+ sudo systemctl enable chrony
+ sudo systemctl restart chrony
+ echo "chrony configured"
+ fi
+
+ # MOTD setup
+ echo "MOTD setup..."
+ sudo cp "${OPENWBBASEDIR}/data/config/profile.d/99-openwb-motd.sh" /etc/profile.d/99-openwb-motd.sh
+ sudo chmod 755 /etc/profile.d/99-openwb-motd.sh
+ echo "done"
+
# tune apt configuration and install required packages
if [ -d "/etc/apt/apt.conf.d" ]; then
if versionMatch "${OPENWBBASEDIR}/data/config/apt/99openwb" "/etc/apt/apt.conf.d/99openwb"; then
@@ -160,8 +182,8 @@ chmod 666 "$LOGFILE"
echo "path '/etc/apt/apt.conf.d' is missing! unsupported system!"
fi
if ((hasInet == 1)); then
- # remove urllib3 version to avoid conflicts
- pip uninstall urllib3 -y
+ echo "ensuring python virtual environment..."
+ ensure_venv "$PLATFORM_VENV"
"${OPENWBBASEDIR}/runs/install_packages.sh"
else
echo "no internet connection, skipping package installation"
@@ -241,7 +263,7 @@ chmod 666 "$LOGFILE"
# detect connected displays
# set default to "true" as fallback if "tvservice" is missing
displayDetected="true"
- if which tvservice >/dev/null; then
+ if [ "$PLATFORM_IS_RPI" = true ] && which tvservice >/dev/null; then
echo "detected 'tvservice', query for connected displays"
output=$(tvservice -l)
echo "$output"
@@ -251,8 +273,11 @@ chmod 666 "$LOGFILE"
else
echo "detected HDMI or LCD display(s)"
fi
+ elif [ "$PLATFORM_VIRT" != "none" ]; then
+ echo "virtualized environment detected, no physical display"
+ displayDetected="false"
else
- echo "'tvservice' not found, assuming a display is present"
+ echo "no tvservice, assuming a display is present"
fi
echo "displayDetected: $displayDetected"
forceDisplaySetup=0
@@ -303,8 +328,8 @@ chmod 666 "$LOGFILE"
"${OPENWBBASEDIR}/runs/update_local_display.sh" $forceDisplaySetup
fi
- # check apache configuration
- "${OPENWBBASEDIR}/runs/setup_apache2.sh"
+ # check caddy configuration
+ "${OPENWBBASEDIR}/runs/setup_caddy.sh"
# check for mosquitto configuration
"${OPENWBBASEDIR}/runs/setup_mosquitto.sh" 1
@@ -316,12 +341,12 @@ chmod 666 "$LOGFILE"
# check for python dependencies
if ((hasInet == 1)); then
- echo "install required python packages with 'pip3'..."
- if pip3 install --only-binary :all: -r "${OPENWBBASEDIR}/requirements.txt"; then
+ echo "install required python packages into venv..."
+ if $PLATFORM_VENV/bin/python3 -m pip install --only-binary :all: -r "${OPENWBBASEDIR}/requirements.txt"; then
echo "done"
else
echo "failed!"
- message="Bei der Installation der benötigten Python-Bibliotheken ist ein Fehler aufgetreten! Bitte die Logdateien prüfen."
+ message="Bei der Installation der benoetigten Python-Bibliotheken ist ein Fehler aufgetreten! Bitte die Logdateien pruefen."
payload=$(printf '{"source": "system", "type": "danger", "message": "%s", "timestamp": %d}' "$message" "$(date +"%s")")
mosquitto_pub -p 1886 -t "openWB/system/messages/$(date +"%s%3N")" -r -m "$payload"
fi
@@ -340,8 +365,8 @@ chmod 666 "$LOGFILE"
echo "no internet connection, skipping version update"
fi
- # set restore dir permissions to allow file upload for apache
- sudo chgrp -R www-data "${OPENWBBASEDIR}/data/restore/." "${OPENWBBASEDIR}/data/data_migration/."
+ # set restore dir permissions to allow file upload for caddy
+ sudo chgrp -R caddy "${OPENWBBASEDIR}/data/restore/." "${OPENWBBASEDIR}/data/data_migration/."
sudo chmod -R g+w "${OPENWBBASEDIR}/data/restore/." "${OPENWBBASEDIR}/data/data_migration/."
# cleanup some folders
diff --git a/runs/backup.sh b/runs/backup.sh
index e7453cbf58..5ba7952d7a 100755
--- a/runs/backup.sh
+++ b/runs/backup.sh
@@ -298,7 +298,7 @@ create_archive() {
fix_permissions() {
echo "setting permissions of new backup file"
- sudo chown openwb:www-data "$BACKUPFILE$FILENAMESUFFIX"
+ sudo chown openwb:caddy "$BACKUPFILE$FILENAMESUFFIX"
sudo chmod 664 "$BACKUPFILE$FILENAMESUFFIX"
}
diff --git a/runs/evse_read_modbus.py b/runs/evse_read_modbus.py
index e513dd6ab8..d736d4fcb5 100644
--- a/runs/evse_read_modbus.py
+++ b/runs/evse_read_modbus.py
@@ -15,4 +15,4 @@
num = int(sys.argv[3])
client = ModbusSerialClient_(str(list(Path("/dev/serial/by-path").glob("*"))[0].resolve()))
-print(client.read_holding_registers(register, [ModbusDataType.INT_16]*num, unit=unit))
+print(client.read_holding_registers(register, [ModbusDataType.INT_16]*num, device_id=unit))
diff --git a/runs/evse_write_modbus.py b/runs/evse_write_modbus.py
index 16f2446618..1f0a31e461 100644
--- a/runs/evse_write_modbus.py
+++ b/runs/evse_write_modbus.py
@@ -15,4 +15,4 @@
value = int(sys.argv[3])
client = ModbusSerialClient_(str(list(Path("/dev/serial/by-path").glob("*"))[0].resolve()))
-client.write_register(register, value, unit=unit)
+client.write_register(register, value, device_id=unit)
diff --git a/runs/evsewritembusdev.py b/runs/evsewritembusdev.py
index 7a5bbfee58..8322d9ae73 100644
--- a/runs/evsewritembusdev.py
+++ b/runs/evsewritembusdev.py
@@ -1,11 +1,11 @@
#!/usr/bin/python3
import sys
-from pymodbus.client.sync import ModbusSerialClient
+from pymodbus.client import ModbusSerialClient
seradd = str(sys.argv[1])
evseid = int(sys.argv[2])
wreg = int(sys.argv[3])
val = int(sys.argv[4])
-client = ModbusSerialClient(method="rtu", port=seradd, baudrate=9600, stopbits=1, bytesize=8, timeout=1)
-rq = client.write_registers(wreg, val, unit=evseid)
+client = ModbusSerialClient(seradd, baudrate=9600, stopbits=1, bytesize=8, timeout=1)
+rq = client.write_registers(wreg, val, device_id=evseid)
diff --git a/runs/install_packages.sh b/runs/install_packages.sh
index f16ed31182..15d255831b 100755
--- a/runs/install_packages.sh
+++ b/runs/install_packages.sh
@@ -1,25 +1,47 @@
#!/bin/bash
+OPENWBBASEDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
+source "${OPENWBBASEDIR}/runs/platform_detect.sh"
+detect_platform
+
+echo "=== Platform Detection ==="
+echo " Architecture: $PLATFORM_ARCH ($PLATFORM_KERNEL)"
+echo " Debian: $PLATFORM_DEBIAN_VERSION ($PLATFORM_DEBIAN_CODENAME)"
+echo " Virtualization: $PLATFORM_VIRT"
+echo " Raspberry Pi: $PLATFORM_IS_RPI"
+echo " 64-bit: $PLATFORM_IS_64BIT"
+echo "==========================="
+
echo "add required repositories..."
-# add mosquitto repository
if [ ! -f /etc/apt/sources.list.d/mosquitto.list ]; then
sudo apt-get -q -y install wget apt-transport-https
sudo wget -q https://repo.mosquitto.org/debian/mosquitto-repo.gpg -O /etc/apt/trusted.gpg.d/mosquitto-repo.gpg
- # get installed debian version
- . /etc/os-release
- sudo wget -q -O /etc/apt/sources.list.d/mosquitto.list "https://repo.mosquitto.org/debian/mosquitto-${VERSION_CODENAME}.list"
+ sudo wget -q -O /etc/apt/sources.list.d/mosquitto.list \
+ "https://repo.mosquitto.org/debian/mosquitto-${PLATFORM_DEBIAN_CODENAME}.list"
fi
echo "done"
echo "install required packages with 'apt-get'..."
sudo apt-get -q update
-sudo apt-get -q -y install \
- vim bc jq curl socat sshpass sudo ssl-cert mmc-utils inotify-tools iptables \
- apache2 libapache2-mod-php \
- php php-gd php-curl php-xml php-json \
- git \
- mosquitto mosquitto-clients \
- python3-pip \
- python3-urllib3 \
- xserver-xorg x11-xserver-utils openbox-lxde-session lightdm lightdm-autologin-greeter accountsservice \
- chromium chromium-l10n
+
+COMMON_PACKAGES=(
+ vim bc jq curl socat sshpass sudo ssl-cert inotify-tools iptables
+ caddy php-fpm
+ php php-gd php-curl php-xml php-json
+ git
+ mosquitto mosquitto-clients
+ python3 python3-venv python3-dev gcc linux-headers-$(uname -r)
+ chrony
+)
+
+if [ "$PLATFORM_IS_RPI" = true ]; then
+ COMMON_PACKAGES+=(mmc-utils)
+fi
+
+sudo apt-get -q -y install "${COMMON_PACKAGES[@]}"
+echo "base packages done"
+
+platform_install_rpi_packages
+
+platform_install_gui_packages
+
echo "done"
diff --git a/runs/platform_detect.sh b/runs/platform_detect.sh
new file mode 100644
index 0000000000..568abe52fa
--- /dev/null
+++ b/runs/platform_detect.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+detect_platform() {
+ PLATFORM_ARCH=$(dpkg --print-architecture 2>/dev/null || echo "unknown")
+ PLATFORM_KERNEL=$(uname -m)
+ PLATFORM_VIRT="none"
+ PLATFORM_IS_RPI=false
+ PLATFORM_IS_64BIT=false
+ PLATFORM_DEBIAN_VERSION=""
+ PLATFORM_DEBIAN_CODENAME=""
+
+ if [ -f /etc/os-release ]; then
+ . /etc/os-release
+ PLATFORM_DEBIAN_VERSION="${VERSION_ID:-unknown}"
+ PLATFORM_DEBIAN_CODENAME="${VERSION_CODENAME:-unknown}"
+ fi
+
+ if command -v systemd-detect-virt >/dev/null 2>&1; then
+ PLATFORM_VIRT=$(systemd-detect-virt 2>/dev/null || echo "none")
+ fi
+
+ if [ -f /proc/device-tree/model ]; then
+ local model
+ model=$(tr -d '\0' < /proc/device-tree/model 2>/dev/null)
+ case "$model" in
+ *Raspberry*Pi* | *RPI*)
+ PLATFORM_IS_RPI=true
+ ;;
+ esac
+ fi
+
+ case "$PLATFORM_KERNEL" in
+ x86_64 | aarch64)
+ PLATFORM_IS_64BIT=true
+ ;;
+ esac
+
+ PLATFORM_VENV="/opt/openwb-venv"
+}
+
+platform_has_gui() {
+ if [ "$PLATFORM_IS_RPI" = true ] || [ "$PLATFORM_VIRT" = "none" ]; then
+ return 0
+ fi
+ return 1
+}
+
+platform_install_gui_packages() {
+ if platform_has_gui; then
+ sudo apt-get -q -y install \
+ xserver-xorg x11-xserver-utils openbox-lxde-session lightdm \
+ lightdm-autologin-greeter accountsservice \
+ chromium chromium-l10n 2>/dev/null || \
+ sudo apt-get -q -y install \
+ xserver-xorg x11-xserver-utils openbox-lxde-session lightdm \
+ lightdm-autologin-greeter accountsservice
+ fi
+}
+
+platform_install_rpi_packages() {
+ if [ "$PLATFORM_IS_RPI" = true ]; then
+ echo "Raspberry Pi detected, installing RPi-specific packages..."
+ sudo apt-get -q -y install gpiozero 2>/dev/null || true
+ fi
+}
+
+ensure_venv() {
+ local venv_path="${1:-$PLATFORM_VENV}"
+ if [ ! -f "$venv_path/bin/python3" ]; then
+ echo "Creating Python virtual environment at $venv_path..."
+ sudo python3 -m venv "$venv_path"
+ sudo chown -R openwb:openwb "$venv_path"
+ $venv_path/bin/python3 -m pip install --upgrade pip
+ echo "venv created."
+ else
+ echo "venv already exists at $venv_path."
+ fi
+}
+
+venv_pip() {
+ $PLATFORM_VENV/bin/python3 -m pip "$@"
+}
+
+versionMatch() {
+ local file=$1
+ local target=$2
+ local currentVersion
+ local installedVersion
+ currentVersion=$(grep -o "openwb-version:[0-9]\+" "$file" 2>/dev/null | grep -o "[0-9]\+$")
+ if [ -r "$target" ]; then
+ installedVersion=$(grep -o "openwb-version:[0-9]\+" "$target" 2>/dev/null | grep -o "[0-9]\+$")
+ else
+ installedVersion=$(sudo grep -o "openwb-version:[0-9]\+" "$target" 2>/dev/null | grep -o "[0-9]\+$")
+ fi
+ if [[ -n "$currentVersion" ]] && [[ "$currentVersion" == "$installedVersion" ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
diff --git a/runs/readmodbus.py b/runs/readmodbus.py
index bc865216e9..0579904265 100644
--- a/runs/readmodbus.py
+++ b/runs/readmodbus.py
@@ -1,14 +1,14 @@
#!/usr/bin/env python3
import sys
-from pymodbus.client.sync import ModbusSerialClient
+from pymodbus.client import ModbusSerialClient
seradd = str(sys.argv[1])
modbusid = int(sys.argv[2])
readreg = int(sys.argv[3])
reganzahl = int(sys.argv[4])
-client = ModbusSerialClient(method="rtu", port=seradd, baudrate=9600, stopbits=1, bytesize=8, timeout=1)
-request = client.read_holding_registers(readreg, reganzahl, unit=modbusid)
+client = ModbusSerialClient(seradd, baudrate=9600, stopbits=1, bytesize=8, timeout=1)
+request = client.read_holding_registers(readreg, count=reganzahl, device_id=modbusid)
if request.isError():
print('Modbus Error:', request)
else:
diff --git a/runs/remoteSupport/remoteSupport.py b/runs/remoteSupport/remoteSupport.py
index f20ab349b6..65f03ea2b7 100755
--- a/runs/remoteSupport/remoteSupport.py
+++ b/runs/remoteSupport/remoteSupport.py
@@ -222,7 +222,7 @@ def on_message(client: mqtt.Client, userdata, msg: mqtt.MQTTMessage):
signal(SIGTERM, handle_terminate) # Handle SIGTERM from systemctl for graceful shutdown
signal(SIGINT, handle_terminate) # Handle SIGINT from keyboard (Strg+C) for graceful shutdown
lt_executable = get_lt_executable()
-client = mqtt.Client(f"openWB-remote-{get_serial()}-{datetime.today().timestamp()}")
+client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, client_id=f"openWB-remote-{get_serial()}-{datetime.today().timestamp()}")
client.on_connect = on_connect
client.on_message = on_message
client.will_set(STATE_TOPIC, json.dumps("offline"), qos=2, retain=True)
diff --git a/runs/setup_apache2.sh b/runs/setup_apache2.sh
deleted file mode 100755
index d2f84bd4b6..0000000000
--- a/runs/setup_apache2.sh
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/bin/bash
-OPENWBBASEDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
-restartService=0
-
-versionMatch() {
- file=$1
- target=$2
- currentVersion=$(grep -o "openwb-version:[0-9]\+" "$file" | grep -o "[0-9]\+$")
- installedVersion=$(sudo grep -o "openwb-version:[0-9]\+" "$target" | grep -o "[0-9]\+$")
- if ((currentVersion == installedVersion)); then
- return 0
- else
- return 1
- fi
-}
-
-updateFile() {
- file=$1
- target=$2
- if versionMatch "$file" "$target"; then
- echo "$target is up to date"
- else
- sudo cp "$file" "$target"
- restartService=1
- fi
-}
-
-enableModule() {
- module=$1
- if sudo a2query -m "$module" -q; then
- echo "module '$module' already enabled"
- else
- echo "module '$module' currently disabled; enabling module"
- sudo a2enmod "$module"
- restartService=1
- fi
-}
-
-disableModule() {
- module=$1
- if sudo a2query -m "$module" -q; then
- echo "module '$module' currently enabled; disabling module"
- sudo a2dismod "$module"
- restartService=1
- else
- echo "module '$module' already disabled"
- fi
-}
-
-enableSite() {
- site=$1
- if sudo a2query -s "$site" -q; then
- echo "site '$site' already enabled"
- else
- echo "site '$site' currently disabled; enabling site"
- sudo a2ensite "$site"
- restartService=1
- fi
-}
-
-disableSite() {
- site=$1
- if sudo a2query -s "$site" -q; then
- echo "site '$site' currently enabled; disabling site"
- sudo a2dissite "$site"
- restartService=1
- else
- echo "site '$site' already disabled"
- fi
-}
-
-# check apache modules
-echo "checking required apache modules..."
-enableModule headers
-enableModule ssl
-enableModule proxy_wstunnel
-
-# default site (http and https)
-echo "apache default site..."
-updateFile "${OPENWBBASEDIR}/data/config/apache/000-default.conf" "/etc/apache2/sites-available/000-default.conf"
-echo "apache localhost site..."
-updateFile "${OPENWBBASEDIR}/data/config/apache/localhost.conf" "/etc/apache2/sites-available/localhost.conf"
-# ssl sites
-echo "apache redirect ssl site..."
-updateFile "${OPENWBBASEDIR}/data/config/apache/apache-redirect-ssl.conf" "/etc/apache2/sites-available/apache-redirect-ssl.conf"
-echo "apache default ssl site..."
-updateFile "${OPENWBBASEDIR}/data/config/apache/apache-openwb-ssl.conf" "/etc/apache2/sites-available/apache-openwb-ssl.conf"
-# http api site (https only)
-echo "apache http api ssl site..."
-updateFile "${OPENWBBASEDIR}/data/config/apache/http-api-ssl.conf" "/etc/apache2/sites-available/http-api-ssl.conf"
-# proplus site
-echo "apache pro plus site..."
-updateFile "${OPENWBBASEDIR}/data/config/apache/apache-proplus.conf" "/etc/apache2/sites-available/apache-proplus.conf"
-
-# enable localhost site
-enableSite localhost
-# disable apache default ssl site
-disableSite default-ssl
-# enable openwb ssl site
-enableSite apache-openwb-ssl
-# check if unencrypted access is configured
-if allowUnencryptedAccess=$(mosquitto_sub -t "openWB/general/allow_unencrypted_access" -p 1886 -C 1 -W 1 --quiet); then
- echo "got 'allow unencrypted access' setting: '$allowUnencryptedAccess'"
-else
- echo "failed getting 'allow unencrypted access' setting! assuming 'true'"
- allowUnencryptedAccess="true"
-fi
-if [[ $allowUnencryptedAccess == "true" ]]; then
- echo "WARNING: unencrypted access is enabled!"
- disableSite apache-redirect-ssl
- disableModule rewrite
- enableSite 000-default
-else
- echo "unencrypted access is disabled"
- disableSite 000-default
- enableSite apache-redirect-ssl
- enableModule rewrite
-fi
-
-# enable http api ssl site if configured
-if httpApiEnabled=$(mosquitto_sub -t "openWB/general/http_api" -p 1886 -C 1 -W 1 --quiet); then
- echo "got 'http api enabled' setting: '$httpApiEnabled'"
-else
- echo "failed getting 'http api enabled' setting! assuming 'false'"
- httpApiEnabled="false"
-fi
-if [[ $httpApiEnabled == "true" ]]; then
- echo "http api is enabled"
- enableSite http-api-ssl
-else
- echo "http api is disabled"
- disableSite http-api-ssl
-fi
-
-# check for pro+
-echo "Pro+ setup..."
-if lsusb | grep -Eq 'RTL8153|AX88179'; then
- echo "second network for pro plus detected"
- # enable pro+ specific configurations
- enableSite apache-proplus
- enableModule proxy_http
-else
- echo "no second network for pro plus detected"
- # disable all pro+ specific configurations
- disableSite apache-proplus
- disableModule proxy_http
-fi
-
-# restart apache if required
-if ((restartService == 1)); then
- echo -n "restarting apache..."
- sudo systemctl restart apache2
- echo "done"
-else
- echo "apache configuration is already up to date"
-fi
diff --git a/runs/setup_caddy.sh b/runs/setup_caddy.sh
new file mode 100644
index 0000000000..81c4b7104e
--- /dev/null
+++ b/runs/setup_caddy.sh
@@ -0,0 +1,212 @@
+#!/bin/bash
+OPENWBBASEDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
+
+detectPhpFpmSocket() {
+ local sock
+ sock=$(ls /run/php/php*fpm*.sock 2>/dev/null | head -1)
+ if [ -n "$sock" ] && [ -S "$sock" ]; then
+ echo "$sock"
+ return 0
+ fi
+ return 1
+}
+
+PHP_SOCK=$(detectPhpFpmSocket)
+if [ -z "$PHP_SOCK" ]; then
+ echo "WARNING: No PHP-FPM socket found, attempting to start PHP-FPM..."
+ sudo systemctl start php*-fpm 2>/dev/null || true
+ PHP_SOCK=$(detectPhpFpmSocket)
+fi
+
+if [ -z "$PHP_SOCK" ]; then
+ echo "ERROR: PHP-FPM is not running and no socket found. Aborting Caddy setup."
+ exit 1
+fi
+echo "PHP-FPM socket: $PHP_SOCK"
+
+CADDYFILE_SRC="${OPENWBBASEDIR}/data/config/caddy/Caddyfile"
+CADDYFILE_DST="/etc/caddy/Caddyfile"
+CADDYFILE_TMP="${CADDYFILE_DST}.tmp"
+
+if [ ! -f "$CADDYFILE_SRC" ]; then
+ echo "ERROR: Caddyfile template not found at $CADDYFILE_SRC"
+ exit 1
+fi
+
+if allowUnencryptedAccess=$(mosquitto_sub -t "openWB/general/allow_unencrypted_access" -p 1886 -C 1 -W 1 --quiet); then
+ echo "got 'allow unencrypted access' setting: '$allowUnencryptedAccess'"
+else
+ echo "failed getting 'allow unencrypted access' setting! assuming 'true'"
+ allowUnencryptedAccess="true"
+fi
+
+if httpApiEnabled=$(mosquitto_sub -t "openWB/general/http_api" -p 1886 -C 1 -W 1 --quiet); then
+ echo "got 'http api enabled' setting: '$httpApiEnabled'"
+else
+ echo "failed getting 'http api enabled' setting! assuming 'false'"
+ httpApiEnabled="false"
+fi
+
+generate_site_block() {
+ local block_name="$1"
+ echo "${block_name} {"
+ if [[ "$block_name" == ":81" ]]; then
+ echo ' bind 127.0.0.1'
+ fi
+ echo ' root * /var/www/html'
+ if [[ "$block_name" == ":443" || "$block_name" == ":8443" ]]; then
+ echo ' tls /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/private/ssl-cert-snakeoil.key'
+ fi
+ echo " php_fastcgi unix/${PHP_SOCK}"
+ echo ' file_server {'
+ echo ' index index.php index.html'
+ echo ' }'
+ echo ' handle_path /openWB/ramdisk/* {'
+ echo ' root * /var/www/html'
+ echo ' file_server browse'
+ echo ' }'
+ echo ' handle_path /openWB/data/backup/* {'
+ echo ' root * /var/www/html'
+ echo ' file_server browse'
+ echo ' }'
+ echo ' handle /ws* {'
+ echo ' reverse_proxy 127.0.0.1:9003'
+ echo ' }'
+ echo ' handle /mqtt* {'
+ echo ' reverse_proxy 127.0.0.1:9003'
+ echo ' }'
+ echo ' header {'
+ echo ' Cache-Control "no-cache, no-store, must-revalidate"'
+ echo ' Pragma "no-cache"'
+ echo ' Expires 0'
+ echo ' }'
+ echo ' @blocked {'
+ echo ' path *.conf'
+ echo ' path *.ini'
+ echo ' path *.py'
+ echo ' path *.sh'
+ echo ' }'
+ echo ' respond @blocked 404'
+ echo ' @clientJson path /openWB/data/clients/*.json'
+ echo ' respond @clientJson 403'
+ echo ' handle_errors {'
+ echo ' @404 expression {http.error.status_code} == 404'
+ echo ' handle @404 {'
+ echo ' rewrite * /openWB/web/error.html'
+ echo ' file_server'
+ echo ' }'
+ echo ' }'
+ if [[ "$block_name" != ":81" ]]; then
+ local logname
+ case "$block_name" in
+ ":80") logname="access" ;;
+ ":443") logname="ssl-access" ;;
+ *) logname="access" ;;
+ esac
+ echo " log {"
+ echo " output file /var/log/caddy/${logname}.log"
+ echo " }"
+ fi
+ echo '}'
+}
+
+{
+ echo '# openwb-version:'"$(grep -o 'openwb-version:[0-9]\+' "$CADDYFILE_SRC" | head -1 | grep -o '[0-9]\+$')"
+ echo '{'
+ echo ' auto_https off'
+ echo '}'
+ echo ''
+
+ if [[ "$allowUnencryptedAccess" == "true" ]]; then
+ echo "WARNING: unencrypted access is enabled!" >&2
+ generate_site_block ":80"
+ else
+ echo "unencrypted access is disabled" >&2
+ echo ':80 {'
+ echo ' redir https://{host}{uri} permanent'
+ echo '}'
+ fi
+ echo ''
+
+ generate_site_block ":443"
+ echo ''
+
+ generate_site_block ":81"
+ echo ''
+
+ if [[ "$httpApiEnabled" == "true" ]]; then
+ echo "http api is enabled" >&2
+ echo ':8443 {'
+ echo ' root * /var/www/html/openWB/runs/http-api'
+ echo ' tls /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/private/ssl-cert-snakeoil.key'
+ echo " php_fastcgi unix/${PHP_SOCK}"
+ echo ' file_server {'
+ echo ' index index.php index.html'
+ echo ' }'
+ echo ' log {'
+ echo ' output file /var/log/caddy/api-access.log'
+ echo ' }'
+ echo '}'
+ else
+ echo "http api is disabled" >&2
+ fi
+ echo ''
+
+ if lsusb 2>/dev/null | grep -qE 'RTL8153|AX88179'; then
+ echo "second network for pro plus detected" >&2
+ echo ':8080 {'
+ echo ' reverse_proxy 192.168.192.50:80'
+ echo '}'
+ else
+ echo "no second network for pro plus detected" >&2
+ fi
+} | sudo tee "$CADDYFILE_TMP" > /dev/null
+
+NEEDS_RESTART=0
+if [ ! -f "$CADDYFILE_DST" ] || ! diff -q "$CADDYFILE_TMP" "$CADDYFILE_DST" > /dev/null 2>&1; then
+ echo "Caddyfile changed, updating..."
+ sudo mv "$CADDYFILE_TMP" "$CADDYFILE_DST"
+ NEEDS_RESTART=1
+else
+ echo "Caddyfile is up to date"
+ sudo rm -f "$CADDYFILE_TMP"
+fi
+
+echo "checking PHP-FPM upload limit..."
+php_dir=""
+for dir in /etc/php/*/fpm/conf.d; do
+ if [ -d "$dir" ]; then
+ php_dir="$dir"
+ break
+ fi
+done
+if [ -n "$php_dir" ]; then
+ if [ ! -f "${php_dir}/20-uploadlimit.ini" ] || ! diff -q "${OPENWBBASEDIR}/data/config/php/fpm/20-uploadlimit.ini" "${php_dir}/20-uploadlimit.ini" > /dev/null 2>&1; then
+ echo "updating PHP upload limit..."
+ sudo cp "${OPENWBBASEDIR}/data/config/php/fpm/20-uploadlimit.ini" "${php_dir}/20-uploadlimit.ini"
+ sudo systemctl restart php*-fpm 2>/dev/null
+ else
+ echo "PHP upload limit already up to date"
+ fi
+else
+ echo "no PHP-FPM config directory found, skipping"
+fi
+
+sudo usermod -aG ssl-cert caddy 2>/dev/null
+sudo mkdir -p /var/log/caddy
+sudo chown caddy:caddy /var/log/caddy
+
+sudo chmod -R a+rX /var/www/html 2>/dev/null
+
+if [[ "$NEEDS_RESTART" == "1" ]]; then
+ echo -n "validating Caddyfile..."
+ if sudo caddy validate --config "$CADDYFILE_DST" --adapter caddyfile 2>&1; then
+ echo -n "restarting caddy..."
+ sudo systemctl restart caddy
+ echo "done"
+ else
+ echo "ERROR: Caddyfile validation failed, not restarting!"
+ fi
+else
+ echo "caddy configuration is already up to date"
+fi
diff --git a/runs/setup_mosquitto.sh b/runs/setup_mosquitto.sh
index f162cebbaf..38b0943432 100755
--- a/runs/setup_mosquitto.sh
+++ b/runs/setup_mosquitto.sh
@@ -1,20 +1,9 @@
#!/bin/bash
OPENWBBASEDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
+source "${OPENWBBASEDIR}/runs/platform_detect.sh"
USER_MANAGEMENT_INIT_FILE="${OPENWBBASEDIR}/ramdisk/init_user_management"
automaticServiceRestart=${1:-0}
-versionMatch() {
- file=$1
- target=$2
- currentVersion=$(grep -o "openwb-version:[0-9]\+" "$file" | grep -o "[0-9]\+$")
- installedVersion=$(sudo grep -o "openwb-version:[0-9]\+" "$target" | grep -o "[0-9]\+$")
- if ((currentVersion == installedVersion)); then
- return 0
- else
- return 1
- fi
-}
-
waitForServiceStop() {
# this function waits for a service to stop and kills the process if it takes too long
# this is necessary at least for mosquitto, as the service is stopped, but the process is still running
diff --git a/runs/setup_network.sh b/runs/setup_network.sh
index 6ddf768e93..5afdb17377 100755
--- a/runs/setup_network.sh
+++ b/runs/setup_network.sh
@@ -1,5 +1,6 @@
#!/bin/bash
OPENWBBASEDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
+source "${OPENWBBASEDIR}/runs/platform_detect.sh"
dhcpcd_config_source="${OPENWBBASEDIR}/data/config/dhcpcd.conf"
dhcpcd_config_target="/etc/dhcpcd.conf"
@@ -7,18 +8,6 @@ dhcpcd_config_target="/etc/dhcpcd.conf"
dnsmasq_config_source="${OPENWBBASEDIR}/data/config/dnsmasq.conf"
dnsmasq_config_target="/etc/dnsmasq.conf"
-function versionMatch() {
- file=$1
- target=$2
- currentVersion=$(grep -o "openwb-version:[0-9]\+" "$file" | grep -o "[0-9]\+$")
- installedVersion=$(grep -o "openwb-version:[0-9]\+" "$target" | grep -o "[0-9]\+$")
- if ((currentVersion == installedVersion)); then
- return 0
- else
- return 1
- fi
-}
-
function update_file() {
file=$1
target=$2
diff --git a/runs/upgrade_stack.sh b/runs/upgrade_stack.sh
new file mode 100644
index 0000000000..4685c36555
--- /dev/null
+++ b/runs/upgrade_stack.sh
@@ -0,0 +1,429 @@
+#!/bin/bash
+OPENWBBASEDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
+source "${OPENWBBASEDIR}/runs/platform_detect.sh"
+detect_platform
+
+UPGRADE_MARKER="${OPENWBBASEDIR}/.stack-version"
+CURRENT_STACK=3
+
+needs_upgrade() {
+ if [ ! -f "$UPGRADE_MARKER" ]; then
+ return 0
+ fi
+ local marker_version
+ marker_version=$(cat "$UPGRADE_MARKER" 2>/dev/null)
+ if [[ "$marker_version" != "$CURRENT_STACK" ]]; then
+ return 0
+ fi
+ return 1
+}
+
+is_python_supported() {
+ local py_bin="${1:-python3}"
+ local major minor
+ major=$($py_bin -c 'import sys; print(sys.version_info.major)' 2>/dev/null)
+ minor=$($py_bin -c 'import sys; print(sys.version_info.minor)' 2>/dev/null)
+ if [[ "$major" -ge 3 && "$minor" -ge 10 ]]; then
+ return 0
+ fi
+ return 1
+}
+
+get_python_version() {
+ $1 -c 'import sys; print("{}.{}".format(sys.version_info.major, sys.version_info.minor))' 2>/dev/null
+}
+
+# --- Main upgrade logic ---
+
+echo "=== openWB Stack Upgrade Check ==="
+echo " OS: Debian $PLATFORM_DEBIAN_VERSION ($PLATFORM_DEBIAN_CODENAME)"
+echo " Arch: $PLATFORM_ARCH ($PLATFORM_KERNEL)"
+echo " Virtualization: $PLATFORM_VIRT"
+echo " Raspberry Pi: $PLATFORM_IS_RPI"
+echo "==================================="
+
+if ! needs_upgrade; then
+ echo "Stack is up to date (version $CURRENT_STACK). No upgrade needed."
+ exit 0
+fi
+
+echo "Stack upgrade required (target: version $CURRENT_STACK). Starting upgrade..."
+
+# --- Step 1: Enable backports on Bookworm ---
+if [[ "$PLATFORM_DEBIAN_CODENAME" == "bookworm" ]]; then
+ echo ""
+ echo "--- Step 1: Enabling bookworm-backports ---"
+ if ! grep -q "bookworm-backports" /etc/apt/sources.list /etc/apt/sources.list.d/*.sources 2>/dev/null; then
+ if [ -f /etc/apt/sources.list.d/debian.sources ]; then
+ if ! grep -q "bookworm-backports" /etc/apt/sources.list.d/debian.sources; then
+ echo "Adding backports to DEB822 sources..."
+ sudo sed -i '/^URIs:.*\/debian$/ { N; /\nSuites:.*bookworm-updates/ s/\(Suites: .*\)/\1 bookworm-backports/ }' /etc/apt/sources.list.d/debian.sources
+ fi
+ else
+ echo "Adding backports to traditional sources.list..."
+ if ! grep -q "bookworm-backports" /etc/apt/sources.list; then
+ echo "deb http://deb.debian.org/debian bookworm-backports main" | sudo tee -a /etc/apt/sources.list > /dev/null
+ fi
+ fi
+ echo "Updating package lists..."
+ sudo apt-get -q update 2>/dev/null
+ else
+ echo "Backports already enabled."
+ fi
+else
+ echo "--- Step 1: Not Bookworm, skipping backports setup ---"
+fi
+
+# --- Step 2: Determine and install Python ---
+echo ""
+echo "--- Step 2: Python installation ---"
+
+PYTHON_TARGET=""
+PYTHON_BIN=""
+
+# Check available Python versions - prefer 3.13, fall back to 3.12, then 3.11+
+for py_ver in 3.13 3.12 3.11 3.10; do
+ py_bin="/usr/bin/python${py_ver}"
+ if [ -x "$py_bin" ]; then
+ if is_python_supported "$py_bin"; then
+ PYTHON_BIN="$py_bin"
+ PYTHON_TARGET="$py_ver"
+ echo "Found system Python $py_ver: $($py_bin --version 2>/dev/null)"
+ break
+ fi
+ fi
+done
+
+if [ -z "$PYTHON_BIN" ]; then
+ echo "No supported Python (>=3.10) found. Installing..."
+ if [[ "$PLATFORM_DEBIAN_CODENAME" == "bookworm" ]]; then
+ echo "Trying python3.13 from bookworm-backports..."
+ sudo apt-get -q -y install -t bookworm-backports python3.13 python3.13-venv python3.13-dev 2>/dev/null
+ if [ -x /usr/bin/python3.13 ]; then
+ PYTHON_BIN="/usr/bin/python3.13"
+ PYTHON_TARGET="3.13"
+ else
+ echo "python3.13 not available in backports, trying python3.12..."
+ sudo apt-get -q -y install -t bookworm-backports python3.12 python3.12-venv python3.12-dev 2>/dev/null
+ if [ -x /usr/bin/python3.12 ]; then
+ PYTHON_BIN="/usr/bin/python3.12"
+ PYTHON_TARGET="3.12"
+ fi
+ fi
+ fi
+
+ if [ -z "$PYTHON_BIN" ]; then
+ echo "Installing default python3 + venv + dev..."
+ sudo apt-get -q -y install python3 python3-venv python3-dev
+ if is_python_supported /usr/bin/python3; then
+ PYTHON_BIN="/usr/bin/python3"
+ PYTHON_TARGET="python3"
+ fi
+ fi
+fi
+
+if [ -z "$PYTHON_BIN" ]; then
+ echo "ERROR: No Python >= 3.10 available! Cannot continue."
+ echo "This system needs manual intervention."
+ exit 1
+fi
+
+echo "Using Python: $PYTHON_BIN ($(get_python_version $PYTHON_BIN))"
+
+# --- Step 3: Create / update virtual environment ---
+echo ""
+echo "--- Step 3: Virtual environment ---"
+
+VENV_PATH="$PLATFORM_VENV"
+VENV_PYTHON_VERSION=""
+if [ -f "$VENV_PATH/bin/python3" ]; then
+ VENV_PYTHON_VERSION=$($VENV_PATH/bin/python3 -c 'import sys; print("{}.{}".format(sys.version_info.major, sys.version_info.minor))' 2>/dev/null)
+fi
+
+VENV_NEEDS_RECREATE=0
+if [ ! -f "$VENV_PATH/bin/python3" ]; then
+ VENV_NEEDS_RECREATE=1
+ echo "No venv found, will create."
+elif ! is_python_supported "$VENV_PATH/bin/python3"; then
+ VENV_NEEDS_RECREATE=1
+ echo "Venv has Python $VENV_PYTHON_VERSION (< 3.10), needs recreation."
+fi
+
+if [[ "$VENV_NEEDS_RECREATE" == "1" ]]; then
+ echo "Creating venv with $PYTHON_BIN at $VENV_PATH..."
+ if [ -d "$VENV_PATH" ]; then
+ echo "Removing old venv..."
+ sudo rm -rf "$VENV_PATH"
+ fi
+ sudo $PYTHON_BIN -m venv "$VENV_PATH"
+ sudo chown -R openwb:openwb "$VENV_PATH"
+ $VENV_PATH/bin/python3 -m pip install --upgrade pip
+ echo "Venv created with Python $($VENV_PATH/bin/python3 --version 2>/dev/null)"
+else
+ echo "Venv already exists with Python $VENV_PYTHON_VERSION, OK."
+fi
+
+# --- Step 4: Web server migration (Apache -> Caddy + PHP-FPM) ---
+echo ""
+echo "--- Step 4: Web server ---"
+
+APACHE_INSTALLED=0
+if dpkg -l apache2 2>/dev/null | grep -q "^ii"; then
+ APACHE_INSTALLED=1
+fi
+
+CADDY_INSTALLED=0
+if dpkg -l caddy 2>/dev/null | grep -q "^ii"; then
+ CADDY_INSTALLED=1
+fi
+
+PHP_FPM_INSTALLED=0
+if systemctl list-unit-files php*-fpm.service 2>/dev/null | grep -q "enabled"; then
+ PHP_FPM_INSTALLED=1
+fi
+
+if [[ "$CADDY_INSTALLED" == "0" ]]; then
+ echo "Installing Caddy + PHP-FPM..."
+ sudo apt-get -q -y install caddy php-fpm php php-gd php-curl php-xml php-json
+
+ if [[ "$APACHE_INSTALLED" == "1" ]]; then
+ echo "Stopping and disabling Apache..."
+ sudo systemctl stop apache2 2>/dev/null || true
+ sudo systemctl disable apache2 2>/dev/null || true
+ fi
+
+ echo "Adding caddy to ssl-cert group..."
+ sudo usermod -aG ssl-cert caddy 2>/dev/null
+
+ echo "Caddy + PHP-FPM installed."
+else
+ echo "Caddy already installed."
+fi
+
+if [[ "$PHP_FPM_INSTALLED" == "0" ]]; then
+ echo "Enabling PHP-FPM..."
+ sudo systemctl enable php*-fpm 2>/dev/null
+ sudo systemctl start php*-fpm 2>/dev/null
+fi
+
+# Ensure webroot is readable
+sudo chmod -R a+rX /var/www/html 2>/dev/null
+
+# --- Step 5: Install remaining required packages ---
+echo ""
+echo "--- Step 5: Additional packages ---"
+
+REQUIRED_PACKAGES="vim bc jq curl socat sshpass sudo ssl-cert inotify-tools iptables git mosquitto mosquitto-clients chrony gcc usbutils"
+
+MISSING_PACKAGES=""
+for pkg in $REQUIRED_PACKAGES; do
+ if ! dpkg -l "$pkg" 2>/dev/null | grep -q "^ii"; then
+ MISSING_PACKAGES="$MISSING_PACKAGES $pkg"
+ fi
+done
+
+if [ -n "$MISSING_PACKAGES" ]; then
+ echo "Installing missing packages:$MISSING_PACKAGES"
+ sudo apt-get -q -y install $MISSING_PACKAGES
+else
+ echo "All required packages already installed."
+fi
+
+# Install linux-headers for evdev build (if not present)
+if ! dpkg -l "linux-headers-$(uname -r)" 2>/dev/null | grep -q "^ii"; then
+ sudo apt-get -q -y install "linux-headers-$(uname -r)" 2>/dev/null || true
+fi
+
+# --- Step 6: Chrony NTP ---
+echo ""
+echo "--- Step 6: NTP (Chrony) ---"
+if ! systemctl is-active --quiet chrony 2>/dev/null; then
+ echo "Configuring chrony..."
+ sudo systemctl stop systemd-timesyncd 2>/dev/null || true
+ sudo systemctl disable systemd-timesyncd 2>/dev/null || true
+ if [ -f "${OPENWBBASEDIR}/data/config/chrony/chrony.conf" ]; then
+ sudo cp "${OPENWBBASEDIR}/data/config/chrony/chrony.conf" /etc/chrony/chrony.conf
+ fi
+ sudo systemctl enable chrony
+ sudo systemctl restart chrony
+ echo "Chrony configured."
+else
+ echo "Chrony already active."
+fi
+
+# --- Step 7: MOTD ---
+echo ""
+echo "--- Step 7: MOTD ---"
+if [ -f "${OPENWBBASEDIR}/data/config/profile.d/99-openwb-motd.sh" ]; then
+ sudo cp "${OPENWBBASEDIR}/data/config/profile.d/99-openwb-motd.sh" /etc/profile.d/99-openwb-motd.sh
+ sudo chmod 755 /etc/profile.d/99-openwb-motd.sh
+ echo "MOTD installed."
+else
+ echo "MOTD file not found, skipping."
+fi
+
+# --- Step 8: Update sudoers ---
+echo ""
+echo "--- Step 8: Sudoers ---"
+if [ -f "${OPENWBBASEDIR}/data/config/sudoers/caddy" ]; then
+ sudo cp "${OPENWBBASEDIR}/data/config/sudoers/caddy" "/etc/sudoers.d/caddy"
+ sudo chmod 440 /etc/sudoers.d/caddy
+ echo "Caddy sudoers installed."
+fi
+# Remove old apache sudoers if present
+if [ -f "/etc/sudoers.d/apache2" ]; then
+ echo "Removing old Apache sudoers..."
+ sudo rm -f "/etc/sudoers.d/apache2"
+fi
+
+# --- Step 9: Update service files ---
+echo ""
+echo "--- Step 9: Service files ---"
+for svc in openwb2 openwb-simpleAPI openwbRemoteSupport; do
+ svc_file="${OPENWBBASEDIR}/data/config/${svc}.service"
+ svc_target="/etc/systemd/system/${svc}.service"
+ if [ -f "$svc_file" ]; then
+ if [ -L "$svc_target" ]; then
+ echo " ${svc}.service already a symlink, OK."
+ else
+ sudo rm -f "$svc_target"
+ sudo ln -s "$svc_file" "$svc_target"
+ echo " ${svc}.service symlinked."
+ fi
+ fi
+done
+sudo systemctl daemon-reload
+
+# --- Step 10: Remove obsolete Apache packages (after everything else is set up) ---
+echo ""
+echo "--- Step 10: Cleanup ---"
+if [[ "$APACHE_INSTALLED" == "1" ]] && [[ "$CADDY_INSTALLED" == "1" ]]; then
+ echo "Removing Apache packages (Caddy is active)..."
+ sudo apt-get -q -y purge libapache2-mod-php apache2 2>/dev/null
+ sudo apt-get -q -y autoremove 2>/dev/null
+ echo "Apache removed."
+else
+ echo "No Apache cleanup needed."
+fi
+
+# --- Step 11: Install Python requirements ---
+echo ""
+echo "--- Step 11: Python requirements ---"
+if [ -f "${OPENWBBASEDIR}/requirements.txt" ]; then
+ echo "Installing Python packages into venv..."
+ if $VENV_PATH/bin/python3 -m pip install --only-binary :all: -r "${OPENWBBASEDIR}/requirements.txt" 2>/dev/null; then
+ echo "Python packages installed (binary only)."
+ else
+ echo "Binary install failed, trying with build..."
+ $VENV_PATH/bin/python3 -m pip install -r "${OPENWBBASEDIR}/requirements.txt" 2>/dev/null
+ echo "Done (with build)."
+ fi
+else
+ echo "requirements.txt not found, skipping."
+fi
+
+# --- Step 12: Run Caddy setup ---
+echo ""
+echo "--- Step 12: Caddy configuration ---"
+if [ -f "${OPENWBBASEDIR}/runs/setup_caddy.sh" ]; then
+ bash "${OPENWBBASEDIR}/runs/setup_caddy.sh"
+else
+ echo "setup_caddy.sh not found, skipping."
+fi
+
+# --- Step 13: Swap (zram on RPi, swapfile on x86) ---
+echo ""
+echo "--- Step 13: Swap setup ---"
+HAS_SWAP=$(wc -l < /proc/swaps 2>/dev/null)
+if [[ "$HAS_SWAP" -le 1 ]]; then
+ if [[ "$PLATFORM_IS_RPI" == "true" ]]; then
+ echo "Raspberry Pi detected: setting up zram swap..."
+ if ! dpkg -l zram-tools 2>/dev/null | grep -q "^ii"; then
+ sudo apt-get -q -y install zram-tools
+ fi
+ if [ ! -f /etc/default/zramswap ] || ! grep -q "^PERCENTAGE=" /etc/default/zramswap 2>/dev/null; then
+ echo "PERCENTAGE=50" | sudo tee /etc/default/zramswap > /dev/null
+ echo "PRIORITY=100" | sudo tee -a /etc/default/zramswap > /dev/null
+ echo "ALGO=lz4" | sudo tee -a /etc/default/zramswap > /dev/null
+ fi
+ sudo systemctl enable zramswap 2>/dev/null
+ sudo systemctl start zramswap 2>/dev/null || sudo systemctl restart zramswap 2>/dev/null
+ echo "zram swap configured (50% of RAM, lz4, priority 100)."
+ else
+ echo "Non-RPi system: setting up swapfile..."
+ if [ ! -f /swapfile ]; then
+ sudo fallocate -l 512M /swapfile
+ sudo chmod 600 /swapfile
+ sudo mkswap /swapfile
+ sudo swapon /swapfile
+ if ! grep -q "^/swapfile" /etc/fstab; then
+ echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab > /dev/null
+ fi
+ echo "512M swapfile created and activated."
+ else
+ echo "Swapfile already exists."
+ fi
+ fi
+else
+ echo "Swap already active ($(wc -l < /proc/swaps) devices)."
+fi
+
+# --- Step 14: Raspberry Pi SD card protection ---
+echo ""
+echo "--- Step 14: SD card protection (RPi only) ---"
+if [[ "$PLATFORM_IS_RPI" == "true" ]]; then
+ FSTAB_MODIFIED=0
+
+ if ! grep -q "tmpfs.*/var/log" /etc/fstab 2>/dev/null; then
+ echo "Adding tmpfs for /var/log..."
+ echo "tmpfs /var/log tmpfs defaults,nosuid,nodev,noatime,size=64M 0 0" | sudo tee -a /etc/fstab > /dev/null
+ sudo mount /var/log 2>/dev/null || true
+ FSTAB_MODIFIED=1
+ else
+ echo "tmpfs /var/log already in fstab."
+ fi
+
+ if ! grep -q "noatime.* / " /etc/fstab 2>/dev/null; then
+ if grep -q "^/dev/.* / " /etc/fstab 2>/dev/null; then
+ echo "Adding noatime to root partition..."
+ sudo sed -i '/^\/dev\/.* \/ / s/defaults/defaults,noatime/' /etc/fstab
+ FSTAB_MODIFIED=1
+ fi
+ else
+ echo "noatime already set on root partition."
+ fi
+
+ if [ -f /etc/systemd/journald.conf ]; then
+ if ! grep -q "^Storage=volatile" /etc/systemd/journald.conf 2>/dev/null; then
+ echo "Setting journald to volatile storage..."
+ sudo sed -i 's/^#*Storage=.*/Storage=volatile/' /etc/systemd/journald.conf
+ sudo systemctl restart systemd-journald 2>/dev/null
+ else
+ echo "journald already volatile."
+ fi
+ fi
+
+ if [[ "$FSTAB_MODIFIED" == "1" ]]; then
+ echo "Root partition noatime will take effect on next boot."
+ fi
+else
+ echo "Not a Raspberry Pi, skipping SD card protection."
+fi
+
+# --- Mark upgrade complete ---
+echo "$CURRENT_STACK" > "$UPGRADE_MARKER"
+echo ""
+echo "=== Stack upgrade to version $CURRENT_STACK complete ==="
+echo " Python: $($VENV_PATH/bin/python3 --version 2>/dev/null)"
+echo " Venv: $VENV_PATH"
+echo " Web: $(dpkg -l caddy 2>/dev/null | grep '^ii' | awk '{print $3}')"
+echo " PHP-FPM: $(systemctl is-active php*-fpm 2>/dev/null || echo unknown)"
+echo " Chrony: $(systemctl is-active chrony 2>/dev/null)"
+if [[ "$PLATFORM_IS_RPI" == "true" ]]; then
+ echo " Swap: zram ($(swapon --show=SIZE --noheadings 2>/dev/null || echo N/A))"
+ echo " SD protection: active"
+else
+ SWAP_SIZE=$(swapon --show=SIZE --noheadings 2>/dev/null | head -1)
+ echo " Swap: ${SWAP_SIZE:-none}"
+fi
+echo "==============================================="
diff --git a/simpleAPI/simpleAPI_mqtt.py b/simpleAPI/simpleAPI_mqtt.py
index 2882fcfd9e..f960d4d45e 100755
--- a/simpleAPI/simpleAPI_mqtt.py
+++ b/simpleAPI/simpleAPI_mqtt.py
@@ -47,7 +47,7 @@ def __init__(self, config_file: str):
self.charge_template_cache: Dict[str, Dict[str, Any]] = {}
# MQTT client setup
- self.client = mqtt.Client()
+ self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
self.client.on_connect = self._on_connect
self.client.on_message = self._on_message
self.client.on_disconnect = self._on_disconnect
From 939b50c50847be13b05f93ee8cd94e605c1cf311 Mon Sep 17 00:00:00 2001
From: Basti <89860334+Xerolux@users.noreply.github.com>
Date: Sun, 3 May 2026 18:11:27 +0200
Subject: [PATCH 2/2] Update Python version matrix in GitHub Actions
---
.github/workflows/github-actions-python.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/github-actions-python.yml b/.github/workflows/github-actions-python.yml
index 0ca01ff4c0..8fb5304588 100644
--- a/.github/workflows/github-actions-python.yml
+++ b/.github/workflows/github-actions-python.yml
@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- python-version: ["3.10", "3.12", "3.13"]
+ python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}