import struct from typing import Generator if __name__ == "app.src.gen3plus.infos_g3p": from app.src.infos import Infos, Register else: # pragma: no cover from infos import Infos, Register class RegisterMap: # make the class read/only by using __slots__ __slots__ = () map = { # 0x41020007: {'reg': Register.DEVICE_SNR, 'fmt': ' Generator[tuple[dict, str], None, None]: '''Generator function yields a json register struct for home-assistant auto configuration and a unique entity string arguments: prfx:str ==> MQTT prefix for the home assistant 'stat_t string snr:str ==> serial number of the inverter, used to build unique entity strings sug_area:str ==> suggested area string from the config file''' # iterate over RegisterMap.map and get the register values for row in RegisterMap.map.values(): info_id = row['reg'] res = self.ha_conf(info_id, ha_prfx, node_id, snr, False, sug_area) # noqa: E501 if res: yield res def parse(self, buf, msg_type: int, rcv_ftype: int) \ -> Generator[tuple[str, bool], None, None]: '''parse a data sequence received from the inverter and stores the values in Infos.db buf: buffer of the sequence to parse''' for idx, row in RegisterMap.map.items(): addr = idx & 0xffff ftype = (idx >> 16) & 0xff mtype = (idx >> 24) & 0xff if ftype != rcv_ftype or mtype != msg_type: continue if isinstance(row, dict): info_id = row['reg'] fmt = row['fmt'] res = struct.unpack_from(fmt, buf, addr) result = res[0] if isinstance(result, (bytearray, bytes)): result = result.decode('utf-8') if 'eval' in row: result = eval(row['eval']) if 'ratio' in row: result = round(result * row['ratio'], 2) keys, level, unit, must_incr, new_val = self._key_obj(info_id) if keys: name, update = self.update_db(keys, must_incr, result) yield keys[0], update else: name = str(f'info-id.0x{addr:x}') update = False self.tracer.log(level, f'{name} : {result}{unit}' f' update: {update}') def ignore_this_device(self, dep: dict) -> bool: '''Checks the equation in the dep dict returns 'False' only if the equation is valid; 'True' in any other case''' if 'reg' in dep: value = self.dev_value(dep['reg']) if not value: return True if 'gte' in dep: return not value >= dep['gte'] elif 'less_eq' in dep: return not value <= dep['less_eq'] return True