Exemple #1
0
    def update(self, response) -> None:
        log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.")
        config = self.component_config["configuration"]

        power = float(jq.compile(config["jq_power"]).input(response).first())
        if power >= 0:
            power = power * -1
        if config["jq_counter"] == "":
            topic_str = "openWB/set/system/device/" + \
                str(self.__device_id)+"/component/" + \
                str(self.component_config["id"])+"/"
            _, counter = self.__sim_count.sim_count(
                power, topic=topic_str, data=self.simulation, prefix="pv")
            inverter_state = InverterState(
                power=power,
                counter=counter,
                currents=[0, 0, 0]
            )
        else:
            counter = jq.compile(config["jq_counter"]).input(response).first()

        inverter_state = InverterState(
            power=power,
            counter=counter
        )
        self.__store.set(inverter_state)
Exemple #2
0
def update_sma_modbus(addresses: Iterable[str]):
    power_total = 0
    energy_total = 0

    for ipaddress in addresses:
        with ModbusClient(ipaddress) as client:
            # AC Wirkleistung über alle Phasen (W) [Pac]:
            power = client.read_holding_registers(30775,
                                                  ModbusDataType.INT_32,
                                                  unit=3)
            # Gesamtertrag (Wh) [E-Total]:
            energy = client.read_holding_registers(30529,
                                                   ModbusDataType.UINT_32,
                                                   unit=3)

            log.debug("%s: power = %d W, energy = %d Wh", ipaddress, power,
                      energy)
            if power == SMA_INT32_NAN:
                log.debug("Power value is NaN - ignoring")
            else:
                power_total += power
            energy_total += energy

    power_total = -max(power_total, 0)
    get_inverter_value_store(1).set(
        InverterState(counter=energy_total, power=power_total))
Exemple #3
0
    def read_state(self):
        def read_scaled_int16(address: int, count: int):
            return scale_registers(
                self.__tcp_client.read_holding_registers(
                    address, [ModbusDataType.INT_16] * (count + 1),
                    unit=self.component_config.configuration.modbus_id))

        def read_scaled_uint16(address: int, count: int):
            return scale_registers(
                self.__tcp_client.read_holding_registers(
                    address, [ModbusDataType.UINT_16] * (count) +
                    [ModbusDataType.INT_16],
                    unit=self.component_config.configuration.modbus_id))

        def read_scaled_uint32(address: int, count: int):
            return scale_registers(
                self.__tcp_client.read_holding_registers(
                    address, [ModbusDataType.UINT_32] * (count) +
                    [ModbusDataType.INT_16],
                    unit=self.component_config.configuration.modbus_id))

        # 40083 = AC Power value (Watt)
        # 40084 = AC Power scale factor
        power = read_scaled_int16(40083, 1)[0] * -1

        # 40093 = AC Lifetime Energy production (Watt hours)
        # 40095 = AC Lifetime scale factor
        exported = read_scaled_uint32(40093, 1)[0]
        # 40072/40073/40074 = AC Phase A/B/C Current value (Amps)
        # 40075 = AC Current scale factor
        currents = read_scaled_uint16(40072, 3)

        return InverterState(power=power, exported=exported, currents=currents)
Exemple #4
0
    def update(self) -> None:
        """ liest die Werte des Moduls aus.
        """
        with self.__tcp_client:
            powers, power = self.__client.get_power()

            version = self.component_config["configuration"]["version"]
            if version == 1:
                power = sum(powers)
            if power > 10:
                power = power*-1
            currents = self.__client.get_currents()

        if isinstance(self.__client, Lovato):
            topic_str = "openWB/set/system/device/" + \
                str(self.__device_id)+"/component/" + \
                str(self.component_config["id"])+"/"
            _, counter = self.__sim_count.sim_count(
                power, topic=topic_str, data=self.__simulation, prefix="pv")
        else:
            counter = self.__client.get_counter()

        log.MainLogger().debug("PV-Kit Leistung[W]: "+str(power))
        inverter_state = InverterState(
            power=power,
            counter=counter,
            currents=currents
        )
        self.__store.set(inverter_state)
Exemple #5
0
 def update(self, client: PowerwallHttpClient, aggregate) -> None:
     pv_watt = aggregate["solar"]["instant_power"]
     if pv_watt > 5:
         pv_watt = pv_watt * -1
     self.__store.set(
         InverterState(exported=aggregate["solar"]["energy_exported"],
                       power=pv_watt))
