From 0734f7a810e2d80e55c0373c3df6a16f9664c72d Mon Sep 17 00:00:00 2001 From: Nils Reiners Date: Mon, 26 May 2025 21:08:16 +0200 Subject: [PATCH] =?UTF-8?q?shelly=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/data_base_csv.cpython-312.pyc | Bin 0 -> 2827 bytes __pycache__/data_base_influx.cpython-312.pyc | Bin 0 -> 1793 bytes __pycache__/heat_pump.cpython-312.pyc | Bin 0 -> 3566 bytes __pycache__/shelly_pro_3m.cpython-312.pyc | Bin 0 -> 3488 bytes data/.~lock.shelly_pro_3m_registers.xlsx# | 1 + ... 1.17(1).xlsx => heat_pump_registers.xlsx} | Bin data/shelly_pro_3m_registers.xlsx | Bin 0 -> 5863 bytes data_base_influx.py | 11 +--- heat_pump.py | 5 +- main.py | 12 ++-- shelly_pro_3m.py | 60 ++++++++++++++++++ 11 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 __pycache__/data_base_csv.cpython-312.pyc create mode 100644 __pycache__/data_base_influx.cpython-312.pyc create mode 100644 __pycache__/heat_pump.cpython-312.pyc create mode 100644 __pycache__/shelly_pro_3m.cpython-312.pyc create mode 100644 data/.~lock.shelly_pro_3m_registers.xlsx# rename data/{ModBus TCPIP 1.17(1).xlsx => heat_pump_registers.xlsx} (100%) create mode 100644 data/shelly_pro_3m_registers.xlsx create mode 100644 shelly_pro_3m.py diff --git a/__pycache__/data_base_csv.cpython-312.pyc b/__pycache__/data_base_csv.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9f08031a9f53d0ead35497d17c7f0573cac9b77 GIT binary patch literal 2827 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 literal 0 HcmV?d00001 diff --git a/__pycache__/heat_pump.cpython-312.pyc b/__pycache__/heat_pump.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..589611a6dd95462866b88126257a783e9cb1fdb6 GIT binary patch literal 3566 zcmb7HU2GHC6~6Q9iDM^roF9|KFaeT{3nXQi-+r=3+Lg>leIlCxq}p>Fd771oJB{=S_8dP@Yns0Jn1# z%3WLKa%NTTNpQ41& zhB=Ejur_LIA@u7EdNf&^ae#f;v&KCV#V?U5jQL(Kn$1h32Vnch5zvU`6x57|c zlswDQ=7O|&Ns^13LaW!Qx%W3r4{c@JK!_@7Fa zo(%IP>%`gm8>*pRuiSvcjW)bDquH!+I2GBR$SO$~Pgcc`Qjg9rB<$jEH z1)H*xBC#=8=_xafiQGM45^cvoxF;+TdiR7LoX|{Uxys>h2}z>rrp4oHs%iO8r=s=f3v-o!m>%frMRx&H=cYSE2J};5cEGWi#v* z0pwqK6t=>_WwFL<4C@Sk#arcbW)4IK z(UdSH#yAzl*iYIJx&*hI6|!PREZKrlpf+I?>8QAV+70*4DlVN-B&Fup>@V3{As)rJ zte6!bO;nQiBxq#H`x7Ya9!iIls2Qy$!D@o-xuzM{(*7Urkx%K#lqr8$PQ+pUh5Jmu zeAF&4*peKUwX8IQEx^i4GB!71C?#29DeT$((d8rj*zOiee>nDXk zbU83q2#hTTuH>X*M|f^$p=1AY$B{zEkv|!W9RoROx*f{LiVwAITW;M^Xx*{cy6d}I zvDN+Djr=Xs%=9}eHOT9m_5jR^!M2&9LU2cMYv-(9*t+*&^TO75?~0Fp{9NGVy61@V z)~#_Mn&W>__n$QcGlN#J$2;ZzX7ME~(a5#S(C=+5sc3x}dJ~ourV`JL!rJlte;1!Y z^vS()WV2boo5ImZ20WoF6x**nZ)zx@VF5IiBVT~X7r%5lr4gcD*a%^y!K{=GMar=E zkW!No?xFkZ3f`@=75xFw_J-oBxNY>+rXk~IMZJC_uB^DuqQ|!Ag;Up24YqX=tgkD5 z84=nu`d#a|?sL@Fx9;;O!<<9m`k}PH^Wv_~@m-yY+IHE8u(nQaSU)vNHbMahAmI?kmV}3 ztroB9qX|obb}wQBUW8^gr9tVt8r4$xHMCk1#V1vr3@pXtfOPo1d6h zACgC1kAnH;_m_O9i@xB~`j(k}3-ukv;O6CEcOlq4=LZzeDTUzMw}q!KZB7gS^!TSw z&U`d;YWCb*-`<}aoIWvqaAshZpS|$8XXbj|-?QN9 zU1@{wUuj3a##}A&!_kN6zlDhX_aG9n+!5Mer!)+6PbBiQR8*sX9AL%4WfC6<*j)sn zNszn?(H@Ow(VzugO2Vlt{LQG?KqfY85QwiPl+XY>@d`4`gR(#IbmCtwe97BYfB bpuu36zoQ-Bpujh%_B+0hXY{~xt5YjJd literal 0 HcmV?d00001 diff --git a/__pycache__/shelly_pro_3m.cpython-312.pyc b/__pycache__/shelly_pro_3m.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c6e8f11faef25956bb569a4b73e285446b9f63e GIT binary patch literal 3488 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 Doxuh> literal 0 HcmV?d00001 diff --git a/data_base_influx.py b/data_base_influx.py index 095fc78..ad0adfb 100644 --- a/data_base_influx.py +++ b/data_base_influx.py @@ -10,8 +10,8 @@ class DataBaseInflux: self.client = InfluxDBClient(url=self.url, token=self.token, org=self.org) self.write_api = self.client.write_api() - def store_data(self, data: dict): - measurement = "messungen" # Fest auf "messungen" gesetzt + def store_data(self, device_name: str, data: dict): + measurement = device_name # Fest auf "messungen" gesetzt point = Point(measurement) @@ -25,9 +25,4 @@ class DataBaseInflux: # Punkt in InfluxDB schreiben self.write_api.write(bucket=self.bucket, org=self.org, record=point) -db = DataBaseInflux( - url="http://localhost:8086", - token="Cw_naEZyvJ3isiAh1P4Eq3TsjcHmzzDFS7SlbKDsS6ZWL04fMEYixWqtNxGThDdG27S9aW5g7FP9eiq5z1rsGA==", - org="allmende", - bucket="allmende_db" -) + diff --git a/heat_pump.py b/heat_pump.py index 951518d..92b7dc7 100644 --- a/heat_pump.py +++ b/heat_pump.py @@ -3,7 +3,8 @@ import pandas as pd import time class HeatPump: - def __init__(self, ip_address: str): + def __init__(self, device_name: str, ip_address: str): + self.device_name = device_name self.ip = ip_address self.client = None self.connect_to_modbus() @@ -25,7 +26,7 @@ class HeatPump: def get_registers(self): # Excel-Datei mit den Input-Registerinformationen - excel_path = "data/ModBus TCPIP 1.17(1).xlsx" + excel_path = "data/heat_pump_registers.xlsx" xls = pd.ExcelFile(excel_path) df_input_registers = xls.parse('04 Input Register') diff --git a/main.py b/main.py index bc5d29b..72989c0 100644 --- a/main.py +++ b/main.py @@ -3,22 +3,24 @@ from datetime import datetime from data_base_csv import DataBaseCsv from data_base_influx import DataBaseInflux from heat_pump import HeatPump +from shelly_pro_3m import ShellyPro3m -interval = 10 # z.B. alle 10 Sekunden +interval = 10 -#db = DataBaseCsv('modbus_log.csv') db = DataBaseInflux( url="http://localhost:8086", token="Cw_naEZyvJ3isiAh1P4Eq3TsjcHmzzDFS7SlbKDsS6ZWL04fMEYixWqtNxGThDdG27S9aW5g7FP9eiq5z1rsGA==", org="allmende", bucket="allmende_db" ) -hp = HeatPump(ip_address='10.0.0.10') + +hp = HeatPump(device_name='hp_master', ip_address='10.0.0.10') +shelly = ShellyPro3m(device_name='wohnung_2_6', ip_address='192.168.1.121') while True: now = datetime.now() if now.second % interval == 0 and now.microsecond < 100_000: - db.store_data(hp.get_data()) - + db.store_data(hp.device_name, hp.get_data()) + db.store_data(shelly.device_name, shelly.get_data()) time.sleep(0.1) diff --git a/shelly_pro_3m.py b/shelly_pro_3m.py new file mode 100644 index 0000000..581cf99 --- /dev/null +++ b/shelly_pro_3m.py @@ -0,0 +1,60 @@ +from pymodbus.client import ModbusTcpClient +import pandas as pd +import time + +class ShellyPro3m: + def __init__(self, device_name: str, ip_address: str): + self.device_name = device_name + self.ip = ip_address + self.client = None + self.connect_to_modbus() + self.registers = None + self.get_registers() + + def connect_to_modbus(self): + port = 502 + self.client = ModbusTcpClient(self.ip, port=port) + try: + if not self.client.connect(): + print("Verbindung zur Wärmepumpe fehlgeschlagen.") + exit(1) + print("Verbindung zur Wärmepumpe 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 = "data/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_data(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 + + value = result.registers[0] / 10.0 + + print(f"Adresse {address} - {info['desc']}: {value}") + data[f"{address} - {info['desc']}"] = value + return data