예제 #1
0
def update_byd(bydhvip: str, bydhvuser: str, bydhvpass: str):
    log.debug("Beginning update")
    response = requests.get('http://' + bydhvip + '/asp/RunData.asp',
                            auth=(bydhvuser, bydhvpass))
    response.raise_for_status()
    get_bat_value_store(1).set(BydParser.parse(response.text))
    log.debug("Update completed successfully")
예제 #2
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)))
예제 #3
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"]))
예제 #4
0
파일: solaredge.py 프로젝트: okaegi/openWB
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)))
예제 #5
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")
예제 #6
0
 def __init__(self, component_config: dict,
              tcp_client: modbus.ModbusClient) -> None:
     self.component_config = component_config
     self.__tcp_client = tcp_client
     self.__store = get_bat_value_store(component_config["id"])
     self.component_info = ComponentInfo.from_component_config(
         component_config)
예제 #7
0
파일: bat.py 프로젝트: benderl/openWB
 def __init__(self, device_id: int, component_config: Union[Dict, LgBatSetup]) -> None:
     self.__device_id = device_id
     self.component_config = dataclass_from_dict(LgBatSetup, component_config)
     self.__sim_count = simcount.SimCountFactory().get_sim_counter()()
     self.__simulation = {}
     self.__store = get_bat_value_store(self.component_config.id)
     self.component_info = ComponentInfo.from_component_config(self.component_config)
예제 #8
0
파일: bat.py 프로젝트: LKuemmel/openWB
 def __init__(self, device_id: int, component_config: dict) -> None:
     self.__device_id = device_id
     self.component_config = component_config
     self.__sim_count = simcount.SimCountFactory().get_sim_counter()()
     self.__simulation = {}
     self.__store = get_bat_value_store(component_config["id"])
     self.component_info = ComponentInfo.from_component_config(component_config)
예제 #9
0
 def __init__(self, component_config: Union[Dict, SmaSunnyIslandBatSetup],
              tcp_client: modbus.ModbusTcpClient_) -> None:
     self.component_config = dataclass_from_dict(SmaSunnyIslandBatSetup,
                                                 component_config)
     self.__tcp_client = tcp_client
     self.__store = get_bat_value_store(self.component_config.id)
     self.component_info = ComponentInfo.from_component_config(
         self.component_config)
예제 #10
0
파일: e3dc.py 프로젝트: yankee42/openWB
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))
예제 #11
0
파일: bat.py 프로젝트: yankee42/openWB
 def __init__(self, device_id: int, component_config: dict) -> None:
     self.__device_id = device_id
     self.component_config = component_config
     ip_address = component_config["configuration"]["ip_address"]
     self.__tcp_client = modbus.ModbusClient(ip_address, 502)
     self.__sim_count = simcount.SimCountFactory().get_sim_counter()()
     self.__simulation = {}
     self.__store = get_bat_value_store(component_config["id"])
     self.component_info = ComponentInfo.from_component_config(component_config)
예제 #12
0
파일: bat.py 프로젝트: benderl/openWB
 def __init__(self,
              modbus_id: int,
              component_config: Union[Dict, GoodWeBatSetup],
              tcp_client: modbus.ModbusTcpClient_) -> None:
     self.__modbus_id = modbus_id
     self.component_config = dataclass_from_dict(GoodWeBatSetup, component_config)
     self.__tcp_client = tcp_client
     self.__store = get_bat_value_store(self.component_config.id)
     self.component_info = ComponentInfo.from_component_config(self.component_config)
예제 #13
0
파일: bat.py 프로젝트: LKuemmel/openWB
 def __init__(self, device_id: int, component_config: dict,
              tcp_client: modbus.ModbusClient) -> None:
     self.component_config = component_config
     factory = kit_bat_version_factory(
         component_config["configuration"]["version"])
     self.__client = factory(component_config["configuration"]["id"],
                             tcp_client)
     self.__tcp_client = tcp_client
     self.__store = get_bat_value_store(component_config["id"])
     self.component_info = ComponentInfo.from_component_config(
         component_config)
