From 0f4d41b466cdb97112ccf7100f6c796f045aec11 Mon Sep 17 00:00:00 2001 From: Stefan Allius Date: Sat, 30 Sep 2023 16:11:32 +0200 Subject: [PATCH] add some code comments --- app/src/infos.py | 69 +++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/app/src/infos.py b/app/src/infos.py index 02f9ce1..e7b492c 100644 --- a/app/src/infos.py +++ b/app/src/infos.py @@ -6,6 +6,7 @@ class Infos: def __init__(self): self.db = {} self.tracer = logging.getLogger('data') + __info_devs={ 'controller':{ 'name':'Controller', 'mdl':0x00092f90, 'mf':0x000927c0, 'sw':0x00092ba8}, 'inverter': {'via':'controller', 'name':'Micro Inverter', 'mdl':0x00000032, 'mf':0x00000014, 'sw':0x0000001e}, @@ -15,18 +16,20 @@ class Infos: 'input_pv4': {'via':'inverter', 'name':'Module PV4'}, } __info_defs={ - # collector values: + # collector values used for device registration: 0x00092ba8: {'name':['collector', 'Collector_Fw_Version'], 'level': logging.INFO, 'unit': ''}, 0x000927c0: {'name':['collector', 'Chip_Type'], 'level': logging.DEBUG, 'unit': ''}, 0x00092f90: {'name':['collector', 'Chip_Model'], 'level': logging.DEBUG, 'unit': ''}, 0x00095a88: {'name':['collector', 'Trace_URL'], 'level': logging.DEBUG, 'unit': ''}, 0x00095aec: {'name':['collector', 'Logger_URL'], 'level': logging.DEBUG, 'unit': ''}, - # inverter values: + + # inverter values used for device registration: 0x0000000a: {'name':['inverter', 'Product_Name'], 'level': logging.DEBUG, 'unit': ''}, 0x00000014: {'name':['inverter', 'Manufacturer'], 'level': logging.DEBUG, 'unit': ''}, 0x0000001e: {'name':['inverter', 'Version'], 'level': logging.INFO, 'unit': ''}, 0x00000028: {'name':['inverter', 'Serial_Number'], 'level': logging.DEBUG, 'unit': ''}, 0x00000032: {'name':['inverter', 'Equipment_Model'], 'level': logging.DEBUG, 'unit': ''}, + # events 0x00000191: {'name':['events', '401_'], 'level': logging.DEBUG, 'unit': ''}, 0x00000192: {'name':['events', '402_'], 'level': logging.DEBUG, 'unit': ''}, @@ -44,6 +47,7 @@ class Infos: 0x0000019e: {'name':['events', '414_'], 'level': logging.DEBUG, 'unit': ''}, 0x0000019f: {'name':['events', '415_GridFreqOverRating'], 'level': logging.DEBUG, 'unit': ''}, 0x000001a0: {'name':['events', '416_'], 'level': logging.DEBUG, 'unit': ''}, + # grid measures: 0x000003e8: {'name':['grid', 'Voltage'], 'level': logging.DEBUG, 'unit': 'V', 'ha':{'dev':'inverter', 'dev_cla': 'voltage', 'stat_cla': 'measurement', 'id':'out_volt_', 'fmt':'| float','name': 'Grid Voltage'}}, 0x0000044c: {'name':['grid', 'Current'], 'level': logging.DEBUG, 'unit': 'A', 'ha':{'dev':'inverter', 'dev_cla': 'current', 'stat_cla': 'measurement', 'id':'out_cur_', 'fmt':'| float','name': 'Grid Current'}}, @@ -55,16 +59,16 @@ class Infos: # input measures: 0x000006a4: {'name':['input', 'pv1', 'Voltage'], 'level': logging.DEBUG, 'unit': 'V', 'ha':{'dev':'input_pv1', 'dev_cla': 'voltage', 'stat_cla': 'measurement', 'id':'volt_pv1_', 'name': 'Voltage', 'val_tpl' :"{{ (value_json['pv1']['Voltage'] | float)}}", 'unvisible':1}}, 0x00000708: {'name':['input', 'pv1', 'Current'], 'level': logging.DEBUG, 'unit': 'A', 'ha':{'dev':'input_pv1', 'dev_cla': 'current', 'stat_cla': 'measurement', 'id':'cur_pv1_', 'name': 'Current', 'val_tpl' :"{{ (value_json['pv1']['Current'] | float)}}", 'unvisible':1}}, - 0x0000076c: {'name':['input', 'pv1', 'Power'], 'level': logging.INFO, 'unit': 'W', 'ha':{'dev':'input_pv1', 'dev_cla': 'power', 'stat_cla': 'measurement', 'id':'power_pv1_','name': 'Power', 'val_tpl' :"{{ (value_json['pv1']['Power'] | float)}}"}}, + 0x0000076c: {'name':['input', 'pv1', 'Power'], 'level': logging.INFO, 'unit': 'W', 'ha':{'dev':'input_pv1', 'dev_cla': 'power', 'stat_cla': 'measurement', 'id':'power_pv1_','name': 'Power', 'val_tpl' :"{{ (value_json['pv1']['Power'] | float)}}"}}, 0x000007d0: {'name':['input', 'pv2', 'Voltage'], 'level': logging.DEBUG, 'unit': 'V', 'ha':{'dev':'input_pv2', 'dev_cla': 'voltage', 'stat_cla': 'measurement', 'id':'volt_pv2_', 'name': 'Voltage', 'val_tpl' :"{{ (value_json['pv2']['Voltage'] | float)}}", 'unvisible':1}}, 0x00000834: {'name':['input', 'pv2', 'Current'], 'level': logging.DEBUG, 'unit': 'A', 'ha':{'dev':'input_pv2', 'dev_cla': 'current', 'stat_cla': 'measurement', 'id':'cur_pv2_', 'name': 'Current', 'val_tpl' :"{{ (value_json['pv2']['Current'] | float)}}", 'unvisible':1}}, - 0x00000898: {'name':['input', 'pv2', 'Power'], 'level': logging.INFO, 'unit': 'W', 'ha':{'dev':'input_pv2', 'dev_cla': 'power', 'stat_cla': 'measurement', 'id':'power_pv2_','name': 'Power', 'val_tpl' :"{{ (value_json['pv2']['Power'] | float)}}"}}, + 0x00000898: {'name':['input', 'pv2', 'Power'], 'level': logging.INFO, 'unit': 'W', 'ha':{'dev':'input_pv2', 'dev_cla': 'power', 'stat_cla': 'measurement', 'id':'power_pv2_','name': 'Power', 'val_tpl' :"{{ (value_json['pv2']['Power'] | float)}}"}}, 0x000008fc: {'name':['input', 'pv3', 'Voltage'], 'level': logging.DEBUG, 'unit': 'V', 'ha':{'dev':'input_pv3', 'dev_cla': 'voltage', 'stat_cla': 'measurement', 'id':'volt_pv3_', 'name': 'Voltage', 'val_tpl' :"{{ (value_json['pv3']['Voltage'] | float)}}", 'unvisible':1}}, 0x00000960: {'name':['input', 'pv3', 'Current'], 'level': logging.DEBUG, 'unit': 'A', 'ha':{'dev':'input_pv3', 'dev_cla': 'current', 'stat_cla': 'measurement', 'id':'cur_pv3_', 'name': 'Current', 'val_tpl' :"{{ (value_json['pv3']['Current'] | float)}}", 'unvisible':1}}, - 0x000009c4: {'name':['input', 'pv3', 'Power'], 'level': logging.DEBUG, 'unit': 'W', 'ha':{'dev':'input_pv3', 'dev_cla': 'power', 'stat_cla': 'measurement', 'id':'power_pv3_','name': 'Power', 'val_tpl' :"{{ (value_json['pv3']['Power'] | float)}}"}}, + 0x000009c4: {'name':['input', 'pv3', 'Power'], 'level': logging.DEBUG, 'unit': 'W', 'ha':{'dev':'input_pv3', 'dev_cla': 'power', 'stat_cla': 'measurement', 'id':'power_pv3_','name': 'Power', 'val_tpl' :"{{ (value_json['pv3']['Power'] | float)}}"}}, 0x00000a28: {'name':['input', 'pv4', 'Voltage'], 'level': logging.DEBUG, 'unit': 'V', 'ha':{'dev':'input_pv4', 'dev_cla': 'voltage', 'stat_cla': 'measurement', 'id':'volt_pv4_', 'name': 'Voltage', 'val_tpl' :"{{ (value_json['pv4']['Voltage'] | float)}}", 'unvisible':1}}, 0x00000a8c: {'name':['input', 'pv4', 'Current'], 'level': logging.DEBUG, 'unit': 'A', 'ha':{'dev':'input_pv4', 'dev_cla': 'current', 'stat_cla': 'measurement', 'id':'cur_pv4_', 'name': 'Current', 'val_tpl' :"{{ (value_json['pv4']['Current'] | float)}}", 'unvisible':1}}, - 0x00000af0: {'name':['input', 'pv4', 'Power'], 'level': logging.DEBUG, 'unit': 'W', 'ha':{'dev':'input_pv4', 'dev_cla': 'power', 'stat_cla': 'measurement', 'id':'power_pv4_','name': 'Power', 'val_tpl' :"{{ (value_json['pv4']['Power'] | float)}}"}}, + 0x00000af0: {'name':['input', 'pv4', 'Power'], 'level': logging.DEBUG, 'unit': 'W', 'ha':{'dev':'input_pv4', 'dev_cla': 'power', 'stat_cla': 'measurement', 'id':'power_pv4_','name': 'Power', 'val_tpl' :"{{ (value_json['pv4']['Power'] | float)}}"}}, 0x00000c1c: {'name':['input', 'pv1', 'Daily_Generation'], 'level': logging.DEBUG, 'unit': 'kWh', 'ha':{'dev':'input_pv1', 'dev_cla': 'energy', 'stat_cla': 'total_increasing', 'id':'daily_gen_pv1_','name': 'Daily Generation', 'val_tpl' :"{{ (value_json['pv1']['Daily_Generation'] | float)}}"}}, 0x00000c80: {'name':['input', 'pv1', 'Total_Generation'], 'level': logging.DEBUG, 'unit': 'kWh', 'ha':{'dev':'input_pv1', 'dev_cla': 'energy', 'stat_cla': 'total', 'id':'total_gen_pv1_','name': 'Total Generation', 'val_tpl' :"{{ (value_json['pv1']['Total_Generation'] | float)}}"}}, 0x00000ce4: {'name':['input', 'pv2', 'Daily_Generation'], 'level': logging.DEBUG, 'unit': 'kWh', 'ha':{'dev':'input_pv2', 'dev_cla': 'energy', 'stat_cla': 'total_increasing', 'id':'daily_gen_pv2_','name': 'Daily Generation', 'val_tpl' :"{{ (value_json['pv2']['Daily_Generation'] | float)}}"}}, @@ -85,66 +89,77 @@ class Infos: } def dev_value(self, idx:str|int) -> str|int|float|None: + ''' + returns the stored device value from our databse + + idx:int ==> lookup the value in the database and return it as str, int or flout. If the value is not available return 'None' + idx:str ==> returns the string as a fixed value without a database loopup + ''' if type (idx) is str: - return idx + return idx # return idx as a fixed value elif idx in self.__info_defs: dict = self.db row = self.__info_defs[idx] keys = row['name'] - for key in keys: - if key not in dict: - return None - dict = dict[key] - return dict + for key in keys: + if key not in dict: + return None # value not found in the database + dict = dict[key] + return dict # value of the reqeusted entry + + return None # unknwon idx, not in __info_defs def ha_confs(self, prfx="tsun/garagendach/", snr='123', sug_area =''): tab = self.__info_defs for key in tab: row = tab[key] + + #check if we have details for home assistant if 'ha' in row: ha = row['ha'] - attr = {} + attr = {} # dict to collect all the sensor entity details if 'name' in ha: - attr['name'] = ha['name'] # eg. 'name': "Actual Power" + attr['name'] = ha['name'] # take the entity name from the ha dict else: - attr['name'] = row['name'][-1] # eg. 'name': "Actual Power" + attr['name'] = row['name'][-1] # otherwise take a name from the name array attr['stat_t'] = prfx +row['name'][0] # eg. 'stat_t': "tsun/garagendach/grid" attr['dev_cla'] = ha['dev_cla'] # eg. 'dev_cla': 'power' attr['stat_cla'] = ha['stat_cla'] # eg. 'stat_cla': "measurement" - attr['uniq_id'] = ha['id']+snr # eg. 'uniq_id':'out_power_123' + attr['uniq_id'] = ha['id']+snr # build the 'uniq_id' from the id str + the serial no of the inverter if 'val_tpl' in ha: - attr['val_tpl'] = ha['val_tpl'] # eg. 'val_tpl': "{{ value_json['Output_Power']|float }}" + attr['val_tpl'] = ha['val_tpl'] # get value template for complexe data structures elif 'fmt' in ha: attr['val_tpl'] = '{{value_json' + f"['{row['name'][-1]}'] {ha['fmt']}" + '}}' # eg. 'val_tpl': "{{ value_json['Output_Power']|float }}" if 'unit' in row: - attr['unit_of_meas'] = row['unit'] # eg. 'unit_of_meas': 'W' + attr['unit_of_meas'] = row['unit'] # optional add a 'unit_of_meas' e.g. 'W' if 'icon' in ha: - attr['icon'] = ha['icon'] # eg. 'icon':'mdi:solar-power' + attr['icon'] = ha['icon'] # optional add an icon for the entity if 'nat_prc' in ha: - attr['suggested_display_precision'] = ha['nat_prc'] - #if 'unvisible' in ha: - # attr['entity_registry_visible_default'] = 'False' + attr['suggested_display_precision'] = ha['nat_prc'] # optional add the precison of floats # eg. 'dev':{'name':'Microinverter','mdl':'MS-600','ids':["inverter_123"],'mf':'TSUN','sa': 'auf Garagendach'} # attr['dev'] = {'name':'Microinverter','mdl':'MS-600','ids':[f'inverter_{snr}'],'mf':'TSUN','sa': 'auf Garagendach'} if 'dev' in ha: device = self.__info_devs[ha['dev']] dev = {} + + # the same name fpr 'name' and 'suggested area', so we get dedicated devices in home assistant with short value name and headline if 'name' in device: dev['name'] = device['name'] dev['sa'] = device['name'] - else: - dev['name'] = sug_area - dev['sa'] = sug_area + # fixme: we ignore the suggested area, since one area make no sense for multiple devices + #else: + # dev['name'] = sug_area + # dev['sa'] = sug_area - if 'via' in device: + if 'via' in device: # add the link to the parent device dev['via_device'] = f"{device['via']}_{snr}" - for key in ('mdl','mf', 'sw', 'hw'): + for key in ('mdl','mf', 'sw', 'hw'): # add optional values fpr 'modell', 'manufaturer', 'sw version' and 'hw version' if key in device: data = self.dev_value(device[key]) if data is not None: dev[key] = data