Пример #1
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)
Пример #2
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))
Пример #3
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."
         )
Пример #4
0
def update(address: str, second_battery: int):
    # `second_battery` is 0 or 1
    log.debug("Beginning update")
    bat_info = ComponentInfo(None, "Solaredge", "bat")
    with SingleComponentUpdateContext(bat_info):
        with ModbusClient(address) as client:
            update_solaredge_battery(client, range(1, 2 + second_battery))
    log.debug("Update completed successfully")
Пример #5
0
def update(address1: str, address2: str, read_external: int, pvmodul: str):
    # read_external is 0 or 1
    log.debug("Beginning update")
    addresses = [address for address in [address1, address2] if address != "none"]
    pv_other = pvmodul != "none"
    bat_info = ComponentInfo(None, "E3DC", "bat")
    with SingleComponentUpdateContext(bat_info):
        update_e3dc_battery(addresses, read_external, pv_other)
    log.debug("Update completed successfully")
Пример #6
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.")
Пример #7
0
 def update(self) -> None:
     log.debug("Start device reading " + str(self.components))
     if self.components:
         for component in self.components.values():
             # Auch wenn bei einer Komponente ein Fehler auftritt, sollen alle anderen noch ausgelesen werden.
             with SingleComponentUpdateContext(component.component_info):
                 component.update()
     else:
         log.warning(
             self.device_config.name +
             ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden."
         )
Пример #8
0
def update(bydhvip: str, bydhvuser: str, bydhvpass: str):
    '''BYD Speicher bieten zwei HTML-Seiten, auf denen Informationen abgegriffen werden können:
    /asp/Home.asp und /asp/RunData.asp. Aktuell (2022-03) ist die Leistungsangabe (Power) auf der
    RunData.asp auf ganze kW gerundet und somit für openWB nicht brauchbar.
    '''
    log.debug("Beginning update")
    bat_info = ComponentInfo(None, "BYD", "bat")
    with SingleComponentUpdateContext(bat_info):
        # response = req.get_http_session().get('http://' + bydhvip + '/asp/RunData.asp', auth=(bydhvuser, bydhvpass))
        response = req.get_http_session().get('http://' + bydhvip +
                                              '/asp/Home.asp',
                                              auth=(bydhvuser, bydhvpass))
        get_bat_value_store(1).set(BydParser.parse(response.text))
    log.debug("Update completed successfully")
Пример #9
0
def read_inverter(ip1: str, webbox: int, ip2: str, ip3: str, ip4: str,
                  version: int, hybrid: int, num: int,
                  sunny_boy_smart_energy: int):
    def create_webbox_inverter(address: str):
        return SmaWebboxInverter(address, SmaWebboxInverterSetup(id=num))

    def create_modbus_inverter(address: str):
        config = SmaSunnyBoyInverterSetup(
            id=num,
            configuration=SmaSunnyBoyInverterConfiguration(
                hybrid=bool(hybrid), version=SmaInverterVersion(version)))
        return inverter.SmaSunnyBoyInverter(
            0, config, modbus.ModbusTcpClient_(address, 502))

    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 inv in itertools.chain((inverter1, ), inverters_additional):
            state = inv.read()
            total_power += state.power
            total_energy += state.exported
        if hybrid == 1:
            if sunny_boy_smart_energy == 0:
                bat_comp = bat.SunnyBoyBat(0, SmaSunnyBoyBatSetup(),
                                           modbus.ModbusTcpClient_(ip1, 502))
            else:
                bat_comp = bat_smart_energy.SunnyBoySmartEnergyBat(
                    0, SmaSunnyBoySmartEnergyBatSetup(),
                    modbus.ModbusTcpClient_(ip1, 502))
            bat_state = bat_comp.read()
            total_power -= bat_state.power
            total_energy = total_energy + bat_state.imported - bat_state.exported
        get_inverter_value_store(num).set(
            InverterState(exported=total_energy, power=total_power))
Пример #10
0
def read_legacy(
        component_type: str,
        ip_address: str,
        meter_id: int,
        variant: int,
        ip_address2: str = "none",
        num: Optional[int] = None) -> None:

    device_config = Fronius()
    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].component_descriptor.configuration_factory()
        if component_type == "bat":
            component_config.configuration.meter_id = meter_id
        elif component_type == "counter_sm":
            component_config.configuration.variant = variant
            component_config.configuration.meter_id = meter_id
    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('Fronius IP-Adresse: ' + ip_address)

    if component_type == "bat" or "counter" in component_type:
        dev.update()
    elif component_type == "inverter" and num:
        inverter1 = inverter.FroniusInverter(num, component_config, dev.device_config.configuration)
        with SingleComponentUpdateContext(inverter1.component_info):
            total_power = inverter1.read_power()
            if ip_address2 != "none":
                dev.device_config.configuration.ip_address = ip_address2
                inverter2 = inverter.FroniusInverter(num, component_config, dev.device_config.configuration)
                total_power += inverter2.read_power()
            get_inverter_value_store(num).set(inverter1.fill_inverter_state(total_power))
    else:
        raise Exception("illegal component num " + str(num) + ". Should be an int if it is an inverter.")
Пример #11
0
 def update(self) -> None:
     with SingleComponentUpdateContext(self.component_info):
         self.value_store.set(
             CarState(
                 soc=api.fetch_soc(self.config.akey, self.config.token)))
