def __update_variant_2(self) -> BatState: # Auslesen einer Sonnenbatterie Eco 6 über die integrierte REST-API des Batteriesystems battery_soc = int(float(self.__read_variant_2_element("M05"))) battery_export_power = int(float(self.__read_variant_2_element("M01"))) battery_import_power = int(float(self.__read_variant_2_element("M02"))) battery_power = battery_import_power - battery_export_power return BatState(power=battery_power, soc=battery_soc)
def update_using_powerwall_client(client: PowerwallHttpClient): aggregate = client.get_json("/api/meters/aggregates") get_bat_value_store(1).set( BatState(imported=aggregate["battery"]["energy_imported"], exported=aggregate["battery"]["energy_exported"], power=-aggregate["battery"]["instant_power"], soc=client.get_json("/api/system_status/soe")["percentage"]))
def update(self) -> None: log.MainLogger().debug("Komponente " + self.component_config["name"] + " auslesen.") # keine Unterschiede zwischen den Versionen sdmid = 85 time.sleep(0.1) voltage = self.__tcp_client.read_holding_registers( 0x0100, ModbusDataType.INT_16, unit=sdmid) time.sleep(0.1) current = self.__tcp_client.read_holding_registers( 0x0101, ModbusDataType.INT_16, unit=sdmid) power = voltage * current * -1 / 100 log.MainLogger().debug( "Alpha Ess Leistung[W]: %f, Speicher-Register: Spannung[V]: %f, Strom[A]: %f" % (power, voltage, current)) time.sleep(0.1) soc_reg = self.__tcp_client.read_holding_registers( 0x0102, ModbusDataType.INT_16, unit=sdmid) soc = int(soc_reg * 0.1) topic_str = "openWB/set/system/device/" + str( self.__device_id) + "/component/" + str( self.component_config["id"]) + "/" imported, exported = self.__sim_count.sim_count(power, topic=topic_str, data=self.__simulation, prefix="speicher") bat_state = BatState(power=power, soc=soc, imported=imported, exported=exported) self.__store.set(bat_state)
def update(self) -> None: log.MainLogger().debug("Komponente " + self.component_config["name"] + " auslesen.") unit = 1 with self.__tcp_client: soc = int( self.__tcp_client.read_input_registers( 13022, ModbusDataType.INT_16, unit=unit) / 10) resp = self.__tcp_client.delegate.read_input_registers(13000, 1, unit=unit) binary = bin(resp.registers[0])[2:].zfill(8) power = self.__tcp_client.read_input_registers( 13021, ModbusDataType.INT_16, unit=unit) if binary[5] == "1": power = power * -1 topic_str = "openWB/set/system/device/" + str( self.__device_id) + "/component/" + str( self.component_config["id"]) + "/" imported, exported = self.__sim_count.sim_count(power, topic=topic_str, data=self.__simulation, prefix="speicher") bat_state = BatState(power=power, soc=soc, imported=imported, exported=exported) self.__store.set(bat_state)
def update(self, client: PowerwallHttpClient, aggregate) -> None: self.__store.set( BatState( imported=aggregate["battery"]["energy_imported"], exported=aggregate["battery"]["energy_exported"], power=-aggregate["battery"]["instant_power"], soc=client.get_json("/api/system_status/soe")["percentage"]))
def update(self, response) -> None: config = self.component_config.configuration power = jq.compile(config.jq_power).input(response).first() if config.jq_soc != "": soc = jq.compile(config.jq_soc).input(response).first() else: soc = 0 if config.jq_imported != "" and config.jq_exported != "": imported = jq.compile(config.jq_imported).input(response).first() exported = jq.compile(config.jq_exported).input(response).first() else: topic_str = "openWB/set/system/device/" + str( self.__device_id)+"/component/"+str(self.component_config.id)+"/" imported, exported = self.__sim_count.sim_count( power, topic=topic_str, data=self.simulation, prefix="speicher" ) bat_state = BatState( power=power, soc=soc, imported=imported, exported=exported ) self.__store.set(bat_state)
def update(self): log.MainLogger().debug("Start kit reading") # TCP-Verbindung schließen möglichst bevor etwas anderes gemacht wird, um im Fehlerfall zu verhindern, # dass offene Verbindungen den Modbus-Adapter blockieren. with self.__tcp_client: if isinstance(self.__client, Sdm630): _, power = self.__client.get_power() power = power * -1 else: _, power = self.__client.get_power() if isinstance(self.__client, Lovato): topic_str = "openWB/set/system/device/" + str( self.__device_id) + "/component/" + str( self.component_config["id"]) + "/" imported, exported = self.__sim_count.sim_count( power, topic=topic_str, data=self.simulation, prefix="speicher") else: imported = self.__client.get_imported() exported = self.__client.get_exported() bat_state = BatState(imported=imported, exported=exported, power=power) log.MainLogger().debug("Speicher-Kit Leistung[W]: " + str(bat_state.power)) self.__store.set(bat_state)
def update_using_cookie(address: str, cookie): aggregate = read_aggregate(address, cookie) get_bat_value_store(1).set( BatState(imported=aggregate["battery"]["energy_imported"], exported=aggregate["battery"]["energy_exported"], power=-aggregate["battery"]["instant_power"], soc=read_soc(address, cookie)))
def __update_variant_0(self) -> BatState: # Auslesen einer Sonnenbatterie Eco 4 über die integrierte JSON-API des Batteriesystems battery_state = self.__read_variant_0() battery_soc = int(battery_state["M05"]) battery_export_power = int(battery_state["M34"]) battery_import_power = int(battery_state["M35"]) battery_power = battery_import_power - battery_export_power return BatState(power=battery_power, soc=battery_soc)
def update(self) -> None: log.MainLogger().debug("Komponente " + self.component_config["name"] + " auslesen.") bat_state = BatState(power=self.__get_power(), soc=self.__get_soc(), imported=self.__get_imported(), exported=self.__get_exported()) self.__store.set(bat_state)
def update_solaredge_battery(client: ModbusClient, slave_ids: Iterable[int]): all_socs = [client.read_holding_registers( 62852, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=slave_id ) for slave_id in slave_ids] storage_powers = [ client.read_holding_registers( 62836, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=slave_id ) for slave_id in slave_ids ] log.debug("Battery SoCs=%s, powers=%s", all_socs, storage_powers) get_bat_value_store(1).set(BatState(power=sum(storage_powers), soc=mean(all_socs)))
def __update_variant_1(self) -> BatState: # Auslesen einer Sonnenbatterie 8 oder 10 über die integrierte JSON-API v1 des Batteriesystems ''' example data: { "Apparent_output": 225, "BackupBuffer": "0", "BatteryCharging": false, "BatteryDischarging": false, "Consumption_Avg": 2114, "Consumption_W": 2101, "Fac": 49.97200393676758, "FlowConsumptionBattery": false, "FlowConsumptionGrid": true, "FlowConsumptionProduction": false, "FlowGridBattery": false, "FlowProductionBattery": false, "FlowProductionGrid": false, "GridFeedIn_W": -2106, "IsSystemInstalled": 1, "OperatingMode": "2", "Pac_total_W": -5, "Production_W": 0, "RSOC": 6, "RemainingCapacity_Wh": 2377, "Sac1": 75, "Sac2": 75, "Sac3": 75, "SystemStatus": "OnGrid", "Timestamp": "2021-12-13 07:54:48", "USOC": 0, "Uac": 231, "Ubat": 48, "dischargeNotAllowed": true, "generator_autostart": false, "NVM_REINIT_STATUS": 0 } ''' battery_state = self.__read_variant_1() battery_power = -battery_state["Pac_total_W"] log.debug('Speicher Leistung: ' + str(battery_power)) battery_soc = battery_state["USOC"] log.debug('Speicher SoC: ' + str(battery_soc)) topic_str = "openWB/set/system/device/" + str( self.__device_id) + "/component/" + str( self.component_config.id) + "/" imported, exported = self.__sim_count.sim_count(battery_power, topic=topic_str, data=self.simulation, prefix="speicher") return BatState(power=battery_power, soc=battery_soc, imported=imported, exported=exported)
def update(self) -> None: power, soc = self.get_values() topic_str = "openWB/set/system/device/" + str( self.__device_config.id)+"/component/"+str(self.component_config.id)+"/" imported, exported = self.__sim_count.sim_count( power, topic=topic_str, data=self.simulation, prefix="speicher" ) bat_state = BatState( power=power, soc=soc, imported=imported, exported=exported ) self.__store.set(bat_state)
def update(self, resp: Dict) -> None: power = resp["1121"]["1"] soc = resp["1074"]["1"] topic_str = "openWB/set/system/device/" + str( self.__device_id) + "/component/" + str( self.component_config["id"]) + "/" imported, exported = self.__sim_count.sim_count(power, topic=topic_str, data=self.__simulation, prefix="speicher") bat_state = BatState(power=power, soc=soc, imported=imported, exported=exported) self.__store.set(bat_state)
def read(self) -> BatState: unit = 3 with self.__tcp_client: soc = self.__tcp_client.read_holding_registers( 30845, ModbusDataType.INT_32, unit=unit) power = self.__tcp_client.read_holding_registers( 30775, ModbusDataType.INT_32, unit=unit) * -1 imported, exported = self.__tcp_client.read_holding_registers( 30595, [ModbusDataType.INT_32] * 2, unit=unit) return BatState(power=power, soc=soc, imported=imported, exported=exported)
def update(self) -> None: log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") unit = 60 power = self.__tcp_client.read_input_registers(6, ModbusDataType.FLOAT_32, unit=unit) imported = self.__tcp_client.read_input_registers(14, ModbusDataType.FLOAT_32, unit=unit) * 48 exported = self.__tcp_client.read_input_registers(16, ModbusDataType.FLOAT_32, unit=unit) * 48 soc = self.__tcp_client.read_input_registers(4, ModbusDataType.FLOAT_32, unit=unit) bat_state = BatState( power=power, soc=soc, imported=imported, exported=exported ) self.__store.set(bat_state)
def update(self) -> None: with self.__tcp_client: power = self.__tcp_client.read_holding_registers(35183, ModbusDataType.INT_16, unit=self.__modbus_id)*-1 soc = self.__tcp_client.read_holding_registers(37007, ModbusDataType.UINT_16, unit=self.__modbus_id) imported = self.__tcp_client.read_holding_registers( 35206, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100 exported = self.__tcp_client.read_holding_registers( 35209, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100 bat_state = BatState( power=power, soc=soc, imported=imported, exported=exported ) self.__store.set(bat_state)
def update(self) -> None: log.MainLogger().debug("Komponente " + self.component_config["name"] + " auslesen.") unit = 3 with self.__tcp_client: soc = self.__tcp_client.read_holding_registers( 30845, ModbusDataType.INT_32, unit=unit) power = self.__tcp_client.read_holding_registers( 30775, ModbusDataType.INT_32, unit=unit) * -1 [imported, exported] = self.__tcp_client.read_holding_registers( 30595, [ModbusDataType.INT_32] * 2, unit=unit) bat_state = BatState(power=power, soc=soc, imported=imported, exported=exported) self.__store.set(bat_state)
def update(self) -> None: unit = 60 with self.__tcp_client: power = self.__tcp_client.read_input_registers( 6, ModbusDataType.FLOAT_32, unit=unit) imported = self.__tcp_client.read_input_registers( 14, ModbusDataType.FLOAT_32, unit=unit) * 48 exported = self.__tcp_client.read_input_registers( 16, ModbusDataType.FLOAT_32, unit=unit) * 48 soc = self.__tcp_client.read_input_registers( 4, ModbusDataType.FLOAT_32, unit=unit) bat_state = BatState(power=power, soc=soc, imported=imported, exported=exported) self.__store.set(bat_state)
def update(self): log.MainLogger().debug("Start kit reading") # TCP-Verbindung schließen möglichst bevor etwas anderes gemacht wird, um im Fehlerfall zu verhindern, # dass offene Verbindungen den Modbus-Adapter blockieren. with self.__tcp_client: imported = self.__client.get_imported() exported = self.__client.get_exported() if self.component_config["configuration"]["version"] == 2: _, power = self.__client.get_power() power = power * -1 else: _, power = self.__client.get_power() bat_state = BatState(imported=imported, exported=exported, power=power) log.MainLogger().debug("Speicher-Kit Leistung[W]: " + str(bat_state.power)) self.__store.set(bat_state)
def update_e3dc_battery(addresses: Iterable[str], read_external: int, pv_other: bool): soc = 0 count = 0 battery_power = 0 # pv_external - > pv Leistung die als externe Produktion an e3dc angeschlossen ist # nur auslesen wenn als relevant parametrisiert (read_external = 1) , sonst doppelte Auslesung pv_external = 0 # pv -> pv Leistung die direkt an e3dc angeschlossen ist pv = 0 for address in addresses: log.debug("Battery Ip: %s, read_external %d pv_other %s", address, read_external, pv_other) count += 1 with ModbusClient(address, port=502) as client: # 40082 SoC soc += client.read_holding_registers(40082, ModbusDataType.INT_16, unit=1) # 40069 Speicherleistung battery_power += client.read_holding_registers(40069, ModbusDataType.INT_32, wordorder=Endian.Little, unit=1) # 40067 PV Leistung pv += (client.read_holding_registers(40067, ModbusDataType.INT_32, wordorder=Endian.Little, unit=1) * -1) if read_external == 1: # 40075 externe PV Leistung pv_external += client.read_holding_registers(40075, ModbusDataType.INT_32, wordorder=Endian.Little, unit=1) soc = soc / count log.debug("Battery soc %d battery_power %d pv %d pv_external %d count ip %d", soc, battery_power, pv, pv_external, count) counter_import, counter_export = SimCountFactory().get_sim_counter()().sim_count(battery_power, prefix="speicher") get_bat_value_store(1).set(BatState(power=battery_power, soc=soc, imported=counter_import, exported=counter_export)) # pv_other sagt aus, ob WR definiert ist, und dessen PV Leistung auch gilt # wenn 0 gilt nur PV und pv_external aus e3dc pv_total = pv + pv_external # Wenn wr1 nicht definiert ist, gilt nur die PV Leistung die hier im Modul ermittelt wurde # als gesamte PV Leistung für wr1 if not pv_other or pv_total != 0: # Wenn wr1 definiert ist, gilt die bestehende PV Leistung aus Wr1 und das was hier im Modul ermittelt wurde # als gesamte PV Leistung für wr1 if pv_other: try: pv_total = pv_total + files.pv[0].power.read() except: pass log.debug("wr update pv_other %s pv_total %d", pv_other, pv_total) _, counter_pv = SimCountFactory().get_sim_counter()().sim_count(pv_total, prefix="pv") get_inverter_value_store(1).set(InverterState(counter=counter_pv, power=pv_total))
def read_state(self): unit = self.component_config.configuration.modbus_id soc = self.__tcp_client.read_holding_registers( 62852, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=unit) power = self.__tcp_client.read_holding_registers( 62836, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=unit) topic_str = "openWB/set/system/device/" + str( self.__device_id)+"/component/"+str(self.component_config.id)+"/" imported, exported = self.__sim_count.sim_count( power, topic=topic_str, data=self.simulation, prefix="speicher" ) return BatState( power=power, soc=soc, imported=imported, exported=exported )
def update(self) -> None: log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") with self.__tcp_client: power = self.__tcp_client.read_holding_registers(6, ModbusDataType.INT_32, unit=1) * -1 soc = int(self.__tcp_client.read_holding_registers(8, ModbusDataType.INT_32, unit=1)) topic_str = "openWB/set/system/device/" + str( self.__device_id)+"/component/"+str(self.component_config["id"])+"/" imported, exported = self.__sim_count.sim_count( power, topic=topic_str, data=self.__simulation, prefix="speicher" ) bat_state = BatState( power=power, soc=soc, imported=imported, exported=exported ) self.__store.set(bat_state)
def update(self) -> None: with self.__tcp_client: power = self.__tcp_client.read_input_registers( 22, ModbusDataType.INT_16, unit=self.__modbus_id) soc = self.__tcp_client.read_input_registers( 28, ModbusDataType.UINT_16, unit=self.__modbus_id) topic_str = "openWB/set/system/device/" + str( self.__device_id) + "/component/" + str( self.component_config.id) + "/" imported, exported = self.__sim_count.sim_count(power, topic=topic_str, data=self.simulation, prefix="speicher") bat_state = BatState(power=power, soc=soc, imported=imported, exported=exported) self.__store.set(bat_state)
def update(self) -> None: with self.__tcp_client: # Die beiden Register müssen zwingend zusammen ausgelesen werden, sonst scheitert die zweite Abfrage. soc, power = self.__tcp_client.read_holding_registers( 46, [ModbusDataType.INT_16] * 2, unit=64) power = power * -1 topic_str = "openWB/set/system/device/" + str( self.__device_id) + "/component/" + str( self.component_config.id) + "/" imported, exported = self.__sim_count.sim_count(power, topic=topic_str, data=self.simulation, prefix="speicher") bat_state = BatState(power=power, soc=soc, imported=imported, exported=exported) self.__store.set(bat_state)
def update(self) -> None: MainLogger().debug("Komponente " + self.component_config["name"] + " auslesen.") with self.__tcp_client: power = self.__tcp_client.read_holding_registers( 35183, ModbusDataType.INT_16, unit=self.__modbus_id) * -1 soc = self.__tcp_client.read_holding_registers( 37007, ModbusDataType.UINT_16, unit=self.__modbus_id) imported = self.__tcp_client.read_holding_registers( 35206, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100 exported = self.__tcp_client.read_holding_registers( 35209, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100 bat_state = BatState(power=power, soc=soc, imported=imported, exported=exported) self.__store.set(bat_state)
def update(self) -> None: imported = self.__get_imported() exported = self.__get_exported() power = self.__get_power() if imported is None or exported is None: topic_str = "openWB/set/system/device/" + str( self.__device_id) + "/component/" + str( self.component_config.id) + "/" imported, exported = self.__sim_count.sim_count( power, topic=topic_str, data=self.simulation, prefix="speicher") bat_state = BatState(power=power, soc=self.__get_soc(), imported=imported, exported=exported) self.__store.set(bat_state)
def update(self) -> None: time.sleep(0.1) power = self.__tcp_client.read_holding_registers(37765, ModbusDataType.INT_32, unit=self.__modbus_id) time.sleep(0.1) soc = self.__tcp_client.read_holding_registers( 37760, ModbusDataType.INT_16, unit=self.__modbus_id) / 10 topic_str = "openWB/set/system/device/" + str( self.__device_id) + "/component/" + str( self.component_config.id) + "/" imported, exported = self.__sim_count.sim_count(power, topic=topic_str, data=self.simulation, prefix="speicher") bat_state = BatState(power=power, soc=soc, imported=imported, exported=exported) self.__store.set(bat_state)
def update(self) -> BatState: log.MainLogger().debug("Komponente " + self.component_config["name"] + " auslesen.") meter_id = str(self.device_config["meter_id"]) resp_json = req.get_http_session().get( 'http://' + self.device_config["ip_address"] + '/solar_api/v1/GetPowerFlowRealtimeData.fcgi', params=(('Scope', 'System'), ), timeout=5).json() try: power = int(resp_json["Body"]["Data"]["Site"]["P_Akku"]) * -1 except TypeError: # Wenn WR aus bzw. im Standby (keine Antwort), ersetze leeren Wert durch eine 0. power = 0 try: resp_json_id = dict(resp_json["Body"]["Data"]) if "Inverters" in resp_json_id: soc = float(resp_json_id["Inverters"]["1"]["SOC"]) else: soc = float( resp_json_id.get(meter_id)["Controller"] ["StateOfCharge_Relative"]) except TypeError: # Wenn WR aus bzw. im Standby (keine Antwort), ersetze leeren Wert durch eine 0. soc = 0 topic_str = "openWB/set/system/device/" + str( self.__device_id) + "/component/" + str( self.component_config["id"]) + "/" imported, exported = self.__sim_count.sim_count(power, topic=topic_str, data=self.__simulation, prefix="speicher") bat_state = BatState(power=power, soc=soc, imported=imported, exported=exported) return bat_state
def read(self) -> BatState: unit = 3 with self.__tcp_client: soc = self.__tcp_client.read_holding_registers( 30845, ModbusDataType.UINT_32, unit=unit) imp = self.__tcp_client.read_holding_registers( 31393, ModbusDataType.INT_32, unit=unit) exp = self.__tcp_client.read_holding_registers( 31395, ModbusDataType.INT_32, unit=unit) if imp > 5: power = imp else: power = exp * -1 exported = self.__tcp_client.read_holding_registers( 31401, ModbusDataType.UINT_64, unit=3) imported = self.__tcp_client.read_holding_registers( 31397, ModbusDataType.UINT_64, unit=3) return BatState(power=power, soc=soc, imported=imported, exported=exported)