Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checking Xiaomi Aqara devices unavailability states #11631

Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
98b933c
added unavailability tracker, updated sensor component
PaulAnnekov Dec 3, 2017
a4c364d
change hass argument position according to position in binary_sensor
PaulAnnekov Dec 4, 2017
f1e4bcc
added hass argument to binary_sensor, updated is_on(), it can be UNAV…
PaulAnnekov Dec 4, 2017
e88b9e9
updated switch component to support unavailability feature
PaulAnnekov Dec 4, 2017
2be53f9
updated light component to support unavailability feature
PaulAnnekov Dec 4, 2017
4bac87d
updated cover component to support unavailability feature
PaulAnnekov Dec 4, 2017
87434f5
set _hass property
PaulAnnekov Dec 20, 2017
d13dc37
added unavailability tracker, updated sensor component
PaulAnnekov Dec 3, 2017
07a0213
change hass argument position according to position in binary_sensor
PaulAnnekov Dec 4, 2017
ac6150a
added hass argument to binary_sensor, updated is_on(), it can be UNAV…
PaulAnnekov Dec 4, 2017
661ceb9
updated switch component to support unavailability feature
PaulAnnekov Dec 4, 2017
078522b
updated light component to support unavailability feature
PaulAnnekov Dec 4, 2017
96a1503
updated cover component to support unavailability feature
PaulAnnekov Dec 4, 2017
16df8df
set _hass property
PaulAnnekov Dec 20, 2017
5c3341f
sync with upstream/dev
PaulAnnekov Jan 6, 2018
3385020
fixed error with wrong arguments number during callback call
PaulAnnekov Jan 13, 2018
e687288
reset unavailability state on new message received from device
PaulAnnekov Jan 13, 2018
ada08f4
use locks to fix race condition during managing _state property
PaulAnnekov Jan 13, 2018
b92197e
overriden state() method for some components to check for STATE_UNAVA…
PaulAnnekov Jan 13, 2018
d43a512
fixed linter
PaulAnnekov Jan 13, 2018
d606510
removed blank line
PaulAnnekov Jan 13, 2018
4543291
use available() method instead of changing _state
PaulAnnekov Jan 14, 2018
056bc43
filter motion sensors 'heartbeat', was removed from PyXiaomiGateway
PaulAnnekov Jan 14, 2018
f3e4fd7
Merge branch 'dev' into feature-xiaomi-check-devices-unavailability
PaulAnnekov Jan 14, 2018
0d130b2
Merge branch 'dev' into feature-xiaomi-check-devices-unavailability
PaulAnnekov Jan 14, 2018
c048a6a
remove self._hass, use self.hass set by HA on attach
PaulAnnekov Jan 20, 2018
f51ff3d
self.push_data now running in the event loop, use async_schedule_upda…
PaulAnnekov Jan 20, 2018
92409a3
Merge branch 'feature-xiaomi-check-devices-unavailability' of https:/…
PaulAnnekov Jan 20, 2018
2623633
Merge branch 'dev' into feature-xiaomi-check-devices-unavailability
PaulAnnekov Jan 21, 2018
a7ae427
merge fix
PaulAnnekov Jan 21, 2018
a7fab46
removed accidentally added home-assistant-polymer
PaulAnnekov Jan 22, 2018
c7f03bd
bump PyXiaomiGateway version to 0.8.0
PaulAnnekov Jan 22, 2018
d821db3
bump PyXiaomiGateway to 0.8.0
PaulAnnekov Jan 22, 2018
7d778ff
updated methods names and annotations
PaulAnnekov Jan 23, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
66 changes: 37 additions & 29 deletions homeassistant/components/binary_sensor/xiaomi_aqara.py
Expand Up @@ -28,13 +28,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if model in ['motion', 'sensor_motion.aq2']:
devices.append(XiaomiMotionSensor(device, hass, gateway))
elif model in ['magnet', 'sensor_magnet.aq2']:
devices.append(XiaomiDoorSensor(device, gateway))
devices.append(XiaomiDoorSensor(device, hass, gateway))
elif model == 'sensor_wleak.aq1':
devices.append(XiaomiWaterLeakSensor(device, gateway))
devices.append(XiaomiWaterLeakSensor(device, hass, gateway))
elif model == 'smoke':
devices.append(XiaomiSmokeSensor(device, gateway))
devices.append(XiaomiSmokeSensor(device, hass, gateway))
elif model == 'natgas':
devices.append(XiaomiNatgasSensor(device, gateway))
devices.append(XiaomiNatgasSensor(device, hass, gateway))
elif model in ['switch', 'sensor_switch.aq2', 'sensor_switch.aq3']:
devices.append(XiaomiButton(device, 'Switch', 'status',
hass, gateway))
Expand All @@ -56,13 +56,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class XiaomiBinarySensor(XiaomiDevice, BinarySensorDevice):
"""Representation of a base XiaomiBinarySensor."""

