Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
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"]))
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
 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"]))
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
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)))
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
Archivo: bat.py Proyecto: okaegi/openWB
 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)
Ejemplo n.º 11
0
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)))
Ejemplo n.º 12
0
 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)
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
 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)
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
    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)
Ejemplo n.º 17
0
    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)
Ejemplo n.º 18
0
    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)
Ejemplo n.º 19
0
    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)
Ejemplo n.º 20
0
    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)
Ejemplo n.º 21
0
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))
Ejemplo n.º 22
0
    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
        )
Ejemplo n.º 23
0
    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)
Ejemplo n.º 24
0
    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)
Ejemplo n.º 25
0
    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)
Ejemplo n.º 26
0
Archivo: bat.py Proyecto: okaegi/openWB
    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)
Ejemplo n.º 27
0
    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)
Ejemplo n.º 28
0
    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)
Ejemplo n.º 29
0
Archivo: bat.py Proyecto: okaegi/openWB
    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
Ejemplo n.º 30
0
    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)