예제 #14
0
파일: bat.py 프로젝트: benderl/openWB
 def __init__(self,
              device_id: int,
              component_config: Union[Dict, SolaredgeBatSetup],
              tcp_client: modbus.ModbusTcpClient_) -> None:
     self.__device_id = device_id
     self.component_config = dataclass_from_dict(SolaredgeBatSetup, component_config)
     self.__tcp_client = tcp_client
     self.__sim_count = simcount.SimCountFactory().get_sim_counter()()
     self.simulation = {}
     self.__store = get_bat_value_store(self.component_config.id)
     self.component_info = ComponentInfo.from_component_config(self.component_config)
예제 #15
0
 def __init__(
         self, device_id: int, device_address: str, device_variant: int,
         component_config: Union[Dict, SonnenbatterieBatSetup]) -> None:
     self.__device_id = device_id
     self.__device_address = device_address
     self.__device_variant = device_variant
     self.component_config = dataclass_from_dict(SonnenbatterieBatSetup,
                                                 component_config)
     self.__sim_count = simcount.SimCountFactory().get_sim_counter()()
     self.simulation = {}
     self.__store = get_bat_value_store(self.component_config.id)
     self.component_info = ComponentInfo.from_component_config(
         self.component_config)
예제 #16
0
 def __init__(self, device_id: int, component_config: dict,
              tcp_client: modbus.ModbusClient) -> None:
     self.__device_id = device_id
     self.component_config = component_config
     factory = kit_bat_version_factory(
         component_config["configuration"]["version"])
     self.__client = factory(component_config["configuration"]["id"],
                             tcp_client)
     self.__tcp_client = tcp_client
     self.__sim_count = simcount.SimCountFactory().get_sim_counter()()
     self.simulation = {}
     self.__store = get_bat_value_store(component_config["id"])
     self.component_info = ComponentInfo.from_component_config(
         component_config)
예제 #17
0
파일: bat.py 프로젝트: okaegi/openWB
    def __init__(self, component_config: dict, domain: str) -> None:
        self.__get_power = create_request_function(
            domain, component_config["configuration"]["power_path"])
        self.__get_imported = create_request_function(
            domain, component_config["configuration"]["imported_path"])
        self.__get_exported = create_request_function(
            domain, component_config["configuration"]["exported_path"])
        self.__get_soc = create_request_function(
            domain, component_config["configuration"]["soc_path"])

        self.component_config = component_config
        self.__store = get_bat_value_store(component_config["id"])
        self.component_info = ComponentInfo.from_component_config(
            component_config)
예제 #18
0
파일: bat.py 프로젝트: benderl/openWB
 def __init__(self, device_id: int,
              component_config: Union[Dict, BatKitFlexSetup],
              tcp_client: modbus.ModbusTcpClient_) -> None:
     self.__device_id = device_id
     self.component_config = dataclass_from_dict(BatKitFlexSetup,
                                                 component_config)
     factory = kit_bat_version_factory(
         self.component_config.configuration.version)
     self.__client = factory(self.component_config.configuration.id,
                             tcp_client)
     self.__tcp_client = tcp_client
     self.__sim_count = simcount.SimCountFactory().get_sim_counter()()
     self.simulation = {}
     self.__store = get_bat_value_store(self.component_config.id)
     self.component_info = ComponentInfo.from_component_config(
         self.component_config)