def __init__(self, device, name, xiaomi_hub, data_key, device_class):
def __init__(self, device, name, hass, xiaomi_hub, data_key, device_class):
"""Initialize the XiaomiSmokeSensor."""
self._data_key = data_key
self._device_class = device_class
self._should_poll = False
self._density = 0
XiaomiDevice.__init__(self, device, name, xiaomi_hub)
XiaomiDevice.__init__(self, device, name, hass, xiaomi_hub)

@property
def should_poll(self):
Expand All @@ -88,11 +88,11 @@ def update(self):
class XiaomiNatgasSensor(XiaomiBinarySensor):
"""Representation of a XiaomiNatgasSensor."""

def __init__(self, device, xiaomi_hub):
def __init__(self, device, hass, xiaomi_hub):
"""Initialize the XiaomiSmokeSensor."""
self._density = None
XiaomiBinarySensor.__init__(self, device, 'Natgas Sensor', xiaomi_hub,
'alarm', 'gas')
XiaomiBinarySensor.__init__(self, device, 'Natgas Sensor', hass,
xiaomi_hub, 'alarm', 'gas')

@property
def device_state_attributes(self):
Expand All @@ -101,7 +101,7 @@ def device_state_attributes(self):
attrs.update(super().device_state_attributes)
return attrs

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
if DENSITY in data:
self._density = int(data.get(DENSITY))
Expand Down Expand Up @@ -129,8 +129,8 @@ def __init__(self, device, hass, xiaomi_hub):
"""Initialize the XiaomiMotionSensor."""
self._hass = hass
self._no_motion_since = 0
XiaomiBinarySensor.__init__(self, device, 'Motion Sensor', xiaomi_hub,
'status', 'motion')
XiaomiBinarySensor.__init__(self, device, 'Motion Sensor', hass,
xiaomi_hub, 'status', 'motion')

@property
def device_state_attributes(self):
Expand All @@ -139,8 +139,16 @@ def device_state_attributes(self):
attrs.update(super().device_state_attributes)
return attrs

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
if raw_data['cmd'] == 'heartbeat':
_LOGGER.debug(
'Skipping heartbeat of the motion sensor. '
'It can introduce an incorrect state because of a firmware '
'bug (https://github.com/home-assistant/home-assistant/pull/'
'11631#issuecomment-357507744).')
return

self._should_poll = False
if NO_MOTION in data: # handle push from the hub
self._no_motion_since = data[NO_MOTION]
Expand Down Expand Up @@ -173,11 +181,11 @@ def parse_data(self, data):
class XiaomiDoorSensor(XiaomiBinarySensor):
"""Representation of a XiaomiDoorSensor."""

def __init__(self, device, xiaomi_hub):
def __init__(self, device, hass, xiaomi_hub):
"""Initialize the XiaomiDoorSensor."""
self._open_since = 0
XiaomiBinarySensor.__init__(self, device, 'Door Window Sensor',
xiaomi_hub, 'status', 'opening')
hass, xiaomi_hub, 'status', 'opening')

@property
def device_state_attributes(self):
Expand All @@ -186,7 +194,7 @@ def device_state_attributes(self):
attrs.update(super().device_state_attributes)
return attrs

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
self._should_poll = False
if NO_CLOSE in data: # handle push from the hub
Expand Down Expand Up @@ -214,12 +222,12 @@ def parse_data(self, data):
class XiaomiWaterLeakSensor(XiaomiBinarySensor):
"""Representation of a XiaomiWaterLeakSensor."""

def __init__(self, device, xiaomi_hub):
def __init__(self, device, hass, xiaomi_hub):
"""Initialize the XiaomiWaterLeakSensor."""
XiaomiBinarySensor.__init__(self, device, 'Water Leak Sensor',
xiaomi_hub, 'status', 'moisture')
hass, xiaomi_hub, 'status', 'moisture')

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
self._should_poll = False

