Shelly zu Energymeter Victron / Carlo Gavazzi EM24 für GX / Venus OS

Der chaotische Hauptfaden

Moderatoren: Heaterman, Finger, Sven, TDI, Marsupilami72, duese

Antworten
nero
Beiträge: 740
Registriert: Mo 12. Aug 2013, 11:58
Wohnort: Oberbayern

Shelly zu Energymeter Victron / Carlo Gavazzi EM24 für GX / Venus OS

Beitrag von nero »

Edit: Der Murks unten läuft.

Der Code Sammelt Daten von einem Shelly (1pm) und stellt die Leistung via Modbus zur Verfügung. Und zwar in einer Form wie es ein EM24 Ethernet von Carlo Gavazzi / Victron tun würde.
Damit kann man Shellys in ein Victron GX einbinden. Dort kann man Konfigurieren als was sich das Energiemeter einbindet. Standard ist Netz Messung ("Grid"). Ich habe es als PV Inverter am Multiplus Ausgang konfiguriert. Ein Shelly3em wird vermutlich in kürze noch als Gridmeter kommen.
Etwas mehr Erklärung in der Röhre: https://www.youtube.com/watch?v=5n8DMf9HP0c


Port ist auf 1502 gesetzt, damit alles im ohne zicken im Userlevel laufen kann. Die GX erlaubt frei Port wahl.

Abhängigkeiten: benötigt wird nur

Code: Alles auswählen

pip3 install pyModbusTCP
Den Code als deingewaehlernamefuerdasskipt.py speichern. Shelly IP anpassen. Bei mehreren simulierten EM24 dessen Seriennummer ändern.
Das Skript auf eine Maschine mit python3 kopieren. zB einem raspberry py.
Bei mir lauft es aber zZ als cron @reboot autostart. (ggf als service einrichten, das würde dem Pfusch aber nicht gerecht werden)

Code: Alles auswählen

from pyModbusTCP.server import ModbusServer, DataBank
import json
import sys
from urllib import request
import time
import threading

s_pow = None

def getpow():
    global s_pow
    return s_pow


def shellyget():
    global s_pow
    err = 0
    while 1:
        try:
            l = request.urlopen("http://192.168.2.249/status").read().decode("utf-8")
            j =  json.loads(l)
            p = j["meters"][0]["power"]
            err = 0
        except:
            err += 1
            if err > 5:
                s_pow = None
            time.sleep(1)
            continue

        s_pow = int(10*float(p))

        time.sleep(20)


class Regs(DataBank):

    def __init__(self):
        # turn off allocation of memory for standard modbus object types
        # only "holding registers" space will be replaced by dynamic build values.
        super().__init__(virtual_mode=True)

    def get_holding_registers(self, address, number=1, srv_info=None):
        
        #print("reg: ", address, "#: ", number)
       
        if number > 1000:
            return 
        else:
            if address == 11:
                return [1648]               # 12 type       1648->EM24DINAV23XE1X
            if address == 770:
                return [8*256+1*256+1]            # 771 - rev meas
            if address == 772:
                return [8*256+6*256+1]            # 773 - rev com
            if address == 4098:
                return [0]                      # meas sys 3P.n
            if address == 20480:        
                return [ord('B')*256+ord('V'), ord('0')*256+ord('4'), ord('2')*256+ord('0'), ord('0')*256+ord('3'),ord('1')*256+ord('0'), ord('0')*256+ord('1'), ord('1')*256]       # SN-> BK0390085001X
            if address == 40960:
                return [7]                  # Appl H  (all)
            if address == 0 and number == 80:
                #return [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]
                p = getpow()  # p in W*10
                if s_pow == None:
                    return
                
                V = 2300

                V_L1_N = V
                V_L1_N_h = 0                          # (V >> 16) & 0xFFFF 
                A_L1 = int(p * 1000 / V) & 0xFFFF
                A_L1_h = (int(p * 1000 / V) >> 16) & 0xFFFF
                P_S = p & 0xFFFF
                P_S_h = (p >> 16) & 0xFFFF
                VA_S = P_S
                VA_S_h = P_S_h
                                                                                ### FIXME !!! only 16 bit used
                    # p5 EM24 E1 COMMUNICATION PROTOCOL pdf
                return [V_L1_N, V_L1_N_h, 0, 0, 0, 0,  #V L-N
                        0,    0, 0, 0, 0, 0,         #V L-L
                        A_L1, A_L1_h, 0, 0, 0, 0,         #A
                        p,    0, 0, 0, 0, 0,         #W
                        0,    0, 0, 0, 0, 0,         #VA
                        0,    0, 0, 0, 0, 0,         #var
                        0,    0, 0, 0,               #V
                        P_S,    P_S_h,               #W (sum)
                        VA_S,   VA_S_h,              #VA (sum)  
                        0,    0,                     #var (sum)  
                        0,    0,                       
                        0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            if address == 41216:
                return [3]                  # switch locked 
            return 


if __name__ == '__main__': 
    #print("run yeah!")
    threading.Thread(target = shellyget).start()

    # init modbus server and start it
    server = ModbusServer(host='0.0.0.0', port=1502, data_bank=Regs())
    #print (server)
    server.start()



#reg:  11 #:  1             # type
#reg:  40960 #:  1          #application
#reg:  40960 #:  1          #application
#reg:  770 #:  1            # 771 - rev meas
#reg:  772 #:  1            # 773 - rev com
#reg:  4098 #:  1           # 4099 - meas sys 
#reg:  20480 #:  7          # snum ascii

> crontab -e

dann in einer Zeile ergänzen:

Code: Alles auswählen

@reboot python3 /pfad/zum/skript.py 
Was noch fehlt:
* Jetzt gibt es nur die Leistung. Spannung, Strom wird nur stumpf gesetzt.
* Und es werden nur die niederwertigen 16bit geschrieben. Bei >3KW gibt es einen überlauf
* Sowas von Pfusch
* Shelly3EM (und andere shellys) - Kann aber anhand dem Beispiel einfach ergänzt werden

Was nett wäre:
* Das ganze in einen Tasmota Fork einpflegen

Mitarbeit und Ergänzungen Willkommen
Dateianhänge
em24zeigtwasvdpnovnposd.png
Zuletzt geändert von nero am Fr 3. Nov 2023, 18:02, insgesamt 3-mal geändert.
nero
Beiträge: 740
Registriert: Mo 12. Aug 2013, 11:58
Wohnort: Oberbayern

Re: Shelly zu Victron / Carlo Gavazzi EM24 für GX / Venus OS

Beitrag von nero »

Update: siehe oben
pvinverttervndopnvdpos.JPG
Antworten