Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
    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
Пример #5
0
    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