fixed, working version of sdm630_mqtt

This commit is contained in:
Franzi 2024-08-05 14:23:12 +02:00
parent c02c770776
commit 0f304ea949
Signed by: kunsi
GPG key ID: 12E3D2136B818350

View file

@ -31,6 +31,8 @@ class SDM630_MQTT:
self.mqtt.on_connect = self._on_mqtt_connect self.mqtt.on_connect = self._on_mqtt_connect
self.mqtt.on_disconnect = self._on_mqtt_disconnect self.mqtt.on_disconnect = self._on_mqtt_disconnect
self.idx = 0
def _publish(self, topic, msg): def _publish(self, topic, msg):
LOG.debug(f"_publish({topic!r}, {msg!r})") LOG.debug(f"_publish({topic!r}, {msg!r})")
self.mqtt.publish(f"{self.mqtt_prefix.rstrip('/')}/{topic}", msg) self.mqtt.publish(f"{self.mqtt_prefix.rstrip('/')}/{topic}", msg)
@ -45,67 +47,71 @@ class SDM630_MQTT:
LOG.debug("_start()") LOG.debug("_start()")
self.mqtt.connect(self.mqtt_host, self.mqtt_port, 10) self.mqtt.connect(self.mqtt_host, self.mqtt_port, 10)
self.mqtt.loop_start() self.mqtt.loop_start()
self.modbus.open()
def stop(self): def stop(self):
LOG.debug("_stop()")
self.modbus.close()
self.mqtt.loop_stop() self.mqtt.loop_stop()
self.mqtt.disconnect() self.mqtt.disconnect()
def request_and_publish(self): def request_and_publish(self):
self.modbus.open() for readable, address in {
for idx, (readable, address) in enumerate( "active-power/L1": 0x000C,
{ "active-power/L2": 0x000E,
"active-power/L1": 0x000C, "active-power/L3": 0x0010,
"active-power/L2": 0x000E, "active-power/total": 0x0034,
"active-power/L3": 0x0010, "apparent-power/L1": 0x0012,
"active-power/total": 0x0034, "apparent-power/L2": 0x0014,
"apparent-power/L1": 0x0012, "apparent-power/L3": 0x0016,
"apparent-power/L2": 0x0014, "apparent-power/total": 0x0038,
"apparent-power/L3": 0x0016, "current-demand/L1": 0x0102,
"apparent-power/total": 0x0038, "current-demand/L2": 0x0104,
"current-demand/L1": 0x0102, "current-demand/L3": 0x0106,
"current-demand/L2": 0x0104, "current-demand/N": 0x0068,
"current-demand/L3": 0x0106, "current-demand/max_L1": 0x0108,
"current-demand/N": 0x0068, "current-demand/max_L2": 0x010A,
"current-demand/max_L1": 0x0108, "current-demand/max_L3": 0x010C,
"current-demand/max_L2": 0x010A, "current-demand/max_N": 0x006A,
"current-demand/max_L3": 0x010C, "current/L1": 0x0006,
"current-demand/max_N": 0x006A, "current/L2": 0x0008,
"current/L1": 0x0006, "current/L3": 0x000A,
"current/L2": 0x0008, "current/average": 0x002E,
"current/L3": 0x000A, "current/neutral": 0x00E0,
"current/average": 0x002E, "current/total": 0x0030,
"current/neutral": 0x00E0, "export_kVArh": 0x004C,
"current/total": 0x0030, "export_kWh": 0x004A,
"export_kVArh": 0x004C, "frequency": 0x0046,
"export_kWh": 0x004A, "import_kVArh": 0x004E,
"frequency": 0x0046, "import_kWh": 0x0048,
"import_kVArh": 0x004E, "phase-angle/L1": 0x0024,
"import_kWh": 0x0048, "phase-angle/L2": 0x0026,
"phase-angle/L1": 0x0024, "phase-angle/L3": 0x0028,
"phase-angle/L2": 0x0026, "phase-angle/total": 0x003E,
"phase-angle/L3": 0x0028, "power-demand/max": 0x0056,
"phase-angle/total": 0x003E, "power-demand/total": 0x0054,
"power-demand/max": 0x0056, "power-factor/L1": 0x001E,
"power-demand/total": 0x0054, "power-factor/L2": 0x0020,
"power-factor/L1": 0x001E, "power-factor/L3": 0x0022,
"power-factor/L2": 0x0020, "power-factor/total": 0x003E,
"power-factor/L3": 0x0022, "reactive-power/L1": 0x0018,
"power-factor/total": 0x003E, "reactive-power/L2": 0x001A,
"reactive-power/L1": 0x0018, "reactive-power/L3": 0x001E,
"reactive-power/L2": 0x001A, "reactive-power/total": 0x003C,
"reactive-power/L3": 0x001E, "voltage/L1_L2": 0x00C8,
"reactive-power/total": 0x003C, "voltage/L1_N": 0x0000,
"voltage/L1_L2": 0x00C8, "voltage/L2_L3": 0x00CA,
"voltage/L1_N": 0x0000, "voltage/L2_N": 0x0002,
"voltage/L2_L3": 0x00CA, "voltage/L3_L1": 0x00CC,
"voltage/L2_N": 0x0002, "voltage/L3_N": 0x0004,
"voltage/L3_L1": 0x00CC, "voltage/average": 0x002A,
"voltage/L3_N": 0x0004, }.items():
"voltage/average": 0x002A,
}.items()
):
try: try:
read = self.modbus.read_input_registers(address, 2) read = self.modbus.read_input_registers(address, 2)
self.idx += 1
if read is None:
LOG.error(f'reading {readable} was None: {self.modbus.last_error_as_txt}')
continue
longs = word_list_to_long(read) longs = word_list_to_long(read)
if len(longs) == 1: if len(longs) == 1:
self._publish(readable, decode_ieee(longs[0])) self._publish(readable, decode_ieee(longs[0]))
@ -113,10 +119,10 @@ class SDM630_MQTT:
self._publish(readable, sum([decode_ieee(x) for x in longs])) self._publish(readable, sum([decode_ieee(x) for x in longs]))
except Exception: except Exception:
LOG.exception(f'error while reading {readable} from meter') LOG.exception(f'error while reading {readable} from meter')
if idx % 20: if self.idx >= 20:
self.modbus.close() self.modbus.close()
self.modbus.open() self.modbus.open()
self.modbus.close() self.idx = 0
if __name__ == "__main__": if __name__ == "__main__":
@ -127,11 +133,12 @@ if __name__ == "__main__":
except Exception as e: except Exception as e:
print(f"Usage: {argv[0]} config.toml") print(f"Usage: {argv[0]} config.toml")
exit(1) exit(1)
client = SDM630_MQTT(config)
client.start()
try: try:
client = SDM630_MQTT(config)
client.start()
while True: while True:
client.request_and_publish() client.request_and_publish()
except Exception as e: except Exception as e:
LOG.exception("oops") LOG.exception("oops")
finally:
client.stop() client.stop()