Exemple #6
0
def read_legacy(ip1: str, webbox: int, ip2: str, ip3: str, ip4: str, version: int, num: int) -> None:
    def create_webbox_inverter(address: str):
        config = inverter_webbox.get_default_config()
        config["id"] = num
        return inverter_webbox.SmaWebboxInverter(0, address, config)

    def create_modbus_inverter(address: str):
        config = inverter_modbus_tcp.get_default_config()
        config["id"] = num
        config["configuration"]["version"] = SmaInverterVersion(version)
        return inverter_modbus_tcp.SmaModbusTcpInverter(0, address, config)

    inverter1 = (create_webbox_inverter if webbox else create_modbus_inverter)(ip1)
    inverters_additional = (create_modbus_inverter(address) for address in [ip2, ip3, ip4] if address != "none")
    # In legacy we were able to configure multiple IP-Addresses for a single SMA-component, effectively creating a
    # virtual component that represents the sum of its subcomponents. This was probably done in order to circumvent
    # the limitation to have a maximum of two inverters configured in legacy.
    # Since openWB 2 does not have a limitation on the number of inverters we do not implement this there. However
    # we still need to implement this for the read_legacy-bridge.
    # Here we act like we only update the first inverter, while we actually query all inverters and sum them up:
    with SingleComponentUpdateContext(inverter1.component_info):
        total_power = 0
        total_energy = 0
        for inverter in itertools.chain((inverter1,), inverters_additional):
            state = inverter.read_inverter_state()
            total_power += state.power
            total_energy += state.counter
        get_inverter_value_store(num).set(InverterState(counter=total_energy, power=total_power))
Exemple #7
0
    def update(self) -> None:
        log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.")

        vc_count = self.component_config["configuration"]["vc_count"]
        vc_type = self.component_config["configuration"]["vc_type"]

        if vc_type == 'VS':
            mb_unit = 40
            mb_register = 20  # MB:20; ID: 15010; PV power kW
        elif vc_type == 'VT':
            mb_unit = 20
            mb_register = 8  # MB:8; ID: 11004; Power of the PV generator kW
        else:
            raise FaultState.error("Unbekannter VC-Typ: "+str(vc_type))
        power = 0
        for i in range(1, vc_count+1):
            mb_unit_dev = mb_unit+i
            power += self.__tcp_client.read_input_registers(mb_register, ModbusDataType.FLOAT_32, unit=mb_unit_dev)
        power = power * -1000

        if vc_type == 'VS':
            mb_register = 46  # MB:46; ID: 15023; Desc: Total PV produced energy MWh
        elif vc_type == 'VT':
            mb_register = 18  # MB:18; ID: 11009; Desc: Total produced energy MWh
        counter = 0
        for i in range(1, vc_count + 1):
            mb_unit_dev = mb_unit + i
            counter += self.__tcp_client.read_input_registers(mb_register, ModbusDataType.FLOAT_32, unit=mb_unit_dev)
        counter = counter * 1000000

        inverter_state = InverterState(
            power=power,
            counter=counter
        )
        self.__store.set(inverter_state)
Exemple #8
0
    def update(self) -> float:
        log.MainLogger().debug("Komponente " + self.component_config["name"] +
                               " auslesen.")

        # Rückgabewert ist die aktuelle Wirkleistung in [W].
        params = (('Scope', 'System'), )
        response = req.get_http_session().get(
            'http://' + self.device_config["ip_address"] +
            '/solar_api/v1/GetPowerFlowRealtimeData.fcgi',
            params=params,
            timeout=3)
        try:
            power = float(response.json()["Body"]["Data"]["Site"]["P_PV"])
        except TypeError:
            # Ohne PV Produktion liefert der WR 'null', ersetze durch Zahl 0
            power = 0

        power2 = self.__get_wr2()
        power += power2
        power1 = power
        power *= -1
        topic = "openWB/set/system/device/" + str(
            self.__device_id) + "/component/" + str(
                self.component_config["id"]) + "/"
        _, counter = self.__sim_count.sim_count(power,
                                                topic=topic,
                                                data=self.__simulation,
                                                prefix="pv")

        inverter_state = InverterState(power=power, counter=counter)
        self.__store.set(inverter_state)
        # Rückgabe der Leistung des ersten WR ohne Vorzeichenumkehr
        return power1
