Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Klasse für B+GE-TECH WS100-1943 Modbus Zähler #23

Open
DocZoid opened this issue Apr 30, 2023 · 13 comments
Open

Klasse für B+GE-TECH WS100-1943 Modbus Zähler #23

DocZoid opened this issue Apr 30, 2023 · 13 comments

Comments

@DocZoid
Copy link

DocZoid commented Apr 30, 2023

Hier meine einfache Klasse für den WS100 Zähler:
`
class WS100(ModBusRTU):
"""
Driver class for energy meter 'WS100'
This energy meter can be deliver only one value: the front displayed energy value.
"""

def __init__(self, logger, serial_if, serial_if_baud, serial_if_byte,
             serial_if_par, serial_if_stop, slave_addr, timeout):
    super().__init__(logger, serial_if, serial_if_baud, serial_if_byte,
                     serial_if_par, serial_if_stop, slave_addr, timeout)
    # Konfiguration der Input Register nach Datenblatt
    self.input_register = {
        "Gesamtwirkleistung": {
            "port": 261, "digits": 0, "Unit": "W", "use": True},
        "Total_kwh": {
            "port": 271, "digits": 2, "Unit": "kWh", "use": True},
    }

def read_input_values(self, input_register_keys=None):
    """
    Read all in self.input_register defined data points and stored the result as float value
    into self.data dictionary
    :return: self.data dictionary
    """
    self.data = {}
    if input_register_keys is None:
        input_register_keys = self.get_input_keys()
    if self.instrument is not None:
        for key in input_register_keys:
            self.log.debug("try: key='{}', reg='{}', digits='{}'".format(key, self.input_register[key]["port"],
                                                                         self.input_register[key]["digits"]))
            if self.input_register[key]["use"] is True:

                fehler = 0
                while True:  # Anzahl der Versuche
                    try:
                        messwert = self.read_data_point_from_meter(func_code=4, 
                                                                   reg_addr=self.input_register[key]["port"],
                                                                   number_of_reg=self.input_register[key]["digits"])
                                                        
                    except OSError:
                        fehler += 1
                        self.log.error("Kommunikationserror Nr. {}".format(fehler))
                        sleep(5)
                        if fehler > 5:  # Anzahl der Versuche
                            raise OSError
                    else:
                        break

                if messwert is None:
                    self.log.warn("Value '{}' not available".format(key))
                else:
                    self.data[key] = messwert
                self.log.debug("Value '{}' = '{}'".format(key, self.data[key]))
            else:
                self.log.debug("Value '{}' not used!".format(key))
                pass
    else:
        err_msg = "No instrument available!"
        self.log.error(err_msg)
        return None
    return self.data

def get_input_keys(self):
    """
    Hilfsmethode zur Erstellung der Intervallklassen
    :return:
    """
    input_register_keys = [key for key in self.input_register]
    return input_register_keys

`
Sehr viel copy&paste und ich habe noch keine Werte über 2 Bytes, das wird noch nicht funktionieren (reiche ich nach). Die Register weichen von der Beschreibung und von den Registern in mbpoll (modbus test-tool) ab, was ich mir noch nicht erklären kann, aber das liegt möglicherweise an der 2-Bytes-Erfassung (statt 4).

