Exemple #1
0
 def update(self) -> None:
     log.MainLogger().debug("Start device reading " + str(self._components))
     if len(self._components) == 1:
         for component in self._components:
             if isinstance(self._components[component], inverter.PowerdogInverter):
                 with SingleComponentUpdateContext(self._components[component].component_info):
                     self._components[component].update()
             else:
                 raise Exception(
                     "Wenn ein EVU-Zähler konfiguriert wurde, muss immer auch ein WR konfiguriert sein.")
     elif len(self._components) == 2:
         with MultiComponentUpdateContext(self._components):
             for component in self._components:
                 if isinstance(self._components[component], counter.PowerdogCounter):
                     home_consumption = self._components[component].update()
                 elif isinstance(self._components[component], inverter.PowerdogInverter):
                     inverter_power = self._components[component].update()
                 else:
                     raise Exception(
                         "illegal component type " + self._components[component].component_config["type"] +
                         ". Allowed values: " + ','.join(COMPONENT_TYPE_TO_MODULE.keys()))
             counter_power = home_consumption + inverter_power
             for component in self._components:
                 if isinstance(self._components[component], counter.PowerdogCounter):
                     self._components[component].set_counter_state(counter_power)
     else:
         log.MainLogger().warning(
             self.device_config["name"] +
             ": Es konnten keine Werte gelesen werden, da noch keine oder zu viele Komponenten konfiguriert wurden."
         )
Exemple #2
0
    def update(self, resp: Dict) -> None:
        log.MainLogger().debug("Komponente " + self.component_config["name"] +
                               " auslesen.")
        power = resp["2913"]["0"]
        frequency = resp["2914"]["0"] / 100
        powers = self.__parse_list_values(resp, 2897)
        voltages = self.__parse_list_values(resp, 2833, 100)
        currents = self.__parse_list_values(resp, 2865, 100)
        try:
            power_factors = self.__parse_list_values(resp, 2881)
        except KeyError:
            log.MainLogger().debug(
                "Powerfaktor sollte laut Doku enthalten sein, ID 2881 kann aber nicht ermittelt werden."
            )
            power_factors = None
        topic_str = "openWB/set/system/device/{}/component/{}/".format(
            self.__device_id, self.component_config["id"])
        imported, exported = self.__sim_count.sim_count(power,
                                                        topic=topic_str,
                                                        data=self.simulation,
                                                        prefix="bezug")

        counter_state = CounterState(imported=imported,
                                     exported=exported,
                                     power=power,
                                     powers=powers,
                                     currents=currents,
                                     voltages=voltages,
                                     frequency=frequency)
        if power_factors:
            counter_state.power_factors = power_factors
        self.__store.set(counter_state)
Exemple #3
0
def read_legacy(component_type: str, version: int, ip_address: str, port: int,
                id: int, num: Optional[int]):
    """ Ausführung des Moduls als Python-Skript
    """
    COMPONENT_TYPE_TO_MODULE = {
        "bat": bat,
        "counter": counter,
        "inverter": inverter
    }
    log.MainLogger().debug('Start reading flex')
    device_config = get_default_config()
    device_config["configuration"]["ip_address"] = ip_address
    device_config["configuration"]["port"] = port
    dev = Device(device_config)
    if component_type in COMPONENT_TYPE_TO_MODULE:
        component_config = COMPONENT_TYPE_TO_MODULE[
            component_type].get_default_config()
    else:
        raise Exception("illegal component type " + component_type +
                        ". Allowed values: " +
                        ','.join(COMPONENT_TYPE_TO_MODULE.keys()))

    component_config["id"] = num
    component_config["configuration"]["version"] = version
    component_config["configuration"]["id"] = id
    dev.add_component(component_config)

    log.MainLogger().debug('openWB flex Version: ' + str(version))
    log.MainLogger().debug('openWB flex-Kit IP-Adresse: ' + str(ip_address))
    log.MainLogger().debug('openWB flex-Kit Port: ' + str(port))
    log.MainLogger().debug('openWB flex-Kit ID: ' + str(id))

    dev.update()
