* Add ZHA core typing helper. * Add aux_channels to ZHA rule matching. * Add match rule claim_channels() method. * Expose underlying zigpy device. * Not sure we need this one. * Move "base" channels. * Framework for channel discovery. * Make DEVICE_CLASS and REMOTE_DEVICE_TYPE default dicts. * Remove attribute reporting configuration registry. * Refactor channels. - Refactor zha events - Use compound IDs and unique_ids - Refactor signal dispatching on attribute updates * Use unique id compatible with entities unique ids. * Refactor ZHA Entity registry. Let match rule to check for the match. * Refactor discovery to use new channels. * Cleanup ZDO channel. Remove unused zha store call. * Handle channel configuration and initialization. * Refactor ZHA Device to use new channels. * Refactor ZHA Gateway to use new discovery framework. Use hass.data for entity info intermediate store. * Don't keep entities in hass.data. * ZHA gateway new discovery framework. * Refactor ZHA platform loading. * Don't update ZHA entities, when restoring from zigpy. * ZHA entity discover tests. * Add AnalogInput sensor. * Remove 0xFC02 based entity from Keen smart vents. * Clean up IAS channels. * Refactor entity restoration. * Fix lumi.router entities name. * Rename EndpointsChannel to ChannelPool. * Make Channels.pools a list. * Fix cover test. * Fix FakeDevice class. * Fix device actions. * Fix channels typing. * Revert update_before_add=False * Refactor channel class matching. * Use a helper function for adding entities. * Make Pylint happy. * Rebase cleanup. * Update coverage for ZHA device type overrides. * Use cluster_id for single output cluster registry. * Remove ZHA typing from coverage. * Fix tests. * Address comments. * Address comments.
256 lines
8.5 KiB
Python
256 lines
8.5 KiB
Python
"""Test ZHA registries."""
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
|
|
import homeassistant.components.zha.core.registries as registries
|
|
|
|
MANUFACTURER = "mock manufacturer"
|
|
MODEL = "mock model"
|
|
|
|
|
|
@pytest.fixture
|
|
def zha_device():
|
|
"""Return a mock of ZHA device."""
|
|
dev = mock.MagicMock()
|
|
dev.manufacturer = MANUFACTURER
|
|
dev.model = MODEL
|
|
return dev
|
|
|
|
|
|
@pytest.fixture
|
|
def channels(channel):
|
|
"""Return a mock of channels."""
|
|
|
|
return [channel("level", 8), channel("on_off", 6)]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"rule, matched",
|
|
[
|
|
(registries.MatchRule(), False),
|
|
(registries.MatchRule(channel_names={"level"}), True),
|
|
(registries.MatchRule(channel_names={"level", "no match"}), False),
|
|
(registries.MatchRule(channel_names={"on_off"}), True),
|
|
(registries.MatchRule(channel_names={"on_off", "no match"}), False),
|
|
(registries.MatchRule(channel_names={"on_off", "level"}), True),
|
|
(registries.MatchRule(channel_names={"on_off", "level", "no match"}), False),
|
|
# test generic_id matching
|
|
(registries.MatchRule(generic_ids={"channel_0x0006"}), True),
|
|
(registries.MatchRule(generic_ids={"channel_0x0008"}), True),
|
|
(registries.MatchRule(generic_ids={"channel_0x0006", "channel_0x0008"}), True),
|
|
(
|
|
registries.MatchRule(
|
|
generic_ids={"channel_0x0006", "channel_0x0008", "channel_0x0009"}
|
|
),
|
|
False,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
generic_ids={"channel_0x0006", "channel_0x0008"},
|
|
channel_names={"on_off", "level"},
|
|
),
|
|
True,
|
|
),
|
|
# manufacturer matching
|
|
(registries.MatchRule(manufacturers="no match"), False),
|
|
(registries.MatchRule(manufacturers=MANUFACTURER), True),
|
|
(
|
|
registries.MatchRule(manufacturers="no match", aux_channels="aux_channel"),
|
|
False,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
manufacturers=MANUFACTURER, aux_channels="aux_channel"
|
|
),
|
|
True,
|
|
),
|
|
(registries.MatchRule(models=MODEL), True),
|
|
(registries.MatchRule(models="no match"), False),
|
|
(registries.MatchRule(models=MODEL, aux_channels="aux_channel"), True),
|
|
(registries.MatchRule(models="no match", aux_channels="aux_channel"), False),
|
|
# match everything
|
|
(
|
|
registries.MatchRule(
|
|
generic_ids={"channel_0x0006", "channel_0x0008"},
|
|
channel_names={"on_off", "level"},
|
|
manufacturers=MANUFACTURER,
|
|
models=MODEL,
|
|
),
|
|
True,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
channel_names="on_off", manufacturers={"random manuf", MANUFACTURER}
|
|
),
|
|
True,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
channel_names="on_off", manufacturers={"random manuf", "Another manuf"}
|
|
),
|
|
False,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
channel_names="on_off", manufacturers=lambda x: x == MANUFACTURER
|
|
),
|
|
True,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
channel_names="on_off", manufacturers=lambda x: x != MANUFACTURER
|
|
),
|
|
False,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
channel_names="on_off", models={"random model", MODEL}
|
|
),
|
|
True,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
channel_names="on_off", models={"random model", "Another model"}
|
|
),
|
|
False,
|
|
),
|
|
(
|
|
registries.MatchRule(channel_names="on_off", models=lambda x: x == MODEL),
|
|
True,
|
|
),
|
|
(
|
|
registries.MatchRule(channel_names="on_off", models=lambda x: x != MODEL),
|
|
False,
|
|
),
|
|
],
|
|
)
|
|
def test_registry_matching(rule, matched, channels):
|
|
"""Test strict rule matching."""
|
|
assert rule.strict_matched(MANUFACTURER, MODEL, channels) is matched
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"rule, matched",
|
|
[
|
|
(registries.MatchRule(), False),
|
|
(registries.MatchRule(channel_names={"level"}), True),
|
|
(registries.MatchRule(channel_names={"level", "no match"}), False),
|
|
(registries.MatchRule(channel_names={"on_off"}), True),
|
|
(registries.MatchRule(channel_names={"on_off", "no match"}), False),
|
|
(registries.MatchRule(channel_names={"on_off", "level"}), True),
|
|
(registries.MatchRule(channel_names={"on_off", "level", "no match"}), False),
|
|
(
|
|
registries.MatchRule(channel_names={"on_off", "level"}, models="no match"),
|
|
True,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
channel_names={"on_off", "level"},
|
|
models="no match",
|
|
manufacturers="no match",
|
|
),
|
|
True,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
channel_names={"on_off", "level"},
|
|
models="no match",
|
|
manufacturers=MANUFACTURER,
|
|
),
|
|
True,
|
|
),
|
|
# test generic_id matching
|
|
(registries.MatchRule(generic_ids={"channel_0x0006"}), True),
|
|
(registries.MatchRule(generic_ids={"channel_0x0008"}), True),
|
|
(registries.MatchRule(generic_ids={"channel_0x0006", "channel_0x0008"}), True),
|
|
(
|
|
registries.MatchRule(
|
|
generic_ids={"channel_0x0006", "channel_0x0008", "channel_0x0009"}
|
|
),
|
|
False,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
generic_ids={"channel_0x0006", "channel_0x0008", "channel_0x0009"},
|
|
models="mo match",
|
|
),
|
|
False,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
generic_ids={"channel_0x0006", "channel_0x0008", "channel_0x0009"},
|
|
models=MODEL,
|
|
),
|
|
True,
|
|
),
|
|
(
|
|
registries.MatchRule(
|
|
generic_ids={"channel_0x0006", "channel_0x0008"},
|
|
channel_names={"on_off", "level"},
|
|
),
|
|
True,
|
|
),
|
|
# manufacturer matching
|
|
(registries.MatchRule(manufacturers="no match"), False),
|
|
(registries.MatchRule(manufacturers=MANUFACTURER), True),
|
|
(registries.MatchRule(models=MODEL), True),
|
|
(registries.MatchRule(models="no match"), False),
|
|
# match everything
|
|
(
|
|
registries.MatchRule(
|
|
generic_ids={"channel_0x0006", "channel_0x0008"},
|
|
channel_names={"on_off", "level"},
|
|
manufacturers=MANUFACTURER,
|
|
models=MODEL,
|
|
),
|
|
True,
|
|
),
|
|
],
|
|
)
|
|
def test_registry_loose_matching(rule, matched, channels):
|
|
"""Test loose rule matching."""
|
|
assert rule.loose_matched(MANUFACTURER, MODEL, channels) is matched
|
|
|
|
|
|
def test_match_rule_claim_channels_color(channel):
|
|
"""Test channel claiming."""
|
|
ch_color = channel("color", 0x300)
|
|
ch_level = channel("level", 8)
|
|
ch_onoff = channel("on_off", 6)
|
|
|
|
rule = registries.MatchRule(channel_names="on_off", aux_channels={"color", "level"})
|
|
claimed = rule.claim_channels([ch_color, ch_level, ch_onoff])
|
|
assert {"color", "level", "on_off"} == set([ch.name for ch in claimed])
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"rule, match",
|
|
[
|
|
(registries.MatchRule(channel_names={"level"}), {"level"}),
|
|
(registries.MatchRule(channel_names={"level", "no match"}), {"level"}),
|
|
(registries.MatchRule(channel_names={"on_off"}), {"on_off"}),
|
|
(registries.MatchRule(generic_ids="channel_0x0000"), {"basic"}),
|
|
(
|
|
registries.MatchRule(channel_names="level", generic_ids="channel_0x0000"),
|
|
{"basic", "level"},
|
|
),
|
|
(registries.MatchRule(channel_names={"level", "power"}), {"level", "power"}),
|
|
(
|
|
registries.MatchRule(
|
|
channel_names={"level", "on_off"}, aux_channels={"basic", "power"}
|
|
),
|
|
{"basic", "level", "on_off", "power"},
|
|
),
|
|
(registries.MatchRule(channel_names={"color"}), set()),
|
|
],
|
|
)
|
|
def test_match_rule_claim_channels(rule, match, channel, channels):
|
|
"""Test channel claiming."""
|
|
ch_basic = channel("basic", 0)
|
|
channels.append(ch_basic)
|
|
ch_power = channel("power", 1)
|
|
channels.append(ch_power)
|
|
|
|
claimed = rule.claim_channels(channels)
|
|
assert match == set([ch.name for ch in claimed])
|