def __init__(cls, name, bases, nmspc): # noqa: N805 super(Registry, cls).__init__(name, bases, nmspc) if hasattr(cls, "cluster_id"): cls.cluster_id = t.ClusterId(cls.cluster_id) manufacturer_attributes = getattr(cls, "manufacturer_attributes", None) if manufacturer_attributes: cls.attributes = {**cls.attributes, **manufacturer_attributes} cls.attridx: Dict[str, int] = { attr_name: attr_id for attr_id, (attr_name, _) in cls.attributes.items() } for commands_type in ("server_commands", "client_commands"): commands = getattr(cls, commands_type, None) manufacturer_specific = getattr(cls, f"manufacturer_{commands_type}", {}) commands_idx = {} if manufacturer_specific: commands = {**commands, **manufacturer_specific} setattr(cls, commands_type, commands) for command_id, (command_name, _, _) in commands.items(): commands_idx[command_name] = command_id setattr(cls, f"_{commands_type}_idx", commands_idx) if getattr(cls, "_skip_registry", False): if cls.__name__ != "CustomCluster": cls._registry_custom_clusters.add(cls) return if hasattr(cls, "cluster_id"): cls._registry[cls.cluster_id] = cls if hasattr(cls, "cluster_id_range"): cls._registry_range[cls.cluster_id_range] = cls
def __init__(cls, name, bases, nmspc): # noqa: N805 super(Registry, cls).__init__(name, bases, nmspc) if hasattr(cls, "cluster_id"): cls.cluster_id = t.ClusterId(cls.cluster_id) if hasattr(cls, "attributes"): cls.attridx = {} for attrid, (attrname, datatype) in cls.attributes.items(): cls.attridx[attrname] = attrid if hasattr(cls, "server_commands"): cls._server_command_idx = {} for command_id, details in cls.server_commands.items(): command_name, schema, is_reply = details cls._server_command_idx[command_name] = command_id if hasattr(cls, "client_commands"): cls._client_command_idx = {} for command_id, details in cls.client_commands.items(): command_name, schema, is_reply = details cls._client_command_idx[command_name] = command_id if getattr(cls, "_skip_registry", False): return if hasattr(cls, "cluster_id"): cls._registry[cls.cluster_id] = cls if hasattr(cls, "cluster_id_range"): cls._registry_range[cls.cluster_id_range] = cls
def from_id( cls, endpoint: EndpointType, cluster_id: int, is_server: bool = True ) -> ClusterType: if cluster_id in cls._registry: c = cls._registry[cluster_id](endpoint, is_server) return c else: for cluster_id_range, cluster in cls._registry_range.items(): if cluster_id_range[0] <= cluster_id <= cluster_id_range[1]: c = cluster(endpoint, is_server) c.cluster_id = t.ClusterId(cluster_id) return c LOGGER.warning("Unknown cluster %s", cluster_id) c = cls(endpoint, is_server) c.cluster_id = t.ClusterId(cluster_id) return c
def from_id(cls, endpoint: EndpointType, cluster_id: int, is_server: bool = True) -> Cluster: cluster_id = t.ClusterId(cluster_id) if cluster_id in cls._registry: return cls._registry[cluster_id](endpoint, is_server) for (start, end), cluster in cls._registry_range.items(): if start <= cluster_id <= end: cluster = cluster(endpoint, is_server) cluster.cluster_id = cluster_id return cluster LOGGER.debug("Unknown cluster 0x%04X", cluster_id) cluster = cls(endpoint, is_server) cluster.cluster_id = cluster_id return cluster
def __init_subclass__(cls): # Fail on deprecated attribute presence for a in ("attributes", "client_commands", "server_commands"): if not hasattr(cls, f"manufacturer_{a}"): continue raise TypeError( f"`manufacturer_{a}` is deprecated. Copy the parent class's `{a}`" f" dictionary and update it with your manufacturer-specific `{a}`. Make" f" sure to specify that it is manufacturer-specific through the " f" appropriate constructor or tuple!") if cls.cluster_id is not None: cls.cluster_id = t.ClusterId(cls.cluster_id) # Clear the caches and lookup tables. Their contents should correspond exactly # to what's in their respective command/attribute dictionaries. cls.attributes_by_name = {} cls.commands_by_name = {} cls._server_commands_idx = {} cls._client_commands_idx = {} # Compile command definitions for commands, index in [ (cls.server_commands, cls._server_commands_idx), (cls.client_commands, cls._client_commands_idx), ]: for command_id, command in list(commands.items()): if isinstance(command, tuple): # Backwards compatibility with old command tuples name, schema, is_reply = command command = foundation.ZCLCommandDef( id=command_id, name=name, schema=convert_list_schema(schema, command_id, is_reply), is_reply=is_reply, ) else: command = command.replace(id=command_id) if command.name in cls.commands_by_name: raise TypeError( f"Command name {command} is not unique in {cls}: {cls.commands_by_name}" ) index[command.name] = command.id command = command.with_compiled_schema() commands[command.id] = command cls.commands_by_name[command.name] = command # Compile attributes for attr_id, attr in list(cls.attributes.items()): if isinstance(attr, tuple): if len(attr) == 2: attr_name, attr_type = attr attr_manuf_specific = False else: attr_name, attr_type, attr_manuf_specific = attr attr = foundation.ZCLAttributeDef( id=attr_id, name=attr_name, type=attr_type, is_manufacturer_specific=attr_manuf_specific, ) else: attr = attr.replace(id=attr_id) cls.attributes[attr.id] = attr cls.attributes_by_name[attr.name] = attr if cls._skip_registry: return if cls.cluster_id is not None: cls._registry[cls.cluster_id] = cls if cls.cluster_id_range is not None: cls._registry_range[cls.cluster_id_range] = cls