Пример #1
0
def test_add_to_registry_legacy_sig(fake_dev):
    reg = DeviceRegistry()

    quirk_list = mock.MagicMock()
    model_dict = mock.MagicMock(spec_set=dict)
    model_dict.__getitem__.return_value = quirk_list
    manuf_dict = mock.MagicMock()
    manuf_dict.__getitem__.return_value = model_dict

    reg._registry = manuf_dict

    fake_dev.signature = {
        1: {},
        2: {},
        3: {
            "manufacturer": mock.sentinel.legacy_manufacturer,
            "model": mock.sentinel.legacy_model,
        },
    }

    reg.add_to_registry(fake_dev)
    assert manuf_dict.__getitem__.call_count == 1
    assert manuf_dict.__getitem__.call_args[0][
        0] is mock.sentinel.legacy_manufacturer
    assert model_dict.__getitem__.call_count == 1
    assert model_dict.__getitem__.call_args[0][0] is mock.sentinel.legacy_model
    assert quirk_list.append.call_count == 1
    assert quirk_list.append.call_args[0][0] is fake_dev
Пример #2
0
def test_reg_get_model(fake_dev):
    assert DeviceRegistry.get_model(fake_dev) is None

    fake_dev.signature = {
        1: {},
        2: {},
        3: {
            "model": mock.sentinel.legacy_model
        }
    }
    assert DeviceRegistry.get_model(fake_dev) is mock.sentinel.legacy_model

    fake_dev.signature = {
        1: {},
        2: {},
        3: {
            "model": mock.sentinel.legacy_model
        },
        "endpoints": {
            1: {},
            2: {},
            3: {
                "model": mock.sentinel.ep_model
            }
        },
        "model": mock.sentinel.model,
    }
    assert DeviceRegistry.get_model(fake_dev) is mock.sentinel.model
Пример #3
0
def test_reg_get_manufacturer(fake_dev):
    assert DeviceRegistry.get_manufacturer(fake_dev) is None

    fake_dev.signature = {
        1: {},
        2: {},
        3: {
            "manufacturer": mock.sentinel.legacy_manufacturer
        },
    }
    assert (DeviceRegistry.get_manufacturer(fake_dev) is
            mock.sentinel.legacy_manufacturer)

    fake_dev.signature = {
        1: {},
        2: {},
        3: {
            "manufacturer": mock.sentinel.legacy_manufacturer
        },
        "endpoints": {
            1: {},
            2: {},
            3: {
                "manufacturer": mock.sentinel.ep_manufacturer
            }
        },
        "manufacturer": mock.sentinel.manufacturer,
    }
    assert DeviceRegistry.get_manufacturer(
        fake_dev) is mock.sentinel.manufacturer
Пример #4
0
def test_remove_new_sig(fake_dev):
    fake_dev.signature = {
        1: {},
        2: {},
        3: {
            'manufacturer': mock.sentinel.legacy_manufacturer,
            'model': mock.sentinel.legacy_model,
        },
        'endpoints': {
            1: {
                'manufacturer': mock.sentinel.manufacturer,
                'model': mock.sentinel.model,
            }
        },
        'manufacturer': mock.sentinel.dev_manufacturer,
        'model': mock.sentinel.dev_model,
    }

    reg = DeviceRegistry()

    quirk_list = mock.MagicMock()
    model_dict = mock.MagicMock(spec_set=dict)
    model_dict.__getitem__.return_value = quirk_list
    manuf_dict = mock.MagicMock()
    manuf_dict.__getitem__.return_value = model_dict
    reg._registry = manuf_dict

    reg.remove(fake_dev)
    assert manuf_dict.__getitem__.call_count == 1
    assert manuf_dict.__getitem__.call_args[0][0] is mock.sentinel.dev_manufacturer
    assert model_dict.__getitem__.call_count == 1
    assert model_dict.__getitem__.call_args[0][0] is mock.sentinel.dev_model
    assert quirk_list.append.call_count == 0
    assert quirk_list.remove.call_count == 1
    assert quirk_list.remove.call_args[0][0] is fake_dev
Пример #5
0
def test_model_manuf_device_sig(real_device):
    class TestDevice:
        signature = {}

        def __init__(*args, **kwargs):
            pass

        def get_signature(self):
            pass

    registry = DeviceRegistry()
    registry.add_to_registry(TestDevice)

    assert registry.get_device(real_device) is real_device

    TestDevice.signature["endpoints"] = {
        1: {
            "profile_id": 255,
            "device_type": 255,
            "input_clusters": [3],
            "output_clusters": [6],
        }
    }

    TestDevice.signature["model"] = "x"
    assert registry.get_device(real_device) is real_device

    TestDevice.signature["model"] = "model"
    TestDevice.signature["manufacturer"] = "x"
    assert registry.get_device(real_device) is real_device

    TestDevice.signature["manufacturer"] = "manufacturer"
    assert isinstance(registry.get_device(real_device), TestDevice)
