mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 10:17:51 +00:00
Various enhancements for WeMo component/platforms (#19419)
* WeMo - Various fixes and improvements Various fixes & improvements to the WeMo components, including: -- Fixes to rediscovery -- New reset filter service for the WeMo Humidifier -- Switched the remainder of the WeMo components to async IO -- Removed any remaining IO in entity properties and moved them to the polling/subscription update process * WeMo - Fix pywemo version and remove test code from WeMo fan component * WeMo Humidifier - Add services.yaml entry for reset filter life service * WeMo - Update binary_sensor component to use asyncio * WeMo - Add available property to binary_sensor component * WeMo - Fixed line length issue * WeMo - Fix issue with discovering the same device multiple times * WeMo - Fix for the fix for discovering devices multiple times * WeMo - Fix long lines * WeMo - Fixes from code review * WeMo - Breaking Change - entity_ids is now required on wemo_set_humidity * WeMo - Code review fixes * WeMo - Code review fixes * WeMo - Code review fixes
This commit is contained in:
parent
ef6c39f911
commit
7f0dd442fd
@ -4,7 +4,10 @@ Support for WeMo sensors.
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/binary_sensor.wemo/
|
||||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
import async_timeout
|
||||
import requests
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
@ -41,48 +44,90 @@ class WemoBinarySensor(BinarySensorDevice):
|
||||
"""Initialize the WeMo sensor."""
|
||||
self.wemo = device
|
||||
self._state = None
|
||||
self._available = True
|
||||
self._update_lock = None
|
||||
self._model_name = self.wemo.model_name
|
||||
self._name = self.wemo.name
|
||||
self._serialnumber = self.wemo.serialnumber
|
||||
|
||||
wemo = hass.components.wemo
|
||||
wemo.SUBSCRIPTION_REGISTRY.register(self.wemo)
|
||||
wemo.SUBSCRIPTION_REGISTRY.on(self.wemo, None, self._update_callback)
|
||||
|
||||
def _update_callback(self, _device, _type, _params):
|
||||
"""Handle state changes."""
|
||||
_LOGGER.info("Subscription update for %s", _device)
|
||||
def _subscription_callback(self, _device, _type, _params):
|
||||
"""Update the state by the Wemo sensor."""
|
||||
_LOGGER.debug("Subscription update for %s", self.name)
|
||||
updated = self.wemo.subscription_update(_type, _params)
|
||||
self._update(force_update=(not updated))
|
||||
self.hass.add_job(
|
||||
self._async_locked_subscription_callback(not updated))
|
||||
|
||||
if not hasattr(self, 'hass'):
|
||||
async def _async_locked_subscription_callback(self, force_update):
|
||||
"""Handle an update from a subscription."""
|
||||
# If an update is in progress, we don't do anything
|
||||
if self._update_lock.locked():
|
||||
return
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed with subscriptions."""
|
||||
return False
|
||||
await self._async_locked_update(force_update)
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Wemo sensor added to HASS."""
|
||||
# Define inside async context so we know our event loop
|
||||
self._update_lock = asyncio.Lock()
|
||||
|
||||
registry = self.hass.components.wemo.SUBSCRIPTION_REGISTRY
|
||||
await self.hass.async_add_executor_job(registry.register, self.wemo)
|
||||
registry.on(self.wemo, None, self._subscription_callback)
|
||||
|
||||
async def async_update(self):
|
||||
"""Update WeMo state.
|
||||
|
||||
Wemo has an aggressive retry logic that sometimes can take over a
|
||||
minute to return. If we don't get a state after 5 seconds, assume the
|
||||
Wemo sensor is unreachable. If update goes through, it will be made
|
||||
available again.
|
||||
"""
|
||||
# If an update is in progress, we don't do anything
|
||||
if self._update_lock.locked():
|
||||
return
|
||||
|
||||
try:
|
||||
with async_timeout.timeout(5):
|
||||
await asyncio.shield(self._async_locked_update(True))
|
||||
except asyncio.TimeoutError:
|
||||
_LOGGER.warning('Lost connection to %s', self.name)
|
||||
self._available = False
|
||||
|
||||
async def _async_locked_update(self, force_update):
|
||||
"""Try updating within an async lock."""
|
||||
async with self._update_lock:
|
||||
await self.hass.async_add_executor_job(self._update, force_update)
|
||||
|
||||
def _update(self, force_update=True):
|
||||
"""Update the sensor state."""
|
||||
try:
|
||||
self._state = self.wemo.get_state(force_update)
|
||||
|
||||
if not self._available:
|
||||
_LOGGER.info('Reconnected to %s', self.name)
|
||||
self._available = True
|
||||
except AttributeError as err:
|
||||
_LOGGER.warning("Could not update status for %s (%s)",
|
||||
self.name, err)
|
||||
self._available = False
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return the id of this WeMo device."""
|
||||
return self.wemo.serialnumber
|
||||
"""Return the id of this WeMo sensor."""
|
||||
return self._serialnumber
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the service if any."""
|
||||
return self.wemo.name
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if sensor is on."""
|
||||
return self._state
|
||||
|
||||
def update(self):
|
||||
"""Update WeMo state."""
|
||||
self._update(force_update=True)
|
||||
|
||||
def _update(self, force_update=True):
|
||||
try:
|
||||
self._state = self.wemo.get_state(force_update)
|
||||
except AttributeError as err:
|
||||
_LOGGER.warning(
|
||||
"Could not update status for %s (%s)", self.name, err)
|
||||
@property
|
||||
def available(self):
|
||||
"""Return true if sensor is available."""
|
||||
return self._available
|
||||
|
@ -209,8 +209,15 @@ wemo_set_humidity:
|
||||
description: Set the target humidity of WeMo humidifier devices.
|
||||
fields:
|
||||
entity_id:
|
||||
description: Names of the WeMo humidifier entities (0 or more entities, if no entity_id is provided, all WeMo humidifiers will have the target humidity set).
|
||||
description: Names of the WeMo humidifier entities (1 or more entity_ids are required).
|
||||
example: 'fan.wemo_humidifier'
|
||||
target_humidity:
|
||||
description: Target humidity. This is a float value between 0 and 100, but will be mapped to the humidity levels that WeMo humidifiers support (45, 50, 55, 60, and 100/Max) by rounding the value down to the nearest supported value.
|
||||
example: 56.5
|
||||
|
||||
wemo_reset_filter_life:
|
||||
description: Reset the WeMo Humidifier's filter life to 100%.
|
||||
fields:
|
||||
entity_id:
|
||||
description: Names of the WeMo humidifier entities (1 or more entity_ids are required).
|
||||
example: 'fan.wemo_humidifier'
|
||||
|
@ -78,11 +78,17 @@ HASS_FAN_SPEED_TO_WEMO = {v: k for (k, v) in WEMO_FAN_SPEED_TO_HASS.items()
|
||||
SERVICE_SET_HUMIDITY = 'wemo_set_humidity'
|
||||
|
||||
SET_HUMIDITY_SCHEMA = vol.Schema({
|
||||
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
|
||||
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
|
||||
vol.Required(ATTR_TARGET_HUMIDITY):
|
||||
vol.All(vol.Coerce(float), vol.Range(min=0, max=100))
|
||||
})
|
||||
|
||||
SERVICE_RESET_FILTER_LIFE = 'wemo_reset_filter_life'
|
||||
|
||||
RESET_FILTER_LIFE_SCHEMA = vol.Schema({
|
||||
vol.Required(ATTR_ENTITY_ID): cv.entity_ids
|
||||
})
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up discovered WeMo humidifiers."""
|
||||
@ -111,22 +117,29 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
def service_handle(service):
|
||||
"""Handle the WeMo humidifier services."""
|
||||
entity_ids = service.data.get(ATTR_ENTITY_ID)
|
||||
target_humidity = service.data.get(ATTR_TARGET_HUMIDITY)
|
||||
|
||||
if entity_ids:
|
||||
humidifiers = [device for device in hass.data[DATA_KEY].values() if
|
||||
humidifiers = [device for device in
|
||||
hass.data[DATA_KEY].values() if
|
||||
device.entity_id in entity_ids]
|
||||
else:
|
||||
humidifiers = hass.data[DATA_KEY].values()
|
||||
|
||||
if service.service == SERVICE_SET_HUMIDITY:
|
||||
target_humidity = service.data.get(ATTR_TARGET_HUMIDITY)
|
||||
|
||||
for humidifier in humidifiers:
|
||||
humidifier.set_humidity(target_humidity)
|
||||
elif service.service == SERVICE_RESET_FILTER_LIFE:
|
||||
for humidifier in humidifiers:
|
||||
humidifier.reset_filter_life()
|
||||
|
||||
# Register service(s)
|
||||
hass.services.register(
|
||||
DOMAIN, SERVICE_SET_HUMIDITY, service_handle,
|
||||
schema=SET_HUMIDITY_SCHEMA)
|
||||
|
||||
hass.services.register(
|
||||
DOMAIN, SERVICE_RESET_FILTER_LIFE, service_handle,
|
||||
schema=RESET_FILTER_LIFE_SCHEMA)
|
||||
|
||||
|
||||
class WemoHumidifier(FanEntity):
|
||||
"""Representation of a WeMo humidifier."""
|
||||
@ -137,7 +150,6 @@ class WemoHumidifier(FanEntity):
|
||||
self._state = None
|
||||
self._available = True
|
||||
self._update_lock = None
|
||||
|
||||
self._fan_mode = None
|
||||
self._target_humidity = None
|
||||
self._current_humidity = None
|
||||
@ -145,9 +157,6 @@ class WemoHumidifier(FanEntity):
|
||||
self._filter_life = None
|
||||
self._filter_expired = None
|
||||
self._last_fan_on_mode = WEMO_FAN_MEDIUM
|
||||
|
||||
# look up model name, name, and serial number
|
||||
# once as it incurs network traffic
|
||||
self._model_name = self.wemo.model_name
|
||||
self._name = self.wemo.name
|
||||
self._serialnumber = self.wemo.serialnumber
|
||||
@ -211,12 +220,12 @@ class WemoHumidifier(FanEntity):
|
||||
return WEMO_FAN_SPEED_TO_HASS.get(self._fan_mode)
|
||||
|
||||
@property
|
||||
def speed_list(self: FanEntity) -> list:
|
||||
def speed_list(self) -> list:
|
||||
"""Get the list of available speeds."""
|
||||
return SUPPORTED_SPEEDS
|
||||
|
||||
@property
|
||||
def supported_features(self: FanEntity) -> int:
|
||||
def supported_features(self) -> int:
|
||||
"""Flag supported features."""
|
||||
return SUPPORTED_FEATURES
|
||||
|
||||
@ -276,22 +285,22 @@ class WemoHumidifier(FanEntity):
|
||||
self.name, err)
|
||||
self._available = False
|
||||
|
||||
def turn_on(self: FanEntity, speed: str = None, **kwargs) -> None:
|
||||
def turn_on(self, speed: str = None, **kwargs) -> None:
|
||||
"""Turn the switch on."""
|
||||
if speed is None:
|
||||
self.wemo.set_state(self._last_fan_on_mode)
|
||||
else:
|
||||
self.set_speed(speed)
|
||||
|
||||
def turn_off(self: FanEntity, **kwargs) -> None:
|
||||
def turn_off(self, **kwargs) -> None:
|
||||
"""Turn the switch off."""
|
||||
self.wemo.set_state(WEMO_FAN_OFF)
|
||||
|
||||
def set_speed(self: FanEntity, speed: str) -> None:
|
||||
def set_speed(self, speed: str) -> None:
|
||||
"""Set the fan_mode of the Humidifier."""
|
||||
self.wemo.set_state(HASS_FAN_SPEED_TO_WEMO.get(speed))
|
||||
|
||||
def set_humidity(self: FanEntity, humidity: float) -> None:
|
||||
def set_humidity(self, humidity: float) -> None:
|
||||
"""Set the target humidity level for the Humidifier."""
|
||||
if humidity < 50:
|
||||
self.wemo.set_humidity(WEMO_HUMIDITY_45)
|
||||
@ -303,3 +312,7 @@ class WemoHumidifier(FanEntity):
|
||||
self.wemo.set_humidity(WEMO_HUMIDITY_60)
|
||||
elif humidity >= 100:
|
||||
self.wemo.set_humidity(WEMO_HUMIDITY_100)
|
||||
|
||||
def reset_filter_life(self) -> None:
|
||||
"""Reset the filter life to 100%."""
|
||||
self.wemo.reset_filter_life()
|
||||
|
@ -4,9 +4,12 @@ Support for Belkin WeMo lights.
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/light.wemo/
|
||||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
import requests
|
||||
import async_timeout
|
||||
|
||||
from homeassistant import util
|
||||
from homeassistant.components.light import (
|
||||
@ -74,40 +77,52 @@ class WemoLight(Light):
|
||||
|
||||
def __init__(self, device, update_lights):
|
||||
"""Initialize the WeMo light."""
|
||||
self.light_id = device.name
|
||||
self.wemo = device
|
||||
self.update_lights = update_lights
|
||||
self._state = None
|
||||
self._update_lights = update_lights
|
||||
self._available = True
|
||||
self._update_lock = None
|
||||
self._brightness = None
|
||||
self._hs_color = None
|
||||
self._color_temp = None
|
||||
self._is_on = None
|
||||
self._name = self.wemo.name
|
||||
self._unique_id = self.wemo.uniqueID
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Wemo light added to HASS."""
|
||||
# Define inside async context so we know our event loop
|
||||
self._update_lock = asyncio.Lock()
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return the ID of this light."""
|
||||
return self.wemo.uniqueID
|
||||
return self._unique_id
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the light."""
|
||||
return self.wemo.name
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def brightness(self):
|
||||
"""Return the brightness of this light between 0..255."""
|
||||
return self.wemo.state.get('level', 255)
|
||||
return self._brightness
|
||||
|
||||
@property
|
||||
def hs_color(self):
|
||||
"""Return the hs color values of this light."""
|
||||
xy_color = self.wemo.state.get('color_xy')
|
||||
return color_util.color_xy_to_hs(*xy_color) if xy_color else None
|
||||
return self._hs_color
|
||||
|
||||
@property
|
||||
def color_temp(self):
|
||||
"""Return the color temperature of this light in mireds."""
|
||||
return self.wemo.state.get('temperature_mireds')
|
||||
return self._color_temp
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if device is on."""
|
||||
return self.wemo.state['onoff'] != 0
|
||||
return self._is_on
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
@ -117,7 +132,7 @@ class WemoLight(Light):
|
||||
@property
|
||||
def available(self):
|
||||
"""Return if light is available."""
|
||||
return self.wemo.state['available']
|
||||
return self._available
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn the light on."""
|
||||
@ -145,9 +160,40 @@ class WemoLight(Light):
|
||||
transitiontime = int(kwargs.get(ATTR_TRANSITION, 0))
|
||||
self.wemo.turn_off(transition=transitiontime)
|
||||
|
||||
def update(self):
|
||||
def _update(self, force_update=True):
|
||||
"""Synchronize state with bridge."""
|
||||
self.update_lights(no_throttle=True)
|
||||
self._update_lights(no_throttle=force_update)
|
||||
self._state = self.wemo.state
|
||||
|
||||
self._is_on = self._state.get('onoff') != 0
|
||||
self._brightness = self._state.get('level', 255)
|
||||
self._color_temp = self._state.get('temperature_mireds')
|
||||
self._available = True
|
||||
|
||||
xy_color = self._state.get('color_xy')
|
||||
|
||||
if xy_color:
|
||||
self._hs_color = color_util.color_xy_to_hs(*xy_color)
|
||||
else:
|
||||
self._hs_color = None
|
||||
|
||||
async def async_update(self):
|
||||
"""Synchronize state with bridge."""
|
||||
# If an update is in progress, we don't do anything
|
||||
if self._update_lock.locked():
|
||||
return
|
||||
|
||||
try:
|
||||
with async_timeout.timeout(5):
|
||||
await asyncio.shield(self._async_locked_update(True))
|
||||
except asyncio.TimeoutError:
|
||||
_LOGGER.warning('Lost connection to %s', self.name)
|
||||
self._available = False
|
||||
|
||||
async def _async_locked_update(self, force_update):
|
||||
"""Try updating within an async lock."""
|
||||
async with self._update_lock:
|
||||
await self.hass.async_add_executor_job(self._update, force_update)
|
||||
|
||||
|
||||
class WemoDimmer(Light):
|
||||
@ -156,46 +202,79 @@ class WemoDimmer(Light):
|
||||
def __init__(self, device):
|
||||
"""Initialize the WeMo dimmer."""
|
||||
self.wemo = device
|
||||
self._brightness = None
|
||||
self._state = None
|
||||
self._available = True
|
||||
self._update_lock = None
|
||||
self._brightness = None
|
||||
self._model_name = self.wemo.model_name
|
||||
self._name = self.wemo.name
|
||||
self._serialnumber = self.wemo.serialnumber
|
||||
|
||||
def _subscription_callback(self, _device, _type, _params):
|
||||
"""Update the state by the Wemo device."""
|
||||
_LOGGER.debug("Subscription update for %s", self.name)
|
||||
updated = self.wemo.subscription_update(_type, _params)
|
||||
self.hass.add_job(
|
||||
self._async_locked_subscription_callback(not updated))
|
||||
|
||||
async def _async_locked_subscription_callback(self, force_update):
|
||||
"""Handle an update from a subscription."""
|
||||
# If an update is in progress, we don't do anything
|
||||
if self._update_lock.locked():
|
||||
return
|
||||
|
||||
await self._async_locked_update(force_update)
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Register update callback."""
|
||||
wemo = self.hass.components.wemo
|
||||
# The register method uses a threading condition, so call via executor.
|
||||
# and await to wait until the task is done.
|
||||
await self.hass.async_add_job(
|
||||
wemo.SUBSCRIPTION_REGISTRY.register, self.wemo)
|
||||
# The on method just appends to a defaultdict list.
|
||||
wemo.SUBSCRIPTION_REGISTRY.on(self.wemo, None, self._update_callback)
|
||||
"""Wemo dimmer added to HASS."""
|
||||
# Define inside async context so we know our event loop
|
||||
self._update_lock = asyncio.Lock()
|
||||
|
||||
def _update_callback(self, _device, _type, _params):
|
||||
"""Update the state by the Wemo device."""
|
||||
_LOGGER.debug("Subscription update for %s", _device)
|
||||
updated = self.wemo.subscription_update(_type, _params)
|
||||
self._update(force_update=(not updated))
|
||||
self.schedule_update_ha_state()
|
||||
registry = self.hass.components.wemo.SUBSCRIPTION_REGISTRY
|
||||
await self.hass.async_add_executor_job(registry.register, self.wemo)
|
||||
registry.on(self.wemo, None, self._subscription_callback)
|
||||
|
||||
async def async_update(self):
|
||||
"""Update WeMo state.
|
||||
|
||||
Wemo has an aggressive retry logic that sometimes can take over a
|
||||
minute to return. If we don't get a state after 5 seconds, assume the
|
||||
Wemo dimmer is unreachable. If update goes through, it will be made
|
||||
available again.
|
||||
"""
|
||||
# If an update is in progress, we don't do anything
|
||||
if self._update_lock.locked():
|
||||
return
|
||||
|
||||
try:
|
||||
with async_timeout.timeout(5):
|
||||
await asyncio.shield(self._async_locked_update(True))
|
||||
except asyncio.TimeoutError:
|
||||
_LOGGER.warning('Lost connection to %s', self.name)
|
||||
self._available = False
|
||||
self.wemo.reconnect_with_device()
|
||||
|
||||
async def _async_locked_update(self, force_update):
|
||||
"""Try updating within an async lock."""
|
||||
async with self._update_lock:
|
||||
await self.hass.async_add_executor_job(self._update, force_update)
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return the ID of this WeMo dimmer."""
|
||||
return self.wemo.serialnumber
|
||||
return self._serialnumber
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the dimmer if any."""
|
||||
return self.wemo.name
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Flag supported features."""
|
||||
return SUPPORT_BRIGHTNESS
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed with subscriptions."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def brightness(self):
|
||||
"""Return the brightness of this light between 1 and 100."""
|
||||
@ -210,11 +289,17 @@ class WemoDimmer(Light):
|
||||
"""Update the device state."""
|
||||
try:
|
||||
self._state = self.wemo.get_state(force_update)
|
||||
|
||||
wemobrightness = int(self.wemo.get_brightness(force_update))
|
||||
self._brightness = int((wemobrightness * 255) / 100)
|
||||
|
||||
if not self._available:
|
||||
_LOGGER.info('Reconnected to %s', self.name)
|
||||
self._available = True
|
||||
except AttributeError as err:
|
||||
_LOGGER.warning("Could not update status for %s (%s)",
|
||||
self.name, err)
|
||||
self._available = False
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn the dimmer on."""
|
||||
@ -232,3 +317,8 @@ class WemoDimmer(Light):
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn the dimmer off."""
|
||||
self.wemo.off()
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return if dimmer is available."""
|
||||
return self._available
|
||||
|
@ -64,10 +64,12 @@ class WemoSwitch(SwitchDevice):
|
||||
self.maker_params = None
|
||||
self.coffeemaker_mode = None
|
||||
self._state = None
|
||||
self._mode_string = None
|
||||
self._available = True
|
||||
self._update_lock = None
|
||||
# look up model name once as it incurs network traffic
|
||||
self._model_name = self.wemo.model_name
|
||||
self._name = self.wemo.name
|
||||
self._serialnumber = self.wemo.serialnumber
|
||||
|
||||
def _subscription_callback(self, _device, _type, _params):
|
||||
"""Update the state by the Wemo device."""
|
||||
@ -85,24 +87,15 @@ class WemoSwitch(SwitchDevice):
|
||||
await self._async_locked_update(force_update)
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""Device should poll.
|
||||
|
||||
Subscriptions push the state, however it won't detect if a device
|
||||
is no longer available. Use polling to detect if a device is available.
|
||||
"""
|
||||
return True
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return the ID of this WeMo switch."""
|
||||
return self.wemo.serialnumber
|
||||
return self._serialnumber
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the switch if any."""
|
||||
return self.wemo.name
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
@ -169,7 +162,7 @@ class WemoSwitch(SwitchDevice):
|
||||
def detail_state(self):
|
||||
"""Return the state of the device."""
|
||||
if self.coffeemaker_mode is not None:
|
||||
return self.wemo.mode_string
|
||||
return self._mode_string
|
||||
if self.insight_params:
|
||||
standby_state = int(self.insight_params['state'])
|
||||
if standby_state == WEMO_ON:
|
||||
@ -242,6 +235,7 @@ class WemoSwitch(SwitchDevice):
|
||||
"""Update the device state."""
|
||||
try:
|
||||
self._state = self.wemo.get_state(force_update)
|
||||
|
||||
if self._model_name == 'Insight':
|
||||
self.insight_params = self.wemo.insight_params
|
||||
self.insight_params['standby_state'] = (
|
||||
@ -250,6 +244,7 @@ class WemoSwitch(SwitchDevice):
|
||||
self.maker_params = self.wemo.maker_params
|
||||
elif self._model_name == 'CoffeeMaker':
|
||||
self.coffeemaker_mode = self.wemo.mode
|
||||
self._mode_string = self.wemo.mode_string
|
||||
|
||||
if not self._available:
|
||||
_LOGGER.info('Reconnected to %s', self.name)
|
||||
|
@ -96,6 +96,8 @@ def setup(hass, config):
|
||||
|
||||
# Only register a device once
|
||||
if serial in KNOWN_DEVICES:
|
||||
_LOGGER.debug('Ignoring known device %s %s',
|
||||
service, discovery_info)
|
||||
return
|
||||
_LOGGER.debug('Discovered unique device %s', serial)
|
||||
KNOWN_DEVICES.append(serial)
|
||||
@ -123,6 +125,7 @@ def setup(hass, config):
|
||||
|
||||
devices = []
|
||||
|
||||
_LOGGER.debug("Scanning statically configured WeMo devices...")
|
||||
for host, port in config.get(DOMAIN, {}).get(CONF_STATIC, []):
|
||||
url = setup_url_for_address(host, port)
|
||||
|
||||
@ -139,16 +142,19 @@ def setup(hass, config):
|
||||
_LOGGER.error('Unable to access %s (%s)', url, err)
|
||||
continue
|
||||
|
||||
if not [d[1] for d in devices
|
||||
if d[1].serialnumber == device.serialnumber]:
|
||||
devices.append((url, device))
|
||||
|
||||
if config.get(DOMAIN, {}).get(CONF_DISCOVERY):
|
||||
_LOGGER.debug("Scanning for WeMo devices.")
|
||||
devices.extend(
|
||||
(setup_url_for_device(device), device)
|
||||
for device in pywemo.discover_devices())
|
||||
_LOGGER.debug("Scanning for WeMo devices...")
|
||||
for device in pywemo.discover_devices():
|
||||
if not [d[1] for d in devices
|
||||
if d[1].serialnumber == device.serialnumber]:
|
||||
devices.append((setup_url_for_device(device), device))
|
||||
|
||||
for url, device in devices:
|
||||
_LOGGER.debug('Adding wemo at %s:%i', device.host, device.port)
|
||||
_LOGGER.debug('Adding WeMo device at %s:%i', device.host, device.port)
|
||||
|
||||
discovery_info = {
|
||||
'model_name': device.model_name,
|
||||
|
Loading…
x
Reference in New Issue
Block a user