Expand All @@ -243,11 +251,11 @@ def parse_data(self, data):
class XiaomiSmokeSensor(XiaomiBinarySensor):
"""Representation of a XiaomiSmokeSensor."""

def __init__(self, device, xiaomi_hub):
def __init__(self, device, hass, xiaomi_hub):
"""Initialize the XiaomiSmokeSensor."""
self._density = 0
XiaomiBinarySensor.__init__(self, device, 'Smoke Sensor', xiaomi_hub,
'alarm', 'smoke')
XiaomiBinarySensor.__init__(self, device, 'Smoke Sensor', hass,
xiaomi_hub, 'alarm', 'smoke')

@property
def device_state_attributes(self):
Expand All @@ -256,7 +264,7 @@ def device_state_attributes(self):
attrs.update(super().device_state_attributes)
return attrs

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
if DENSITY in data:
self._density = int(data.get(DENSITY))
Expand All @@ -283,8 +291,8 @@ def __init__(self, device, name, data_key, hass, xiaomi_hub):
"""Initialize the XiaomiButton."""
self._hass = hass
self._last_action = None
XiaomiBinarySensor.__init__(self, device, name, xiaomi_hub,
data_key, None)
XiaomiBinarySensor.__init__(self, device, name, hass,
xiaomi_hub, data_key, None)

@property
def device_state_attributes(self):
Expand All @@ -293,7 +301,7 @@ def device_state_attributes(self):
attrs.update(super().device_state_attributes)
return attrs

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
value = data.get(self._data_key)
if value is None:
Expand Down Expand Up @@ -333,8 +341,8 @@ def __init__(self, device, hass, xiaomi_hub):
self._hass = hass
self._last_action = None
self._state = False
XiaomiBinarySensor.__init__(self, device, 'Cube', xiaomi_hub,
None, None)
XiaomiBinarySensor.__init__(self, device, 'Cube', hass,
xiaomi_hub, None, None)

@property
def device_state_attributes(self):
Expand All @@ -343,7 +351,7 @@ def device_state_attributes(self):
attrs.update(super().device_state_attributes)
return attrs

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
if 'status' in data:
self._hass.bus.fire('cube_action', {
Expand Down
8 changes: 4 additions & 4 deletions homeassistant/components/cover/xiaomi_aqara.py
Expand Up @@ -20,18 +20,18 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
devices.append(XiaomiGenericCover(device, "Curtain",
{'status': 'status',
'pos': 'curtain_level'},
gateway))
hass, gateway))
add_devices(devices)


class XiaomiGenericCover(XiaomiDevice, CoverDevice):
"""Representation of a XiaomiGenericCover."""

def __init__(self, device, name, data_key, xiaomi_hub):
def __init__(self, device, name, data_key, hass, xiaomi_hub):
"""Initialize the XiaomiGenericCover."""
self._data_key = data_key
self._pos = 0
XiaomiDevice.__init__(self, device, name, xiaomi_hub)
XiaomiDevice.__init__(self, device, name, hass, xiaomi_hub)

@property
def current_cover_position(self):
Expand Down Expand Up @@ -59,7 +59,7 @@ def set_cover_position(self, position, **kwargs):
"""Move the cover to a specific position."""
self._write_to_hub(self._sid, **{self._data_key['pos']: str(position)})

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
if ATTR_CURTAIN_LEVEL in data:
self._pos = int(data[ATTR_CURTAIN_LEVEL])
Expand Down
8 changes: 4 additions & 4 deletions homeassistant/components/light/xiaomi_aqara.py
Expand Up @@ -19,27 +19,27 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
model = device['model']
if model == 'gateway':
devices.append(XiaomiGatewayLight(device, 'Gateway Light',
gateway))
hass, gateway))
add_devices(devices)


class XiaomiGatewayLight(XiaomiDevice, Light):
"""Representation of a XiaomiGatewayLight."""

def __init__(self, device, name, xiaomi_hub):
def __init__(self, device, name, hass, xiaomi_hub):
"""Initialize the XiaomiGatewayLight."""
self._data_key = 'rgb'
self._rgb = (255, 255, 255)
self._brightness = 180

XiaomiDevice.__init__(self, device, name, xiaomi_hub)
XiaomiDevice.__init__(self, device, name, hass, xiaomi_hub)