Exemple #9
0
    def update(self) -> None:
        modbus_id = self.component_config.configuration.modbus_id
        with self.__tcp_client:
            if self.component_config.configuration.mppt:
                try:
                    power = self.__tcp_client.read_holding_registers(789, ModbusDataType.UINT_16, unit=modbus_id) / -10
                except Exception as e:
                    if "GatewayPathUnavailable" in str(e):
                        power = 0
                        log.debug(self.component_config.name +
                                  ": Reg 789 konnte nicht gelesen werden, Power auf 0 gesetzt.")
                    else:
                        raise
            else:
                # Adresse 808-810 ac output connected pv
                # Adresse 811-813 ac input connected pv
                # Adresse 850 mppt Leistung
                power_temp1 = self.__tcp_client.read_holding_registers(808, [ModbusDataType.UINT_16]*6, unit=100)
                power_temp2 = self.__tcp_client.read_holding_registers(850, ModbusDataType.UINT_16, unit=100)
                power = (sum(power_temp1)+power_temp2) * -1

        topic_str = "openWB/set/system/device/" + str(self.__device_id)+"/component/" + \
            str(self.component_config.id)+"/"
        _, exported = self.__sim_count.sim_count(power,
                                                 topic=topic_str,
                                                 data=self.simulation,
                                                 prefix="pv%s" % ("" if self.component_config.id == 1 else "2"))
        inverter_state = InverterState(
            power=power,
            exported=exported
        )
        self.__store.set(inverter_state)
Exemple #10
0
def update(num: int, speichermodul: str, wrkostalpikoip: str):
    log.debug('Wechselrichter Kostal Piko Var 1 Speicher: ' + speichermodul)
    log.debug('Wechselrichter Kostal Piko Var 1 IP: ' + wrkostalpikoip)

    # Auslesen eines Kostal Piko WR über die integrierte API des WR. Rückgabewert ist die aktuelle Wattleistung.
    if speichermodul != "none":
        params = (('dxsEntries', ['33556736', '251658753)']), )
        pvwatttmp = requests.get('http://' + wrkostalpikoip + '/api/dxs.json',
                                 params=params,
                                 timeout=5).json()
    else:
        params = (('dxsEntries', ['67109120', '251658753)']), )
        pvwatttmp = requests.get('http://' + wrkostalpikoip + '/api/dxs.json',
                                 params=params,
                                 timeout=5).json()

    # aktuelle Ausgangsleistung am WR [W]
    pvwatt = int(pvwatttmp["dxsEntries"][0]["value"])

    if pvwatt > 5:
        pvwatt = pvwatt * -1

    log.debug('WR Leistung: ' + str(pvwatt))
    # Gesamtzählerstand am WR [kWh]
    pvkwh = int(pvwatttmp['dxsEntries'][1]['value'])

    get_inverter_value_store(num).set(
        InverterState(counter=pvkwh * 1000, power=pvwatt))
Exemple #11
0
    def update(self) -> None:
        vc_count = self.component_config.configuration.vc_count
        vc_type = self.component_config.configuration.vc_type

        with self.__tcp_client:
            if vc_type == 'VS':
                mb_unit = 40
                mb_register = 20  # MB:20; ID: 15010; PV power kW
            elif vc_type == 'VT':
                mb_unit = 20
                mb_register = 8  # MB:8; ID: 11004; Power of the PV generator kW
            else:
                raise FaultState.error("Unbekannter VC-Typ: " + str(vc_type))
            power = 0
            for i in range(1, vc_count + 1):
                mb_unit_dev = mb_unit + i
                power += self.__tcp_client.read_input_registers(
                    mb_register, ModbusDataType.FLOAT_32, unit=mb_unit_dev)
            power = power * -1000

            if vc_type == 'VS':
                mb_register = 46  # MB:46; ID: 15023; Desc: Total PV produced energy MWh
            elif vc_type == 'VT':
                mb_register = 18  # MB:18; ID: 11009; Desc: Total produced energy MWh
            exported = 0
            for i in range(1, vc_count + 1):
                mb_unit_dev = mb_unit + i
                exported += self.__tcp_client.read_input_registers(
                    mb_register, ModbusDataType.FLOAT_32, unit=mb_unit_dev)
            exported = exported * 1000000

        inverter_state = InverterState(power=power, exported=exported)
        self.__store.set(inverter_state)