Пример #6
0
def test_model_manuf_device_sig(real_device):
    class TestDevice:
        signature = {}

        def __init__(*args, **kwargs):
            pass

        def get_signature(self):
            pass

    registry = DeviceRegistry()
    registry.add_to_registry(TestDevice)

    assert registry.get_device(real_device) is real_device

    TestDevice.signature[SIG_ENDPOINTS] = {
        1: {
            SIG_EP_PROFILE: 255,
            SIG_EP_TYPE: 255,
            SIG_EP_INPUT: [3],
            SIG_EP_OUTPUT: [6],
        }
    }

    TestDevice.signature[SIG_MODEL] = "x"
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[SIG_MODEL] = "model"
    TestDevice.signature[SIG_MANUFACTURER] = "x"
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[SIG_MANUFACTURER] = "manufacturer"
    assert isinstance(registry.get_device(real_device), TestDevice)
Пример #7
0
def test_model_manuf_device_sig(real_device):
    class TestDevice:
        signature = {}

        def __init__(*args, **kwargs):
            pass

        def get_signature(self):
            pass

    registry = DeviceRegistry()
    registry.add_to_registry(TestDevice)

    assert registry.get_device(real_device) is real_device

    TestDevice.signature['endpoints'] = {
        1: {
            'profile_id': 255,
            'device_type': 255,
            'input_clusters': [3],
            'output_clusters': [6],
        }
    }

    TestDevice.signature['model'] = 'x'
    assert registry.get_device(real_device) is real_device

    TestDevice.signature['model'] = 'model'
    TestDevice.signature['manufacturer'] = 'x'
    assert registry.get_device(real_device) is real_device

    TestDevice.signature['manufacturer'] = 'manufacturer'
    assert isinstance(registry.get_device(real_device), TestDevice)
Пример #8
0
def test_quirk_match_order(real_device, real_device_2):
    """Test quirk matching order to allow user overrides via custom quirks."""

    class BuiltInQuirk(zigpy.quirks.CustomDevice):
        signature = {
            SIG_MODELS_INFO: (("manufacturer", "model"),),
            SIG_ENDPOINTS: {
                1: {
                    SIG_EP_PROFILE: 255,
                    SIG_EP_TYPE: 255,
                    SIG_EP_INPUT: [3],
                    SIG_EP_OUTPUT: [6],
                }
            },
        }

        def get_signature(self):
            pass

    class CustomQuirk(BuiltInQuirk):
        pass

    registry = DeviceRegistry()
    registry.add_to_registry(BuiltInQuirk)
    # With only a single matching quirk there is no choice but to use the first one
    assert type(registry.get_device(real_device)) is BuiltInQuirk

    registry.add_to_registry(CustomQuirk)
    # A quirk registered later that also matches the device will be preferred
    assert type(registry.get_device(real_device)) is CustomQuirk
Пример #9
0
def test_add_to_registry_models_info(fake_dev):
    fake_dev.signature = {
        1: {},
        2: {},
        3: {
            "manufacturer": mock.sentinel.legacy_manufacturer,
            "model": mock.sentinel.legacy_model,
        },
        "endpoints": {
            1: {
                "manufacturer": mock.sentinel.manufacturer,
                "model": mock.sentinel.model,
            }
        },
        SIG_MODELS_INFO: [
            (mock.sentinel.manuf_1, mock.sentinel.model_1),
            (mock.sentinel.manuf_2, mock.sentinel.model_2),
        ],
    }

    reg = DeviceRegistry()

    quirk_list = mock.MagicMock()
    model_dict = mock.MagicMock(spec_set=dict)
    model_dict.__getitem__.return_value = quirk_list
    manuf_dict = mock.MagicMock()
    manuf_dict.__getitem__.return_value = model_dict
    reg._registry = manuf_dict

    reg.add_to_registry(fake_dev)
    assert manuf_dict.__getitem__.call_count == 2
    assert manuf_dict.__getitem__.call_args_list[0][0][
        0] is mock.sentinel.manuf_1
    assert manuf_dict.__getitem__.call_args_list[1][0][
        0] is mock.sentinel.manuf_2
    assert model_dict.__getitem__.call_count == 2
    assert model_dict.__getitem__.call_args_list[0][0][
        0] is mock.sentinel.model_1
    assert model_dict.__getitem__.call_args_list[1][0][
        0] is mock.sentinel.model_2
    assert quirk_list.append.call_count == 2
    assert quirk_list.append.call_args_list[0][0][0] is fake_dev
    assert quirk_list.append.call_args_list[1][0][0] is fake_dev
    quirk_list.reset_mock()
    model_dict.reset_mock()
    manuf_dict.reset_mock()
Пример #10
0
def test_reg_get_manufacturer(fake_dev):
    assert DeviceRegistry.get_manufacturer(fake_dev) is None

    fake_dev.signature = {
        1: {},
        2: {},
        3: {'manufacturer': mock.sentinel.legacy_manufacturer},
    }
    assert DeviceRegistry.get_manufacturer(fake_dev) is mock.sentinel.legacy_manufacturer

    fake_dev.signature = {
        1: {},
        2: {},
        3: {'manufacturer': mock.sentinel.legacy_manufacturer},
        'endpoints': {
            1: {},
            2: {},
            3: {'manufacturer': mock.sentinel.ep_manufacturer}
        },
        'manufacturer': mock.sentinel.manufacturer
    }
    assert DeviceRegistry.get_manufacturer(fake_dev) is mock.sentinel.manufacturer
Пример #11
0
import logging
from typing import Any, Dict, Optional

import zigpy.device
import zigpy.endpoint
from zigpy.quirks.registry import DeviceRegistry
import zigpy.zcl
import zigpy.zcl.foundation as foundation

_LOGGER = logging.getLogger(__name__)

_DEVICE_REGISTRY = DeviceRegistry()


def get_device(device, registry=_DEVICE_REGISTRY):
    """Get a CustomDevice object, if one is available"""
    return registry.get_device(device)


class Registry(type):
    def __init__(cls, name, bases, nmspc):  # noqa: N805
        super(Registry, cls).__init__(name, bases, nmspc)
        if hasattr(cls, "signature"):
            _DEVICE_REGISTRY.add_to_registry(cls)


class CustomDevice(zigpy.device.Device, metaclass=Registry):
    replacement = {}

    def __init__(self, application, ieee, nwk, replaces):
        super().__init__(application, ieee, nwk)
Пример #12
0
def _dev_reg(device):
    registry = DeviceRegistry()
    registry.add_to_registry(device)
    return registry
Пример #13
0
def test_get_device_old_signature(real_device):
    class TestDevice:
        signature = {}

        def __init__(*args, **kwargs):
            pass

        def get_signature(self):
            pass

    registry = DeviceRegistry()
    registry.add_to_registry(TestDevice)

    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1] = {'profile_id': 1}
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]['profile_id'] = 255
    TestDevice.signature[1]['device_type'] = 1
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]['device_type'] = 255
    TestDevice.signature[1]['input_clusters'] = [1]
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]['input_clusters'] = [3]
    TestDevice.signature[1]['output_clusters'] = [1]
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]['output_clusters'] = [6]
    TestDevice.signature[1]['model'] = 'x'
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]['model'] = 'model'
    TestDevice.signature[1]['manufacturer'] = 'x'
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]['manufacturer'] = 'manufacturer'
    assert isinstance(registry.get_device(real_device), TestDevice)
Пример #14
0
def test_get_device_old_signature(real_device):
    class TestDevice:
        signature = {}

        def __init__(*args, **kwargs):
            pass

        def get_signature(self):
            pass

    registry = DeviceRegistry()
    registry.add_to_registry(TestDevice)

    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1] = {"profile_id": 1}
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]["profile_id"] = 255
    TestDevice.signature[1]["device_type"] = 1
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]["device_type"] = 255
    TestDevice.signature[1]["input_clusters"] = [1]
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]["input_clusters"] = [3]
    TestDevice.signature[1]["output_clusters"] = [1]
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]["output_clusters"] = [6]
    TestDevice.signature[1]["model"] = "x"
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]["model"] = "model"
    TestDevice.signature[1]["manufacturer"] = "x"
    assert registry.get_device(real_device) is real_device

    TestDevice.signature[1]["manufacturer"] = "manufacturer"
    assert isinstance(registry.get_device(real_device), TestDevice)
