Alexa motion sensor (#17798)

* Alexa: add motion sensors

* Alexa: add motion sensor tests

* Fix comparison and lint
This commit is contained in:
Abílio Costa 2018-10-26 22:43:31 +01:00 committed by Paulus Schoutsen
parent 8a4c78b69f
commit 6b7cbca04c
2 changed files with 64 additions and 0 deletions

View file

@ -81,6 +81,9 @@ class _DisplayCategory:
# Indicates light sources or fixtures.
LIGHT = "LIGHT"
# Indicates an endpoint that detects and reports motion.
MOTION_SENSOR = "MOTION_SENSOR"
# An endpoint that cannot be described in on of the other categories.
OTHER = "OTHER"
@ -441,6 +444,29 @@ class _AlexaContactSensor(_AlexaInterface):
return 'NOT_DETECTED'
class _AlexaMotionSensor(_AlexaInterface):
def __init__(self, hass, entity):
_AlexaInterface.__init__(self, entity)
self.hass = hass
def name(self):
return 'Alexa.MotionSensor'
def properties_supported(self):
return [{'name': 'detectionState'}]
def properties_retrievable(self):
return True
def get_property(self, name):
if name != 'detectionState':
raise _UnsupportedProperty(name)
if self.entity.state == STATE_ON:
return 'DETECTED'
return 'NOT_DETECTED'
class _AlexaThermostatController(_AlexaInterface):
def __init__(self, hass, entity):
_AlexaInterface.__init__(self, entity)
@ -655,16 +681,21 @@ class _SensorCapabilities(_AlexaEntity):
@ENTITY_ADAPTERS.register(binary_sensor.DOMAIN)
class _BinarySensorCapabilities(_AlexaEntity):
TYPE_CONTACT = 'contact'
TYPE_MOTION = 'motion'
def default_display_categories(self):
sensor_type = self.get_type()
if sensor_type is self.TYPE_CONTACT:
return [_DisplayCategory.CONTACT_SENSOR]
if sensor_type is self.TYPE_MOTION:
return [_DisplayCategory.MOTION_SENSOR]
def interfaces(self):
sensor_type = self.get_type()
if sensor_type is self.TYPE_CONTACT:
yield _AlexaContactSensor(self.hass, self.entity)
elif sensor_type is self.TYPE_MOTION:
yield _AlexaMotionSensor(self.hass, self.entity)
def get_type(self):
"""Return the type of binary sensor."""
@ -676,6 +707,8 @@ class _BinarySensorCapabilities(_AlexaEntity):
'window',
):
return self.TYPE_CONTACT
if attrs.get(ATTR_DEVICE_CLASS) == 'motion':
return self.TYPE_MOTION
class _Cause:

View file

@ -725,6 +725,37 @@ def test_contact_sensor(hass):
'DETECTED')
@asyncio.coroutine
def test_motion_sensor(hass):
"""Test motion sensor discovery."""
device = (
'binary_sensor.test_motion',
'on',
{
'friendly_name': "Test Motion Sensor",
'device_class': 'motion',
}
)
appliance = yield from discovery_test(device, hass)
assert appliance['endpointId'] == 'binary_sensor#test_motion'
assert appliance['displayCategories'][0] == 'MOTION_SENSOR'
assert appliance['friendlyName'] == 'Test Motion Sensor'
(capability,) = assert_endpoint_capabilities(
appliance,
'Alexa.MotionSensor')
assert capability['interface'] == 'Alexa.MotionSensor'
properties = capability['properties']
assert properties['retrievable'] is True
assert {'name': 'detectionState'} in properties['supported']
properties = yield from reported_properties(hass,
'binary_sensor#test_motion')
properties.assert_equal('Alexa.MotionSensor', 'detectionState',
'DETECTED')
@asyncio.coroutine
def test_unknown_sensor(hass):
"""Test sensors of unknown quantities are not discovered."""