Exemple #12
0
def update_using_cookie(address: str, cookie):
    aggregate = read_aggregate(address, cookie)
    pv_watt = aggregate["solar"]["instant_power"]
    if pv_watt > 5:
        pv_watt = pv_watt * -1
    get_inverter_value_store(1).set(
        InverterState(counter=aggregate["solar"]["energy_exported"],
                      power=pv_watt))
def parse_kostal_piko_var2_html(html: str):
    result = re.search(r"aktuell</td>\s*<td[^>]*>\s*(\d+).*Gesamtenergie</td>\s*<td[^>]*>\s*(\d+)", html, re.DOTALL)
    if result is None:
        raise Exception("Given HTML does not match the expected regular expression. Ignoring.")
    return InverterState(
        counter=int(result.group(2)) * 1000,
        power=-int(result.group(1))
    )
Exemple #14
0
def update_using_powerwall_client(client: PowerwallHttpClient):
    aggregate = client.get_json("/api/meters/aggregates")
    pv_watt = aggregate["solar"]["instant_power"]
    if pv_watt > 5:
        pv_watt = pv_watt * -1
    get_inverter_value_store(1).set(
        InverterState(counter=aggregate["solar"]["energy_exported"],
                      power=pv_watt))
Exemple #15
0
    def update(self) -> None:
        log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.")

        inverter_state = InverterState(
            power=self.__get_power(),
            counter=self.__get_counter()
        )
        self.__store.set(inverter_state)
Exemple #16
0
 def update(self) -> None:
     log.MainLogger().debug("Komponente " + self.component_config["name"] +
                            " auslesen.")
     inverter_state = InverterState(
         # for compatibility: in 1.x power URL values are positive!
         power=(-self.__get_power() if compatibility.is_ramdisk_in_use()
                else self.__get_power()),
         counter=self.__get_counter())
     self.__store.set(inverter_state)
Exemple #17
0
    def read_inverter_state(self) -> InverterState:
        log.debug("Komponente "+self.component_config["name"]+" auslesen.")
        data = {'RPC': '{"version": "1.0","proc": "GetPlantOverview","id": "1","format": "JSON"}'}
        response = req.get_http_session().post(
            'http://' + self.__device_address + '/rpc', data=data, timeout=3).json()

        return InverterState(
            counter=float(response["result"]["overview"][2]["value"]) * 1000,
            power=-int(response["result"]["overview"][0]["value"])
        )
Exemple #18
0
    def fill_inverter_state(self, power):
        topic_str = "openWB/set/system/device/" + str(self.__device_id) + \
            "/component/" + str(self.component_config.id)+"/"
        _, exported = self.__sim_count.sim_count(
            power,
            topic=topic_str,
            data=self.simulation,
            prefix="pv%s" % ("" if self.component_config.id == 1 else "2"))

        return InverterState(power=power, exported=exported)
Exemple #19
0
def read_legacy(component_type: str,
                address: str,
                bat_module: str,
                bat_ip: str,
                bat_username: str,
                bat_password: str,
                num: Optional[int] = None) -> None:
    dev = Device(
        KostalPiko(configuration=KostalPikoConfiguration(ip_address=address)))
    if component_type in COMPONENT_TYPE_TO_MODULE:
        component_config = COMPONENT_TYPE_TO_MODULE[
            component_type].component_descriptor.configuration_factory()
    else:
        raise Exception("illegal component type " + component_type +
                        ". Allowed values: " +
                        ','.join(COMPONENT_TYPE_TO_MODULE.keys()))
    component_config.id = num
    dev.add_component(component_config)

    log.debug('KostalPiko IP-Adresse: ' + address)
    log.debug('KostalPiko Speicher: ' + bat_module)

    if component_type == "inverter":
        with SingleComponentUpdateContext(
                dev.components["component" + str(num)].component_info):
            power, exported = dev.components["component" +
                                             str(num)].get_values()
            if bat_module == "speicher_bydhv":
                bat_power = _get_byd_bat_power(bat_ip, bat_username,
                                               bat_password, num)
                power -= bat_power
            get_inverter_value_store(num).set(
                InverterState(power=power, exported=exported))
    elif component_type == "counter":
        with SingleComponentUpdateContext(
                dev.components["componentNone"].component_info):
            home_consumption, powers = dev.components[
                "componentNone"].get_values()
            if bat_module == "speicher_bydhv":
                bat_power = _get_byd_bat_power(bat_ip, bat_username,
                                               bat_password, num)
                home_consumption += bat_power

            dev.add_component(KostalPikoInverterSetup(id=num))
            inverter_power, _ = dev.components["component" +
                                               str(num)].get_values()

            power = home_consumption + inverter_power
            imported, exported = simcount.SimCountFactory().get_sim_counter()(
            ).sim_count(power, topic="topic_str", data={}, prefix="bezug")
            counter_state = CounterState(imported=imported,
                                         exported=exported,
                                         power=power,
                                         powers=powers)
            get_counter_value_store(None).set(counter_state)