Dazu noch am Ende der Datei das Mapping auf WS100 hinzufügen:
def get_device_list(): device_list = { "WS100": WS100,

Wenn erforderlich ein DB model anlegen:
class WS100(BaseModel): ts = peewee.DateTimeField(primary_key=True) gesamtwirkleistung = peewee.FloatField(null=True) total_kwh = peewee.FloatField(null=True)

Schnittstelle initial ist 9600,8,N,1

@Hofei90
Copy link
Owner

Hofei90 commented May 2, 2023

das wird noch nicht funktionieren (reiche ich nach). Die Register weichen von der Beschreibung und von den Registern in mbpoll (modbus test-tool) ab, was ich mir noch nicht erklären kann, aber das liegt möglicherweise an der 2-Bytes-Erfassung (statt 4).

Hallo, vielen Dank für deine Klasse. Was konkret meinst du mit dem oben zitierten?
Das auslesen funktioniert aber und du erhältst die passenden Werte?

@Zentris
Copy link

Zentris commented May 2, 2023

Wenn ich das richtig sehe, ist die "digits"-Länge bei der Gesamtwirkleistung "0", sollte aber "2" sein.
Die Startadresse derselben sollte nach meinen Unterlagen (https://xn--stromzhler-v5a.eu/media/pdf/d6/91/23/WS100-19xx_DE.pdf) bei 260 (0x104) liegen.

Bitte nochmal prüfen.

@DocZoid
Copy link
Author

DocZoid commented May 3, 2023

Der Parameter ist in den existierenden Klassen schon falsch verwendet. Bzw. genaugenommen falsch benannt.
Auf jeden Fall wird er übergeben an Instrument.read_register (Parameter dort: number_of_decimals=number_of_reg), was eben die Anzahl der Nachkommastellen im Ergebniswert beziffern soll (https://minimalmodbus.readthedocs.io/en/stable/apiminimalmodbus.html).
Digits=2 bedeutet also, dass der Wert anschließend durch 100 geteilt wird, Aber die Gesamtwirkleistung ist ganzzahlig.
Das mit den Adressen verstehe ich überhaupt nicht. mbpoll scheint mir überall falsche Adressen zurückzugeben. Aufruf z.B.:
mbpoll -a 1 -m rtu -r 260 -c 20 -t 3 -b 9600 -P none /dev/ttyUSB_modbus
Dort steht dann an den Adressen 262 und 272 die Leistung und der Ertrag.
Die Doku sagt 260 und 270 (104 und 10E).
Im Code angeben muss ich 261 und 271. Läuft so bei mir und liefert korrekte Werte zurück (auch mit digits 0 und 2). Liegt vielleicht am Zahlenformat (Big oder Little Endian), habe ich nicht weiter geprüft - aber dann sollte ich auch keine Leistung über 255 vernünftig auslesen können.

@DocZoid
Copy link
Author

DocZoid commented May 3, 2023

Was Sinn ergeben könnte (um damit auch die Frage nach der 2 oder 4-Byte-Erfassung zu beantworten):
Jedes Register hat 2 Bytes (16 Bit), aber viele Werte des Zählers haben 32 Bit:
INT32(5+0)
Wenn mbpoll immer das Register 1 zu groß zurückgeben würde, dann würde an den Registern aus der Doku (260+270) zumindest 0 stehen, was das höherwertige word sein müsste, und ich lesen dann nur das niederwertige word aus (261+271). Das wird nur funktionieren bis 655 kWh.

@adw93
Copy link

adw93 commented Jun 11, 2024

Hallo,
ich bin ganz neu in der Materie und habe seit einigen Tagen auch den WS100-1943 (scheint wohl ein neuer Link zu sein - zumindest funktioniert der alte Link oben bei Zentris nicht mehr ?) und bin nach langem Suchen, nach den Möglichkeiten der Auswertung, zum Glück auf dieses Projekt gestoßen.

Habt Ihr die Anpassung denn inzwischen hinbekommen oder wurde die Umsetzung aufgegeben?
Es steht leider kein Ergebnis/keine Rückmeldung im weitern Verlauf... (ist immerhin schon ein Jahr her...) :-)

Ich würde mich riesig über Hilfe und oder eine Rückmeldung freuen
VG

@Hofei90
Copy link
Owner

Hofei90 commented Jun 26, 2024

Hallo,
ich kann dir gerne den obenstehenden Code integrieren. Ob dies funktioniert, oder wie in den weiteren Kommentare die entsprechenden Anmerkungen zutreffen kann ich nicht beurteilen. Das müsstest du dann selbst testen/überprüfen.

@adw93
Copy link

adw93 commented Jun 26, 2024

Hallo, ich kann dir gerne den obenstehenden Code integrieren. Ob dies funktioniert, oder wie in den weiteren Kommentare die entsprechenden Anmerkungen zutreffen kann ich nicht beurteilen. Das müsstest du dann selbst testen/überprüfen.

Ja, gerne - das wäre ja schon mal Super nett!
ich stehe allerdings gerade noch vor der Auswahl (wie gesagt ich bin ganz neu in der Materie...) welchen Pi ich dafür nehmen soll
der neueste (pi5) muss es wohl nicht sein
RASP PI 4 B 1GB Raspberry Pi 4 B, 4x 1.5 GHz, 1 GB RAM, WLAN, BT oder ist der schon viel zu groß?

@Hofei90
Copy link
Owner

Hofei90 commented Jun 27, 2024

Der Code ist integriert in dem Zweig add_WS100-1943.
Ob die Modbus Register passen oder die Anmerkung von Zentris zutrifft musst du austesten und ggf. anpassen.

Für allgemeine Fragen und der Einrichtung des Raspberry Pis möchte ich dir folgendes Forum empfehlen: https://forum-raspberrypi.de/

@adw93
Copy link

adw93 commented Jun 27, 2024

vielen Dank, ich werde mich an dem Link und an deinem Haupt Thread (versuchen) langzuhangeln...

vielleicht eine dumme Frage - aber do finde ich den Code bzw. den "Zweig add_WS100-1943" denn dann später?

@adw93
Copy link

adw93 commented Aug 8, 2024

Hallo Hofei90,

so, ich taste mich heran:

  • der Pi 4 liegt vor mir und läuft(!)
  • jetzt hangele ich mich an deiner Anleitung entlang - Vorbereitungen/ Benötigte Python Module /

leider bekomme ich bei dem Code-Block
apt install build-essential libssl-dev libffi-dev python3-dev libpq5 git git clone https://github.com/Hofei90/smartmeter.git /home/pi/smartmeter cd /home/pi/smartmeter pip3 install --user -r requirements.txt git submodule init && git submodule update

eine Fehlermeldung:
`cd /home/pi/smartmeter
pip3 install --user -r requirements.txt
git submodule init && git submodule update
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
fatal: could not create leading directories of '/home/pi/smartmeter': Permission denied
bash: cd: /home/pi/smartmeter: No such file or directory
error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.
`
ich komme hier leider nicht weiter :-(

@MrX123123
Copy link

MrX123123 commented Aug 8, 2024 via email

@adw93
Copy link

adw93 commented Aug 8, 2024

vielen Dank für die schnelle Antntwort Sorry, ich bin blutiger Anfänger,
wie vergebe ich dem Benuter die Rechte und welche braucht er?

@MrX123123
Copy link

MrX123123 commented Aug 8, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants