From 418fd48a255dcf9201153fab334283468be7c3ca Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 25 Mar 2024 23:33:25 +0100 Subject: [PATCH] Support for exporting meter events --- solaredge_modbus.py | 5 ++++- sunspec.py | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/solaredge_modbus.py b/solaredge_modbus.py index ed4bfd6..24acafb 100644 --- a/solaredge_modbus.py +++ b/solaredge_modbus.py @@ -17,7 +17,8 @@ metric_data = { "ac_voltage_volts": ["gauge", "Output bus voltage"], 'ac_frequency_hertz': ["gauge", "Output bus frequency"], 'ac_power_watts': ["gauge", "Active/Reactive/Apparent AC power"], - 'ac_power_factor': ["gauge", "AC Phase factor"] + 'ac_power_factor': ["gauge", "AC Phase factor"], + 'meter_event': ["gauge", 'Power meter event'] } def export(d, m): @@ -51,6 +52,8 @@ def export(d, m): yield ('energy_watthours_total', {'meter': meter}, m.energy_real[meter]) yield ('ac_frequency_hertz', {'meter': 'mains'}, m.frequency) + for event in m.events: + yield ('meter_event', {'event': event}, float(m.events[event])) diff --git a/sunspec.py b/sunspec.py index fa33e70..cf8eed3 100644 --- a/sunspec.py +++ b/sunspec.py @@ -55,6 +55,14 @@ class CommonBlock: self.serial = regs.read_bytes(50, 32) self.device = regs.read_uint16(66) +meter_events_bits = { 2: 'Power Failure', + 3: 'Under Voltage', + 4: 'Low PF', + 5: 'Over Current', + 6: 'Over Voltage', + 7: 'Missing Sensor' } + + class Meter: def __init__(self, regs): blocks16 = (('ac_current', 0, ('total', 'a', 'b', 'c'), 0.1), @@ -95,6 +103,12 @@ class Meter: self.frequency = regs.read_int16(14, scale=15) + event_bits = regs.read_uint32(103) + self.events = {} + for bit in meter_events_bits: + self.events[meter_events_bits[bit]] = bool(event_bits & (1 << bit)) + + status_codes = [None, 'off', 'sleep', 'start', 'on', 'throttled', 'stop', 'fault', 'setup'] class InverterBlock: @@ -134,9 +148,11 @@ class Inverter: if not self._conn.connect(): raise ConnectionFailed() - def registers(self, addr, length): + def registers(self, addr, length, device=None): + if device is None: + device = self._device self.connect() - rs = self._conn.read_holding_registers(addr, length, slave=self._device) + rs = self._conn.read_holding_registers(addr, length, slave=device) return Registers(rs, length) def common_block(self):