Exemple #20
0
    def update(self, bat: bool) -> float:
        log.MainLogger().debug("Komponente " + self.component_config["name"] +
                               " auslesen.")
        gen24 = self.component_config["configuration"]["gen24"]

        # Rückgabewert ist die aktuelle Wirkleistung in [W].
        params = (('Scope', 'System'), )
        response = req.get_http_session().get(
            'http://' + self.device_config["ip_address"] +
            '/solar_api/v1/GetPowerFlowRealtimeData.fcgi',
            params=params,
            timeout=3)
        try:
            power = float(response.json()["Body"]["Data"]["Site"]["P_PV"])
        except TypeError:
            # Ohne PV Produktion liefert der WR 'null', ersetze durch Zahl 0
            power = 0

        power2, counter2 = self.__get_wr2()
        power += power2
        power1 = power
        power *= -1
        topic = "openWB/set/system/device/" + str(
            self.__device_id) + "/component/" + str(
                self.component_config["id"]) + "/"
        if gen24:
            _, counter = self.__sim_count.sim_count(power,
                                                    topic=topic,
                                                    data=self.__simulation,
                                                    prefix="pv")
        else:
            counter = float(response.json()["Body"]["Data"]["Site"]["E_Total"])
            daily_yield = float(
                response.json()["Body"]["Data"]["Site"]["E_Day"])
            counter, counter_start, counter_offset = self.__calculate_offset(
                counter, daily_yield)
            counter = counter + counter2
            if counter > 0:
                counter = self.__add_and_save_offset(daily_yield, counter,
                                                     counter_start,
                                                     counter_offset)

        if bat is True:
            _, counter = self.__sim_count.sim_count(power,
                                                    topic=topic,
                                                    data=self.__simulation,
                                                    prefix="pv")

        inverter_state = InverterState(power=power,
                                       counter=counter,
                                       currents=[0, 0, 0])
        self.__store.set(inverter_state)
        # Rückgabe der Leistung des ersten WR ohne Vorzeichenumkehr
        return power1
Exemple #21
0
 def update(self, response: Dict) -> None:
     power = float(response["statistics"]["pcs_pv_total_power"]) * -1
     topic_str = "openWB/set/system/device/" + \
         str(self.__device_id)+"/component/" + \
         str(self.component_config.id)+"/"
     _, exported = self.__sim_count.sim_count(power,
                                              topic=topic_str,
                                              data=self.__simulation,
                                              prefix="pv")
     inverter_state = InverterState(exported=exported, power=power)
     self.__store.set(inverter_state)
Exemple #22
0
 def __update_variant_2(self) -> InverterState:
     # Auslesen einer Sonnenbatterie Eco 6 über die integrierte REST-API des Batteriesystems
     pv_power = -int(self.__read_variant_2_element("M03"))
     log.MainLogger().debug('Speicher PV Leistung: ' + str(pv_power))
     topic_str = "openWB/set/system/device/" + str(
         self.__device_id) + "/component/" + str(
             self.component_config["id"]) + "/"
     _, exported = self.__sim_count.sim_count(pv_power,
                                              topic=topic_str,
                                              data=self.__simulation,
                                              prefix="pv")
     return InverterState(counter=exported, power=pv_power)
