Skip to content

Commit

Permalink
Support for quriky nimbu
Browse files Browse the repository at this point in the history
  • Loading branch information
w1ll1am23 committed Sep 9, 2018
1 parent 0d7ee9b commit 87563bf
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 17 deletions.
10 changes: 5 additions & 5 deletions homeassistant/components/climate/wink.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,24 +118,24 @@ def device_state_attributes(self):
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)

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
Expand Down
161 changes: 150 additions & 11 deletions homeassistant/components/wink/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
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__)

Expand Down Expand Up @@ -73,11 +73,25 @@
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",
Expand Down Expand Up @@ -145,6 +159,23 @@
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'
Expand Down Expand Up @@ -432,8 +463,23 @@ def delete_device(call):
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']:
Expand Down Expand Up @@ -495,41 +541,68 @@ def service_handle(service):
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


Expand Down Expand Up @@ -596,6 +669,7 @@ def __init__(self, wink, hass):
self.wink.name())

def _pubnub_update(self, message):
_LOGGER.debug(message)
try:
if message is None:
_LOGGER.error("Error on pubnub update for %s "
Expand Down Expand Up @@ -740,3 +814,68 @@ def device_state_attributes(self):
attributes["chime_mode"] = chime_mode

return attributes


class WinkNimbusDialDevice(WinkDevice):
"""Representation of the Quirky Nimbus device."""

def __init__(self, nimbus, dial, hass):
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)
41 changes: 41 additions & 0 deletions homeassistant/components/wink/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 fo 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: Home the dial should move in response to higer 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"]
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1158,7 +1158,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
Expand Down

0 comments on commit 87563bf

Please sign in to comment.