From 214f3dfae593f67bda1df78c3efed3601cdd57f3 Mon Sep 17 00:00:00 2001 From: Stefan Allius Date: Sun, 7 Apr 2024 10:29:05 +0200 Subject: [PATCH 1/5] Add manufacturuer and modell type for pv modules --- app/src/infos.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/app/src/infos.py b/app/src/infos.py index afcc4a7..21c121e 100644 --- a/app/src/infos.py +++ b/app/src/infos.py @@ -34,21 +34,33 @@ class Register(Enum): PV1_VOLTAGE = 100 PV1_CURRENT = 101 PV1_POWER = 102 + PV1_MANUFACTURER = 103 + PV1_MODEL = 104 PV2_VOLTAGE = 110 PV2_CURRENT = 111 PV2_POWER = 112 + PV2_MANUFACTURER = 113 + PV2_MODEL = 114 PV3_VOLTAGE = 120 PV3_CURRENT = 121 PV3_POWER = 122 + PV3_MANUFACTURER = 123 + PV3_MODEL = 124 PV4_VOLTAGE = 130 PV4_CURRENT = 131 PV4_POWER = 132 + PV4_MANUFACTURER = 133 + PV4_MODEL = 134 PV5_VOLTAGE = 140 PV5_CURRENT = 141 PV5_POWER = 142 + PV5_MANUFACTURER = 143 + PV5_MODEL = 144 PV6_VOLTAGE = 150 PV6_CURRENT = 151 PV6_POWER = 152 + PV6_MANUFACTURER = 153 + PV6_MODEL = 154 PV1_DAILY_GENERATION = 200 PV1_TOTAL_GENERATION = 201 PV2_DAILY_GENERATION = 210 @@ -153,12 +165,12 @@ class Infos: 'proxy': {'singleton': True, 'name': 'Proxy', 'mf': 'Stefan Allius'}, # noqa: E501 'controller': {'via': 'proxy', 'name': 'Controller', 'mdl': Register.CHIP_MODEL, 'mf': Register.CHIP_TYPE, 'sw': Register.COLLECTOR_FW_VERSION}, # noqa: E501 'inverter': {'via': 'controller', 'name': 'Micro Inverter', 'mdl': Register.EQUIPMENT_MODEL, 'mf': Register.MANUFACTURER, 'sw': Register.VERSION}, # noqa: E501 - 'input_pv1': {'via': 'inverter', 'name': 'Module PV1'}, - 'input_pv2': {'via': 'inverter', 'name': 'Module PV2', 'dep': {'reg': Register.NO_INPUTS, 'gte': 2}}, # noqa: E501 - 'input_pv3': {'via': 'inverter', 'name': 'Module PV3', 'dep': {'reg': Register.NO_INPUTS, 'gte': 3}}, # noqa: E501 - 'input_pv4': {'via': 'inverter', 'name': 'Module PV4', 'dep': {'reg': Register.NO_INPUTS, 'gte': 4}}, # noqa: E501 - 'input_pv5': {'via': 'inverter', 'name': 'Module PV5', 'dep': {'reg': Register.NO_INPUTS, 'gte': 5}}, # noqa: E501 - 'input_pv6': {'via': 'inverter', 'name': 'Module PV6', 'dep': {'reg': Register.NO_INPUTS, 'gte': 6}}, # noqa: E501 + 'input_pv1': {'via': 'inverter', 'name': 'Module PV1', 'mdl': Register.PV1_MODEL, 'mf': Register.PV1_MANUFACTURER}, # noqa: E501 + 'input_pv2': {'via': 'inverter', 'name': 'Module PV2', 'mdl': Register.PV2_MODEL, 'mf': Register.PV2_MANUFACTURER, 'dep': {'reg': Register.NO_INPUTS, 'gte': 2}}, # noqa: E501 + 'input_pv3': {'via': 'inverter', 'name': 'Module PV3', 'mdl': Register.PV3_MODEL, 'mf': Register.PV3_MANUFACTURER, 'dep': {'reg': Register.NO_INPUTS, 'gte': 3}}, # noqa: E501 + 'input_pv4': {'via': 'inverter', 'name': 'Module PV4', 'mdl': Register.PV4_MODEL, 'mf': Register.PV4_MANUFACTURER, 'dep': {'reg': Register.NO_INPUTS, 'gte': 4}}, # noqa: E501 + 'input_pv5': {'via': 'inverter', 'name': 'Module PV5', 'mdl': Register.PV5_MODEL, 'mf': Register.PV5_MANUFACTURER, 'dep': {'reg': Register.NO_INPUTS, 'gte': 5}}, # noqa: E501 + 'input_pv6': {'via': 'inverter', 'name': 'Module PV6', 'mdl': Register.PV6_MODEL, 'mf': Register.PV6_MANUFACTURER, 'dep': {'reg': Register.NO_INPUTS, 'gte': 6}}, # noqa: E501 } __comm_type_val_tpl = "{%set com_types = ['n/a','Wi-Fi', 'G4', 'G5', 'GPRS'] %}{{com_types[value_json['Communication_Type']|int(0)]|default(value_json['Communication_Type'])}}" # noqa: E501 From 93b89062f5bafbbf5256184a2f72844e0858e45a Mon Sep 17 00:00:00 2001 From: Stefan Allius Date: Sun, 7 Apr 2024 19:41:05 +0200 Subject: [PATCH 2/5] Read pv module details for HA from config file --- CHANGELOG.md | 2 ++ app/config/default_config.toml | 10 +++++++++- app/src/config.py | 26 +++++++++++++++++++++++++- app/src/gen3/talent.py | 5 +++-- app/src/gen3plus/solarman_v5.py | 9 +++++---- app/src/infos.py | 30 ++++++++++++++++++++++++++++++ 6 files changed, 74 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d50288f..86483ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Prepare support of inverters with 6 MTPPs - Clear `Daily Generation` values at midnigth +- Read pv module details from config file and use it for the Home Assistant registration + see: [#43](https://github.com/s-allius/tsun-gen3-proxy/issues/43) ## [0.6.0] - 2024-04-02 diff --git a/app/config/default_config.toml b/app/config/default_config.toml index fccc54b..050ca32 100644 --- a/app/config/default_config.toml +++ b/app/config/default_config.toml @@ -31,13 +31,21 @@ inverters.allow_all = true # allow inverters, even if we have no inverter mapp [inverters."R170000000000001"] #node_id = '' # Optional, MQTT replacement for inverters serial number #suggested_area = '' # Optional, suggested installation area for home-assistant +#pv1 = {type = 'RSM40-8-395M', manufacturer = 'Risen'} +#pv2 = {type = 'RSM40-8-395M', manufacturer = 'Risen'} #[inverters."R17xxxxxxxxxxxx2"] #node_id = '' # Optional, MQTT replacement for inverters serial number #suggested_area = '' # Optional, suggested installation area for home-assistant +#pv1 = {type = 'RSM40-8-405M', manufacturer = 'Risen'} +#pv2 = {type = 'RSM40-8-405M', manufacturer = 'Risen'} [inverters."Y170000000000001"] -#monitor_sn = 2000000000 # The "Monitoring SN:" can be found on a sticker enclosed with the inverter +monitor_sn = 2000000000 # The "Monitoring SN:" can be found on a sticker enclosed with the inverter #node_id = '' # Optional, MQTT replacement for inverters serial number #suggested_area = '' # Optional, suggested installation place for home-assistant +#pv1 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} +#pv2 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} +#pv3 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} +#pv4 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} diff --git a/app/src/config.py b/app/src/config.py index 3778e09..589bb6c 100644 --- a/app/src/config.py +++ b/app/src/config.py @@ -45,7 +45,31 @@ class Config(): if len(s) > 0 and s[-1] != '/' else s)), - Optional('suggested_area', default=""): Use(str) + Optional('suggested_area', default=""): Use(str), + Optional('pv1'): { + Optional('type'): Use(str), + Optional('manufacturer'): Use(str), + }, + Optional('pv2'): { + Optional('type'): Use(str), + Optional('manufacturer'): Use(str), + }, + Optional('pv3'): { + Optional('type'): Use(str), + Optional('manufacturer'): Use(str), + }, + Optional('pv4'): { + Optional('type'): Use(str), + Optional('manufacturer'): Use(str), + }, + Optional('pv5'): { + Optional('type'): Use(str), + Optional('manufacturer'): Use(str), + }, + Optional('pv6'): { + Optional('type'): Use(str), + Optional('manufacturer'): Use(str), + } }} }, ignore_extra_keys=True ) diff --git a/app/src/gen3/talent.py b/app/src/gen3/talent.py index 0bc08a8..46302ac 100644 --- a/app/src/gen3/talent.py +++ b/app/src/gen3/talent.py @@ -59,7 +59,7 @@ class Talent(Message): # deallocated by the garbage collector ==> we get a memory leak self.switch.clear() - def set_serial_no(self, serial_no: str): + def __set_serial_no(self, serial_no: str): if self.unique_id == serial_no: logger.debug(f'SerialNo: {serial_no}') @@ -72,6 +72,7 @@ class Talent(Message): self.node_id = inv['node_id'] self.sug_area = inv['suggested_area'] logger.debug(f'SerialNo {serial_no} allowed! area:{self.sug_area}') # noqa: E501 + self.db.set_pv_module_details(inv) else: self.node_id = '' self.sug_area = '' @@ -95,7 +96,7 @@ class Talent(Message): hex_dump_memory(logging.INFO, f'Received from {self.addr}:', self._recv_buffer, self.header_len+self.data_len) - self.set_serial_no(self.id_str.decode("utf-8")) + self.__set_serial_no(self.id_str.decode("utf-8")) self.__dispatch_msg() self.__flush_recv_msg() return diff --git a/app/src/gen3plus/solarman_v5.py b/app/src/gen3plus/solarman_v5.py index c09512b..fc189b3 100644 --- a/app/src/gen3plus/solarman_v5.py +++ b/app/src/gen3plus/solarman_v5.py @@ -70,7 +70,7 @@ class SolarmanV5(Message): # deallocated by the garbage collector ==> we get a memory leak self.switch.clear() - def set_serial_no(self, snr: int): + def __set_serial_no(self, snr: int): serial_no = str(snr) if self.unique_id == serial_no: logger.debug(f'SerialNo: {serial_no}') @@ -87,6 +87,7 @@ class SolarmanV5(Message): self.node_id = inv['node_id'] self.sug_area = inv['suggested_area'] logger.debug(f'SerialNo {serial_no} allowed! area:{self.sug_area}') # noqa: E501 + self.db.set_pv_module_details(inv) if not found: self.node_id = '' @@ -112,7 +113,7 @@ class SolarmanV5(Message): self._recv_buffer, self.header_len+self.data_len+2) if self.__trailer_is_ok(self._recv_buffer, self.header_len + self.data_len + 2): - self.set_serial_no(self.snr) + self.__set_serial_no(self.snr) self.__dispatch_msg() self.__flush_recv_msg() return @@ -352,9 +353,9 @@ class SolarmanV5(Message): ftype = result[0] # always 2 valid = result[1] == 1 # status ts = result[2] - repeat = result[3] # always 60 + set_hb = result[3] # always 60 or 120 logger.info(f'ftype:{ftype} accepted:{valid}' - f' ts:{ts:08x} repeat:{repeat}s') + f' ts:{ts:08x} nextHeartbeat: {set_hb}s') dt = datetime.fromtimestamp(ts) logger.info(f'ts: {dt.strftime("%Y-%m-%d %H:%M:%S")}') diff --git a/app/src/infos.py b/app/src/infos.py index 21c121e..88e70c4 100644 --- a/app/src/infos.py +++ b/app/src/infos.py @@ -193,6 +193,19 @@ class Infos: Register.MAX_DESIGNED_POWER: {'name': ['inverter', 'Max_Designed_Power'], 'level': logging.DEBUG, 'unit': 'W', 'ha': {'dev': 'inverter', 'dev_cla': None, 'stat_cla': None, 'id': 'designed_power_', 'fmt': '| string + " W"', 'name': 'Max Designed Power', 'icon': 'mdi:lightning-bolt', 'ent_cat': 'diagnostic'}}, # noqa: E501 Register.RATED_POWER: {'name': ['inverter', 'Rated_Power'], 'level': logging.DEBUG, 'unit': 'W', 'ha': {'dev': 'inverter', 'dev_cla': None, 'stat_cla': None, 'id': 'rated_power_', 'fmt': '| string + " W"', 'name': 'Rated Power', 'icon': 'mdi:lightning-bolt', 'ent_cat': 'diagnostic'}}, # noqa: E501 + Register.PV1_MANUFACTURER: {'name': ['inverter', 'PV1_Manufacturer'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV1_MODEL: {'name': ['inverter', 'PV1_Model'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV2_MANUFACTURER: {'name': ['inverter', 'PV2_Manufacturer'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV2_MODEL: {'name': ['inverter', 'PV2_Model'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV3_MANUFACTURER: {'name': ['inverter', 'PV3_Manufacturer'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV3_MODEL: {'name': ['inverter', 'PV3_Model'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV4_MANUFACTURER: {'name': ['inverter', 'PV4_Manufacturer'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV4_MODEL: {'name': ['inverter', 'PV4_Model'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV5_MANUFACTURER: {'name': ['inverter', 'PV5_Manufacturer'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV5_MODEL: {'name': ['inverter', 'PV5_Model'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV6_MANUFACTURER: {'name': ['inverter', 'PV6_Manufacturer'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + Register.PV6_MODEL: {'name': ['inverter', 'PV6_Model'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 + # proxy: Register.INVERTER_CNT: {'name': ['proxy', 'Inverter_Cnt'], 'singleton': True, 'ha': {'dev': 'proxy', 'comp': 'sensor', 'dev_cla': None, 'stat_cla': None, 'id': 'inv_count_', 'fmt': '| int', 'name': 'Active Inverter Connections', 'icon': 'mdi:counter'}}, # noqa: E501 Register.UNKNOWN_SNR: {'name': ['proxy', 'Unknown_SNR'], 'singleton': True, 'ha': {'dev': 'proxy', 'comp': 'sensor', 'dev_cla': None, 'stat_cla': None, 'id': 'unknown_snr_', 'fmt': '| int', 'name': 'Unknown Serial No', 'icon': 'mdi:counter', 'ent_cat': 'diagnostic'}}, # noqa: E501 @@ -530,3 +543,20 @@ class Infos: elif 'less_eq' in dep: return not value <= dep['less_eq'] return True + + def set_pv_module_details(self, inv: dict) -> None: + map = {'pv1': {'manufacturer': Register.PV1_MANUFACTURER, 'model': Register.PV1_MODEL}, # noqa: E501 + 'pv2': {'manufacturer': Register.PV2_MANUFACTURER, 'model': Register.PV2_MODEL}, # noqa: E501 + 'pv3': {'manufacturer': Register.PV3_MANUFACTURER, 'model': Register.PV3_MODEL}, # noqa: E501 + 'pv4': {'manufacturer': Register.PV4_MANUFACTURER, 'model': Register.PV4_MODEL}, # noqa: E501 + 'pv5': {'manufacturer': Register.PV5_MANUFACTURER, 'model': Register.PV5_MODEL}, # noqa: E501 + 'pv6': {'manufacturer': Register.PV6_MANUFACTURER, 'model': Register.PV6_MODEL} # noqa: E501 + } + + for key, reg in map.items(): + if key in inv: + if 'manufacturer' in inv[key]: + self.set_db_def_value(reg['manufacturer'], + inv[key]['manufacturer']) + if 'type' in inv[key]: + self.set_db_def_value(reg['model'], inv[key]['type']) From 9d395af9861897aa184dbd55bef34908c5d92db0 Mon Sep 17 00:00:00 2001 From: Stefan Allius Date: Sun, 7 Apr 2024 20:52:07 +0200 Subject: [PATCH 3/5] add samples for pv module configurations --- app/config/default_config.toml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/config/default_config.toml b/app/config/default_config.toml index 050ca32..cd95d75 100644 --- a/app/config/default_config.toml +++ b/app/config/default_config.toml @@ -31,21 +31,21 @@ inverters.allow_all = true # allow inverters, even if we have no inverter mapp [inverters."R170000000000001"] #node_id = '' # Optional, MQTT replacement for inverters serial number #suggested_area = '' # Optional, suggested installation area for home-assistant -#pv1 = {type = 'RSM40-8-395M', manufacturer = 'Risen'} -#pv2 = {type = 'RSM40-8-395M', manufacturer = 'Risen'} +#pv1 = {type = 'RSM40-8-395M', manufacturer = 'Risen'} # Optional, PV module descr +#pv2 = {type = 'RSM40-8-395M', manufacturer = 'Risen'} # Optional, PV module descr #[inverters."R17xxxxxxxxxxxx2"] #node_id = '' # Optional, MQTT replacement for inverters serial number #suggested_area = '' # Optional, suggested installation area for home-assistant -#pv1 = {type = 'RSM40-8-405M', manufacturer = 'Risen'} -#pv2 = {type = 'RSM40-8-405M', manufacturer = 'Risen'} +#pv1 = {type = 'RSM40-8-405M', manufacturer = 'Risen'} # Optional, PV module descr +#pv2 = {type = 'RSM40-8-405M', manufacturer = 'Risen'} # Optional, PV module descr [inverters."Y170000000000001"] monitor_sn = 2000000000 # The "Monitoring SN:" can be found on a sticker enclosed with the inverter #node_id = '' # Optional, MQTT replacement for inverters serial number #suggested_area = '' # Optional, suggested installation place for home-assistant -#pv1 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} -#pv2 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} -#pv3 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} -#pv4 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} +#pv1 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} # Optional, PV module descr +#pv2 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} # Optional, PV module descr +#pv3 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} # Optional, PV module descr +#pv4 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} # Optional, PV module descr From 06b896d6e969af9b12766441574afdec05e7b7fb Mon Sep 17 00:00:00 2001 From: Stefan Allius Date: Sun, 7 Apr 2024 20:52:48 +0200 Subject: [PATCH 4/5] add samples for pv module configurations --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 538f7cf..3487ce8 100644 --- a/README.md +++ b/README.md @@ -127,15 +127,23 @@ inverters.allow_all = false # True: allow inverters, even if we have no invert [inverters."R17xxxxxxxxxxxx1"] node_id = 'inv1' # Optional, MQTT replacement for inverters serial number suggested_area = 'roof' # Optional, suggested installation area for home-assistant +pv1 = {type = 'RSM40-8-395M', manufacturer = 'Risen'} # Optional, PV module descr +pv2 = {type = 'RSM40-8-395M', manufacturer = 'Risen'} # Optional, PV module descr [inverters."R17xxxxxxxxxxxx2"] node_id = 'inv2' # Optional, MQTT replacement for inverters serial number suggested_area = 'balcony' # Optional, suggested installation area for home-assistant +pv1 = {type = 'RSM40-8-405M', manufacturer = 'Risen'} # Optional, PV module descr +pv2 = {type = 'RSM40-8-405M', manufacturer = 'Risen'} # Optional, PV module descr [inverters."Y17xxxxxxxxxxxx1"] monitor_sn = 2000000000 # The "Monitoring SN:" can be found on a sticker enclosed with the inverter node_id = 'inv_3' # MQTT replacement for inverters serial number suggested_area = 'garage' # suggested installation place for home-assistant +pv1 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} # Optional, PV module descr +pv2 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} # Optional, PV module descr +pv3 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} # Optional, PV module descr +pv4 = {type = 'RSM40-8-410M', manufacturer = 'Risen'} # Optional, PV module descr ``` From 97da24c8397e13878e464f2a57763209cd199890 Mon Sep 17 00:00:00 2001 From: Stefan Allius Date: Sun, 7 Apr 2024 22:44:53 +0200 Subject: [PATCH 5/5] add missing tests --- app/src/infos.py | 2 +- app/tests/test_infos.py | 46 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/app/src/infos.py b/app/src/infos.py index 88e70c4..5fa0697 100644 --- a/app/src/infos.py +++ b/app/src/infos.py @@ -123,7 +123,7 @@ class ClrAtMidnight: dict = dict[prfx] for key in keys[1:-1]: - if key not in dict: # pragma: no cover + if key not in dict: dict[key] = {} dict = dict[key] dict[keys[-1]] = 0 diff --git a/app/tests/test_infos.py b/app/tests/test_infos.py index f799456..8bf419d 100644 --- a/app/tests/test_infos.py +++ b/app/tests/test_infos.py @@ -530,12 +530,18 @@ def test_clr_at_midnight(): i.set_db_def_value(Register.NO_INPUTS, 2) val = i.dev_value(Register.NO_INPUTS) # valid addr but not initiliazed assert val == 2 - + i.info_defs[Register.TEST_REG1] = { # add a entry with incomplete ha definition + 'name': ['test', 'grp', 'REG_1'], 'ha': {'dev_cla': None } + } i.reg_clr_at_midnight('tsun/inv_1/') # tsun/inv_2/input assert json.dumps(ClrAtMidnight.db['tsun/inv_1/total']) == json.dumps({'Daily_Generation': 0}) assert json.dumps(ClrAtMidnight.db['tsun/inv_1/input']) == json.dumps({"pv1": {"Daily_Generation": 0}, "pv2": {"Daily_Generation": 0}}) + i.reg_clr_at_midnight('tsun/inv_1/') + assert json.dumps(ClrAtMidnight.db['tsun/inv_1/total']) == json.dumps({'Daily_Generation': 0}) + assert json.dumps(ClrAtMidnight.db['tsun/inv_1/input']) == json.dumps({"pv1": {"Daily_Generation": 0}, "pv2": {"Daily_Generation": 0}}) + test = 0 for key, data in ClrAtMidnight.elm(): if key == 'tsun/inv_1/total': @@ -546,3 +552,41 @@ def test_clr_at_midnight(): test += 1 assert test == 2 assert json.dumps(ClrAtMidnight.db) == json.dumps({}) + + i.reg_clr_at_midnight('tsun/inv_1/') + + + + +def test_pv_module_config(): + i = InfosG3() + # i.set_db_def_value(Register.NO_INPUTS, 2) + + dt = { + 'pv1':{'manufacturer':'TSUN1','type': 'Module 100W'}, + 'pv2':{'manufacturer':'TSUN2'}, + 'pv3':{'manufacturer':'TSUN3','type': 'Module 300W'}, + 'pv4':{'type': 'Module 400W'}, + 'pv5':{}, + } + i.set_pv_module_details(dt) + assert 'TSUN1' == i.dev_value(Register.PV1_MANUFACTURER) + assert 'TSUN2' == i.dev_value(Register.PV2_MANUFACTURER) + assert 'TSUN3' == i.dev_value(Register.PV3_MANUFACTURER) + assert None == i.dev_value(Register.PV4_MANUFACTURER) + assert None == i.dev_value(Register.PV5_MANUFACTURER) + assert 'Module 100W' == i.dev_value(Register.PV1_MODEL) + assert None == i.dev_value(Register.PV2_MODEL) + assert 'Module 300W' == i.dev_value(Register.PV3_MODEL) + assert 'Module 400W' == i.dev_value(Register.PV4_MODEL) + assert None == i.dev_value(Register.PV5_MODEL) + +def test_broken_info_defs(): + i = InfosG3() + val = i.get_db_value(Register.NO_INPUTS, 666) + assert val == 666 + i.info_defs[Register.TEST_REG1] = 'test' # add a string instead of a dict + val = i.get_db_value(Register.TEST_REG1, 666) + assert val == 666 + i.set_db_def_value(Register.TEST_REG1, 2) +