Example #1
0
def update(ipaddress: str):
    log.debug("Beginning update")
    client = ModbusClient(ipaddress, port=502)
    #40074 EVU Punkt negativ -> Einspeisung in Watt
    power_all = client.read_holding_registers(40073,
                                              ModbusDataType.INT_32,
                                              wordorder=Endian.Little,
                                              unit=1)
    #40130 Phasenleistung in Watt
    # max 6 Leistungsmesser verbaut ab 410105, typ 1 ist evu
    # bei den meisten e3dc auf 40128
    #for i in range (40104,40132,4):
    for i in range(40128, 40103, -4):
        #powers = client.read_holding_registers(40129, [ModbusDataType.INT_16] * 3, unit=1)
        powers = client.read_holding_registers(i, [ModbusDataType.INT_16] * 4,
                                               unit=1)
        log.debug("I: %d, p[0] typ %d p[1] a1 %d p[2] a2 %d p[3] a3 %d", i,
                  powers[0], powers[1], powers[2], powers[3])
        if powers[0] == 1:
            log.debug("Evu Leistungsmessung gefunden")
            break
    counter_import, counter_export = SimCountFactory().get_sim_counter()(
    ).sim_count(power_all, prefix="bezug")
    get_counter_value_store(1).set(
        CounterState(imported=counter_import,
                     exported=counter_export,
                     power=power_all,
                     powers=powers[1:]))
    log.debug("Update completed successfully")
Example #2
0
def update_solaredge_battery(client: ModbusClient, slave_ids: Iterable[int]):
    all_socs = [client.read_holding_registers(
        62852, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=slave_id
    ) for slave_id in slave_ids]
    storage_powers = [
        client.read_holding_registers(
            62836, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=slave_id
        ) for slave_id in slave_ids
    ]
    log.debug("Battery SoCs=%s, powers=%s", all_socs, storage_powers)
    get_bat_value_store(1).set(BatState(power=sum(storage_powers), soc=mean(all_socs)))
Example #3
0
def update(ipaddress: str, modbusport: int, slaveid: int):
    log.debug("Beginning update")
    client = ModbusClient(ipaddress, port=modbusport)

    def read_scaled_int16(address: int, count: int):
        return scale_registers(
            client.read_holding_registers(address, [ModbusDataType.INT_16] *
                                          (count + 1),
                                          unit=slaveid))

    # 40206: Total Real Power (sum of active phases)
    # 40206/40207/40208: Real Power by phase
    # 40210: AC Real Power Scale Factor
    powers = [-power for power in read_scaled_int16(40206, 4)]

    # 40191/40192/40193: AC Current by phase
    # 40194: AC Current Scale Factor
    currents = read_scaled_int16(40191, 3)

    # 40196/40197/40198: Voltage per phase
    # 40203: AC Voltage Scale Factor
    voltages = read_scaled_int16(40196, 7)[:3]

    # 40204: AC Frequency
    # 40205: AC Frequency Scale Factor
    frequency, = read_scaled_int16(40204, 1)

    # 40222/40223/40224: Power factor by phase (unit=%)
    # 40225: AC Power Factor Scale Factor
    power_factors = [
        power_factor / 100 for power_factor in read_scaled_int16(40222, 3)
    ]

    # 40234: Total Imported Real Energy
    counter_imported = client.read_holding_registers(40234,
                                                     ModbusDataType.UINT_32,
                                                     unit=slaveid)

    # 40226: Total Exported Real Energy
    counter_exported = client.read_holding_registers(40226,
                                                     ModbusDataType.UINT_32,
                                                     unit=slaveid)

    get_counter_value_store(1).set(
        CounterState(imported=counter_imported,
                     exported=counter_exported,
                     power=powers[0],
                     powers=powers[1:],
                     voltages=voltages,
                     currents=currents,
                     power_factors=power_factors,
                     frequency=frequency))
    log.debug("Update completed successfully")
Example #4
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))