Support for the Quirky Nimbus (#16520)
* Support for quriky nimbu * Fixed lint * fixed some typospull/16253/merge
parent
aec134c47a
commit
f43d9ba680
|
@ -118,7 +118,7 @@ class WinkThermostat(WinkDevice, ClimateDevice):
|
|||
self.hass, self.target_temperature_low, self.temperature_unit,
|
||||
PRECISION_TENTHS)
|
||||
|
||||
if self.external_temperature:
|
||||
if self.external_temperature is not None:
|
||||
data[ATTR_EXTERNAL_TEMPERATURE] = show_temp(
|
||||
self.hass, self.external_temperature, self.temperature_unit,
|
||||
PRECISION_TENTHS)
|
||||
|
@ -126,16 +126,16 @@ class WinkThermostat(WinkDevice, ClimateDevice):
|
|||
if self.smart_temperature:
|
||||
data[ATTR_SMART_TEMPERATURE] = self.smart_temperature
|
||||
|
||||
if self.occupied:
|
||||
if self.occupied is not None:
|
||||
data[ATTR_OCCUPIED] = self.occupied
|
||||
|
||||
if self.eco_target:
|
||||
if self.eco_target is not None:
|
||||
data[ATTR_ECO_TARGET] = self.eco_target
|
||||
|
||||
if self.heat_on:
|
||||
if self.heat_on is not None:
|
||||
data[ATTR_HEAT_ON] = self.heat_on
|
||||
|
||||
if self.cool_on:
|
||||
if self.cool_on is not None:
|
||||
data[ATTR_COOL_ON] = self.cool_on
|
||||
|
||||
current_humidity = self.current_humidity
|
||||
|
|
|
@ -26,7 +26,7 @@ from homeassistant.helpers.entity_component import EntityComponent
|
|||
from homeassistant.helpers.event import track_time_interval
|
||||
from homeassistant.util.json import load_json, save_json
|
||||
|
||||
REQUIREMENTS = ['python-wink==1.9.1', 'pubnubsub-handler==1.0.2']
|
||||
REQUIREMENTS = ['python-wink==1.10.1', 'pubnubsub-handler==1.0.2']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -73,11 +73,25 @@ SERVICE_SET_AUTO_SHUTOFF = "siren_set_auto_shutoff"
|
|||
SERVICE_SIREN_STROBE_ENABLED = "set_siren_strobe_enabled"
|
||||
SERVICE_CHIME_STROBE_ENABLED = "set_chime_strobe_enabled"
|
||||
SERVICE_ENABLE_SIREN = "enable_siren"
|
||||
SERVICE_SET_DIAL_CONFIG = "set_nimbus_dial_configuration"
|
||||
SERVICE_SET_DIAL_STATE = "set_nimbus_dial_state"
|
||||
|
||||
ATTR_VOLUME = "volume"
|
||||
ATTR_TONE = "tone"
|
||||
ATTR_ENABLED = "enabled"
|
||||
ATTR_AUTO_SHUTOFF = "auto_shutoff"
|
||||
ATTR_MIN_VALUE = "min_value"
|
||||
ATTR_MAX_VALUE = "max_value"
|
||||
ATTR_ROTATION = "rotation"
|
||||
ATTR_SCALE = "scale"
|
||||
ATTR_TICKS = "ticks"
|
||||
ATTR_MIN_POSITION = "min_position"
|
||||
ATTR_MAX_POSITION = "max_position"
|
||||
ATTR_VALUE = "value"
|
||||
ATTR_LABELS = "labels"
|
||||
|
||||
SCALES = ["linear", "log"]
|
||||
ROTATIONS = ["cw", "ccw"]
|
||||
|
||||
VOLUMES = ["low", "medium", "high"]
|
||||
TONES = ["doorbell", "fur_elise", "doorbell_extended", "alert",
|
||||
|
@ -145,6 +159,23 @@ ENABLED_SIREN_SCHEMA = vol.Schema({
|
|||
vol.Required(ATTR_ENABLED): cv.boolean
|
||||
})
|
||||
|
||||
DIAL_CONFIG_SCHEMA = vol.Schema({
|
||||
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
|
||||
vol.Optional(ATTR_MIN_VALUE): vol.Coerce(int),
|
||||
vol.Optional(ATTR_MAX_VALUE): vol.Coerce(int),
|
||||
vol.Optional(ATTR_MIN_POSITION): cv.positive_int,
|
||||
vol.Optional(ATTR_MAX_POSITION): cv.positive_int,
|
||||
vol.Optional(ATTR_ROTATION): vol.In(ROTATIONS),
|
||||
vol.Optional(ATTR_SCALE): vol.In(SCALES),
|
||||
vol.Optional(ATTR_TICKS): cv.positive_int
|
||||
})
|
||||
|
||||
DIAL_STATE_SCHEMA = vol.Schema({
|
||||
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
|
||||
vol.Required(ATTR_VALUE): vol.Coerce(int),
|
||||
vol.Optional(ATTR_LABELS): cv.ensure_list(cv.string)
|
||||
})
|
||||
|
||||
WINK_COMPONENTS = [
|
||||
'binary_sensor', 'sensor', 'light', 'switch', 'lock', 'cover', 'climate',
|
||||
'fan', 'alarm_control_panel', 'scene'
|
||||
|
@ -432,8 +463,23 @@ def setup(hass, config):
|
|||
DOMAIN, SERVICE_SET_PAIRING_MODE, set_pairing_mode,
|
||||
schema=SET_PAIRING_MODE_SCHEMA)
|
||||
|
||||
def service_handle(service):
|
||||
"""Handle services."""
|
||||
def nimbus_service_handle(service):
|
||||
"""Handle nimbus services."""
|
||||
entity_id = service.data.get('entity_id')[0]
|
||||
_all_dials = []
|
||||
for sensor in hass.data[DOMAIN]['entities']['sensor']:
|
||||
if isinstance(sensor, WinkNimbusDialDevice):
|
||||
_all_dials.append(sensor)
|
||||
for _dial in _all_dials:
|
||||
if _dial.entity_id == entity_id:
|
||||
if service.service == SERVICE_SET_DIAL_CONFIG:
|
||||
_dial.set_configuration(**service.data)
|
||||
if service.service == SERVICE_SET_DIAL_STATE:
|
||||
_dial.wink.set_state(service.data.get("value"),
|
||||
service.data.get("labels"))
|
||||
|
||||
def siren_service_handle(service):
|
||||
"""Handle siren services."""
|
||||
entity_ids = service.data.get('entity_id')
|
||||
all_sirens = []
|
||||
for switch in hass.data[DOMAIN]['entities']['switch']:
|
||||
|
@ -495,41 +541,68 @@ def setup(hass, config):
|
|||
if sirens:
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_SET_AUTO_SHUTOFF,
|
||||
service_handle,
|
||||
siren_service_handle,
|
||||
schema=SET_AUTO_SHUTOFF_SCHEMA)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_ENABLE_SIREN,
|
||||
service_handle,
|
||||
siren_service_handle,
|
||||
schema=ENABLED_SIREN_SCHEMA)
|
||||
|
||||
if has_dome_or_wink_siren:
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_SET_SIREN_TONE,
|
||||
service_handle,
|
||||
siren_service_handle,
|
||||
schema=SET_SIREN_TONE_SCHEMA)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_ENABLE_CHIME,
|
||||
service_handle,
|
||||
siren_service_handle,
|
||||
schema=SET_CHIME_MODE_SCHEMA)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_SET_SIREN_VOLUME,
|
||||
service_handle,
|
||||
siren_service_handle,
|
||||
schema=SET_VOLUME_SCHEMA)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_SET_CHIME_VOLUME,
|
||||
service_handle,
|
||||
siren_service_handle,
|
||||
schema=SET_VOLUME_SCHEMA)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_SIREN_STROBE_ENABLED,
|
||||
service_handle,
|
||||
siren_service_handle,
|
||||
schema=SET_STROBE_ENABLED_SCHEMA)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_CHIME_STROBE_ENABLED,
|
||||
service_handle,
|
||||
siren_service_handle,
|
||||
schema=SET_STROBE_ENABLED_SCHEMA)
|
||||
|
||||
component.add_entities(sirens)
|
||||
|
||||
nimbi = []
|
||||
dials = {}
|
||||
all_nimbi = pywink.get_cloud_clocks()
|
||||
all_dials = []
|
||||
for nimbus in all_nimbi:
|
||||
if nimbus.object_type() == "cloud_clock":
|
||||
nimbi.append(nimbus)
|
||||
dials[nimbus.object_id()] = []
|
||||
for nimbus in all_nimbi:
|
||||
if nimbus.object_type() == "dial":
|
||||
dials[nimbus.parent_id()].append(nimbus)
|
||||
|
||||
for nimbus in nimbi:
|
||||
for dial in dials[nimbus.object_id()]:
|
||||
all_dials.append(WinkNimbusDialDevice(nimbus, dial, hass))
|
||||
|
||||
if nimbi:
|
||||
hass.services.register(DOMAIN, SERVICE_SET_DIAL_CONFIG,
|
||||
nimbus_service_handle,
|
||||
schema=DIAL_CONFIG_SCHEMA)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_SET_DIAL_STATE,
|
||||
nimbus_service_handle,
|
||||
schema=DIAL_STATE_SCHEMA)
|
||||
|
||||
component.add_entities(all_dials)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
@ -596,6 +669,7 @@ class WinkDevice(Entity):
|
|||
self.wink.name())
|
||||
|
||||
def _pubnub_update(self, message):
|
||||
_LOGGER.debug(message)
|
||||
try:
|
||||
if message is None:
|
||||
_LOGGER.error("Error on pubnub update for %s "
|
||||
|
@ -740,3 +814,70 @@ class WinkSirenDevice(WinkDevice):
|
|||
attributes["chime_mode"] = chime_mode
|
||||
|
||||
return attributes
|
||||
|
||||
|
||||
class WinkNimbusDialDevice(WinkDevice):
|
||||
"""Representation of the Quirky Nimbus device."""
|
||||
|
||||
def __init__(self, nimbus, dial, hass):
|
||||
"""Initialize the Nimbus dial."""
|
||||
super().__init__(dial, hass)
|
||||
self.parent = nimbus
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_added_to_hass(self):
|
||||
"""Call when entity is added to hass."""
|
||||
self.hass.data[DOMAIN]['entities']['sensor'].append(self)
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return dials current value."""
|
||||
return self.wink.state()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the device."""
|
||||
return self.parent.name() + " dial " + str(self.wink.index() + 1)
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the device state attributes."""
|
||||
attributes = super(WinkNimbusDialDevice, self).device_state_attributes
|
||||
dial_attributes = self.dial_attributes()
|
||||
|
||||
return {**attributes, **dial_attributes}
|
||||
|
||||
def dial_attributes(self):
|
||||
"""Return the dial only attributes."""
|
||||
return {
|
||||
"labels": self.wink.labels(),
|
||||
"position": self.wink.position(),
|
||||
"rotation": self.wink.rotation(),
|
||||
"max_value": self.wink.max_value(),
|
||||
"min_value": self.wink.min_value(),
|
||||
"num_ticks": self.wink.ticks(),
|
||||
"scale_type": self.wink.scale(),
|
||||
"max_position": self.wink.max_position(),
|
||||
"min_position": self.wink.min_position()
|
||||
}
|
||||
|
||||
def set_configuration(self, **kwargs):
|
||||
"""
|
||||
Set the dial config.
|
||||
|
||||
Anything not sent will default to current setting.
|
||||
"""
|
||||
attributes = {**self.dial_attributes(), **kwargs}
|
||||
|
||||
min_value = attributes["min_value"]
|
||||
max_value = attributes["max_value"]
|
||||
rotation = attributes["rotation"]
|
||||
ticks = attributes["num_ticks"]
|
||||
scale = attributes["scale_type"]
|
||||
min_position = attributes["min_position"]
|
||||
max_position = attributes["max_position"]
|
||||
|
||||
self.wink.set_configuration(min_value, max_value, rotation,
|
||||
scale=scale, ticks=ticks,
|
||||
min_position=min_position,
|
||||
max_position=max_position)
|
||||
|
|
|
@ -111,3 +111,44 @@ set_chime_volume:
|
|||
volume:
|
||||
description: Volume level. One of ["low", "medium", "high"]
|
||||
example: "low"
|
||||
|
||||
set_nimbus_dial_configuration:
|
||||
description: Set the configuration of an individual nimbus dial
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of the entity to set.
|
||||
example: 'wink.nimbus_dial_3'
|
||||
rotation:
|
||||
description: Direction dial hand should spin ["cw" or "ccw"]
|
||||
example: 'cw'
|
||||
ticks:
|
||||
description: Number of times the hand should move
|
||||
example: 12
|
||||
scale:
|
||||
description: How the dial should move in response to higher values ["log" or "linear"]
|
||||
example: "linear"
|
||||
min_value:
|
||||
description: The minimum value allowed to be set
|
||||
example: 0
|
||||
max_value:
|
||||
description: The maximum value allowd to be set
|
||||
example: 500
|
||||
min_position:
|
||||
description: The minimum position the dial hand can rotate to generally [0-360]
|
||||
example: 0
|
||||
max_position:
|
||||
description: The maximum position the dial hand can rotate to generally [0-360]
|
||||
example: 360
|
||||
|
||||
set_nimbus_dial_state:
|
||||
description: Set the value and lables of an individual nimbus dial
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name fo the entity to set.
|
||||
example: 'wink.nimbus_dial_3'
|
||||
value:
|
||||
description: The value that should be set (Should be between min_value and max_value)
|
||||
example: 250
|
||||
labels:
|
||||
description: The values shown on the dial labels ["Dial 1", "test"] the first value is what is shown by default the second value is shown when the nimbus is pressed
|
||||
example: ["example", "test"]
|
|
@ -1160,7 +1160,7 @@ python-velbus==2.0.19
|
|||
python-vlc==1.1.2
|
||||
|
||||
# homeassistant.components.wink
|
||||
python-wink==1.9.1
|
||||
python-wink==1.10.1
|
||||
|
||||
# homeassistant.components.sensor.swiss_public_transport
|
||||
python_opendata_transport==0.1.3
|
||||
|
|
Loading…
Reference in New Issue