Device Registry (#15980)
* First draft * Generate device id * No obscure registry * Dont store config_entry_id in device * Storage * Small mistake on rebase * Do storage more like entity registry * Improve device identification * Add tests * Remove deconz device support from PR * Fix hound comments, voff! * Fix comments and clean up * Fix proper indentation * Fix pydoc issues * Fix mochad component to not use self.device * Fix mochad light platform to not use self.device * Fix TankUtilitySensor to not use self.device * Fix Soundtouch to not use self.device * Fix Plex to not use self.device * Fix Emby to not use self.device * Fix Heatmiser to not use self.device * Fix Wemo lights to not use self.device * Fix Lifx to not use self.device * Fix Radiotherm to not use self.device * Fix Juicenet to not use self.device * Fix Qwikswitch to not use self.device * Fix Xiaomi miio to not use self.device * Fix Nest to not use self.device * Fix Tellduslive to not use self.device * Fix Knx to not use self.device * Clean up a small mistake in soundtouch * Fix comment from Ballob * Fix bad indentation * Fix indentatin * Lint * Remove unused variable * Lintpull/16125/head
parent
7e7f9bc6ac
commit
0009be595c
|
@ -105,7 +105,7 @@ class KNXBinarySensor(BinarySensorDevice):
|
|||
|
||||
def __init__(self, hass, device):
|
||||
"""Initialize of KNX binary sensor."""
|
||||
self.device = device
|
||||
self._device = device
|
||||
self.hass = hass
|
||||
self.async_register_callbacks()
|
||||
self.automations = []
|
||||
|
@ -116,12 +116,12 @@ class KNXBinarySensor(BinarySensorDevice):
|
|||
async def after_update_callback(device):
|
||||
"""Call after device was updated."""
|
||||
await self.async_update_ha_state()
|
||||
self.device.register_device_updated_cb(after_update_callback)
|
||||
self._device.register_device_updated_cb(after_update_callback)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the KNX device."""
|
||||
return self.device.name
|
||||
return self._device.name
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
@ -136,9 +136,9 @@ class KNXBinarySensor(BinarySensorDevice):
|
|||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of this sensor."""
|
||||
return self.device.device_class
|
||||
return self._device.device_class
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if the binary sensor is on."""
|
||||
return self.device.is_on()
|
||||
return self._device.is_on()
|
||||
|
|
|
@ -130,7 +130,7 @@ class NestBinarySensor(NestSensorDevice, BinarySensorDevice):
|
|||
|
||||
def update(self):
|
||||
"""Retrieve latest state."""
|
||||
value = getattr(self.device, self.variable)
|
||||
value = getattr(self._device, self.variable)
|
||||
if self.variable in STRUCTURE_BINARY_TYPES:
|
||||
self._state = bool(STRUCTURE_BINARY_STATE_MAP
|
||||
[self.variable].get(value))
|
||||
|
@ -154,4 +154,5 @@ class NestActivityZoneSensor(NestBinarySensor):
|
|||
|
||||
def update(self):
|
||||
"""Retrieve latest state."""
|
||||
self._state = self.device.has_ongoing_motion_in_zone(self.zone.zone_id)
|
||||
self._state = self._device.has_ongoing_motion_in_zone(
|
||||
self.zone.zone_id)
|
||||
|
|
|
@ -31,4 +31,4 @@ class TelldusLiveSensor(TelldusLiveEntity, BinarySensorDevice):
|
|||
@property
|
||||
def is_on(self):
|
||||
"""Return true if switch is on."""
|
||||
return self.device.is_on
|
||||
return self._device.is_on
|
||||
|
|
|
@ -46,7 +46,7 @@ class NestCamera(Camera):
|
|||
"""Initialize a Nest Camera."""
|
||||
super(NestCamera, self).__init__()
|
||||
self.structure = structure
|
||||
self.device = device
|
||||
self._device = device
|
||||
self._location = None
|
||||
self._name = None
|
||||
self._online = None
|
||||
|
@ -93,7 +93,7 @@ class NestCamera(Camera):
|
|||
# Calling Nest API in is_streaming setter.
|
||||
# device.is_streaming would not immediately change until the process
|
||||
# finished in Nest Cam.
|
||||
self.device.is_streaming = False
|
||||
self._device.is_streaming = False
|
||||
|
||||
def turn_on(self):
|
||||
"""Turn on camera."""
|
||||
|
@ -105,15 +105,15 @@ class NestCamera(Camera):
|
|||
# Calling Nest API in is_streaming setter.
|
||||
# device.is_streaming would not immediately change until the process
|
||||
# finished in Nest Cam.
|
||||
self.device.is_streaming = True
|
||||
self._device.is_streaming = True
|
||||
|
||||
def update(self):
|
||||
"""Cache value from Python-nest."""
|
||||
self._location = self.device.where
|
||||
self._name = self.device.name
|
||||
self._online = self.device.online
|
||||
self._is_streaming = self.device.is_streaming
|
||||
self._is_video_history_enabled = self.device.is_video_history_enabled
|
||||
self._location = self._device.where
|
||||
self._name = self._device.name
|
||||
self._online = self._device.online
|
||||
self._is_streaming = self._device.is_streaming
|
||||
self._is_video_history_enabled = self._device.is_video_history_enabled
|
||||
|
||||
if self._is_video_history_enabled:
|
||||
# NestAware allowed 10/min
|
||||
|
@ -130,7 +130,7 @@ class NestCamera(Camera):
|
|||
"""Return a still image response from the camera."""
|
||||
now = utcnow()
|
||||
if self._ready_for_snapshot(now):
|
||||
url = self.device.snapshot_url
|
||||
url = self._device.snapshot_url
|
||||
|
||||
try:
|
||||
response = requests.get(url)
|
||||
|
|
|
@ -58,7 +58,6 @@ class HeatmiserV3Thermostat(ClimateDevice):
|
|||
def __init__(self, heatmiser, device, name, serport):
|
||||
"""Initialize the thermostat."""
|
||||
self.heatmiser = heatmiser
|
||||
self.device = device
|
||||
self.serport = serport
|
||||
self._current_temperature = None
|
||||
self._name = name
|
||||
|
|
|
@ -118,7 +118,7 @@ class KNXClimate(ClimateDevice):
|
|||
|
||||
def __init__(self, hass, device):
|
||||
"""Initialize of a KNX climate device."""
|
||||
self.device = device
|
||||
self._device = device
|
||||
self.hass = hass
|
||||
self.async_register_callbacks()
|
||||
|
||||
|
@ -126,7 +126,7 @@ class KNXClimate(ClimateDevice):
|
|||
def supported_features(self):
|
||||
"""Return the list of supported features."""
|
||||
support = SUPPORT_TARGET_TEMPERATURE
|
||||
if self.device.supports_operation_mode:
|
||||
if self._device.supports_operation_mode:
|
||||
support |= SUPPORT_OPERATION_MODE
|
||||
return support
|
||||
|
||||
|
@ -135,12 +135,12 @@ class KNXClimate(ClimateDevice):
|
|||
async def after_update_callback(device):
|
||||
"""Call after device was updated."""
|
||||
await self.async_update_ha_state()
|
||||
self.device.register_device_updated_cb(after_update_callback)
|
||||
self._device.register_device_updated_cb(after_update_callback)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the KNX device."""
|
||||
return self.device.name
|
||||
return self._device.name
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
@ -160,41 +160,41 @@ class KNXClimate(ClimateDevice):
|
|||
@property
|
||||
def current_temperature(self):
|
||||
"""Return the current temperature."""
|
||||
return self.device.temperature.value
|
||||
return self._device.temperature.value
|
||||
|
||||
@property
|
||||
def target_temperature_step(self):
|
||||
"""Return the supported step of target temperature."""
|
||||
return self.device.setpoint_shift_step
|
||||
return self._device.setpoint_shift_step
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
"""Return the temperature we try to reach."""
|
||||
return self.device.target_temperature.value
|
||||
return self._device.target_temperature.value
|
||||
|
||||
@property
|
||||
def min_temp(self):
|
||||
"""Return the minimum temperature."""
|
||||
return self.device.target_temperature_min
|
||||
return self._device.target_temperature_min
|
||||
|
||||
@property
|
||||
def max_temp(self):
|
||||
"""Return the maximum temperature."""
|
||||
return self.device.target_temperature_max
|
||||
return self._device.target_temperature_max
|
||||
|
||||
async def async_set_temperature(self, **kwargs):
|
||||
"""Set new target temperature."""
|
||||
temperature = kwargs.get(ATTR_TEMPERATURE)
|
||||
if temperature is None:
|
||||
return
|
||||
await self.device.set_target_temperature(temperature)
|
||||
await self._device.set_target_temperature(temperature)
|
||||
await self.async_update_ha_state()
|
||||
|
||||
@property
|
||||
def current_operation(self):
|
||||
"""Return current operation ie. heat, cool, idle."""
|
||||
if self.device.supports_operation_mode:
|
||||
return self.device.operation_mode.value
|
||||
if self._device.supports_operation_mode:
|
||||
return self._device.operation_mode.value
|
||||
return None
|
||||
|
||||
@property
|
||||
|
@ -202,11 +202,11 @@ class KNXClimate(ClimateDevice):
|
|||
"""Return the list of available operation modes."""
|
||||
return [operation_mode.value for
|
||||
operation_mode in
|
||||
self.device.get_supported_operation_modes()]
|
||||
self._device.get_supported_operation_modes()]
|
||||
|
||||
async def async_set_operation_mode(self, operation_mode):
|
||||
"""Set operation mode."""
|
||||
if self.device.supports_operation_mode:
|
||||
if self._device.supports_operation_mode:
|
||||
from xknx.knx import HVACOperationMode
|
||||
knx_operation_mode = HVACOperationMode(operation_mode)
|
||||
await self.device.set_operation_mode(knx_operation_mode)
|
||||
await self._device.set_operation_mode(knx_operation_mode)
|
||||
|
|
|
@ -57,7 +57,7 @@ class NestThermostat(ClimateDevice):
|
|||
"""Initialize the thermostat."""
|
||||
self._unit = temp_unit
|
||||
self.structure = structure
|
||||
self.device = device
|
||||
self._device = device
|
||||
self._fan_list = [STATE_ON, STATE_AUTO]
|
||||
|
||||
# Set the default supported features
|
||||
|
@ -68,13 +68,13 @@ class NestThermostat(ClimateDevice):
|
|||
self._operation_list = [STATE_OFF]
|
||||
|
||||
# Add supported nest thermostat features
|
||||
if self.device.can_heat:
|
||||
if self._device.can_heat:
|
||||
self._operation_list.append(STATE_HEAT)
|
||||
|
||||
if self.device.can_cool:
|
||||
if self._device.can_cool:
|
||||
self._operation_list.append(STATE_COOL)
|
||||
|
||||
if self.device.can_heat and self.device.can_cool:
|
||||
if self._device.can_heat and self._device.can_cool:
|
||||
self._operation_list.append(STATE_AUTO)
|
||||
self._support_flags = (self._support_flags |
|
||||
SUPPORT_TARGET_TEMPERATURE_HIGH |
|
||||
|
@ -83,7 +83,7 @@ class NestThermostat(ClimateDevice):
|
|||
self._operation_list.append(STATE_ECO)
|
||||
|
||||
# feature of device
|
||||
self._has_fan = self.device.has_fan
|
||||
self._has_fan = self._device.has_fan
|
||||
if self._has_fan:
|
||||
self._support_flags = (self._support_flags | SUPPORT_FAN_MODE)
|
||||
|
||||
|
@ -125,7 +125,7 @@ class NestThermostat(ClimateDevice):
|
|||
@property
|
||||
def unique_id(self):
|
||||
"""Unique ID for this device."""
|
||||
return self.device.serial
|
||||
return self._device.serial
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -202,7 +202,7 @@ class NestThermostat(ClimateDevice):
|
|||
_LOGGER.debug("Nest set_temperature-output-value=%s", temp)
|
||||
try:
|
||||
if temp is not None:
|
||||
self.device.target = temp
|
||||
self._device.target = temp
|
||||
except nest.nest.APIError as api_error:
|
||||
_LOGGER.error("An error occurred while setting temperature: %s",
|
||||
api_error)
|
||||
|
@ -220,7 +220,7 @@ class NestThermostat(ClimateDevice):
|
|||
_LOGGER.error(
|
||||
"An error occurred while setting device mode. "
|
||||
"Invalid operation mode: %s", operation_mode)
|
||||
self.device.mode = device_mode
|
||||
self._device.mode = device_mode
|
||||
|
||||
@property
|
||||
def operation_list(self):
|
||||
|
@ -254,7 +254,7 @@ class NestThermostat(ClimateDevice):
|
|||
def set_fan_mode(self, fan_mode):
|
||||
"""Turn fan on/off."""
|
||||
if self._has_fan:
|
||||
self.device.fan = fan_mode.lower()
|
||||
self._device.fan = fan_mode.lower()
|
||||
|
||||
@property
|
||||
def min_temp(self):
|
||||
|
@ -268,20 +268,20 @@ class NestThermostat(ClimateDevice):
|
|||
|
||||
def update(self):
|
||||
"""Cache value from Python-nest."""
|
||||
self._location = self.device.where
|
||||
self._name = self.device.name
|
||||
self._humidity = self.device.humidity
|
||||
self._temperature = self.device.temperature
|
||||
self._mode = self.device.mode
|
||||
self._target_temperature = self.device.target
|
||||
self._fan = self.device.fan
|
||||
self._location = self._device.where
|
||||
self._name = self._device.name
|
||||
self._humidity = self._device.humidity
|
||||
self._temperature = self._device.temperature
|
||||
self._mode = self._device.mode
|
||||
self._target_temperature = self._device.target
|
||||
self._fan = self._device.fan
|
||||
self._away = self.structure.away == 'away'
|
||||
self._eco_temperature = self.device.eco_temperature
|
||||
self._locked_temperature = self.device.locked_temperature
|
||||
self._min_temperature = self.device.min_temperature
|
||||
self._max_temperature = self.device.max_temperature
|
||||
self._is_locked = self.device.is_locked
|
||||
if self.device.temperature_scale == 'C':
|
||||
self._eco_temperature = self._device.eco_temperature
|
||||
self._locked_temperature = self._device.locked_temperature
|
||||
self._min_temperature = self._device.min_temperature
|
||||
self._max_temperature = self._device.max_temperature
|
||||
self._is_locked = self._device.is_locked
|
||||
if self._device.temperature_scale == 'C':
|
||||
self._temperature_scale = TEMP_CELSIUS
|
||||
else:
|
||||
self._temperature_scale = TEMP_FAHRENHEIT
|
||||
|
|
|
@ -120,7 +120,7 @@ class RadioThermostat(ClimateDevice):
|
|||
|
||||
def __init__(self, device, hold_temp, away_temps):
|
||||
"""Initialize the thermostat."""
|
||||
self.device = device
|
||||
self._device = device
|
||||
self._target_temperature = None
|
||||
self._current_temperature = None
|
||||
self._current_operation = STATE_IDLE
|
||||
|
@ -137,8 +137,8 @@ class RadioThermostat(ClimateDevice):
|
|||
|
||||
# Fan circulate mode is only supported by the CT80 models.
|
||||
import radiotherm
|
||||
self._is_model_ct80 = isinstance(self.device,
|
||||
radiotherm.thermostat.CT80)
|
||||
self._is_model_ct80 = isinstance(
|
||||
self._device, radiotherm.thermostat.CT80)
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
|
@ -194,7 +194,7 @@ class RadioThermostat(ClimateDevice):
|
|||
"""Turn fan on/off."""
|
||||
code = FAN_MODE_TO_CODE.get(fan_mode, None)
|
||||
if code is not None:
|
||||
self.device.fmode = code
|
||||
self._device.fmode = code
|
||||
|
||||
@property
|
||||
def current_temperature(self):
|
||||
|
@ -234,15 +234,15 @@ class RadioThermostat(ClimateDevice):
|
|||
# First time - get the name from the thermostat. This is
|
||||
# normally set in the radio thermostat web app.
|
||||
if self._name is None:
|
||||
self._name = self.device.name['raw']
|
||||
self._name = self._device.name['raw']
|
||||
|
||||
# Request the current state from the thermostat.
|
||||
data = self.device.tstat['raw']
|
||||
data = self._device.tstat['raw']
|
||||
|
||||
current_temp = data['temp']
|
||||
if current_temp == -1:
|
||||
_LOGGER.error('%s (%s) was busy (temp == -1)', self._name,
|
||||
self.device.host)
|
||||
self._device.host)
|
||||
return
|
||||
|
||||
# Map thermostat values into various STATE_ flags.
|
||||
|
@ -277,30 +277,30 @@ class RadioThermostat(ClimateDevice):
|
|||
temperature = round_temp(temperature)
|
||||
|
||||
if self._current_operation == STATE_COOL:
|
||||
self.device.t_cool = temperature
|
||||
self._device.t_cool = temperature
|
||||
elif self._current_operation == STATE_HEAT:
|
||||
self.device.t_heat = temperature
|
||||
self._device.t_heat = temperature
|
||||
elif self._current_operation == STATE_AUTO:
|
||||
if self._tstate == STATE_COOL:
|
||||
self.device.t_cool = temperature
|
||||
self._device.t_cool = temperature
|
||||
elif self._tstate == STATE_HEAT:
|
||||
self.device.t_heat = temperature
|
||||
self._device.t_heat = temperature
|
||||
|
||||
# Only change the hold if requested or if hold mode was turned
|
||||
# on and we haven't set it yet.
|
||||
if kwargs.get('hold_changed', False) or not self._hold_set:
|
||||
if self._hold_temp or self._away:
|
||||
self.device.hold = 1
|
||||
self._device.hold = 1
|
||||
self._hold_set = True
|
||||
else:
|
||||
self.device.hold = 0
|
||||
self._device.hold = 0
|
||||
|
||||
def set_time(self):
|
||||
"""Set device time."""
|
||||
# Calling this clears any local temperature override and
|
||||
# reverts to the scheduled temperature.
|
||||
now = datetime.datetime.now()
|
||||
self.device.time = {
|
||||
self._device.time = {
|
||||
'day': now.weekday(),
|
||||
'hour': now.hour,
|
||||
'minute': now.minute
|
||||
|
@ -309,13 +309,13 @@ class RadioThermostat(ClimateDevice):
|
|||
def set_operation_mode(self, operation_mode):
|
||||
"""Set operation mode (auto, cool, heat, off)."""
|
||||
if operation_mode in (STATE_OFF, STATE_AUTO):
|
||||
self.device.tmode = TEMP_MODE_TO_CODE[operation_mode]
|
||||
self._device.tmode = TEMP_MODE_TO_CODE[operation_mode]
|
||||
|
||||
# Setting t_cool or t_heat automatically changes tmode.
|
||||
elif operation_mode == STATE_COOL:
|
||||
self.device.t_cool = self._target_temperature
|
||||
self._device.t_cool = self._target_temperature
|
||||
elif operation_mode == STATE_HEAT:
|
||||
self.device.t_heat = self._target_temperature
|
||||
self._device.t_heat = self._target_temperature
|
||||
|
||||
def turn_away_mode_on(self):
|
||||
"""Turn away on.
|
||||
|
|
|
@ -96,7 +96,7 @@ class KNXCover(CoverDevice):
|
|||
|
||||
def __init__(self, hass, device):
|
||||
"""Initialize the cover."""
|
||||
self.device = device
|
||||
self._device = device
|
||||
self.hass = hass
|
||||
self.async_register_callbacks()
|
||||
|
||||
|
@ -108,12 +108,12 @@ class KNXCover(CoverDevice):
|
|||
async def after_update_callback(device):
|
||||
"""Call after device was updated."""
|
||||
await self.async_update_ha_state()
|
||||
self.device.register_device_updated_cb(after_update_callback)
|
||||
self._device.register_device_updated_cb(after_update_callback)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the KNX device."""
|
||||
return self.device.name
|
||||
return self._device.name
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
@ -130,56 +130,56 @@ class KNXCover(CoverDevice):
|
|||
"""Flag supported features."""
|
||||
supported_features = SUPPORT_OPEN | SUPPORT_CLOSE | \
|
||||
SUPPORT_SET_POSITION | SUPPORT_STOP
|
||||
if self.device.supports_angle:
|
||||
if self._device.supports_angle:
|
||||
supported_features |= SUPPORT_SET_TILT_POSITION
|
||||
return supported_features
|
||||
|
||||
@property
|
||||
def current_cover_position(self):
|
||||
"""Return the current position of the cover."""
|
||||
return self.device.current_position()
|
||||
return self._device.current_position()
|
||||
|
||||
@property
|
||||
def is_closed(self):
|
||||
"""Return if the cover is closed."""
|
||||
return self.device.is_closed()
|
||||
return self._device.is_closed()
|
||||
|
||||
async def async_close_cover(self, **kwargs):
|
||||
"""Close the cover."""
|
||||
if not self.device.is_closed():
|
||||
await self.device.set_down()
|
||||
if not self._device.is_closed():
|
||||
await self._device.set_down()
|
||||
self.start_auto_updater()
|
||||
|
||||
async def async_open_cover(self, **kwargs):
|
||||
"""Open the cover."""
|
||||
if not self.device.is_open():
|
||||
await self.device.set_up()
|
||||
if not self._device.is_open():
|
||||
await self._device.set_up()
|
||||
self.start_auto_updater()
|
||||
|
||||
async def async_set_cover_position(self, **kwargs):
|
||||
"""Move the cover to a specific position."""
|
||||
if ATTR_POSITION in kwargs:
|
||||
position = kwargs[ATTR_POSITION]
|
||||
await self.device.set_position(position)
|
||||
await self._device.set_position(position)
|
||||
self.start_auto_updater()
|
||||
|
||||
async def async_stop_cover(self, **kwargs):
|
||||
"""Stop the cover."""
|
||||
await self.device.stop()
|
||||
await self._device.stop()
|
||||
self.stop_auto_updater()
|
||||
|
||||
@property
|
||||
def current_cover_tilt_position(self):
|
||||
"""Return current tilt position of cover."""
|
||||
if not self.device.supports_angle:
|
||||
if not self._device.supports_angle:
|
||||
return None
|
||||
return self.device.current_angle()
|
||||
return self._device.current_angle()
|
||||
|
||||
async def async_set_cover_tilt_position(self, **kwargs):
|
||||
"""Move the cover tilt to a specific position."""
|
||||
if ATTR_TILT_POSITION in kwargs:
|
||||
tilt_position = kwargs[ATTR_TILT_POSITION]
|
||||
await self.device.set_angle(tilt_position)
|
||||
await self._device.set_angle(tilt_position)
|
||||
|
||||
def start_auto_updater(self):
|
||||
"""Start the autoupdater to update HASS while cover is moving."""
|
||||
|
@ -197,7 +197,7 @@ class KNXCover(CoverDevice):
|
|||
def auto_updater_hook(self, now):
|
||||
"""Call for the autoupdater."""
|
||||
self.async_schedule_update_ha_state()
|
||||
if self.device.position_reached():
|
||||
if self._device.position_reached():
|
||||
self.stop_auto_updater()
|
||||
|
||||
self.hass.add_job(self.device.auto_stop_if_necessary())
|
||||
self.hass.add_job(self._device.auto_stop_if_necessary())
|
||||
|
|
|
@ -28,19 +28,19 @@ class TelldusLiveCover(TelldusLiveEntity, CoverDevice):
|
|||
@property
|
||||
def is_closed(self):
|
||||
"""Return the current position of the cover."""
|
||||
return self.device.is_down
|
||||
return self._device.is_down
|
||||
|
||||
def close_cover(self, **kwargs):
|
||||
"""Close the cover."""
|
||||
self.device.down()
|
||||
self._device.down()
|
||||
self.changed()
|
||||
|
||||
def open_cover(self, **kwargs):
|
||||
"""Open the cover."""
|
||||
self.device.up()
|
||||
self._device.up()
|
||||
self.changed()
|
||||
|
||||
def stop_cover(self, **kwargs):
|
||||
"""Stop the cover."""
|
||||
self.device.stop()
|
||||
self._device.stop()
|
||||
self.changed()
|
||||
|
|
|
@ -46,29 +46,29 @@ class JuicenetDevice(Entity):
|
|||
def __init__(self, device, sensor_type, hass):
|
||||
"""Initialise the sensor."""
|
||||
self.hass = hass
|
||||
self.device = device
|
||||
self._device = device
|
||||
self.type = sensor_type
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the device."""
|
||||
return self.device.name()
|
||||
return self._device.name()
|
||||
|
||||
def update(self):
|
||||
"""Update state of the device."""
|
||||
self.device.update_state()
|
||||
self._device.update_state()
|
||||
|
||||
@property
|
||||
def _manufacturer_device_id(self):
|
||||
"""Return the manufacturer device id."""
|
||||
return self.device.id()
|
||||
return self._device.id()
|
||||
|
||||
@property
|
||||
def _token(self):
|
||||
"""Return the device API token."""
|
||||
return self.device.token()
|
||||
return self._device.token()
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique ID."""
|
||||
return "{}-{}".format(self.device.id(), self.type)
|
||||
return "{}-{}".format(self._device.id(), self.type)
|
||||
|
|
|
@ -79,7 +79,7 @@ class KNXLight(Light):
|
|||
|
||||
def __init__(self, hass, device):
|
||||
"""Initialize of KNX light."""
|
||||
self.device = device
|
||||
self._device = device
|
||||
self.hass = hass
|
||||
self.async_register_callbacks()
|
||||
|
||||
|
@ -89,12 +89,12 @@ class KNXLight(Light):
|
|||
async def after_update_callback(device):
|
||||
"""Call after device was updated."""
|
||||
await self.async_update_ha_state()
|
||||
self.device.register_device_updated_cb(after_update_callback)
|
||||
self._device.register_device_updated_cb(after_update_callback)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the KNX device."""
|
||||
return self.device.name
|
||||
return self._device.name
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
@ -109,15 +109,15 @@ class KNXLight(Light):
|
|||
@property
|
||||
def brightness(self):
|
||||
"""Return the brightness of this light between 0..255."""
|
||||
return self.device.current_brightness \
|
||||
if self.device.supports_brightness else \
|
||||
return self._device.current_brightness \
|
||||
if self._device.supports_brightness else \
|
||||
None
|
||||
|
||||
@property
|
||||
def hs_color(self):
|
||||
"""Return the HS color value."""
|
||||
if self.device.supports_color:
|
||||
return color_util.color_RGB_to_hs(*self.device.current_color)
|
||||
if self._device.supports_color:
|
||||
return color_util.color_RGB_to_hs(*self._device.current_color)
|
||||
return None
|
||||
|
||||
@property
|
||||
|
@ -143,30 +143,30 @@ class KNXLight(Light):
|
|||
@property
|
||||
def is_on(self):
|
||||
"""Return true if light is on."""
|
||||
return self.device.state
|
||||
return self._device.state
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Flag supported features."""
|
||||
flags = 0
|
||||
if self.device.supports_brightness:
|
||||
if self._device.supports_brightness:
|
||||
flags |= SUPPORT_BRIGHTNESS
|
||||
if self.device.supports_color:
|
||||
if self._device.supports_color:
|
||||
flags |= SUPPORT_COLOR
|
||||
return flags
|
||||
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Turn the light on."""
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
if self.device.supports_brightness:
|
||||
await self.device.set_brightness(int(kwargs[ATTR_BRIGHTNESS]))
|
||||
if self._device.supports_brightness:
|
||||
await self._device.set_brightness(int(kwargs[ATTR_BRIGHTNESS]))
|
||||
elif ATTR_HS_COLOR in kwargs:
|
||||
if self.device.supports_color:
|
||||
await self.device.set_color(color_util.color_hs_to_RGB(
|
||||
if self._device.supports_color:
|
||||
await self._device.set_color(color_util.color_hs_to_RGB(
|
||||
*kwargs[ATTR_HS_COLOR]))
|
||||
else:
|
||||
await self.device.set_on()
|
||||
await self._device.set_on()
|
||||
|
||||
async def async_turn_off(self, **kwargs):
|
||||
"""Turn the light off."""
|
||||
await self.device.set_off()
|
||||
await self._device.set_off()
|
||||
|
|
|
@ -389,7 +389,7 @@ class LIFXLight(Light):
|
|||
|
||||
def __init__(self, device, effects_conductor):
|
||||
"""Initialize the light."""
|
||||
self.device = device
|
||||
self.light = device
|
||||
self.effects_conductor = effects_conductor
|
||||
self.registered = True
|
||||
self.postponed_update = None
|
||||
|
@ -403,28 +403,28 @@ class LIFXLight(Light):
|
|||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique ID."""
|
||||
return self.device.mac_addr
|
||||
return self.light.mac_addr
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the device."""
|
||||
return self.device.label
|
||||
return self.light.label
|
||||
|
||||
@property
|
||||
def who(self):
|
||||
"""Return a string identifying the device."""
|
||||
return "%s (%s)" % (self.device.ip_addr, self.name)
|
||||
return "%s (%s)" % (self.light.ip_addr, self.name)
|
||||
|
||||
@property
|
||||
def min_mireds(self):
|
||||
"""Return the coldest color_temp that this light supports."""
|
||||
kelvin = lifx_features(self.device)['max_kelvin']
|
||||
kelvin = lifx_features(self.light)['max_kelvin']
|
||||
return math.floor(color_util.color_temperature_kelvin_to_mired(kelvin))
|
||||
|
||||
@property
|
||||
def max_mireds(self):
|
||||
"""Return the warmest color_temp that this light supports."""
|
||||
kelvin = lifx_features(self.device)['min_kelvin']
|
||||
kelvin = lifx_features(self.light)['min_kelvin']
|
||||
return math.ceil(color_util.color_temperature_kelvin_to_mired(kelvin))
|
||||
|
||||
@property
|
||||
|
@ -432,7 +432,7 @@ class LIFXLight(Light):
|
|||
"""Flag supported features."""
|
||||
support = SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION | SUPPORT_EFFECT
|
||||
|
||||
device_features = lifx_features(self.device)
|
||||
device_features = lifx_features(self.light)
|
||||
if device_features['min_kelvin'] != device_features['max_kelvin']:
|
||||
support |= SUPPORT_COLOR_TEMP
|
||||
|
||||
|
@ -441,12 +441,12 @@ class LIFXLight(Light):
|
|||
@property
|
||||
def brightness(self):
|
||||
"""Return the brightness of this light between 0..255."""
|
||||
return convert_16_to_8(self.device.color[2])
|
||||
return convert_16_to_8(self.light.color[2])
|
||||
|
||||
@property
|
||||
def color_temp(self):
|
||||
"""Return the color temperature."""
|
||||
_, sat, _, kelvin = self.device.color
|
||||
_, sat, _, kelvin = self.light.color
|
||||
if sat:
|
||||
return None
|
||||
return color_util.color_temperature_kelvin_to_mired(kelvin)
|
||||
|
@ -454,12 +454,12 @@ class LIFXLight(Light):
|
|||
@property
|
||||
def is_on(self):
|
||||
"""Return true if device is on."""
|
||||
return self.device.power_level != 0
|
||||
return self.light.power_level != 0
|
||||
|
||||
@property
|
||||
def effect(self):
|
||||
"""Return the name of the currently running effect."""
|
||||
effect = self.effects_conductor.effect(self.device)
|
||||
effect = self.effects_conductor.effect(self.light)
|
||||
if effect:
|
||||
return 'lifx_effect_' + effect.name
|
||||
return None
|
||||
|
@ -497,7 +497,7 @@ class LIFXLight(Light):
|
|||
async def set_state(self, **kwargs):
|
||||
"""Set a color on the light and turn it on/off."""
|
||||
async with self.lock:
|
||||
bulb = self.device
|
||||
bulb = self.light
|
||||
|
||||
await self.effects_conductor.stop([bulb])
|
||||
|
||||
|
@ -545,12 +545,12 @@ class LIFXLight(Light):
|
|||
|
||||
async def set_power(self, ack, pwr, duration=0):
|
||||
"""Send a power change to the device."""
|
||||
await ack(partial(self.device.set_power, pwr, duration=duration))
|
||||
await ack(partial(self.light.set_power, pwr, duration=duration))
|
||||
|
||||
async def set_color(self, ack, hsbk, kwargs, duration=0):
|
||||
"""Send a color change to the device."""
|
||||
hsbk = merge_hsbk(self.device.color, hsbk)
|
||||
await ack(partial(self.device.set_color, hsbk, duration=duration))
|
||||
hsbk = merge_hsbk(self.light.color, hsbk)
|
||||
await ack(partial(self.light.set_color, hsbk, duration=duration))
|
||||
|
||||
async def default_effect(self, **kwargs):
|
||||
"""Start an effect with default parameters."""
|
||||
|
@ -563,7 +563,7 @@ class LIFXLight(Light):
|
|||
async def async_update(self):
|
||||
"""Update bulb status."""
|
||||
if self.available and not self.lock.locked():
|
||||
await AwaitAioLIFX().wait(self.device.get_color)
|
||||
await AwaitAioLIFX().wait(self.light.get_color)
|
||||
|
||||
|
||||
class LIFXWhite(LIFXLight):
|
||||
|
@ -600,7 +600,7 @@ class LIFXColor(LIFXLight):
|
|||
@property
|
||||
def hs_color(self):
|
||||
"""Return the hs value."""
|
||||
hue, sat, _, _ = self.device.color
|
||||
hue, sat, _, _ = self.light.color
|
||||
hue = hue / 65535 * 360
|
||||
sat = sat / 65535 * 100
|
||||
return (hue, sat) if sat else None
|
||||
|
@ -611,7 +611,7 @@ class LIFXStrip(LIFXColor):
|
|||
|
||||
async def set_color(self, ack, hsbk, kwargs, duration=0):
|
||||
"""Send a color change to the device."""
|
||||
bulb = self.device
|
||||
bulb = self.light
|
||||
num_zones = len(bulb.color_zones)
|
||||
|
||||
zones = kwargs.get(ATTR_ZONES)
|
||||
|
@ -659,7 +659,7 @@ class LIFXStrip(LIFXColor):
|
|||
while self.available and zone < top:
|
||||
# Each get_color_zones can update 8 zones at once
|
||||
resp = await AwaitAioLIFX().wait(partial(
|
||||
self.device.get_color_zones,
|
||||
self.light.get_color_zones,
|
||||
start_index=zone))
|
||||
if resp:
|
||||
zone += 8
|
||||
|
|
|
@ -54,8 +54,8 @@ class MochadLight(Light):
|
|||
self._name = dev.get(CONF_NAME,
|
||||
'x10_light_dev_{}'.format(self._address))
|
||||
self._comm_type = dev.get(mochad.CONF_COMM_TYPE, 'pl')
|
||||
self.device = device.Device(ctrl, self._address,
|
||||
comm_type=self._comm_type)
|
||||
self.light = device.Device(ctrl, self._address,
|
||||
comm_type=self._comm_type)
|
||||
self._brightness = 0
|
||||
self._state = self._get_device_status()
|
||||
self._brightness_levels = dev.get(CONF_BRIGHTNESS_LEVELS) - 1
|
||||
|
@ -68,7 +68,7 @@ class MochadLight(Light):
|
|||
def _get_device_status(self):
|
||||
"""Get the status of the light from mochad."""
|
||||
with mochad.REQ_LOCK:
|
||||
status = self.device.get_status().rstrip()
|
||||
status = self.light.get_status().rstrip()
|
||||
return status == 'on'
|
||||
|
||||
@property
|
||||
|
@ -98,12 +98,12 @@ class MochadLight(Light):
|
|||
if self._brightness > brightness:
|
||||
bdelta = self._brightness - brightness
|
||||
mochad_brightness = self._calculate_brightness_value(bdelta)
|
||||
self.device.send_cmd("dim {}".format(mochad_brightness))
|
||||
self.light.send_cmd("dim {}".format(mochad_brightness))
|
||||
self._controller.read_data()
|
||||
elif self._brightness < brightness:
|
||||
bdelta = brightness - self._brightness
|
||||
mochad_brightness = self._calculate_brightness_value(bdelta)
|
||||
self.device.send_cmd("bright {}".format(mochad_brightness))
|
||||
self.light.send_cmd("bright {}".format(mochad_brightness))
|
||||
self._controller.read_data()
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
|
@ -112,10 +112,10 @@ class MochadLight(Light):
|
|||
with mochad.REQ_LOCK:
|
||||
if self._brightness_levels > 32:
|
||||
out_brightness = self._calculate_brightness_value(brightness)
|
||||
self.device.send_cmd('xdim {}'.format(out_brightness))
|
||||
self.light.send_cmd('xdim {}'.format(out_brightness))
|
||||
self._controller.read_data()
|
||||
else:
|
||||
self.device.send_cmd("on")
|
||||
self.light.send_cmd("on")
|
||||
self._controller.read_data()
|
||||
# There is no persistence for X10 modules so a fresh on command
|
||||
# will be full brightness
|
||||
|
@ -128,7 +128,7 @@ class MochadLight(Light):
|
|||
def turn_off(self, **kwargs):
|
||||
"""Send the command to turn the light on."""
|
||||
with mochad.REQ_LOCK:
|
||||
self.device.send_cmd('off')
|
||||
self.light.send_cmd('off')
|
||||
self._controller.read_data()
|
||||
# There is no persistence for X10 modules so we need to prepare
|
||||
# to track a fresh on command will full brightness
|
||||
|
|
|
@ -27,9 +27,9 @@ class QSLight(QSToggleEntity, Light):
|
|||
@property
|
||||
def brightness(self):
|
||||
"""Return the brightness of this light (0-255)."""
|
||||
return self.device.value if self.device.is_dimmer else None
|
||||
return self._device.value if self._device.is_dimmer else None
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Flag supported features."""
|
||||
return SUPPORT_BRIGHTNESS if self.device.is_dimmer else 0
|
||||
return SUPPORT_BRIGHTNESS if self._device.is_dimmer else 0
|
||||
|
|
|
@ -38,7 +38,7 @@ class TelldusLiveLight(TelldusLiveEntity, Light):
|
|||
@property
|
||||
def brightness(self):
|
||||
"""Return the brightness of this light between 0..255."""
|
||||
return self.device.dim_level
|
||||
return self._device.dim_level
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
|
@ -48,15 +48,15 @@ class TelldusLiveLight(TelldusLiveEntity, Light):
|
|||
@property
|
||||
def is_on(self):
|
||||
"""Return true if light is on."""
|
||||
return self.device.is_on
|
||||
return self._device.is_on
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn the light on."""
|
||||
brightness = kwargs.get(ATTR_BRIGHTNESS, self._last_brightness)
|
||||
self.device.dim(level=brightness)
|
||||
self._device.dim(level=brightness)
|
||||
self.changed()
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn the light off."""
|
||||
self.device.turn_off()
|
||||
self._device.turn_off()
|
||||
self.changed()
|
||||
|
|
|
@ -76,39 +76,39 @@ class WemoLight(Light):
|
|||
def __init__(self, device, update_lights):
|
||||
"""Initialize the WeMo light."""
|
||||
self.light_id = device.name
|
||||
self.device = device
|
||||
self.wemo = device
|
||||
self.update_lights = update_lights
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return the ID of this light."""
|
||||
return self.device.uniqueID
|
||||
return self.wemo.uniqueID
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the light."""
|
||||
return self.device.name
|
||||
return self.wemo.name
|
||||
|
||||
@property
|
||||
def brightness(self):
|
||||
"""Return the brightness of this light between 0..255."""
|
||||
return self.device.state.get('level', 255)
|
||||
return self.wemo.state.get('level', 255)
|
||||
|
||||
@property
|
||||
def hs_color(self):
|
||||
"""Return the hs color values of this light."""
|
||||
xy_color = self.device.state.get('color_xy')
|
||||
xy_color = self.wemo.state.get('color_xy')
|
||||
return color_util.color_xy_to_hs(*xy_color) if xy_color else None
|
||||
|
||||
@property
|
||||
def color_temp(self):
|
||||
"""Return the color temperature of this light in mireds."""
|
||||
return self.device.state.get('temperature_mireds')
|
||||
return self.wemo.state.get('temperature_mireds')
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if device is on."""
|
||||
return self.device.state['onoff'] != 0
|
||||
return self.wemo.state['onoff'] != 0
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
|
@ -118,7 +118,7 @@ class WemoLight(Light):
|
|||
@property
|
||||
def available(self):
|
||||
"""Return if light is available."""
|
||||
return self.device.state['available']
|
||||
return self.wemo.state['available']
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn the light on."""
|
||||
|
@ -128,23 +128,23 @@ class WemoLight(Light):
|
|||
|
||||
if hs_color is not None:
|
||||
xy_color = color_util.color_hs_to_xy(*hs_color)
|
||||
self.device.set_color(xy_color, transition=transitiontime)
|
||||
self.wemo.set_color(xy_color, transition=transitiontime)
|
||||
|
||||
if ATTR_COLOR_TEMP in kwargs:
|
||||
colortemp = kwargs[ATTR_COLOR_TEMP]
|
||||
self.device.set_temperature(mireds=colortemp,
|
||||
transition=transitiontime)
|
||||
self.wemo.set_temperature(mireds=colortemp,
|
||||
transition=transitiontime)
|
||||
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
brightness = kwargs.get(ATTR_BRIGHTNESS, self.brightness or 255)
|
||||
self.device.turn_on(level=brightness, transition=transitiontime)
|
||||
self.wemo.turn_on(level=brightness, transition=transitiontime)
|
||||
else:
|
||||
self.device.turn_on(transition=transitiontime)
|
||||
self.wemo.turn_on(transition=transitiontime)
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn the light off."""
|
||||
transitiontime = int(kwargs.get(ATTR_TRANSITION, 0))
|
||||
self.device.turn_off(transition=transitiontime)
|
||||
self.wemo.turn_off(transition=transitiontime)
|
||||
|
||||
def update(self):
|
||||
"""Synchronize state with bridge."""
|
||||
|
|
|
@ -132,7 +132,7 @@ class EmbyDevice(MediaPlayerDevice):
|
|||
_LOGGER.debug("New Emby Device initialized with ID: %s", device_id)
|
||||
self.emby = emby
|
||||
self.device_id = device_id
|
||||
self.device = self.emby.devices[self.device_id]
|
||||
self._device = self.emby.devices[self.device_id]
|
||||
|
||||
self._hidden = False
|
||||
self._available = True
|
||||
|
@ -150,11 +150,11 @@ class EmbyDevice(MediaPlayerDevice):
|
|||
def async_update_callback(self, msg):
|
||||
"""Handle device updates."""
|
||||
# Check if we should update progress
|
||||
if self.device.media_position:
|
||||
if self.device.media_position != self.media_status_last_position:
|
||||
self.media_status_last_position = self.device.media_position
|
||||
if self._device.media_position:
|
||||
if self._device.media_position != self.media_status_last_position:
|
||||
self.media_status_last_position = self._device.media_position
|
||||
self.media_status_received = dt_util.utcnow()
|
||||
elif not self.device.is_nowplaying:
|
||||
elif not self._device.is_nowplaying:
|
||||
# No position, but we have an old value and are still playing
|
||||
self.media_status_last_position = None
|
||||
self.media_status_received = None
|
||||
|
@ -187,13 +187,13 @@ class EmbyDevice(MediaPlayerDevice):
|
|||
@property
|
||||
def supports_remote_control(self):
|
||||
"""Return control ability."""
|
||||
return self.device.supports_remote_control
|
||||
return self._device.supports_remote_control
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the device."""
|
||||
return 'Emby - {} - {}'.format(self.device.client, self.device.name) \
|
||||
or DEVICE_DEFAULT_NAME
|
||||
return ('Emby - {} - {}'.format(self._device.client, self._device.name)
|
||||
or DEVICE_DEFAULT_NAME)
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
|
@ -203,7 +203,7 @@ class EmbyDevice(MediaPlayerDevice):
|
|||
@property
|
||||
def state(self):
|
||||
"""Return the state of the device."""
|
||||
state = self.device.state
|
||||
state = self._device.state
|
||||
if state == 'Paused':
|
||||
return STATE_PAUSED
|
||||
if state == 'Playing':
|
||||
|
@ -217,17 +217,17 @@ class EmbyDevice(MediaPlayerDevice):
|
|||
def app_name(self):
|
||||
"""Return current user as app_name."""
|
||||
# Ideally the media_player object would have a user property.
|
||||
return self.device.username
|
||||
return self._device.username
|
||||
|
||||
@property
|
||||
def media_content_id(self):
|
||||
"""Content ID of current playing media."""
|
||||
return self.device.media_id
|
||||
return self._device.media_id
|
||||
|
||||
@property
|
||||
def media_content_type(self):
|
||||
"""Content type of current playing media."""
|
||||
media_type = self.device.media_type
|
||||
media_type = self._device.media_type
|
||||
if media_type == 'Episode':
|
||||
return MEDIA_TYPE_TVSHOW
|
||||
if media_type == 'Movie':
|
||||
|
@ -245,7 +245,7 @@ class EmbyDevice(MediaPlayerDevice):
|
|||
@property
|
||||
def media_duration(self):
|
||||
"""Return the duration of current playing media in seconds."""
|
||||
return self.device.media_runtime
|
||||
return self._device.media_runtime
|
||||
|
||||
@property
|
||||
def media_position(self):
|
||||
|
@ -264,42 +264,42 @@ class EmbyDevice(MediaPlayerDevice):
|
|||
@property
|
||||
def media_image_url(self):
|
||||
"""Return the image URL of current playing media."""
|
||||
return self.device.media_image_url
|
||||
return self._device.media_image_url
|
||||
|
||||
@property
|
||||
def media_title(self):
|
||||
"""Return the title of current playing media."""
|
||||
return self.device.media_title
|
||||
return self._device.media_title
|
||||
|
||||
@property
|
||||
def media_season(self):
|
||||
"""Season of current playing media (TV Show only)."""
|
||||
return self.device.media_season
|
||||
return self._device.media_season
|
||||
|
||||
@property
|
||||
def media_series_title(self):
|
||||
"""Return the title of the series of current playing media (TV)."""
|
||||
return self.device.media_series_title
|
||||
return self._device.media_series_title
|
||||
|
||||
@property
|
||||
def media_episode(self):
|
||||
"""Return the episode of current playing media (TV only)."""
|
||||
return self.device.media_episode
|
||||
return self._device.media_episode
|
||||
|
||||
@property
|
||||
def media_album_name(self):
|
||||
"""Return the album name of current playing media (Music only)."""
|
||||
return self.device.media_album_name
|
||||
return self._device.media_album_name
|
||||
|
||||
@property
|
||||
def media_artist(self):
|
||||
"""Return the artist of current playing media (Music track only)."""
|
||||
return self.device.media_artist
|
||||
return self._device.media_artist
|
||||
|
||||
@property
|
||||
def media_album_artist(self):
|
||||
"""Return the album artist of current playing media (Music only)."""
|
||||
return self.device.media_album_artist
|
||||
return self._device.media_album_artist
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
|
@ -313,39 +313,39 @@ class EmbyDevice(MediaPlayerDevice):
|
|||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_play()
|
||||
return self._device.media_play()
|
||||
|
||||
def async_media_pause(self):
|
||||
"""Pause the media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_pause()
|
||||
return self._device.media_pause()
|
||||
|
||||
def async_media_stop(self):
|
||||
"""Stop the media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_stop()
|
||||
return self._device.media_stop()
|
||||
|
||||
def async_media_next_track(self):
|
||||
"""Send next track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_next()
|
||||
return self._device.media_next()
|
||||
|
||||
def async_media_previous_track(self):
|
||||
"""Send next track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_previous()
|
||||
return self._device.media_previous()
|
||||
|
||||
def async_media_seek(self, position):
|
||||
"""Send seek command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_seek(position)
|
||||
return self._device.media_seek(position)
|
||||
|
|
|
@ -454,7 +454,7 @@ class PlexClient(MediaPlayerDevice):
|
|||
elif self._player_state == 'paused':
|
||||
self._is_player_active = True
|
||||
self._state = STATE_PAUSED
|
||||
elif self.device:
|
||||
elif self._device:
|
||||
self._is_player_active = False
|
||||
self._state = STATE_IDLE
|
||||
else:
|
||||
|
@ -528,11 +528,6 @@ class PlexClient(MediaPlayerDevice):
|
|||
"""Return the library name of playing media."""
|
||||
return self._app_name
|
||||
|
||||
@property
|
||||
def device(self):
|
||||
"""Return the device, if any."""
|
||||
return self._device
|
||||
|
||||
@property
|
||||
def marked_unavailable(self):
|
||||
"""Return time device was marked unavailable."""
|
||||
|
@ -671,7 +666,7 @@ class PlexClient(MediaPlayerDevice):
|
|||
SUPPORT_TURN_OFF)
|
||||
# Not all devices support playback functionality
|
||||
# Playback includes volume, stop/play/pause, etc.
|
||||
if self.device and 'playback' in self._device_protocol_capabilities:
|
||||
if self._device and 'playback' in self._device_protocol_capabilities:
|
||||
return (SUPPORT_PAUSE | SUPPORT_PREVIOUS_TRACK |
|
||||
SUPPORT_NEXT_TRACK | SUPPORT_STOP |
|
||||
SUPPORT_VOLUME_SET | SUPPORT_PLAY |
|
||||
|
@ -681,22 +676,22 @@ class PlexClient(MediaPlayerDevice):
|
|||
|
||||
def set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1."""
|
||||
if self.device and 'playback' in self._device_protocol_capabilities:
|
||||
self.device.setVolume(
|
||||
if self._device and 'playback' in self._device_protocol_capabilities:
|
||||
self._device.setVolume(
|
||||
int(volume * 100), self._active_media_plexapi_type)
|
||||
self._volume_level = volume # store since we can't retrieve
|
||||
|
||||
@property
|
||||
def volume_level(self):
|
||||
"""Return the volume level of the client (0..1)."""
|
||||
if (self._is_player_active and self.device and
|
||||
if (self._is_player_active and self._device and
|
||||
'playback' in self._device_protocol_capabilities):
|
||||
return self._volume_level
|
||||
|
||||
@property
|
||||
def is_volume_muted(self):
|
||||
"""Return boolean if volume is currently muted."""
|
||||
if self._is_player_active and self.device:
|
||||
if self._is_player_active and self._device:
|
||||
return self._volume_muted
|
||||
|
||||
def mute_volume(self, mute):
|
||||
|
@ -706,7 +701,7 @@ class PlexClient(MediaPlayerDevice):
|
|||
- On mute, store volume and set volume to 0
|
||||
- On unmute, set volume to previously stored volume
|
||||
"""
|
||||
if not (self.device and
|
||||
if not (self._device and
|
||||
'playback' in self._device_protocol_capabilities):
|
||||
return
|
||||
|
||||
|
@ -719,18 +714,18 @@ class PlexClient(MediaPlayerDevice):
|
|||
|
||||
def media_play(self):
|
||||
"""Send play command."""
|
||||
if self.device and 'playback' in self._device_protocol_capabilities:
|
||||
self.device.play(self._active_media_plexapi_type)
|
||||
if self._device and 'playback' in self._device_protocol_capabilities:
|
||||
self._device.play(self._active_media_plexapi_type)
|
||||
|
||||
def media_pause(self):
|
||||
"""Send pause command."""
|
||||
if self.device and 'playback' in self._device_protocol_capabilities:
|
||||
self.device.pause(self._active_media_plexapi_type)
|
||||
if self._device and 'playback' in self._device_protocol_capabilities:
|
||||
self._device.pause(self._active_media_plexapi_type)
|
||||
|
||||
def media_stop(self):
|
||||
"""Send stop command."""
|
||||
if self.device and 'playback' in self._device_protocol_capabilities:
|
||||
self.device.stop(self._active_media_plexapi_type)
|
||||
if self._device and 'playback' in self._device_protocol_capabilities:
|
||||
self._device.stop(self._active_media_plexapi_type)
|
||||
|
||||
def turn_off(self):
|
||||
"""Turn the client off."""
|
||||
|
@ -739,17 +734,17 @@ class PlexClient(MediaPlayerDevice):
|
|||
|
||||
def media_next_track(self):
|
||||
"""Send next track command."""
|
||||
if self.device and 'playback' in self._device_protocol_capabilities:
|
||||
self.device.skipNext(self._active_media_plexapi_type)
|
||||
if self._device and 'playback' in self._device_protocol_capabilities:
|
||||
self._device.skipNext(self._active_media_plexapi_type)
|
||||
|
||||
def media_previous_track(self):
|
||||
"""Send previous track command."""
|
||||
if self.device and 'playback' in self._device_protocol_capabilities:
|
||||
self.device.skipPrevious(self._active_media_plexapi_type)
|
||||
if self._device and 'playback' in self._device_protocol_capabilities:
|
||||
self._device.skipPrevious(self._active_media_plexapi_type)
|
||||
|
||||
def play_media(self, media_type, media_id, **kwargs):
|
||||
"""Play a piece of media."""
|
||||
if not (self.device and
|
||||
if not (self._device and
|
||||
'playback' in self._device_protocol_capabilities):
|
||||
return
|
||||
|
||||
|
@ -757,7 +752,7 @@ class PlexClient(MediaPlayerDevice):
|
|||
|
||||
media = None
|
||||
if media_type == 'MUSIC':
|
||||
media = self.device.server.library.section(
|
||||
media = self._device.server.library.section(
|
||||
src['library_name']).get(src['artist_name']).album(
|
||||
src['album_name']).get(src['track_name'])
|
||||
elif media_type == 'EPISODE':
|
||||
|
@ -765,9 +760,9 @@ class PlexClient(MediaPlayerDevice):
|
|||
src['library_name'], src['show_name'],
|
||||
src['season_number'], src['episode_number'])
|
||||
elif media_type == 'PLAYLIST':
|
||||
media = self.device.server.playlist(src['playlist_name'])
|
||||
media = self._device.server.playlist(src['playlist_name'])
|
||||
elif media_type == 'VIDEO':
|
||||
media = self.device.server.library.section(
|
||||
media = self._device.server.library.section(
|
||||
src['library_name']).get(src['video_name'])
|
||||
|
||||
import plexapi.playlist
|
||||
|
@ -785,13 +780,13 @@ class PlexClient(MediaPlayerDevice):
|
|||
target_season = None
|
||||
target_episode = None
|
||||
|
||||
show = self.device.server.library.section(library_name).get(
|
||||
show = self._device.server.library.section(library_name).get(
|
||||
show_name)
|
||||
|
||||
if not season_number:
|
||||
playlist_name = "{} - {} Episodes".format(
|
||||
self.entity_id, show_name)
|
||||
return self.device.server.createPlaylist(
|
||||
return self._device.server.createPlaylist(
|
||||
playlist_name, show.episodes())
|
||||
|
||||
for season in show.seasons():
|
||||
|
@ -808,7 +803,7 @@ class PlexClient(MediaPlayerDevice):
|
|||
if not episode_number:
|
||||
playlist_name = "{} - {} Season {} Episodes".format(
|
||||
self.entity_id, show_name, str(season_number))
|
||||
return self.device.server.createPlaylist(
|
||||
return self._device.server.createPlaylist(
|
||||
playlist_name, target_season.episodes())
|
||||
|
||||
for episode in target_season.episodes():
|
||||
|
@ -826,22 +821,22 @@ class PlexClient(MediaPlayerDevice):
|
|||
|
||||
def _client_play_media(self, media, delete=False, **params):
|
||||
"""Instruct Plex client to play a piece of media."""
|
||||
if not (self.device and
|
||||
if not (self._device and
|
||||
'playback' in self._device_protocol_capabilities):
|
||||
_LOGGER.error("Client cannot play media: %s", self.entity_id)
|
||||
return
|
||||
|
||||
import plexapi.playqueue
|
||||
playqueue = plexapi.playqueue.PlayQueue.create(
|
||||
self.device.server, media, **params)
|
||||
self._device.server, media, **params)
|
||||
|
||||
# Delete dynamic playlists used to build playqueue (ex. play tv season)
|
||||
if delete:
|
||||
media.delete()
|
||||
|
||||
server_url = self.device.server.baseurl.split(':')
|
||||
self.device.sendCommand('playback/playMedia', **dict({
|
||||
'machineIdentifier': self.device.server.machineIdentifier,
|
||||
server_url = self._device.server.baseurl.split(':')
|
||||
self._device.sendCommand('playback/playMedia', **dict({
|
||||
'machineIdentifier': self._device.server.machineIdentifier,
|
||||
'address': server_url[1].strip('/'),
|
||||
'port': server_url[-1],
|
||||
'key': media.key,
|
||||
|
|
|
@ -166,11 +166,6 @@ class SoundTouchDevice(MediaPlayerDevice):
|
|||
"""Return specific soundtouch configuration."""
|
||||
return self._config
|
||||
|
||||
@property
|
||||
def device(self):
|
||||
"""Return Soundtouch device."""
|
||||
return self._device
|
||||
|
||||
def update(self):
|
||||
"""Retrieve the latest data."""
|
||||
self._status = self._device.status()
|
||||
|
@ -323,8 +318,8 @@ class SoundTouchDevice(MediaPlayerDevice):
|
|||
_LOGGER.warning("Unable to create zone without slaves")
|
||||
else:
|
||||
_LOGGER.info("Creating zone with master %s",
|
||||
self.device.config.name)
|
||||
self.device.create_zone([slave.device for slave in slaves])
|
||||
self._device.config.name)
|
||||
self._device.create_zone([slave.device for slave in slaves])
|
||||
|
||||
def remove_zone_slave(self, slaves):
|
||||
"""
|
||||
|
@ -341,8 +336,8 @@ class SoundTouchDevice(MediaPlayerDevice):
|
|||
_LOGGER.warning("Unable to find slaves to remove")
|
||||
else:
|
||||
_LOGGER.info("Removing slaves from zone with master %s",
|
||||
self.device.config.name)
|
||||
self.device.remove_zone_slave([slave.device for slave in slaves])
|
||||
self._device.config.name)
|
||||
self._device.remove_zone_slave([slave.device for slave in slaves])
|
||||
|
||||
def add_zone_slave(self, slaves):
|
||||
"""
|
||||
|
@ -357,5 +352,5 @@ class SoundTouchDevice(MediaPlayerDevice):
|
|||
_LOGGER.warning("Unable to find slaves to add")
|
||||
else:
|
||||
_LOGGER.info("Adding slaves to zone with master %s",
|
||||
self.device.config.name)
|
||||
self.device.add_zone_slave([slave.device for slave in slaves])
|
||||
self._device.config.name)
|
||||
self._device.add_zone_slave([slave.device for slave in slaves])
|
||||
|
|
|
@ -282,12 +282,12 @@ class NestSensorDevice(Entity):
|
|||
|
||||
if device is not None:
|
||||
# device specific
|
||||
self.device = device
|
||||
self._name = "{} {}".format(self.device.name_long,
|
||||
self._device = device
|
||||
self._name = "{} {}".format(self._device.name_long,
|
||||
self.variable.replace('_', ' '))
|
||||
else:
|
||||
# structure only
|
||||
self.device = structure
|
||||
self._device = structure
|
||||
self._name = "{} {}".format(self.structure.name,
|
||||
self.variable.replace('_', ' '))
|
||||
|
||||
|
|
|
@ -61,13 +61,13 @@ class KNXNotificationService(BaseNotificationService):
|
|||
|
||||
def __init__(self, devices):
|
||||
"""Initialize the service."""
|
||||
self.devices = devices
|
||||
self._devices = devices
|
||||
|
||||
@property
|
||||
def targets(self):
|
||||
"""Return a dictionary of registered targets."""
|
||||
ret = {}
|
||||
for device in self.devices:
|
||||
for device in self._devices:
|
||||
ret[device.name] = device.name
|
||||
return ret
|
||||
|
||||
|
@ -80,11 +80,11 @@ class KNXNotificationService(BaseNotificationService):
|
|||
|
||||
async def _async_send_to_all_devices(self, message):
|
||||
"""Send a notification to knx bus to all connected devices."""
|
||||
for device in self.devices:
|
||||
for device in self._devices:
|
||||
await device.set(message)
|
||||
|
||||
async def _async_send_to_device(self, message, names):
|
||||
"""Send a notification to knx bus to device with given names."""
|
||||
for device in self.devices:
|
||||
for device in self._devices:
|
||||
if device.name in names:
|
||||
await device.set(message)
|
||||
|
|
|
@ -98,13 +98,13 @@ class QSToggleEntity(QSEntity):
|
|||
|
||||
def __init__(self, qsid, qsusb):
|
||||
"""Initialize the ToggleEntity."""
|
||||
self.device = qsusb.devices[qsid]
|
||||
super().__init__(qsid, self.device.name)
|
||||
self._device = qsusb.devices[qsid]
|
||||
super().__init__(qsid, self._device.name)
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Check if device is on (non-zero)."""
|
||||
return self.device.value > 0
|
||||
return self._device.value > 0
|
||||
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Turn the device on."""
|
||||
|
|
|
@ -187,11 +187,6 @@ class XiaomiMiioRemote(RemoteDevice):
|
|||
"""Return the name of the remote."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def device(self):
|
||||
"""Return the remote object."""
|
||||
return self._device
|
||||
|
||||
@property
|
||||
def hidden(self):
|
||||
"""Return if we should hide entity."""
|
||||
|
@ -212,7 +207,7 @@ class XiaomiMiioRemote(RemoteDevice):
|
|||
"""Return False if device is unreachable, else True."""
|
||||
from miio import DeviceException
|
||||
try:
|
||||
self.device.info()
|
||||
self._device.info()
|
||||
return True
|
||||
except DeviceException:
|
||||
return False
|
||||
|
@ -247,7 +242,7 @@ class XiaomiMiioRemote(RemoteDevice):
|
|||
|
||||
_LOGGER.debug("Sending payload: '%s'", payload)
|
||||
try:
|
||||
self.device.play(payload)
|
||||
self._device.play(payload)
|
||||
except DeviceException as ex:
|
||||
_LOGGER.error(
|
||||
"Transmit of IR command failed, %s, exception: %s",
|
||||
|
|
|
@ -49,14 +49,14 @@ class JuicenetSensorDevice(JuicenetDevice, Entity):
|
|||
@property
|
||||
def name(self):
|
||||
"""Return the name of the device."""
|
||||
return '{} {}'.format(self.device.name(), self._name)
|
||||
return '{} {}'.format(self._device.name(), self._name)
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon of the sensor."""
|
||||
icon = None
|
||||
if self.type == 'status':
|
||||
status = self.device.getStatus()
|
||||
status = self._device.getStatus()
|
||||
if status == 'standby':
|
||||
icon = 'mdi:power-plug-off'
|
||||
elif status == 'plugged':
|
||||
|
@ -87,19 +87,19 @@ class JuicenetSensorDevice(JuicenetDevice, Entity):
|
|||
"""Return the state."""
|
||||
state = None
|
||||
if self.type == 'status':
|
||||
state = self.device.getStatus()
|
||||
state = self._device.getStatus()
|
||||
elif self.type == 'temperature':
|
||||
state = self.device.getTemperature()
|
||||
state = self._device.getTemperature()
|
||||
elif self.type == 'voltage':
|
||||
state = self.device.getVoltage()
|
||||
state = self._device.getVoltage()
|
||||
elif self.type == 'amps':
|
||||
state = self.device.getAmps()
|
||||
state = self._device.getAmps()
|
||||
elif self.type == 'watts':
|
||||
state = self.device.getWatts()
|
||||
state = self._device.getWatts()
|
||||
elif self.type == 'charge_time':
|
||||
state = self.device.getChargeTime()
|
||||
state = self._device.getChargeTime()
|
||||
elif self.type == 'energy_added':
|
||||
state = self.device.getEnergyAdded()
|
||||
state = self._device.getEnergyAdded()
|
||||
else:
|
||||
state = 'Unknown'
|
||||
return state
|
||||
|
@ -109,7 +109,7 @@ class JuicenetSensorDevice(JuicenetDevice, Entity):
|
|||
"""Return the state attributes."""
|
||||
attributes = {}
|
||||
if self.type == 'status':
|
||||
man_dev_id = self.device.id()
|
||||
man_dev_id = self._device.id()
|
||||
if man_dev_id:
|
||||
attributes["manufacturer_device_id"] = man_dev_id
|
||||
return attributes
|
||||
|
|
|
@ -64,7 +64,7 @@ class KNXSensor(Entity):
|
|||
|
||||
def __init__(self, hass, device):
|
||||
"""Initialize of a KNX sensor."""
|
||||
self.device = device
|
||||
self._device = device
|
||||
self.hass = hass
|
||||
self.async_register_callbacks()
|
||||
|
||||
|
@ -74,12 +74,12 @@ class KNXSensor(Entity):
|
|||
async def after_update_callback(device):
|
||||
"""Call after device was updated."""
|
||||
await self.async_update_ha_state()
|
||||
self.device.register_device_updated_cb(after_update_callback)
|
||||
self._device.register_device_updated_cb(after_update_callback)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the KNX device."""
|
||||
return self.device.name
|
||||
return self._device.name
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
@ -94,12 +94,12 @@ class KNXSensor(Entity):
|
|||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self.device.resolve_state()
|
||||
return self._device.resolve_state()
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit this state is expressed in."""
|
||||
return self.device.unit_of_measurement()
|
||||
return self._device.unit_of_measurement()
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
|
|
|
@ -140,15 +140,15 @@ class NestBasicSensor(NestSensorDevice):
|
|||
self._unit = SENSOR_UNITS.get(self.variable)
|
||||
|
||||
if self.variable in VARIABLE_NAME_MAPPING:
|
||||
self._state = getattr(self.device,
|
||||
self._state = getattr(self._device,
|
||||
VARIABLE_NAME_MAPPING[self.variable])
|
||||
elif self.variable in PROTECT_SENSOR_TYPES \
|
||||
and self.variable != 'color_status':
|
||||
# keep backward compatibility
|
||||
state = getattr(self.device, self.variable)
|
||||
state = getattr(self._device, self.variable)
|
||||
self._state = state.capitalize() if state is not None else None
|
||||
else:
|
||||
self._state = getattr(self.device, self.variable)
|
||||
self._state = getattr(self._device, self.variable)
|
||||
|
||||
|
||||
class NestTempSensor(NestSensorDevice):
|
||||
|
@ -166,12 +166,12 @@ class NestTempSensor(NestSensorDevice):
|
|||
|
||||
def update(self):
|
||||
"""Retrieve latest state."""
|
||||
if self.device.temperature_scale == 'C':
|
||||
if self._device.temperature_scale == 'C':
|
||||
self._unit = TEMP_CELSIUS
|
||||
else:
|
||||
self._unit = TEMP_FAHRENHEIT
|
||||
|
||||
temp = getattr(self.device, self.variable)
|
||||
temp = getattr(self._device, self.variable)
|
||||
if temp is None:
|
||||
self._state = None
|
||||
|
||||
|
|
|
@ -79,15 +79,10 @@ class TankUtilitySensor(Entity):
|
|||
self._token = token
|
||||
self._device = device
|
||||
self._state = STATE_UNKNOWN
|
||||
self._name = "Tank Utility " + self.device
|
||||
self._name = "Tank Utility " + self._device
|
||||
self._unit_of_measurement = SENSOR_UNIT_OF_MEASUREMENT
|
||||
self._attributes = {}
|
||||
|
||||
@property
|
||||
def device(self):
|
||||
"""Return the device identifier."""
|
||||
return self._device
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the device."""
|
||||
|
@ -117,14 +112,14 @@ class TankUtilitySensor(Entity):
|
|||
from tank_utility import auth, device
|
||||
data = {}
|
||||
try:
|
||||
data = device.get_device_data(self._token, self.device)
|
||||
data = device.get_device_data(self._token, self._device)
|
||||
except requests.exceptions.HTTPError as http_error:
|
||||
if (http_error.response.status_code ==
|
||||
requests.codes.unauthorized): # pylint: disable=no-member
|
||||
_LOGGER.info("Getting new token")
|
||||
self._token = auth.get_token(self._email, self._password,
|
||||
force=True)
|
||||
data = device.get_device_data(self._token, self.device)
|
||||
data = device.get_device_data(self._token, self._device)
|
||||
else:
|
||||
raise http_error
|
||||
data.update(data.pop("device", {}))
|
||||
|
|
|
@ -67,7 +67,7 @@ class TelldusLiveSensor(TelldusLiveEntity):
|
|||
@property
|
||||
def _value(self):
|
||||
"""Return value of the sensor."""
|
||||
return self.device.value(*self._id[1:])
|
||||
return self._device.value(*self._id[1:])
|
||||
|
||||
@property
|
||||
def _value_as_temperature(self):
|
||||
|
|
|
@ -63,7 +63,7 @@ class KNXSwitch(SwitchDevice):
|
|||
|
||||
def __init__(self, hass, device):
|
||||
"""Initialize of KNX switch."""
|
||||
self.device = device
|
||||
self._device = device
|
||||
self.hass = hass
|
||||
self.async_register_callbacks()
|
||||
|
||||
|
@ -73,12 +73,12 @@ class KNXSwitch(SwitchDevice):
|
|||
async def after_update_callback(device):
|
||||
"""Call after device was updated."""
|
||||
await self.async_update_ha_state()
|
||||
self.device.register_device_updated_cb(after_update_callback)
|
||||
self._device.register_device_updated_cb(after_update_callback)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the KNX device."""
|
||||
return self.device.name
|
||||
return self._device.name
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
@ -93,12 +93,12 @@ class KNXSwitch(SwitchDevice):
|
|||
@property
|
||||
def is_on(self):
|
||||
"""Return true if device is on."""
|
||||
return self.device.state
|
||||
return self._device.state
|
||||
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Turn the device on."""
|
||||
await self.device.set_on()
|
||||
await self._device.set_on()
|
||||
|
||||
async def async_turn_off(self, **kwargs):
|
||||
"""Turn the device off."""
|
||||
await self.device.set_off()
|
||||
await self._device.set_off()
|
||||
|
|
|
@ -48,7 +48,7 @@ class MochadSwitch(SwitchDevice):
|
|||
self._address = dev[CONF_ADDRESS]
|
||||
self._name = dev.get(CONF_NAME, 'x10_switch_dev_%s' % self._address)
|
||||
self._comm_type = dev.get(mochad.CONF_COMM_TYPE, 'pl')
|
||||
self.device = device.Device(ctrl, self._address,
|
||||
self.switch = device.Device(ctrl, self._address,
|
||||
comm_type=self._comm_type)
|
||||
# Init with false to avoid locking HA for long on CM19A (goes from rf
|
||||
# to pl via TM751, but not other way around)
|
||||
|
@ -71,7 +71,7 @@ class MochadSwitch(SwitchDevice):
|
|||
try:
|
||||
# Recycle socket on new command to recover mochad connection
|
||||
self._controller.reconnect()
|
||||
self.device.send_cmd('on')
|
||||
self.switch.send_cmd('on')
|
||||
# No read data on CM19A which is rf only
|
||||
if self._comm_type == 'pl':
|
||||
self._controller.read_data()
|
||||
|
@ -88,7 +88,7 @@ class MochadSwitch(SwitchDevice):
|
|||
try:
|
||||
# Recycle socket on new command to recover mochad connection
|
||||
self._controller.reconnect()
|
||||
self.device.send_cmd('off')
|
||||
self.switch.send_cmd('off')
|
||||
# No read data on CM19A which is rf only
|
||||
if self._comm_type == 'pl':
|
||||
self._controller.read_data()
|
||||
|
@ -99,7 +99,7 @@ class MochadSwitch(SwitchDevice):
|
|||
def _get_device_status(self):
|
||||
"""Get the status of the switch from mochad."""
|
||||
with mochad.REQ_LOCK:
|
||||
status = self.device.get_status().rstrip()
|
||||
status = self.switch.get_status().rstrip()
|
||||
return status == 'on'
|
||||
|
||||
@property
|
||||
|
|
|
@ -28,14 +28,14 @@ class TelldusLiveSwitch(TelldusLiveEntity, ToggleEntity):
|
|||
@property
|
||||
def is_on(self):
|
||||
"""Return true if switch is on."""
|
||||
return self.device.is_on
|
||||
return self._device.is_on
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn the switch on."""
|
||||
self.device.turn_on()
|
||||
self._device.turn_on()
|
||||
self.changed()
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn the switch off."""
|
||||
self.device.turn_off()
|
||||
self._device.turn_off()
|
||||
self.changed()
|
||||
|
|
|
@ -287,13 +287,14 @@ class TelldusLiveEntity(Entity):
|
|||
self._id = device_id
|
||||
self._client = hass.data[DOMAIN]
|
||||
self._client.entities.append(self)
|
||||
self._name = self.device.name
|
||||
self._device = self._client.device(device_id)
|
||||
self._name = self._device.name
|
||||
_LOGGER.debug('Created device %s', self)
|
||||
|
||||
def changed(self):
|
||||
"""Return the property of the device might have changed."""
|
||||
if self.device.name:
|
||||
self._name = self.device.name
|
||||
if self._device.name:
|
||||
self._name = self._device.name
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
@property
|
||||
|
@ -301,15 +302,10 @@ class TelldusLiveEntity(Entity):
|
|||
"""Return the id of the device."""
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def device(self):
|
||||
"""Return the representation of the device."""
|
||||
return self._client.device(self.device_id)
|
||||
|
||||
@property
|
||||
def _state(self):
|
||||
"""Return the state of the device."""
|
||||
return self.device.state
|
||||
return self._device.state
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
|
@ -347,16 +343,16 @@ class TelldusLiveEntity(Entity):
|
|||
from tellduslive import (BATTERY_LOW,
|
||||
BATTERY_UNKNOWN,
|
||||
BATTERY_OK)
|
||||
if self.device.battery == BATTERY_LOW:
|
||||
if self._device.battery == BATTERY_LOW:
|
||||
return 1
|
||||
if self.device.battery == BATTERY_UNKNOWN:
|
||||
if self._device.battery == BATTERY_UNKNOWN:
|
||||
return None
|
||||
if self.device.battery == BATTERY_OK:
|
||||
if self._device.battery == BATTERY_OK:
|
||||
return 100
|
||||
return self.device.battery # Percentage
|
||||
return self._device.battery # Percentage
|
||||
|
||||
@property
|
||||
def _last_updated(self):
|
||||
"""Return the last update of a device."""
|
||||
return str(datetime.fromtimestamp(self.device.lastUpdated)) \
|
||||
if self.device.lastUpdated else None
|
||||
return str(datetime.fromtimestamp(self._device.lastUpdated)) \
|
||||
if self._device.lastUpdated else None
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
"""Provide a way to connect entities belonging to one device."""
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
import attr
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.loader import bind_hass
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DATA_REGISTRY = 'device_registry'
|
||||
|
||||
STORAGE_KEY = 'core.device_registry'
|
||||
STORAGE_VERSION = 1
|
||||
SAVE_DELAY = 10
|
||||
|
||||
|
||||
@attr.s(slots=True, frozen=True)
|
||||
class DeviceEntry:
|
||||
"""Device Registry Entry."""
|
||||
|
||||
identifiers = attr.ib(type=list)
|
||||
manufacturer = attr.ib(type=str)
|
||||
model = attr.ib(type=str)
|
||||
connection = attr.ib(type=list)
|
||||
name = attr.ib(type=str, default=None)
|
||||
sw_version = attr.ib(type=str, default=None)
|
||||
id = attr.ib(type=str, default=attr.Factory(lambda: uuid.uuid4().hex))
|
||||
|
||||
|
||||
class DeviceRegistry:
|
||||
"""Class to hold a registry of devices."""
|
||||
|
||||
def __init__(self, hass):
|
||||
"""Initialize the device registry."""
|
||||
self.hass = hass
|
||||
self.devices = None
|
||||
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY)
|
||||
|
||||
@callback
|
||||
def async_get_device(self, identifiers: str, connections: tuple):
|
||||
"""Check if device is registered."""
|
||||
for device in self.devices:
|
||||
if any(iden in device.identifiers for iden in identifiers) or \
|
||||
any(conn in device.connection for conn in connections):
|
||||
return device
|
||||
return None
|
||||
|
||||
@callback
|
||||
def async_get_or_create(self, identifiers, manufacturer, model,
|
||||
connection, *, name=None, sw_version=None):
|
||||
"""Get device. Create if it doesn't exist."""
|
||||
device = self.async_get_device(identifiers, connection)
|
||||
|
||||
if device is not None:
|
||||
return device
|
||||
|
||||
device = DeviceEntry(
|
||||
identifiers=identifiers,
|
||||
manufacturer=manufacturer,
|
||||
model=model,
|
||||
connection=connection,
|
||||
name=name,
|
||||
sw_version=sw_version
|
||||
)
|
||||
|
||||
self.devices.append(device)
|
||||
self.async_schedule_save()
|
||||
|
||||
return device
|
||||
|
||||
async def async_load(self):
|
||||
"""Load the device registry."""
|
||||
devices = await self._store.async_load()
|
||||
|
||||
if devices is None:
|
||||
self.devices = []
|
||||
return
|
||||
|
||||
self.devices = [DeviceEntry(**device) for device in devices['devices']]
|
||||
|
||||
@callback
|
||||
def async_schedule_save(self):
|
||||
"""Schedule saving the device registry."""
|
||||
self._store.async_delay_save(self._data_to_save, SAVE_DELAY)
|
||||
|
||||
@callback
|
||||
def _data_to_save(self):
|
||||
"""Data of device registry to store in a file."""
|
||||
data = {}
|
||||
|
||||
data['devices'] = [
|
||||
{
|
||||
'id': entry.id,
|
||||
'identifiers': entry.identifiers,
|
||||
'manufacturer': entry.manufacturer,
|
||||
'model': entry.model,
|
||||
'connection': entry.connection,
|
||||
'name': entry.name,
|
||||
'sw_version': entry.sw_version,
|
||||
} for entry in self.devices
|
||||
]
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@bind_hass
|
||||
async def async_get_registry(hass) -> DeviceRegistry:
|
||||
"""Return device registry instance."""
|
||||
task = hass.data.get(DATA_REGISTRY)
|
||||
|
||||
if task is None:
|
||||
async def _load_reg():
|
||||
registry = DeviceRegistry(hass)
|
||||
await registry.async_load()
|
||||
return registry
|
||||
|
||||
task = hass.data[DATA_REGISTRY] = hass.async_create_task(_load_reg())
|
||||
|
||||
return await task
|
|
@ -130,6 +130,14 @@ class Entity:
|
|||
"""
|
||||
return None
|
||||
|
||||
@property
|
||||
def device(self):
|
||||
"""Return device specific attributes.
|
||||
|
||||
Implemented by platform classes.
|
||||
"""
|
||||
return None
|
||||
|
||||
@property
|
||||
def device_class(self) -> str:
|
||||
"""Return the class of this device, from component DEVICE_CLASSES."""
|
||||
|
|
|
@ -8,7 +8,6 @@ from homeassistant.util.async_ import (
|
|||
run_callback_threadsafe, run_coroutine_threadsafe)
|
||||
|
||||
from .event import async_track_time_interval, async_call_later
|
||||
from .entity_registry import async_get_registry
|
||||
|
||||
SLOW_SETUP_WARNING = 10
|
||||
SLOW_SETUP_MAX_WAIT = 60
|
||||
|
@ -209,11 +208,14 @@ class EntityPlatform:
|
|||
hass = self.hass
|
||||
component_entities = set(hass.states.async_entity_ids(self.domain))
|
||||
|
||||
registry = await async_get_registry(hass)
|
||||
|
||||
device_registry = await \
|
||||
hass.helpers.device_registry.async_get_registry()
|
||||
entity_registry = await \
|
||||
hass.helpers.entity_registry.async_get_registry()
|
||||
tasks = [
|
||||
self._async_add_entity(entity, update_before_add,
|
||||
component_entities, registry)
|
||||
component_entities, entity_registry,
|
||||
device_registry)
|
||||
for entity in new_entities]
|
||||
|
||||
# No entities for processing
|
||||
|
@ -233,7 +235,8 @@ class EntityPlatform:
|
|||
)
|
||||
|
||||
async def _async_add_entity(self, entity, update_before_add,
|
||||
component_entities, registry):
|
||||
component_entities, entity_registry,
|
||||
device_registry):
|
||||
"""Helper method to add an entity to the platform."""
|
||||
if entity is None:
|
||||
raise ValueError('Entity cannot be None')
|
||||
|
@ -269,10 +272,21 @@ class EntityPlatform:
|
|||
else:
|
||||
config_entry_id = None
|
||||
|
||||
entry = registry.async_get_or_create(
|
||||
device = entity.device
|
||||
if device is not None:
|
||||
device = device_registry.async_get_or_create(
|
||||
device['identifiers'], device['manufacturer'],
|
||||
device['model'], device['connection'],
|
||||
sw_version=device.get('sw_version'))
|
||||
device_id = device.id
|
||||
else:
|
||||
device_id = None
|
||||
|
||||
entry = entity_registry.async_get_or_create(
|
||||
self.domain, self.platform_name, entity.unique_id,
|
||||
suggested_object_id=suggested_object_id,
|
||||
config_entry_id=config_entry_id)
|
||||
config_entry_id=config_entry_id,
|
||||
device_id=device_id)
|
||||
|
||||
if entry.disabled:
|
||||
self.logger.info(
|
||||
|
@ -288,7 +302,7 @@ class EntityPlatform:
|
|||
# We won't generate an entity ID if the platform has already set one
|
||||
# We will however make sure that platform cannot pick a registered ID
|
||||
elif (entity.entity_id is not None and
|
||||
registry.async_is_registered(entity.entity_id)):
|
||||
entity_registry.async_is_registered(entity.entity_id)):
|
||||
# If entity already registered, convert entity id to suggestion
|
||||
suggested_object_id = split_entity_id(entity.entity_id)[1]
|
||||
entity.entity_id = None
|
||||
|
@ -302,7 +316,7 @@ class EntityPlatform:
|
|||
suggested_object_id = '{} {}'.format(self.entity_namespace,
|
||||
suggested_object_id)
|
||||
|
||||
entity.entity_id = registry.async_generate_entity_id(
|
||||
entity.entity_id = entity_registry.async_generate_entity_id(
|
||||
self.domain, suggested_object_id)
|
||||
|
||||
# Make sure it is valid in case an entity set the value themselves
|
||||
|
|
|
@ -39,6 +39,7 @@ class RegistryEntry:
|
|||
unique_id = attr.ib(type=str)
|
||||
platform = attr.ib(type=str)
|
||||
name = attr.ib(type=str, default=None)
|
||||
device_id = attr.ib(type=str, default=None)
|
||||
config_entry_id = attr.ib(type=str, default=None)
|
||||
disabled_by = attr.ib(
|
||||
type=str, default=None,
|
||||
|
@ -107,7 +108,8 @@ class EntityRegistry:
|
|||
|
||||
@callback
|
||||
def async_get_or_create(self, domain, platform, unique_id, *,
|
||||
suggested_object_id=None, config_entry_id=None):
|
||||
suggested_object_id=None, config_entry_id=None,
|
||||
device_id=None):
|
||||
"""Get entity. Create if it doesn't exist."""
|
||||
entity_id = self.async_get_entity_id(domain, platform, unique_id)
|
||||
if entity_id:
|
||||
|
@ -116,7 +118,8 @@ class EntityRegistry:
|
|||
return entry
|
||||
|
||||
self._async_update_entity(
|
||||
entity_id, config_entry_id=config_entry_id)
|
||||
entity_id, config_entry_id=config_entry_id,
|
||||
device_id=device_id)
|
||||
return self.entities[entity_id]
|
||||
|
||||
entity_id = self.async_generate_entity_id(
|
||||
|
@ -125,6 +128,7 @@ class EntityRegistry:
|
|||
entity = RegistryEntry(
|
||||
entity_id=entity_id,
|
||||
config_entry_id=config_entry_id,
|
||||
device_id=device_id,
|
||||
unique_id=unique_id,
|
||||
platform=platform,
|
||||
)
|
||||
|
@ -146,7 +150,8 @@ class EntityRegistry:
|
|||
|
||||
@callback
|
||||
def _async_update_entity(self, entity_id, *, name=_UNDEF,
|
||||
config_entry_id=_UNDEF, new_entity_id=_UNDEF):
|
||||
config_entry_id=_UNDEF, new_entity_id=_UNDEF,
|
||||
device_id=_UNDEF):
|
||||
"""Private facing update properties method."""
|
||||
old = self.entities[entity_id]
|
||||
|
||||
|
@ -159,6 +164,9 @@ class EntityRegistry:
|
|||
config_entry_id != old.config_entry_id):
|
||||
changes['config_entry_id'] = config_entry_id
|
||||
|
||||
if (device_id is not _UNDEF and device_id != old.device_id):
|
||||
changes['device_id'] = device_id
|
||||
|
||||
if new_entity_id is not _UNDEF and new_entity_id != old.entity_id:
|
||||
if self.async_is_registered(new_entity_id):
|
||||
raise ValueError('Entity is already registered')
|
||||
|
@ -210,6 +218,7 @@ class EntityRegistry:
|
|||
entities[entity['entity_id']] = RegistryEntry(
|
||||
entity_id=entity['entity_id'],
|
||||
config_entry_id=entity.get('config_entry_id'),
|
||||
device_id=entity.get('device_id'),
|
||||
unique_id=entity['unique_id'],
|
||||
platform=entity['platform'],
|
||||
name=entity.get('name'),
|
||||
|
@ -232,6 +241,7 @@ class EntityRegistry:
|
|||
{
|
||||
'entity_id': entry.entity_id,
|
||||
'config_entry_id': entry.config_entry_id,
|
||||
'device_id': entry.device_id,
|
||||
'unique_id': entry.unique_id,
|
||||
'platform': entry.platform,
|
||||
'name': entry.name,
|
||||
|
|
|
@ -76,18 +76,18 @@ class TestMochadLight(unittest.TestCase):
|
|||
def test_turn_on_with_no_brightness(self):
|
||||
"""Test turn_on."""
|
||||
self.light.turn_on()
|
||||
self.light.device.send_cmd.assert_called_once_with('on')
|
||||
self.light.light.send_cmd.assert_called_once_with('on')
|
||||
|
||||
def test_turn_on_with_brightness(self):
|
||||
"""Test turn_on."""
|
||||
self.light.turn_on(brightness=45)
|
||||
self.light.device.send_cmd.assert_has_calls(
|
||||
self.light.light.send_cmd.assert_has_calls(
|
||||
[mock.call('on'), mock.call('dim 25')])
|
||||
|
||||
def test_turn_off(self):
|
||||
"""Test turn_off."""
|
||||
self.light.turn_off()
|
||||
self.light.device.send_cmd.assert_called_once_with('off')
|
||||
self.light.light.send_cmd.assert_called_once_with('off')
|
||||
|
||||
|
||||
class TestMochadLight256Levels(unittest.TestCase):
|
||||
|
@ -109,17 +109,17 @@ class TestMochadLight256Levels(unittest.TestCase):
|
|||
def test_turn_on_with_no_brightness(self):
|
||||
"""Test turn_on."""
|
||||
self.light.turn_on()
|
||||
self.light.device.send_cmd.assert_called_once_with('xdim 255')
|
||||
self.light.light.send_cmd.assert_called_once_with('xdim 255')
|
||||
|
||||
def test_turn_on_with_brightness(self):
|
||||
"""Test turn_on."""
|
||||
self.light.turn_on(brightness=45)
|
||||
self.light.device.send_cmd.assert_called_once_with('xdim 45')
|
||||
self.light.light.send_cmd.assert_called_once_with('xdim 45')
|
||||
|
||||
def test_turn_off(self):
|
||||
"""Test turn_off."""
|
||||
self.light.turn_off()
|
||||
self.light.device.send_cmd.assert_called_once_with('off')
|
||||
self.light.light.send_cmd.assert_called_once_with('off')
|
||||
|
||||
|
||||
class TestMochadLight64Levels(unittest.TestCase):
|
||||
|
@ -141,14 +141,14 @@ class TestMochadLight64Levels(unittest.TestCase):
|
|||
def test_turn_on_with_no_brightness(self):
|
||||
"""Test turn_on."""
|
||||
self.light.turn_on()
|
||||
self.light.device.send_cmd.assert_called_once_with('xdim 63')
|
||||
self.light.light.send_cmd.assert_called_once_with('xdim 63')
|
||||
|
||||
def test_turn_on_with_brightness(self):
|
||||
"""Test turn_on."""
|
||||
self.light.turn_on(brightness=45)
|
||||
self.light.device.send_cmd.assert_called_once_with('xdim 11')
|
||||
self.light.light.send_cmd.assert_called_once_with('xdim 11')
|
||||
|
||||
def test_turn_off(self):
|
||||
"""Test turn_off."""
|
||||
self.light.turn_off()
|
||||
self.light.device.send_cmd.assert_called_once_with('off')
|
||||
self.light.light.send_cmd.assert_called_once_with('off')
|
||||
|
|
|
@ -76,9 +76,9 @@ class TestMochadSwitch(unittest.TestCase):
|
|||
def test_turn_on(self):
|
||||
"""Test turn_on."""
|
||||
self.switch.turn_on()
|
||||
self.switch.device.send_cmd.assert_called_once_with('on')
|
||||
self.switch.switch.send_cmd.assert_called_once_with('on')
|
||||
|
||||
def test_turn_off(self):
|
||||
"""Test turn_off."""
|
||||
self.switch.turn_off()
|
||||
self.switch.device.send_cmd.assert_called_once_with('off')
|
||||
self.switch.switch.send_cmd.assert_called_once_with('off')
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
"""Tests for the Device Registry."""
|
||||
import pytest
|
||||
|
||||
from homeassistant.helpers import device_registry
|
||||
|
||||
|
||||
def mock_registry(hass, mock_entries=None):
|
||||
"""Mock the Device Registry."""
|
||||
registry = device_registry.DeviceRegistry(hass)
|
||||
registry.devices = mock_entries or []
|
||||
|
||||
async def _get_reg():
|
||||
return registry
|
||||
|
||||
hass.data[device_registry.DATA_REGISTRY] = \
|
||||
hass.loop.create_task(_get_reg())
|
||||
return registry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def registry(hass):
|
||||
"""Return an empty, loaded, registry."""
|
||||
return mock_registry(hass)
|
||||
|
||||
|
||||
async def test_get_or_create_returns_same_entry(registry):
|
||||
"""Make sure we do not duplicate entries."""
|
||||
entry = registry.async_get_or_create(
|
||||
[['bridgeid', '0123']], 'manufacturer', 'model',
|
||||
[['ethernet', '12:34:56:78:90:AB:CD:EF']])
|
||||
entry2 = registry.async_get_or_create(
|
||||
[['bridgeid', '0123']], 'manufacturer', 'model',
|
||||
[['ethernet', '11:22:33:44:55:66:77:88']])
|
||||
entry3 = registry.async_get_or_create(
|
||||
[['bridgeid', '1234']], 'manufacturer', 'model',
|
||||
[['ethernet', '12:34:56:78:90:AB:CD:EF']])
|
||||
|
||||
assert len(registry.devices) == 1
|
||||
assert entry is entry2
|
||||
assert entry is entry3
|
||||
assert entry.identifiers == [['bridgeid', '0123']]
|
||||
|
||||
|
||||
async def test_loading_from_storage(hass, hass_storage):
|
||||
"""Test loading stored devices on start."""
|
||||
hass_storage[device_registry.STORAGE_KEY] = {
|
||||
'version': device_registry.STORAGE_VERSION,
|
||||
'data': {
|
||||
'devices': [
|
||||
{
|
||||
'connection': [
|
||||
[
|
||||
'Zigbee',
|
||||
'01.23.45.67.89'
|
||||
]
|
||||
],
|
||||
'id': 'abcdefghijklm',
|
||||
'identifiers': [
|
||||
[
|
||||
'serial',
|
||||
'12:34:56:78:90:AB:CD:EF'
|
||||
]
|
||||
],
|
||||
'manufacturer': 'manufacturer',
|
||||
'model': 'model',
|
||||
'name': 'name',
|
||||
'sw_version': 'version'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
registry = await device_registry.async_get_registry(hass)
|
||||
|
||||
entry = registry.async_get_or_create(
|
||||
[['serial', '12:34:56:78:90:AB:CD:EF']], 'manufacturer',
|
||||
'model', [['Zigbee', '01.23.45.67.89']])
|
||||
assert entry.id == 'abcdefghijklm'
|
Loading…
Reference in New Issue