Exemple #4
0
 def __update_variant_1(self) -> CounterState:
     # 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
     }
     '''
     counter_state = self.__read_variant_1()
     grid_power = -counter_state["GridFeedIn_W"]
     log.MainLogger().debug('EVU Leistung: ' + str(grid_power))
     # Es wird nur eine Spannung ausgegeben
     grid_voltage = counter_state["Uac"]
     log.MainLogger().debug('EVU Spannung: ' + str(grid_voltage))
     grid_frequency = counter_state["Fac"]
     log.MainLogger().debug('EVU Netzfrequenz: ' + str(grid_frequency))
     topic_str = "openWB/set/system/device/" + str(
         self.__device_id) + "/component/" + str(
             self.component_config["id"]) + "/"
     imported, exported = self.__sim_count.sim_count(grid_power,
                                                     topic=topic_str,
                                                     data=self.__simulation,
                                                     prefix="bezug")
     return CounterState(
         power=grid_power,
         voltages=[grid_voltage] * 3,
         frequency=grid_frequency,
         imported=imported,
         exported=exported,
     )
Exemple #5
0
def calculate_import_export(seconds_since_previous: Number, power1: Number,
                            power2: Number) -> typing.Tuple[Number, Number]:
    try:
        log.MainLogger().debug(
            "simcount Berechnungsgrundlage: vergangene Zeit [s]" +
            str(seconds_since_previous) + ", vorherige Leistung[W]: " +
            str(power1) + ", aktuelle Leistung[W]: " + str(power2))
        power_low = min(power1, power2)
        power_high = max(power1, power2)
        gradient = (power_high - power_low) / seconds_since_previous

        # Berechnung der Gesamtfläche (ohne Beträge, Fläche unterhalb der x-Achse reduziert die Fläche oberhalb der
        # x-Achse)
        def energy_function(seconds):
            return .5 * gradient * seconds**2 + power_low * seconds

        energy_total = energy_function(seconds_since_previous)
        log.MainLogger().debug("simcount Gesamtenergie im Zeitintervall: " +
                               str(energy_total))
        if power_low < 0 < power_high:
            # Berechnung der Fläche im vierten Quadranten -> Export
            power_zero_seconds = -power_low / gradient
            energy_exported = energy_function(power_zero_seconds)
            log.MainLogger().debug(
                "simcount exportierte Energie im Zeitintervall: " +
                str(energy_exported))
            # Betragsmäßige Gesamtfläche: oberhalb der x-Achse = Import, unterhalb der x-Achse: Export
            return energy_total - energy_exported, energy_exported * -1
        return (energy_total, 0) if energy_total >= 0 else (0, -energy_total)
    except Exception as e:
        process_error(e)
Exemple #6
0
 def store_error(self, component_info: ComponentInfo) -> None:
     try:
         if self.fault_state is not FaultStateLevel.NO_ERROR:
             log.MainLogger().error(component_info.name + ": FaultState " +
                                    str(self.fault_state) + ", FaultStr " +
                                    self.fault_str + ", Traceback: \n" +
                                    traceback.format_exc())
         ramdisk = compatibility.is_ramdisk_in_use()
         if ramdisk:
             topic = self.type_topic_mapping_comp.get(
                 component_info.type, component_info.type)
             prefix = "openWB/set/" + topic + "/"
             if component_info.id is not None:
                 if topic == "lp":
                     prefix += str(component_info.id) + "/socF"
                 else:
                     prefix += str(component_info.id) + "/f"
             else:
                 prefix += "f"
             pub.pub_single(prefix + "aultStr", self.fault_str)
             pub.pub_single(prefix + "aultState", self.fault_state.value)
         else:
             topic = self.__type_topic_mapping(component_info.type)
             pub.Pub().pub(
                 "openWB/set/" + topic + "/" + str(component_info.id) +
                 "/get/fault_str", self.fault_str)
             pub.Pub().pub(
                 "openWB/set/" + topic + "/" + str(component_info.id) +
                 "/get/fault_state", self.fault_state.value)
     except Exception:
         log.MainLogger().exception("Fehler im Modul fault_state")
Exemple #7
0
def read_legacy(ip_address: str, modbus_id: int) -> None:
    COMPONENT_TYPE_TO_MODULE = {
        "bat": bat,
        "counter": counter,
        "inverter": inverter
    }

    device_config = get_default_config()
    device_config["configuration"]["ip_address"] = ip_address
    device_config["configuration"]["modbus_id"] = modbus_id
    dev = Device(device_config)
    for component_type in ["bat", "counter", "inverter"]:
        if component_type in COMPONENT_TYPE_TO_MODULE:
            component_config = COMPONENT_TYPE_TO_MODULE[
                component_type].get_default_config()
        else:
            raise Exception("illegal component type " + component_type +
                            ". Allowed values: " +
                            ','.join(COMPONENT_TYPE_TO_MODULE.keys()))
        if component_type == "counter" or component_type == "bat":
            num = None
        else:
            num = 1
        component_config["id"] = num
        dev.add_component(component_config)

    log.MainLogger().debug('Huawei IP-Adresse: ' + str(ip_address))
    log.MainLogger().debug('Huawei Modbus-ID: ' + str(modbus_id))

    dev.update()
Exemple #8
0
    def update(self):
        log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.")
        unit = self.component_config["configuration"]["modbus_id"]
        power = sum(self.__tcp_client.read_holding_registers(2600, [ModbusDataType.INT_16]*3, unit=unit))
        currents = [
            self.__tcp_client.read_holding_registers(reg, ModbusDataType.INT_16, unit=unit) / 10
            for reg in [2617, 2619, 2621]]
        voltages = [
            self.__tcp_client.read_holding_registers(reg, ModbusDataType.UINT_16, unit=unit) / 10
            for reg in [2616, 2618, 2610]]

        topic_str = "openWB/set/system/device/{}/component/{}/".format(
            self.__device_id, self.component_config["id"]
        )
        imported, exported = self.__sim_count.sim_count(
            power,
            topic=topic_str,
            data=self.simulation,
            prefix="bezug"
        )

        counter_state = CounterState(
            voltages=voltages,
            currents=currents,
            imported=imported,
            exported=exported,
            power=power
        )
        log.MainLogger().debug("Victron Leistung[W]: " + str(counter_state.power))
        self.__store.set(counter_state)
Exemple #9
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)
Exemple #10
0
    def update(self):
        log.MainLogger().debug("Komponente " + self.component_config["name"] +
                               " auslesen.")
        with self.__tcp_client:
            power = self.__tcp_client.read_input_registers(
                70, ModbusDataType.INT_32, wordorder=Endian.Little) * -1
            frequency = self.__tcp_client.read_input_registers(
                7, ModbusDataType.UINT_16) / 100
            try:
                powers = [
                    -value for value in self.__tcp_client.read_input_registers(
                        130, [ModbusDataType.INT_32] * 3,
                        wordorder=Endian.Little)
                ]
            except Exception:
                powers = None
            exported, imported = [
                value * 10 for value in self.__tcp_client.read_input_registers(
                    72, [ModbusDataType.UINT_32] * 2, wordorder=Endian.Little)
            ]

        counter_state = CounterState(imported=imported,
                                     exported=exported,
                                     power=power,
                                     powers=powers,
                                     frequency=frequency)
        log.MainLogger().debug("Solax Leistung[W]: " +
                               str(counter_state.power))
        self.__store.set(counter_state)
Exemple #11
0
def read_legacy(component_type: str,
                address: str,
                variant: int,
                num: Optional[int] = None) -> None:
    COMPONENT_TYPE_TO_MODULE = {
        "bat": bat,
        "counter": counter,
        "inverter": inverter
    }
    device_config = get_default_config()
    device_config["configuration"]["ip"] = address
    device_config["configuration"]["variant"] = variant
    dev = Device(device_config)
    if component_type in COMPONENT_TYPE_TO_MODULE:
        component_config = COMPONENT_TYPE_TO_MODULE[
            component_type].get_default_config()
    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.MainLogger().debug('SonnenBatterie address: ' + address)
    log.MainLogger().debug('SonnenBatterie variant: ' + str(variant))
    dev.update()
Exemple #12
0
def read_legacy(component_type: str,
                ip_address: str,
                modbus_id: Optional[int] = 100,
                mppt: Optional[int] = 0,
                num: Optional[int] = None) -> None:
    COMPONENT_TYPE_TO_MODULE = {
        "bat": bat,
        "counter": counter,
        "inverter": inverter
    }

    device_config = get_default_config()
    device_config["configuration"]["ip_address"] = ip_address
    dev = Device(device_config)

    if component_type in COMPONENT_TYPE_TO_MODULE:
        component_config = COMPONENT_TYPE_TO_MODULE[
            component_type].get_default_config()
    else:
        raise Exception("illegal component type " + component_type +
                        ". Allowed values: " +
                        ','.join(COMPONENT_TYPE_TO_MODULE.keys()))
    component_config["id"] = num
    component_config["configuration"]["modbus_id"] = modbus_id
    component_config["configuration"]["mppt"] = mppt
    dev.add_component(component_config)

    log.MainLogger().debug('Victron IP-Adresse: ' + str(ip_address))
    log.MainLogger().debug('Victron Modbus-ID: ' + str(modbus_id))
    log.MainLogger().debug('Victron MPPT: ' + str(mppt))
    dev.update()
Exemple #13
0
def read_legacy(component_type: str,
                source: int,
                version: int,
                ip_address: str,
                num: Optional[int] = None) -> None:
    COMPONENT_TYPE_TO_MODULE = {
        "bat": bat,
        "counter": counter,
        "inverter": inverter
    }
    device_config = get_default_config()
    device_config["configuration"]["source"] = source
    device_config["configuration"]["version"] = version
    device_config["configuration"]["ip_address"] = ip_address
    dev = Device(device_config)

    if component_type in COMPONENT_TYPE_TO_MODULE:
        component_config = COMPONENT_TYPE_TO_MODULE[
            component_type].get_default_config()
    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.MainLogger().debug('alpha_ess Version: ' + str(version))
    log.MainLogger().debug('alpha_ess IP-Adresse: ' + str(ip_address))

    dev.update()
Exemple #14
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)
Exemple #15
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.MainLogger().debug('Speicher Leistung: ' + str(battery_power))
     battery_soc = battery_state["USOC"]
     log.MainLogger().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
     )
Exemple #16
0
 def update(self) -> None:
     log.MainLogger().debug("Start device reading " + str(self._components))
     if self._components:
         for component in self._components:
             # Auch wenn bei einer Komponente ein Fehler auftritt, sollen alle anderen noch ausgelesen werden.
             with SingleComponentUpdateContext(self._components[component].component_info):
                 self._components[component].update()
     else:
         log.MainLogger().warning(
             self.device_config["name"] +
             ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden.")
Exemple #17
0
 def update(self) -> None:
     log.MainLogger().debug("Start device reading " + str(self._components))
     if self._components:
         with MultiComponentUpdateContext(self._components):
             # zuerst den WR auslesen
             for component in self._components:
                 if isinstance(self._components[component],
                               inverter.FroniusInverter):
                     power_inverter = self._components[component].update()
                     break
             else:
                 power_inverter = 0
             # dann Zähler auslesen und Werte verrechnen
             for component in self._components:
                 if isinstance(self._components[component],
                               counter_sm.FroniusSmCounter):
                     counter_state, meter_location = self._components[
                         component].update()
                     if meter_location == meter.MeterLocation.load:
                         # wenn SmartMeter im Verbrauchszweig sitzt sind folgende Annahmen getroffen:
                         # PV Leistung wird gleichmäßig auf alle Phasen verteilt
                         # Spannungen und Leistungsfaktoren sind am Verbrauchszweig == Einspeisepunkt
                         # Hier gehen wir mal davon aus, dass der Wechselrichter seine PV-Leistung gleichmäßig
                         # auf alle Phasen aufteilt.
                         powers = [
                             -1 * power - power_inverter / 3
                             for power in counter_state.powers
                         ]
                         # Wegen der geänderten Leistungen sind die Ströme erneut zu berechnen
                         currents = [
                             powers[i] / counter_state.voltages[i]
                             for i in range(0, 3)
                         ]
                         counter_state.powers = powers
                         counter_state.currents = currents
                     self._components[component].set_counter_state(
                         counter_state)
                     break
                 elif isinstance(self._components[component],
                                 counter_s0.FroniusS0Counter):
                     counter_state = self._components[component].update()
                     counter_state.power += power_inverter
                     self._components[component].set_counter_state(
                         counter_state)
                     break
             for component in self._components:
                 if isinstance(self._components[component], bat.FroniusBat):
                     self._components[component].update()
     else:
         log.MainLogger().warning(
             self.device_config["name"] +
             ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden."
         )
Exemple #18
0
 def update(self) -> None:
     log.MainLogger().debug("Start device reading " + str(self._components))
     if self._components:
         with MultiComponentUpdateContext(self._components):
             response = req.get_http_session().get(self.device_config["configuration"]["ip_address"], timeout=5)
             for component in self._components:
                 self._components[component].update(response.json())
     else:
         log.MainLogger().warning(
             self.device_config["name"] +
             ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden."
         )
Exemple #19
0
 def update(self) -> None:
     log.MainLogger().debug("Komponente '" + str(self.component_config["id"]) + "' "
                            + self.component_config["name"] + " wird auslesen.")
     log.MainLogger().debug("Variante: " + str(self.__device_variant))
     if self.__device_variant == 0:
         state = self.__update_variant_0()
     elif self.__device_variant == 1:
         state = self.__update_variant_1()
     elif self.__device_variant == 2:
         state = self.__update_variant_2()
     else:
         raise FaultState.error("Unbekannte Variante: " + str(self.__device_variant))
     self.__store.set(state)
     log.MainLogger().debug("Komponente "+self.component_config["name"]+" wurde erfolgreich auslesen.")
Exemple #20
0
    def __calculate_offset(self, counter: float,
                           daily_yield: float) -> Tuple[float, float, float]:
        ramdisk = compatibility.is_ramdisk_in_use()
        if ramdisk:
            try:
                with open("/var/www/html/openWB/ramdisk/pvkwh_offset",
                          "r") as f:
                    counter_offset = float(f.read())
            except FileNotFoundError as e:
                log.MainLogger().exception(str(e))
                counter_offset = 0
            try:
                with open("/var/www/html/openWB/ramdisk/pvkwh_start",
                          "r") as f:
                    counter_start = float(f.read())
            except FileNotFoundError as e:
                log.MainLogger().exception(str(e))
                counter_start = counter - daily_yield
                with open("/var/www/html/openWB/ramdisk/pvkwh_start",
                          "w") as f:
                    f.write(str(counter_start))
        else:
            topic = "openWB/system/device/" + str(self.__device_id)+"/component/" + \
                str(self.component_config["id"])+"/counter_offset"
            counter_offset = Offset().offset(topic)
            if counter_offset is None:
                counter_offset = 0
            topic = "openWB/system/device/" + str(self.__device_id)+"/component/" + \
                str(self.component_config["id"])+"/counter_start"
            counter_start = Offset().offset(topic)

        if counter_start is not None:
            counter_new = counter_start + daily_yield + counter_offset
            if counter_new > counter:
                if counter_new - counter >= 100:
                    # Korrigiere Abweichung
                    counter_diff = counter_new - counter - 99
                    counter_offset -= counter_diff
                    counter_new -= counter_diff
                counter = counter_new
            else:
                # Berechne Abweichung als Mittelwert von aktueller und bisheriger Abweichung
                counter_offset = round(
                    (counter_offset + counter - counter_start - daily_yield) /
                    2)
        else:
            counter_start = 0
        return counter, counter_start, counter_offset
Exemple #21
0
    def update(self, bat: bool) -> Tuple[CounterState, MeterLocation]:
        variant = self.component_config["configuration"]["variant"]
        log.MainLogger().debug("Komponente " + self.component_config["name"] +
                               " auslesen.")

        session = req.get_http_session()

        if variant == 0 or variant == 1:
            counter_state, meter_location = self.__update_variant_0_1(session)
        elif variant == 2:
            counter_state, meter_location = self.__update_variant_2(session)
        else:
            raise FaultState.error("Unbekannte Variante: " + str(variant))

        if meter_location == MeterLocation.load:
            response = session.get(
                'http://' + self.device_config["ip_address"] +
                '/solar_api/v1/GetPowerFlowRealtimeData.fcgi',
                params=(('Scope', 'System'), ),
                timeout=5)
            counter_state.power = float(
                response.json()["Body"]["Data"]["Site"]["P_Grid"])
            topic_str = "openWB/set/system/device/{}/component/{}/".format(
                self.__device_id, self.component_config["id"])
            # Beim Energiebezug ist nicht klar, welcher Anteil aus dem Netz bezogen wurde, und was aus
            # dem Wechselrichter kam.
            # Beim Energieexport ist nicht klar, wie hoch der Eigenverbrauch während der Produktion war.
            counter_state.imported, counter_state.exported = self.__sim_count.sim_count(
                counter_state.power,
                topic=topic_str,
                data=self.simulation,
                prefix="bezug")

        return counter_state, meter_location
Exemple #22
0
 def __on_connect(self, client, userdata, flags, rc):
     """ connect to broker and subscribe to set topics
     """
     try:
         client.subscribe(self.topic, 2)
     except Exception:
         log.MainLogger().exception("Fehler in der Restore-Klasse")
Exemple #23
0
    def __update_variant_0_1(
            self, session: Session) -> Tuple[CounterState, MeterLocation]:
        variant = self.component_config["configuration"]["variant"]
        meter_id = self.device_config["meter_id"]
        if variant == 0:
            params = (
                ('Scope', 'Device'),
                ('DeviceId', meter_id),
            )
        elif variant == 1:
            params = (
                ('Scope', 'Device'),
                ('DeviceId', meter_id),
                ('DataCollection', 'MeterRealtimeData'),
            )
        else:
            raise FaultState.error("Unbekannte Generation: " + str(variant))
        response = session.get('http://' + self.device_config["ip_address"] +
                               '/solar_api/v1/GetMeterRealtimeData.cgi',
                               params=params,
                               timeout=5)
        response_json_id = response.json()["Body"]["Data"]
        # old request for variant == 1
        # params = (
        #     ('Scope', 'System'),
        # )
        # response = req.get_http_session().get(
        #     'http://'+self.device_config["ip_address"]+'/solar_api/v1/GetMeterRealtimeData.cgi',
        #  params=params, timeout=5)
        # response_json_id = response["Body"]["Data"][meter_id]
        meter_location = MeterLocation(
            response_json_id["Meter_Location_Current"])
        log.MainLogger().debug("Einbauort: " + str(meter_location))

        power = response_json_id["PowerReal_P_Sum"]
        voltages = [
            response_json_id["Voltage_AC_Phase_" + str(num)]
            for num in range(1, 4)
        ]
        powers = [
            response_json_id["PowerReal_P_Phase_" + str(num)]
            for num in range(1, 4)
        ]
        currents = [powers[i] / voltages[i] for i in range(0, 3)]
        power_factors = [
            response_json_id["PowerFactor_Phase_" + str(num)]
            for num in range(1, 4)
        ]
        frequency = response_json_id["Frequency_Phase_Average"]
        imported = response_json_id["EnergyReal_WAC_Sum_Consumed"]
        exported = response_json_id["EnergyReal_WAC_Sum_Produced"]

        return CounterState(voltages=voltages,
                            currents=currents,
                            powers=powers,
                            imported=imported,
                            exported=exported,
                            power=power,
                            frequency=frequency,
                            power_factors=power_factors), meter_location
Exemple #24
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 #25
0
 def __init__(self, device_config: dict) -> None:
     self._components = {}  # type: Dict[str, inverter.SunwaysInverter]
     try:
         self.device_config = device_config
     except Exception:
         log.MainLogger().exception("Fehler im Modul " +
                                    device_config["name"])
Exemple #26
0
def run_device_legacy(device_config: dict, component_config: dict):
    device = Device(device_config)
    device.add_component(component_config)
    log.MainLogger().debug(
        'Http Konfiguration: ' + str(device_config["configuration"]) + str(component_config["configuration"])
    )
    device.update()
Exemple #27
0
    def update(self, response):
        log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.")
        config = self.component_config["configuration"]

        power = jq.compile(config["jq_power"]).input(response).first()
        if config["jq_imported"] == "" or config["jq_exported"] == "":
            topic_str = "openWB/set/system/device/{}/component/{}/".format(
                self.__device_id, self.component_config["id"]
            )
            imported, exported = self.__sim_count.sim_count(
                power,
                topic=topic_str,
                data=self.simulation,
                prefix="bezug"
            )
        else:
            imported = jq.compile(config["jq_imported"]).input(response).first()
            exported = jq.compile(config["jq_exported"]).input(response).first()

        counter_state = CounterState(
            imported=imported,
            exported=exported,
            power=power
        )
        self.__store.set(counter_state)
Exemple #28
0
 def update(self, unit_id: int):
     log.MainLogger().debug(
         "Komponente "+self.component_config["name"]+" auslesen.")
     time.sleep(0.1)
     factory_method = self.__get_values_factory()
     counter_state = factory_method(unit_id)
     self.__store.set(counter_state)
Exemple #29
0
 def __init__(self, device_config: dict) -> None:
     self._components = {}  # type: Dict[str, siemens_component_classes]
     try:
         self.device_config = device_config
     except Exception:
         log.MainLogger().exception("Fehler im Modul " +
                                    device_config["name"])
Exemple #30
0
def read_legacy(component_type: str, version: int, num: Optional[int] = None):
    """ Ausführung des Moduls als Python-Skript
    """
    COMPONENT_TYPE_TO_MODULE = {
        "bat": bat,
        "counter": counter,
        "inverter": inverter
    }
    device_config = get_default_config()
    dev = Device(device_config)

    if component_type in COMPONENT_TYPE_TO_MODULE:
        component_config = COMPONENT_TYPE_TO_MODULE[
            component_type].get_default_config()
    else:
        raise Exception("illegal component type " + component_type +
                        ". Allowed values: " +
                        ','.join(COMPONENT_TYPE_TO_MODULE.keys()))
    component_config["id"] = num
    component_config["configuration"]["version"] = version
    dev.add_component(component_config)

    log.MainLogger().debug('openWB Version: ' + str(version))

    dev.update()