Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions homeassistant/components/deconz/sensor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Support for deCONZ sensors."""
from pydeconz.sensor import Consumption, Daylight, LightLevel, Power, Switch
from pydeconz.sensor import Consumption, Daylight, LightLevel, Power, Switch, Thermostat

from homeassistant.const import ATTR_TEMPERATURE, ATTR_VOLTAGE, DEVICE_CLASS_BATTERY
from homeassistant.core import callback
Expand Down Expand Up @@ -48,7 +48,7 @@ def async_add_sensor(sensors):
hass.async_create_task(new_event.async_update_device_registry())
gateway.events.append(new_event)

elif not sensor.BINARY:
elif not sensor.BINARY and sensor.type not in Thermostat.ZHATYPE:

new_sensor = DeconzSensor(sensor, gateway)
entity_handler.add_entity(new_sensor)
Expand Down
217 changes: 136 additions & 81 deletions tests/components/deconz/test_binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,79 +1,98 @@
"""deCONZ binary sensor platform tests."""
from unittest.mock import Mock, patch
from copy import deepcopy

from tests.common import mock_coro
from asynctest import patch

from homeassistant import config_entries
from homeassistant.components import deconz
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.setup import async_setup_component

import homeassistant.components.binary_sensor as binary_sensor


SENSOR = {
SENSORS = {
"1": {
"id": "Sensor 1 id",
"name": "Sensor 1 name",
"id": "Presence sensor id",
"name": "Presence sensor",
"type": "ZHAPresence",
"state": {"presence": False},
"config": {},
"state": {"dark": False, "presence": False},
"config": {"on": True, "reachable": True, "temperature": 10},
"uniqueid": "00:00:00:00:00:00:00:00-00",
},
"2": {
"id": "Sensor 2 id",
"name": "Sensor 2 name",
"id": "Temperature sensor id",
"name": "Temperature sensor",
"type": "ZHATemperature",
"state": {"temperature": False},
"config": {},
"uniqueid": "00:00:00:00:00:00:00:01-00",
},
"3": {
"id": "CLIP presence sensor id",
"name": "CLIP presence sensor",
"type": "CLIPPresence",
"state": {},
"config": {},
"uniqueid": "00:00:00:00:00:00:00:02-00",
},
"4": {
"id": "Vibration sensor id",
"name": "Vibration sensor",
"type": "ZHAVibration",
"state": {
"orientation": [1, 2, 3],
"tiltangle": 36,
"vibration": True,
"vibrationstrength": 10,
},
"config": {"on": True, "reachable": True, "temperature": 10},
"uniqueid": "00:00:00:00:00:00:00:03-00",
},
}

BRIDGEID = "0123456789"

ENTRY_CONFIG = {
deconz.config_flow.CONF_API_KEY: "ABCDEF",
deconz.config_flow.CONF_BRIDGEID: "0123456789",
deconz.config_flow.CONF_BRIDGEID: BRIDGEID,
deconz.config_flow.CONF_HOST: "1.2.3.4",
deconz.config_flow.CONF_PORT: 80,
}

ENTRY_OPTIONS = {
deconz.const.CONF_ALLOW_CLIP_SENSOR: True,
deconz.const.CONF_ALLOW_DECONZ_GROUPS: True,
DECONZ_CONFIG = {
"bridgeid": BRIDGEID,
"mac": "00:11:22:33:44:55",
"name": "deCONZ mock gateway",
"sw_version": "2.05.69",
"websocketport": 1234,
}

DECONZ_WEB_REQUEST = {"config": DECONZ_CONFIG}

async def setup_gateway(hass, data, allow_clip_sensor=True):
"""Load the deCONZ binary sensor platform."""
from pydeconz import DeconzSession

loop = Mock()
session = Mock()

ENTRY_OPTIONS[deconz.const.CONF_ALLOW_CLIP_SENSOR] = allow_clip_sensor

async def setup_deconz_integration(hass, config, options, get_state_response):
"""Create the deCONZ gateway."""
config_entry = config_entries.ConfigEntry(
1,
deconz.DOMAIN,
"Mock Title",
ENTRY_CONFIG,
"test",
config_entries.CONN_CLASS_LOCAL_PUSH,
version=1,
domain=deconz.DOMAIN,
title="Mock Title",
data=config,
source="test",
connection_class=config_entries.CONN_CLASS_LOCAL_PUSH,
system_options={},
options=ENTRY_OPTIONS,
options=options,
entry_id="1",
)
gateway = deconz.DeconzGateway(hass, config_entry)
gateway.api = DeconzSession(loop, session, **config_entry.data)
gateway.api.config = Mock()
hass.data[deconz.DOMAIN] = {gateway.bridgeid: gateway}

with patch("pydeconz.DeconzSession.async_get_state", return_value=mock_coro(data)):
await gateway.api.async_load_parameters()

await hass.config_entries.async_forward_entry_setup(config_entry, "binary_sensor")
# To flush out the service call to update the group
with patch(
"pydeconz.DeconzSession.async_get_state", return_value=get_state_response
), patch("pydeconz.DeconzSession.start", return_value=True):
await deconz.async_setup_entry(hass, config_entry)
await hass.async_block_till_done()
return gateway

hass.config_entries._entries.append(config_entry)

return hass.data[deconz.DOMAIN][config[deconz.CONF_BRIDGEID]]


async def test_platform_manually_configured(hass):
Expand All @@ -89,58 +108,94 @@ async def test_platform_manually_configured(hass):

async def test_no_binary_sensors(hass):
"""Test that no sensors in deconz results in no sensor entities."""
data = {}
gateway = await setup_gateway(hass, data)
assert len(hass.data[deconz.DOMAIN][gateway.bridgeid].deconz_ids) == 0
data = deepcopy(DECONZ_WEB_REQUEST)
gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
assert len(gateway.deconz_ids) == 0
assert len(hass.states.async_all()) == 0


async def test_binary_sensors(hass):
"""Test successful creation of binary sensor entities."""
data = {"sensors": SENSOR}
gateway = await setup_gateway(hass, data)
assert "binary_sensor.sensor_1_name" in gateway.deconz_ids
assert "binary_sensor.sensor_2_name" not in gateway.deconz_ids
assert len(hass.states.async_all()) == 1

hass.data[deconz.DOMAIN][gateway.bridgeid].api.sensors["1"].async_update(
{"state": {"on": False}}
data = deepcopy(DECONZ_WEB_REQUEST)
data["sensors"] = deepcopy(SENSORS)
gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
assert "binary_sensor.presence_sensor" in gateway.deconz_ids
assert "binary_sensor.temperature_sensor" not in gateway.deconz_ids
assert "binary_sensor.clip_presence_sensor" not in gateway.deconz_ids
assert "binary_sensor.vibration_sensor" in gateway.deconz_ids
assert len(hass.states.async_all()) == 3

presence_sensor = hass.states.get("binary_sensor.presence_sensor")
assert presence_sensor.state == "off"

async def test_add_new_sensor(hass):
"""Test successful creation of sensor entities."""
data = {}
gateway = await setup_gateway(hass, data)
sensor = Mock()
sensor.name = "name"
sensor.type = "ZHAPresence"
sensor.BINARY = True
sensor.uniqueid = "1"
sensor.register_async_callback = Mock()
async_dispatcher_send(hass, gateway.async_signal_new_device("sensor"), [sensor])
await hass.async_block_till_done()
assert "binary_sensor.name" in gateway.deconz_ids


async def test_do_not_allow_clip_sensor(hass):
"""Test that clip sensors can be ignored."""
data = {}
gateway = await setup_gateway(hass, data, allow_clip_sensor=False)
sensor = Mock()
sensor.name = "name"
sensor.type = "CLIPPresence"
sensor.register_async_callback = Mock()
async_dispatcher_send(hass, gateway.async_signal_new_device("sensor"), [sensor])
temperature_sensor = hass.states.get("binary_sensor.temperature_sensor")
assert temperature_sensor is None

clip_presence_sensor = hass.states.get("binary_sensor.clip_presence_sensor")
assert clip_presence_sensor is None

vibration_sensor = hass.states.get("binary_sensor.vibration_sensor")
assert vibration_sensor.state == "on"

gateway.api.sensors["1"].async_update({"state": {"presence": True}})
await hass.async_block_till_done()
assert len(gateway.deconz_ids) == 0

presence_sensor = hass.states.get("binary_sensor.presence_sensor")
assert presence_sensor.state == "on"

async def test_unload_switch(hass):
"""Test that it works to unload switch entities."""
data = {"sensors": SENSOR}
gateway = await setup_gateway(hass, data)

await gateway.async_reset()
async def test_allow_clip_sensor(hass):
"""Test that CLIP sensors can be allowed."""
data = deepcopy(DECONZ_WEB_REQUEST)
data["sensors"] = deepcopy(SENSORS)
gateway = await setup_deconz_integration(
hass,
ENTRY_CONFIG,
options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: True},
get_state_response=data,
)
assert "binary_sensor.presence_sensor" in gateway.deconz_ids
assert "binary_sensor.temperature_sensor" not in gateway.deconz_ids
assert "binary_sensor.clip_presence_sensor" in gateway.deconz_ids
assert "binary_sensor.vibration_sensor" in gateway.deconz_ids
assert len(hass.states.async_all()) == 4

assert len(hass.states.async_all()) == 0
presence_sensor = hass.states.get("binary_sensor.presence_sensor")
assert presence_sensor.state == "off"

temperature_sensor = hass.states.get("binary_sensor.temperature_sensor")
assert temperature_sensor is None

clip_presence_sensor = hass.states.get("binary_sensor.clip_presence_sensor")
assert clip_presence_sensor.state == "off"

vibration_sensor = hass.states.get("binary_sensor.vibration_sensor")
assert vibration_sensor.state == "on"


async def test_add_new_binary_sensor(hass):
"""Test that adding a new binary sensor works."""
data = deepcopy(DECONZ_WEB_REQUEST)
gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
assert len(gateway.deconz_ids) == 0

state_added = {
"t": "event",
"e": "added",
"r": "sensors",
"id": "1",
"sensor": deepcopy(SENSORS["1"]),
}
gateway.api.async_event_handler(state_added)
await hass.async_block_till_done()

assert "binary_sensor.presence_sensor" in gateway.deconz_ids

presence_sensor = hass.states.get("binary_sensor.presence_sensor")
assert presence_sensor.state == "off"
Loading