Пример #15
0
def test_quirk_wildcard_manufacturer(real_device, real_device_2):
    """Test quirk matching with a wildcard (None) manufacturer."""

    class BaseDev(zigpy.quirks.CustomDevice):
        def get_signature(self):
            pass

    class ModelsQuirk(BaseDev):
        signature = {
            SIG_MODELS_INFO: (("manufacturer", "model"),),
            SIG_ENDPOINTS: {
                1: {
                    SIG_EP_PROFILE: 255,
                    SIG_EP_TYPE: 255,
                    SIG_EP_INPUT: [3],
                    SIG_EP_OUTPUT: [6],
                }
            },
        }

    class ModelsQuirkNoMatch(BaseDev):
        # same model and manufacture, different endpoint signature
        signature = {
            SIG_MODELS_INFO: (("manufacturer", "model"),),
            SIG_ENDPOINTS: {
                1: {
                    SIG_EP_PROFILE: 260,
                    SIG_EP_TYPE: 255,
                    SIG_EP_INPUT: [3],
                    SIG_EP_OUTPUT: [6],
                }
            },
        }

    class ModelOnlyQuirk(BaseDev):
        # Wildcard Manufacturer
        signature = {
            SIG_MODEL: "model",
            SIG_ENDPOINTS: {
                1: {
                    SIG_EP_PROFILE: 255,
                    SIG_EP_TYPE: 255,
                    SIG_EP_INPUT: [3],
                    SIG_EP_OUTPUT: [6],
                }
            },
        }

    class ModelOnlyQuirkNoMatch(BaseDev):
        # Wildcard Manufacturer, none matching endpoint signature
        signature = {
            SIG_MODEL: "model",
            SIG_ENDPOINTS: {
                1: {
                    SIG_EP_PROFILE: 260,
                    SIG_EP_TYPE: 255,
                    SIG_EP_INPUT: [3],
                    SIG_EP_OUTPUT: [6],
                }
            },
        }

    registry = DeviceRegistry()
    for quirk in ModelsQuirk, ModelsQuirkNoMatch, ModelOnlyQuirk, ModelOnlyQuirkNoMatch:
        registry.add_to_registry(quirk)

    quirked = registry.get_device(real_device)
    assert isinstance(quirked, ModelsQuirk)

    quirked = registry.get_device(real_device_2)
    assert isinstance(quirked, ModelOnlyQuirk)

    real_device.manufacturer = (
        "We are expected to match a manufacturer wildcard quirk now"
    )
    quirked = registry.get_device(real_device)
    assert isinstance(quirked, ModelOnlyQuirk)

    real_device.model = "And now we should not match any quirk"
    quirked = registry.get_device(real_device)
    assert quirked is real_device
Пример #16
0
def test_different_manuf_same_model(real_device, real_device_2):
    """Test quirk matching for same model, but different manufacturers."""

    class TestDevice_1(zigpy.quirks.CustomDevice):
        signature = {
            SIG_MODELS_INFO: (("manufacturer", "model"),),
            SIG_ENDPOINTS: {
                1: {
                    SIG_EP_PROFILE: 255,
                    SIG_EP_TYPE: 255,
                    SIG_EP_INPUT: [3],
                    SIG_EP_OUTPUT: [6],
                }
            },
        }

        def get_signature(self):
            pass

    class TestDevice_2(zigpy.quirks.CustomDevice):
        signature = {
            SIG_MODELS_INFO: (("A different manufacturer", "model"),),
            SIG_ENDPOINTS: {
                1: {
                    SIG_EP_PROFILE: 255,
                    SIG_EP_TYPE: 255,
                    SIG_EP_INPUT: [3],
                    SIG_EP_OUTPUT: [6],
                }
            },
        }

        def get_signature(self):
            pass

    registry = DeviceRegistry()
    registry.add_to_registry(TestDevice_1)

    assert isinstance(registry.get_device(real_device), TestDevice_1)

    assert registry.get_device(real_device_2) is real_device_2
    registry.add_to_registry(TestDevice_2)
    assert isinstance(registry.get_device(real_device_2), TestDevice_2)

    assert not zigpy.quirks.get_quirk_list("manufacturer", "no such model")
    assert not zigpy.quirks.get_quirk_list("manufacturer", "no such model", registry)
    assert not zigpy.quirks.get_quirk_list("A different manufacturer", "no such model")
    assert not zigpy.quirks.get_quirk_list(
        "A different manufacturer", "no such model", registry
    )
    assert not zigpy.quirks.get_quirk_list("no such manufacturer", "model")
    assert not zigpy.quirks.get_quirk_list("no such manufacturer", "model", registry)

    manuf1_list = zigpy.quirks.get_quirk_list("manufacturer", "model", registry)
    assert len(manuf1_list) == 1
    assert manuf1_list[0] is TestDevice_1

    manuf2_list = zigpy.quirks.get_quirk_list(
        "A different manufacturer", "model", registry
    )
    assert len(manuf2_list) == 1
    assert manuf2_list[0] is TestDevice_2