Exemple #23
0
    def update(self) -> None:
        with self.__tcp_client:
            power = sum([
                self.__tcp_client.read_holding_registers(
                    reg, ModbusDataType.UINT_32, unit=self.__modbus_id)
                for reg in [35105, 35109, 35113, 35117]
            ]) * -1
            exported = self.__tcp_client.read_holding_registers(
                35191, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100

        inverter_state = InverterState(power=power, exported=exported)
        self.__store.set(inverter_state)
Exemple #24
0
    def update(self) -> None:
        log.MainLogger().debug("Komponente " + self.component_config["name"] +
                               " auslesen.")
        with self.__tcp_client:
            power_temp = self.__tcp_client.read_input_registers(
                10, [ModbusDataType.UINT_16] * 2)
            power = sum(power_temp) * -1
            counter = self.__tcp_client.read_input_registers(
                82, ModbusDataType.UINT_32, wordorder=Endian.Little) * 100

        inverter_state = InverterState(power=power, counter=counter)
        self.__store.set(inverter_state)
Exemple #25
0
    def update(self) -> None:
        with self.__tcp_client:
            power_temp = self.__tcp_client.read_input_registers(
                10, [ModbusDataType.UINT_16] * 2, unit=self.__modbus_id)
            power = sum(power_temp) * -1
            exported = self.__tcp_client.read_input_registers(
                82,
                ModbusDataType.UINT_32,
                wordorder=Endian.Little,
                unit=self.__modbus_id) * 100

        inverter_state = InverterState(power=power, exported=exported)
        self.__store.set(inverter_state)
Exemple #26
0
    def read(self) -> InverterState:
        data = {
            'RPC':
            '{"version": "1.0","proc": "GetPlantOverview","id": "1","format": "JSON"}'
        }
        response = req.get_http_session().post('http://' +
                                               self.__device_address + '/rpc',
                                               data=data,
                                               timeout=3).json()

        return InverterState(
            exported=float(response["result"]["overview"][2]["value"]) * 1000,
            power=-int(response["result"]["overview"][0]["value"]))
Exemple #27
0
    def update(self, resp: Dict) -> None:
        power = resp["1634"]["0"] * -1

        topic_str = "openWB/set/system/device/" + str(self.__device_id) + \
            "/component/" + str(self.component_config.id)+"/"
        _, exported = self.__sim_count.sim_count(
            power,
            topic=topic_str,
            data=self.simulation,
            prefix="pv%s" % ("" if self.component_config.id == 1 else "2"))

        inverter_state = InverterState(power=power, exported=exported)
        self.__store.set(inverter_state)
Exemple #28
0
    def read_state(self) -> InverterState:
        unit = self.component_config.configuration.modbus_id
        # 40380 = "Meter 2/Total Real Power (sum of active phases)" (Watt)
        power = self.__tcp_client.read_holding_registers(40380,
                                                         ModbusDataType.INT_16,
                                                         unit=unit)
        topic_str = "openWB/set/system/device/" + str(self.__device_id) + \
            "/component/" + str(self.component_config.id)+"/"
        _, exported = self.__sim_count.sim_count(power,
                                                 topic=topic_str,
                                                 data=self.simulation,
                                                 prefix="pv")

        return InverterState(exported=exported, power=power)
Exemple #29
0
    def update(self, unit_id: int) -> None:
        reg_p = self.__version_factory()
        power = self.__get_power(unit_id, reg_p)

        topic_str = "openWB/set/system/device/" + \
            str(self.__device_id)+"/component/" + \
            str(self.component_config.id)+"/"
        _, exported = self.__sim_count.sim_count(
            power,
            topic=topic_str,
            data=self.simulation,
            prefix="pv%s" % ("" if self.component_config.id == 1 else "2"))
        inverter_state = InverterState(power=power, exported=exported)
        self.__store.set(inverter_state)
Exemple #30
0
 def __update_variant_1(self) -> InverterState:
     # 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
     }
     '''
     inverter_state = self.__read_variant_1()
     pv_power = -inverter_state["Production_W"]
     log.debug('Speicher PV Leistung: ' + str(pv_power))
     topic_str = "openWB/set/system/device/" + str(
         self.__device_id) + "/component/" + str(
             self.component_config.id) + "/"
     _, exported = self.__sim_count.sim_count(
         pv_power,
         topic=topic_str,
         data=self.simulation,
         prefix="pv%s" % ("" if self.component_config.id == 1 else "2"))
     return InverterState(exported=exported, power=pv_power)