102 lines
4.1 KiB
Python
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
|