@property
def is_on(self):
"""Return true if it is on."""
return self._state

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
value = data.get(self._data_key)
if value is None:
Expand Down
20 changes: 10 additions & 10 deletions homeassistant/components/sensor/xiaomi_aqara.py
Expand Up @@ -15,32 +15,32 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
for device in gateway.devices['sensor']:
if device['model'] == 'sensor_ht':
devices.append(XiaomiSensor(device, 'Temperature',
'temperature', gateway))
'temperature', hass, gateway))
devices.append(XiaomiSensor(device, 'Humidity',
'humidity', gateway))
'humidity', hass, gateway))
elif device['model'] == 'weather.v1':
devices.append(XiaomiSensor(device, 'Temperature',
'temperature', gateway))
'temperature', hass, gateway))
devices.append(XiaomiSensor(device, 'Humidity',
'humidity', gateway))
'humidity', hass, gateway))
devices.append(XiaomiSensor(device, 'Pressure',
'pressure', gateway))
'pressure', hass, gateway))
elif device['model'] == 'sensor_motion.aq2':
devices.append(XiaomiSensor(device, 'Illumination',
'lux', gateway))
'lux', hass, gateway))
elif device['model'] == 'gateway':
devices.append(XiaomiSensor(device, 'Illumination',
'illumination', gateway))
'illumination', hass, gateway))
add_devices(devices)


class XiaomiSensor(XiaomiDevice):
"""Representation of a XiaomiSensor."""

def __init__(self, device, name, data_key, xiaomi_hub):
def __init__(self, device, name, data_key, hass, xiaomi_hub):
"""Initialize the XiaomiSensor."""
self._data_key = data_key
XiaomiDevice.__init__(self, device, name, xiaomi_hub)
XiaomiDevice.__init__(self, device, name, hass, xiaomi_hub)

@property
def unit_of_measurement(self):
Expand All @@ -61,7 +61,7 @@ def state(self):
"""Return the state of the sensor."""
return self._state

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
value = data.get(self._data_key)
if value is None:
Expand Down
23 changes: 12 additions & 11 deletions homeassistant/components/switch/xiaomi_aqara.py
Expand Up @@ -27,49 +27,50 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
model = device['model']
if model == 'plug':
devices.append(XiaomiGenericSwitch(device, "Plug", 'status',
True, gateway))
True, hass, gateway))
elif model == 'ctrl_neutral1':
devices.append(XiaomiGenericSwitch(device, 'Wall Switch',
'channel_0',
False, gateway))
False, hass, gateway))
elif model == 'ctrl_ln1':
devices.append(XiaomiGenericSwitch(device, 'Wall Switch LN',
'channel_0',
False, gateway))
False, hass, gateway))
elif model == 'ctrl_neutral2':
devices.append(XiaomiGenericSwitch(device, 'Wall Switch Left',
'channel_0',
False, gateway))
False, hass, gateway))
devices.append(XiaomiGenericSwitch(device, 'Wall Switch Right',
'channel_1',
False, gateway))
False, hass, gateway))
elif model == 'ctrl_ln2':
devices.append(XiaomiGenericSwitch(device,
'Wall Switch LN Left',
'channel_0',
False, gateway))
False, hass, gateway))
devices.append(XiaomiGenericSwitch(device,
'Wall Switch LN Right',
'channel_1',
False, gateway))
False, hass, gateway))
elif model == '86plug':
devices.append(XiaomiGenericSwitch(device, 'Wall Plug',
'status', True, gateway))
'status', True, hass,
gateway))
add_devices(devices)


class XiaomiGenericSwitch(XiaomiDevice, SwitchDevice):
"""Representation of a XiaomiPlug."""

def __init__(self, device, name, data_key, supports_power_consumption,
xiaomi_hub):
hass, xiaomi_hub):
"""Initialize the XiaomiPlug."""
self._data_key = data_key
self._in_use = None
self._load_power = None
self._power_consumed = None
self._supports_power_consumption = supports_power_consumption
XiaomiDevice.__init__(self, device, name, xiaomi_hub)
XiaomiDevice.__init__(self, device, name, hass, xiaomi_hub)

@property
def icon(self):
Expand Down Expand Up @@ -107,7 +108,7 @@ def turn_off(self):
self._state = False
self.schedule_update_ha_state()

def parse_data(self, data):
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
if IN_USE in data:
self._in_use = int(data[IN_USE])
Expand Down