Files
tsun-gen3-proxy/ha_addons/ha_addon/rootfs/home/proxy/proxy.py
2024-12-02 22:49:56 +01:00

102 lines
4.1 KiB
Python

import asyncio
import logging
import json
from config import Config
from mqtt import Mqtt
from infos import Infos
logger_mqtt = logging.getLogger('mqtt')
class Proxy():
'''class Proxy is a baseclass
The class has some class method for managing common resources like a
connection to the MQTT broker or proxy error counter which are common
for all inverter connection
Instances of the class are connections to an inverter and can have an
optional link to an remote connection to the TSUN cloud. A remote
connection dies with the inverter connection.
class methods:
class_init(): initialize the common resources of the proxy (MQTT
broker, Proxy DB, etc). Must be called before the
first inverter instance can be created
class_close(): release the common resources of the proxy. Should not
be called before any instances of the class are
destroyed
methods:
create_remote(): Establish a client connection to the TSUN cloud
async_publ_mqtt(): Publish data to MQTT broker
'''
@classmethod
def class_init(cls) -> None:
logging.debug('Proxy.class_init')
# initialize the proxy statistics
Infos.static_init()
cls.db_stat = Infos()
ha = Config.get('ha')
cls.entity_prfx = ha['entity_prefix'] + '/'
cls.discovery_prfx = ha['discovery_prefix'] + '/'
cls.proxy_node_id = ha['proxy_node_id'] + '/'
cls.proxy_unique_id = ha['proxy_unique_id']
# call Mqtt singleton to establisch the connection to the mqtt broker
cls.mqtt = Mqtt(cls._cb_mqtt_is_up)
# register all counters which should be reset at midnight.
# This is needed if the proxy is restated before midnight
# and the inverters are offline, cause the normal refgistering
# needs an update on the counters.
# Without this registration here the counters would not be
# reset at midnight when you restart the proxy just before
# midnight!
inverters = Config.get('inverters')
# logger.debug(f'Proxys: {inverters}')
for inv in inverters.values():
if (type(inv) is dict):
node_id = inv['node_id']
cls.db_stat.reg_clr_at_midnight(f'{cls.entity_prfx}{node_id}',
check_dependencies=False)
@classmethod
async def _cb_mqtt_is_up(cls) -> None:
logging.info('Initialize proxy device on home assistant')
# register proxy status counters at home assistant
await cls._register_proxy_stat_home_assistant()
# send values of the proxy status counters
await asyncio.sleep(0.5) # wait a bit, before sending data
Infos.new_stat_data['proxy'] = True # force sending data to sync ha
await cls._async_publ_mqtt_proxy_stat('proxy')
@classmethod
async def _register_proxy_stat_home_assistant(cls) -> None:
'''register all our topics at home assistant'''
for data_json, component, node_id, id in cls.db_stat.ha_proxy_confs(
cls.entity_prfx, cls.proxy_node_id, cls.proxy_unique_id):
logger_mqtt.debug(f"MQTT Register: cmp:'{component}' node_id:'{node_id}' {data_json}") # noqa: E501
await cls.mqtt.publish(f'{cls.discovery_prfx}{component}/{node_id}{id}/config', data_json) # noqa: E501
@classmethod
async def _async_publ_mqtt_proxy_stat(cls, key) -> None:
stat = Infos.stat
if key in stat and Infos.new_stat_data[key]:
data_json = json.dumps(stat[key])
node_id = cls.proxy_node_id
logger_mqtt.debug(f'{key}: {data_json}')
await cls.mqtt.publish(f"{cls.entity_prfx}{node_id}{key}",
data_json)
Infos.new_stat_data[key] = False
@classmethod
def class_close(cls, loop) -> None: # pragma: no cover
logging.debug('Proxy.class_close')
logging.info('Close MQTT Task')
loop.run_until_complete(cls.mqtt.close())
cls.mqtt = None