64 lines
3.4 KiB
Python
64 lines
3.4 KiB
Python
from threading import Event
|
|
from loguru import logger
|
|
from MqttBase import AbstractMqttPublisher
|
|
import json
|
|
import datetime
|
|
|
|
|
|
def floatAdaptor(i):
|
|
return float(f"{i:0.2f}") if i else 0.0
|
|
|
|
def onOffAdaptor(i):
|
|
return i[0] if i else '-1'
|
|
|
|
|
|
REGISTERS = [
|
|
{ "slave":2, "addr":0x0048, "type":"input", "attr": "importEnergyActive", "name":"Import active energy", "unit":"kWh", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x004c, "type":"input", "attr": "importEnergyReactive", "name":"Import reactive energy", "unit":"kVAh", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x004a, "type":"input", "attr": "exportEnergyActive", "name":"Export active energy", "unit":"kWh", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x004e, "type":"input", "attr": "exportEnergyReactive", "name":"Export reactive energy", "unit":"kVAh", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x0012, "type":"input", "attr": "powerApparent", "name":"Apparent Power", "unit":"W", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x000c, "type":"input", "attr": "powerActive", "name":"Active Power", "unit":"W", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x0018, "type":"input", "attr": "powerReactive", "name":"Reactive Power", "unit":"W", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x0058, "type":"input", "attr": "powerDemandPositive", "name":"PositivePowerDemand", "unit":"W", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x005c, "type":"input", "attr": "powerDemandReverse", "name":"ReversePowerDemand", "unit":"W", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x001e, "type":"input", "attr": "factor", "name":"Factor", "unit":"-", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x0024, "type":"input", "attr": "angle", "name":"Angle", "unit":"degree", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x0000, "type":"input", "attr": "voltage", "name":"Voltage", "unit":"V", "adaptor": floatAdaptor },
|
|
{ "slave":2, "addr":0x0006, "type":"input", "attr": "current", "name":"Current", "unit":"A", "adaptor": floatAdaptor },
|
|
{ "slave":1, "addr":0x0001, "type":"holding", "attr": "state", "name":"State", "unit":"-", "adaptor": onOffAdaptor },
|
|
]
|
|
|
|
|
|
class MeterPublish(AbstractMqttPublisher):
|
|
def __init__(self, config, modbusHandler):
|
|
super().__init__(config)
|
|
self.modbusHandler = modbusHandler
|
|
self.registers = REGISTERS
|
|
|
|
def localLoop(self):
|
|
cnt = 0
|
|
while not self.killBill:
|
|
cnt += 1
|
|
topic = self.config["meterPublishTopic"]
|
|
payload = str(cnt)
|
|
|
|
try:
|
|
payload = { r['attr']: r['adaptor'](None) for r in self.registers }
|
|
payload['status'] = "Error"
|
|
payload['timestamp'] = datetime.datetime.isoformat(datetime.datetime.utcnow())
|
|
for reg in self.registers:
|
|
v = self.modbusHandler.readRegister(reg['type'], reg['slave'], reg['addr'])
|
|
logger.debug(f"{reg['name']}: {v} {reg['unit']}")
|
|
payload[reg['attr']] = reg['adaptor'](v)
|
|
payload['status'] = "Ok"
|
|
except Exception as e:
|
|
logger.error(f"Caught exception: {str(e)}")
|
|
|
|
payload['cnt'] = cnt
|
|
payloadStr = json.dumps(payload)
|
|
self.client.publish(topic, payloadStr)
|
|
logger.info(f"mqtt message sent: {topic} -> {payloadStr}")
|
|
|
|
self.killEvent.wait(timeout=float(self.config["meterPublishPeriod"]))
|