Hofei90 / smartmeter

MIT License
21 stars 3 forks source link

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

Open DocZoid opened 1 year ago

DocZoid commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 4 months ago

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 commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

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 commented 2 months ago

Hallo Hofei90,

so, ich taste mich heran:

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 commented 2 months ago

Hi,

Dein Benutzer hat nicht die entsprechenden Rechte für apt/dpkg.

VG Jan

Am 8. August 2024 14:14:53 MESZ schrieb adw @.***>:

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 :-(

-- Reply to this email directly or view it on GitHub: https://github.com/Hofei90/smartmeter/issues/23#issuecomment-2275674011 You are receiving this because you are subscribed to this thread.

Message ID: @.***>

adw93 commented 2 months ago

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 commented 2 months ago

Hi,

Kein Problem. Einfach ein su davor verwenden.

VG Jan

Am 8. August 2024 14:45:30 MESZ schrieb adw @.***>:

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

-- Reply to this email directly or view it on GitHub: https://github.com/Hofei90/smartmeter/issues/23#issuecomment-2275733619 You are receiving this because you commented.

Message ID: @.***>