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
15 changes: 14 additions & 1 deletion homeassistant/components/smartthings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from .config_flow import SmartThingsFlowHandler # noqa
from .const import (
CONF_APP_ID, CONF_INSTALLED_APP_ID, DATA_BROKERS, DATA_MANAGER, DOMAIN,
SIGNAL_SMARTTHINGS_UPDATE, SUPPORTED_PLATFORMS)
EVENT_BUTTON, SIGNAL_SMARTTHINGS_UPDATE, SUPPORTED_PLATFORMS)
from .smartapp import (
setup_smartapp, setup_smartapp_endpoint, validate_installed_app)

Expand Down Expand Up @@ -154,6 +154,19 @@ async def event_handler(self, req, resp, app):
continue
device.status.apply_attribute_update(
evt.component_id, evt.capability, evt.attribute, evt.value)

# Fire events for buttons
if evt.capability == 'button' and evt.attribute == 'button':
data = {
'component_id': evt.component_id,
'device_id': evt.device_id,
'location_id': evt.location_id,
'value': evt.value,
'name': device.label
}
self._hass.bus.async_fire(EVENT_BUTTON, data)
_LOGGER.debug("Fired button event: %s", data)

updated_devices.add(device.device_id)
_LOGGER.debug("Update received with %s events and updated %s devices",
len(req.events), len(updated_devices))
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/smartthings/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
DATA_MANAGER = 'manager'
DATA_BROKERS = 'brokers'
DOMAIN = 'smartthings'
EVENT_BUTTON = "smartthings.button"
SIGNAL_SMARTTHINGS_UPDATE = 'smartthings_update'
SIGNAL_SMARTAPP_PREFIX = 'smartthings_smartap_'
SETTINGS_INSTANCE_ID = "hassInstanceId"
Expand All @@ -25,6 +26,7 @@
]
SUPPORTED_CAPABILITIES = [
'accelerationSensor',
'button',
'colorControl',
'colorTemperature',
'contactSensor',
Expand Down
22 changes: 14 additions & 8 deletions tests/components/smartthings/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,26 +254,32 @@ def _factory(label, capabilities, status: dict = None):
@pytest.fixture(name="event_factory")
def event_factory_fixture():
"""Fixture for creating mock devices."""
def _factory(device_id, event_type="DEVICE_EVENT"):
def _factory(device_id, event_type="DEVICE_EVENT", capability='',
attribute='Updated', value='Value'):
event = Mock()
event.event_type = event_type
event.device_id = device_id
event.component_id = 'main'
event.capability = ''
event.attribute = 'Updated'
event.value = 'Value'
event.capability = capability
event.attribute = attribute
event.value = value
event.location_id = str(uuid4())
return event
return _factory


@pytest.fixture(name="event_request_factory")
def event_request_factory_fixture(event_factory):
"""Fixture for creating mock smartapp event requests."""
def _factory(device_ids):
def _factory(device_ids=None, events=None):
request = Mock()
request.installed_app_id = uuid4()
request.events = [event_factory(id) for id in device_ids]
request.events.append(event_factory(uuid4()))
request.events.append(event_factory(device_ids[0], event_type="OTHER"))
if events is None:
events = []
if device_ids:
events.extend([event_factory(id) for id in device_ids])
events.append(event_factory(uuid4()))
events.append(event_factory(device_ids[0], event_type="OTHER"))
request.events = events
return request
return _factory
31 changes: 22 additions & 9 deletions tests/components/smartthings/test_binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
"""
from pysmartthings import Attribute, Capability

from homeassistant.components.binary_sensor import DEVICE_CLASSES
from homeassistant.components.smartthings import DeviceBroker, binary_sensor
from homeassistant.components.smartthings.const import (
DATA_BROKERS, DOMAIN, SIGNAL_SMARTTHINGS_UPDATE)
DATA_BROKERS, DOMAIN, SIGNAL_SMARTTHINGS_UPDATE, SUPPORTED_CAPABILITIES)
from homeassistant.config_entries import (
CONN_CLASS_CLOUD_PUSH, SOURCE_USER, ConfigEntry)
from homeassistant.const import ATTR_FRIENDLY_NAME
Expand All @@ -32,6 +33,18 @@ async def _setup_platform(hass, *devices):
return config_entry


async def test_mapping_integrity():
"""Test ensures the map dicts have proper integrity."""
# Ensure every CAPABILITY_TO_ATTRIB key is in SUPPORTED_CAPABILITIES
# Ensure every CAPABILITY_TO_ATTRIB value is in ATTRIB_TO_CLASS keys
for capability, attrib in binary_sensor.CAPABILITY_TO_ATTRIB.items():
assert capability in SUPPORTED_CAPABILITIES, capability
assert attrib in binary_sensor.ATTRIB_TO_CLASS.keys(), attrib
# Ensure every ATTRIB_TO_CLASS value is in DEVICE_CLASSES
for device_class in binary_sensor.ATTRIB_TO_CLASS.values():
assert device_class in DEVICE_CLASSES


async def test_async_setup_platform():
"""Test setup platform does nothing (it uses config entries)."""
await binary_sensor.async_setup_platform(None, None, None)
Expand All @@ -58,15 +71,15 @@ async def test_entity_and_device_attributes(hass, device_factory):
# Act
await _setup_platform(hass, device)
# Assert
entity = entity_registry.async_get('binary_sensor.motion_sensor_1_motion')
assert entity
assert entity.unique_id == device.device_id + '.' + Attribute.motion
device_entry = device_registry.async_get_device(
entry = entity_registry.async_get('binary_sensor.motion_sensor_1_motion')
assert entry
assert entry.unique_id == device.device_id + '.' + Attribute.motion
entry = device_registry.async_get_device(
{(DOMAIN, device.device_id)}, [])
assert device_entry
assert device_entry.name == device.label
assert device_entry.model == device.device_type_name
assert device_entry.manufacturer == 'Unavailable'
assert entry
assert entry.name == device.label
assert entry.model == device.device_type_name
assert entry.manufacturer == 'Unavailable'


async def test_update_from_signal(hass, device_factory):
Expand Down
31 changes: 30 additions & 1 deletion tests/components/smartthings/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

from homeassistant.components import smartthings
from homeassistant.components.smartthings.const import (
DATA_BROKERS, DOMAIN, SIGNAL_SMARTTHINGS_UPDATE, SUPPORTED_PLATFORMS)
DATA_BROKERS, DOMAIN, EVENT_BUTTON, SIGNAL_SMARTTHINGS_UPDATE,
SUPPORTED_PLATFORMS)
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.dispatcher import async_dispatcher_connect

Expand Down Expand Up @@ -181,3 +182,31 @@ def signal(ids):
await hass.async_block_till_done()

assert not called


async def test_event_handler_fires_button_events(
hass, device_factory, event_factory, event_request_factory):
"""Test the event handler fires button events."""
device = device_factory('Button 1', ['button'])
event = event_factory(device.device_id, capability='button',
attribute='button', value='pushed')
request = event_request_factory(events=[event])
called = False

def handler(evt):
nonlocal called
called = True
assert evt.data == {
'component_id': 'main',
'device_id': device.device_id,
'location_id': event.location_id,
'value': 'pushed',
'name': device.label
}
hass.bus.async_listen(EVENT_BUTTON, handler)
broker = smartthings.DeviceBroker(
hass, [device], request.installed_app_id)
await broker.event_handler(request, None, None)
await hass.async_block_till_done()

assert called