import struct from pymodbus.client import ModbusTcpClient import pandas as pd import time class ShellyPro3m: def __init__(self, device_name: str, ip_address: str, port: int=502): self.device_name = device_name self.ip = ip_address self.port = port self.client = None self.connect_to_modbus() self.registers = None self.get_registers() def connect_to_modbus(self): port = self.port self.client = ModbusTcpClient(self.ip, port=port) try: if not self.client.connect(): print("Verbindung zum Shelly-Logger fehlgeschlagen.") exit(1) print("Verbindung zum Shelly-Logger erfolgreich.") except KeyboardInterrupt: print("Beendet durch Benutzer (Ctrl+C).") finally: self.client.close() def get_registers(self): # Excel-Datei mit den Input-Registerinformationen excel_path = "modbus_registers/shelly_pro_3m_registers.xlsx" xls = pd.ExcelFile(excel_path) df_input_registers = xls.parse() # Relevante Spalten bereinigen df_clean = df_input_registers[['MB Adresse', 'Beschreibung', 'Variabel Typ']].dropna() df_clean['MB Adresse'] = df_clean['MB Adresse'].astype(int) # Dictionary aus Excel erzeugen self.registers = { row['MB Adresse']: { 'desc': row['Beschreibung'], 'type': 'REAL' if row['Variabel Typ'] == 'REAL' else 'INT' } for _, row in df_clean.iterrows() } def get_state(self): data = {} data['Zeit'] = time.strftime('%Y-%m-%d %H:%M:%S') for address, info in self.registers.items(): reg_type = info['type'] result = self.client.read_input_registers(address, count=2 if reg_type == 'REAL' else 1) if result.isError(): print(f"Fehler beim Lesen von Adresse {address}: {result}") continue packed = struct.pack(">HH", result.registers[1], result.registers[0]) value = round(struct.unpack(">f", packed)[0], 2) print(f"Adresse {address} - {info['desc']}: {value}") data[f"{address} - {info['desc']}"] = value return data