Files
pv-controller/src/pv_controller/MeterPublish.py

56 lines
2.3 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] != 0
REGISTERS = [
{ "slave":2, "addr":0x0048, "type":"input", "attr": "importEnergy", "name":"Import active energy", "unit":"kWh", "adaptor": floatAdaptor },
{ "slave":2, "addr":0x004a, "type":"input", "attr": "exportEnergy", "name":"Export active energy", "unit":"kWh", "adaptor": floatAdaptor },
{ "slave":2, "addr":0x000c, "type":"input", "attr": "power", "name":"Power", "unit":"W", "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"]))