Пример #12
0
def read_legacy(component_type: str,
                ip_address: str,
                port: str,
                slave_id0: str,
                slave_id1: Optional[str] = None,
                slave_id2: Optional[str] = None,
                slave_id3: Optional[str] = None,
                batwrsame: Optional[int] = None,
                extprodakt: Optional[int] = None,
                zweiterspeicher: Optional[int] = None,
                subbat: Optional[int] = None,
                ip2address: Optional[str] = None,
                num: Optional[int] = None) -> None:
    def get_bat_state() -> Tuple[List, List]:
        def create_bat(modbus_id: int) -> bat.SolaredgeBat:
            component_config = SolaredgeBatSetup(
                id=num,
                configuration=SolaredgeBatConfiguration(modbus_id=modbus_id))
            return bat.SolaredgeBat(dev.device_config.id, component_config,
                                    dev.client)

        bats = [create_bat(1)]
        if zweiterspeicher == 1:
            bats.append(create_bat(2))
        soc_bat, power_bat = [], []
        for battery in bats:
            state = battery.read_state()
            power_bat.append(state.power)
            soc_bat.append(state.soc)
        return power_bat, soc_bat

    def get_external_inverter_state(dev: Device, id: int) -> InverterState:
        component_config = SolaredgeExternalInverterSetup(
            id=num,
            configuration=SolaredgeExternalInverterConfiguration(modbus_id=id))

        ext_inverter = external_inverter.SolaredgeExternalInverter(
            dev.device_config.id, component_config, dev.client)
        return ext_inverter.read_state()

    def create_inverter(modbus_id: int) -> inverter.SolaredgeInverter:
        component_config = SolaredgeInverterSetup(
            id=num,
            configuration=SolaredgeInverterConfiguration(modbus_id=modbus_id))
        return inverter.SolaredgeInverter(dev.device_config.id,
                                          component_config, dev.client)

    log.debug("Solaredge IP: " + ip_address + ":" + str(port))
    log.debug("Solaredge Slave-IDs: [" + str(slave_id0) + ", " +
              str(slave_id1) + ", " + str(slave_id2) + ", " + str(slave_id3) +
              "]")
    log.debug("Solaredge Bat-WR-gleiche IP: " + str(batwrsame) +
              ", Externer WR: " + str(extprodakt) + ", 2. Speicher: " +
              str(zweiterspeicher) + ", Speicherleistung subtrahieren: " +
              str(subbat) + " 2. IP: " + str(ip2address) + ", Num: " +
              str(num))

    if port == "":
        parsed_url = parse_url(ip_address)
        ip_address = parsed_url.hostname
        if parsed_url.port:
            port = parsed_url.port
        else:
            port = 502
    dev = Device(
        Solaredge(configuration=SolaredgeConfiguration(ip_address=ip_address,
                                                       port=int(port))))
    if component_type == "counter":
        dev.add_component(
            SolaredgeCounterSetup(id=num,
                                  configuration=SolaredgeCounterConfiguration(
                                      modbus_id=int(slave_id0))))
        log.debug('Solaredge ModbusID: ' + str(slave_id0))
        dev.update()
    elif component_type == "inverter":
        if ip2address == "none":
            modbus_ids = list(
                map(
                    int,
                    filter(lambda id: id.isnumeric(),
                           [slave_id0, slave_id1, slave_id2, slave_id3])))
            inverters = [
                create_inverter(modbus_id) for modbus_id in modbus_ids
            ]
            with SingleComponentUpdateContext(inverters[0].component_info):
                total_power = 0
                total_energy = 0
                total_currents = [0.0] * 3
                with dev.client:
                    for inv in inverters:
                        state = inv.read_state()
                        total_power += state.power
                        total_energy += state.exported
                        total_currents = list(
                            map(add, total_currents, state.currents))

                    if extprodakt:
                        state = get_external_inverter_state(
                            dev, int(slave_id0))
                        total_power -= state.power

                    if batwrsame == 1:
                        bat_power, soc_bat = get_bat_state()
                        if subbat == 1:
                            total_power -= sum(min(p, 0) for p in bat_power)
                        else:
                            total_power -= sum(bat_power)
                if batwrsame == 1:
                    get_bat_value_store(1).set(
                        BatState(power=sum(bat_power), soc=mean(soc_bat)))
                get_inverter_value_store(num).set(
                    InverterState(exported=total_energy,
                                  power=min(0, total_power),
                                  currents=total_currents))
        else:
            inv = create_inverter(int(slave_id0))
            with SingleComponentUpdateContext(inv.component_info):
                with dev.client:
                    state = inv.read_state()
                    total_power = state.power * -1
                    total_energy = state.exported

                if batwrsame == 1:
                    zweiterspeicher = 0
                    bat_power, _ = get_bat_state()
                    total_power -= sum(bat_power)
                    get_bat_value_store(1).set(
                        BatState(power=sum(bat_power), soc=mean(soc_bat)))
                device_config = Solaredge(configuration=SolaredgeConfiguration(
                    ip_address=ip2address))
                dev = Device(device_config)
                inv = create_inverter(int(slave_id0))
                with dev.client:
                    state = inv.read_state()
                    total_power -= state.power
                    total_energy += state.exported
                    if extprodakt:
                        state = get_external_inverter_state(
                            dev, int(slave_id0))
                        total_power -= state.power
                get_inverter_value_store(num).set(
                    InverterState(exported=total_energy, power=total_power))

    elif component_type == "bat":
        with SingleComponentUpdateContext(
                ComponentInfo(0, "Solaredge Speicher", "bat")):
            power_bat, soc_bat = get_bat_state()
            get_bat_value_store(1).set(
                BatState(power=sum(power_bat), soc=mean(soc_bat)))
Пример #13
0
 def update(self) -> None:
     for component in self._components:
         with SingleComponentUpdateContext(component.component_info):
             component.update(self.__session)
Пример #14
0
 def read_datagram(self, datagram: dict) -> bool:
     if self.__serial_matcher(datagram):
         with SingleComponentUpdateContext(self.component_info):
             self.__value_store.set(self.__parser(datagram))
         return True
     return False