예제 #19
0
파일: bat.py 프로젝트: benderl/openWB
    def __init__(self, device_id: int, component_config: Union[Dict,
                                                               HttpBatSetup],
                 url: str) -> None:
        self.__device_id = device_id
        self.component_config = dataclass_from_dict(HttpBatSetup,
                                                    component_config)
        self.__sim_count = simcount.SimCountFactory().get_sim_counter()()
        self.simulation = {}
        self.__store = get_bat_value_store(self.component_config.id)
        self.component_info = ComponentInfo.from_component_config(
            self.component_config)

        self.__get_power = create_request_function(
            url, self.component_config.configuration.power_path)
        self.__get_imported = create_request_function(
            url, self.component_config.configuration.imported_path)
        self.__get_exported = create_request_function(
            url, self.component_config.configuration.exported_path)
        self.__get_soc = create_request_function(
            url, self.component_config.configuration.soc_path)
예제 #20
0
파일: device.py 프로젝트: benderl/openWB
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)))
예제 #21
0
def update_solar_edge(client: ModbusClient, slave_ids: List[int],
                      batwrsame: int, extprodakt: int, zweiterspeicher: int,
                      subbat: int):
    storage_slave_ids = slave_ids[0:1 + zweiterspeicher]
    storage_powers = []
    if batwrsame == 1:
        all_socs = [
            client.read_holding_registers(62852,
                                          ModbusDataType.FLOAT_32,
                                          wordorder=Endian.Little,
                                          unit=slave_id)
            for slave_id in storage_slave_ids
        ]
        storage_powers = [
            client.read_holding_registers(62836,
                                          ModbusDataType.FLOAT_32,
                                          wordorder=Endian.Little,
                                          unit=slave_id)
            for slave_id in storage_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)))

    total_energy = 0
    total_power = 0
    total_currents = [0, 0, 0]

    for slave_id in slave_ids:
        # 40083 = AC Power value (Watt), 40084 = AC Power scale factor
        power_base, power_scale = client.read_holding_registers(
            40083, [ModbusDataType.INT_16] * 2, unit=slave_id)
        total_power -= power_base * math.pow(10, power_scale)
        # 40093 = AC Lifetime Energy production (Watt hours)
        energy_base, energy_scale = client.read_holding_registers(
            40093, [ModbusDataType.UINT_32, ModbusDataType.INT_16],
            unit=slave_id)
        # 40072/40073/40074 = AC Phase A/B/C Current value (Amps)
        # 40075 = AC Current scale factor
        currents = client.read_holding_registers(
            40072, [ModbusDataType.UINT_16] * 3 + [ModbusDataType.INT_16],
            unit=slave_id)
        # Registers that are not applicable to a meter class return the unsupported value. (e.g. Single Phase
        # meters will support only summary and phase A values):
        for i in range(3):
            if currents[i] == UINT16_UNSUPPORTED:
                currents[i] = 0
        log.debug(
            "slave=%d: power=%d*10^%d, energy=%d*10^%d, currents=%s * 10^%d",
            slave_id, power_base, power_scale, energy_base, energy_scale,
            currents[0:3], currents[3])
        total_energy += energy_base * math.pow(10, energy_scale)
        currents_scale = math.pow(10, currents[3])
        for i in range(3):
            total_currents[i] += currents[i] * currents_scale
    if extprodakt == 1:
        # 40380 = "Meter 2/Total Real Power (sum of active phases)" (Watt)
        try:
            total_power -= client.read_holding_registers(40380,
                                                         ModbusDataType.INT_16,
                                                         unit=slave_ids[0])
        except Exception:
            # catch wrong configured "extprodakt"
            log.error(
                "Unable to read secondary SmartMeter! Check configuration!")
    if subbat == 1:
        total_power -= sum(min(p, 0) for p in storage_powers)
    else:
        total_power -= sum(storage_powers)

    get_inverter_value_store(1).set(
        InverterState(counter=total_energy,
                      power=min(0, total_power),
                      currents=total_currents))
예제 #22
0
 def __init__(self, component_config: Union[Dict, TeslaBatSetup]) -> None:
     self.component_config = dataclass_from_dict(TeslaBatSetup,
                                                 component_config)
     self.__store = get_bat_value_store(self.component_config.id)
     self.component_info = ComponentInfo.from_component_config(
         self.component_config)