Wink PubNub v4 (#4561)

* PubNub v4

* Updated to pubnubsub-handler 0.0.5

* Updated requirements_all.txt
This commit is contained in:
William Scanlon 2016-11-30 16:12:26 -05:00 committed by Paulus Schoutsen
parent 406afbb369
commit 4c03d670c1
9 changed files with 82 additions and 80 deletions

View file

@ -4,8 +4,6 @@ Support for Wink binary sensors.
For more details about this platform, please refer to the documentation at
at https://home-assistant.io/components/binary_sensor.wink/
"""
import json
import logging
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.sensor.wink import WinkDevice
@ -34,38 +32,25 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
for sensor in pywink.get_sensors():
if sensor.capability() in SENSOR_TYPES:
add_devices([WinkBinarySensorDevice(sensor)])
add_devices([WinkBinarySensorDevice(sensor, hass)])
for key in pywink.get_keys():
add_devices([WinkBinarySensorDevice(key)])
add_devices([WinkBinarySensorDevice(key, hass)])
for sensor in pywink.get_smoke_and_co_detectors():
add_devices([WinkBinarySensorDevice(sensor)])
add_devices([WinkBinarySensorDevice(sensor, hass)])
class WinkBinarySensorDevice(WinkDevice, BinarySensorDevice, Entity):
"""Representation of a Wink binary sensor."""
def __init__(self, wink):
def __init__(self, wink, hass):
"""Initialize the Wink binary sensor."""
super().__init__(wink)
super().__init__(wink, hass)
wink = get_component('wink')
self._unit_of_measurement = self.wink.UNIT
self.capability = self.wink.capability()
def _pubnub_update(self, message, channel):
try:
if 'data' in message:
json_data = json.dumps(message.get('data'))
else:
json_data = message
self.wink.pubnub_update(json.loads(json_data))
self.update_ha_state()
except (AttributeError, KeyError):
error = "Pubnub returned invalid json for " + self.name
logging.getLogger(__name__).error(error)
self.update_ha_state(True)
@property
def is_on(self):
"""Return true if the binary sensor is on."""

View file

@ -30,7 +30,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Wink thermostat."""
import pywink
temp_unit = hass.config.units.temperature_unit
add_devices(WinkThermostat(thermostat, temp_unit)
add_devices(WinkThermostat(thermostat, hass, temp_unit)
for thermostat in pywink.get_thermostats())
@ -38,9 +38,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class WinkThermostat(WinkDevice, ClimateDevice):
"""Representation of a Wink thermostat."""
def __init__(self, wink, temp_unit):
def __init__(self, wink, hass, temp_unit):
"""Initialize the Wink device."""
super().__init__(wink)
super().__init__(wink, hass)
wink = get_component('wink')
self._config_temp_unit = temp_unit

View file

@ -15,18 +15,18 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Wink cover platform."""
import pywink
add_devices(WinkCoverDevice(shade) for shade in
add_devices(WinkCoverDevice(shade, hass) for shade in
pywink.get_shades())
add_devices(WinkCoverDevice(door) for door in
add_devices(WinkCoverDevice(door, hass) for door in
pywink.get_garage_doors())
class WinkCoverDevice(WinkDevice, CoverDevice):
"""Representation of a Wink cover device."""
def __init__(self, wink):
def __init__(self, wink, hass):
"""Initialize the cover."""
WinkDevice.__init__(self, wink)
WinkDevice.__init__(self, wink, hass)
def close_cover(self):
"""Close the shade."""

View file

@ -23,15 +23,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Wink lights."""
import pywink
add_devices(WinkLight(light) for light in pywink.get_bulbs())
add_devices(WinkLight(light, hass) for light in pywink.get_bulbs())
class WinkLight(WinkDevice, Light):
"""Representation of a Wink light."""
def __init__(self, wink):
def __init__(self, wink, hass):
"""Initialize the Wink device."""
WinkDevice.__init__(self, wink)
WinkDevice.__init__(self, wink, hass)
@property
def is_on(self):

View file

@ -15,15 +15,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Wink platform."""
import pywink
add_devices(WinkLockDevice(lock) for lock in pywink.get_locks())
add_devices(WinkLockDevice(lock, hass) for lock in pywink.get_locks())
class WinkLockDevice(WinkDevice, LockDevice):
"""Representation of a Wink lock."""
def __init__(self, wink):
def __init__(self, wink, hass):
"""Initialize the lock."""
WinkDevice.__init__(self, wink)
WinkDevice.__init__(self, wink, hass)
@property
def is_locked(self):

View file

@ -22,24 +22,25 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
for sensor in pywink.get_sensors():
if sensor.capability() in SENSOR_TYPES:
add_devices([WinkSensorDevice(sensor)])
add_devices([WinkSensorDevice(sensor, hass)])
add_devices(WinkEggMinder(eggtray) for eggtray in pywink.get_eggtrays())
for eggtray in pywink.get_eggtrays():
add_devices([WinkEggMinder(eggtray, hass)])
for piggy_bank in pywink.get_piggy_banks():
try:
if piggy_bank.capability() in SENSOR_TYPES:
add_devices([WinkSensorDevice(piggy_bank)])
add_devices([WinkSensorDevice(piggy_bank, hass)])
except AttributeError:
logging.getLogger(__name__).error("Device is not a sensor")
logging.getLogger(__name__).info("Device is not a sensor")
class WinkSensorDevice(WinkDevice, Entity):
"""Representation of a Wink sensor."""
def __init__(self, wink):
def __init__(self, wink, hass):
"""Initialize the Wink device."""
super().__init__(wink)
super().__init__(wink, hass)
wink = get_component('wink')
self.capability = self.wink.capability()
if self.wink.UNIT == '°':
@ -84,9 +85,9 @@ class WinkSensorDevice(WinkDevice, Entity):
class WinkEggMinder(WinkDevice, Entity):
"""Representation of a Wink Egg Minder."""
def __init__(self, wink):
def __init__(self, wink, hass):
"""Initialize the sensor."""
WinkDevice.__init__(self, wink)
WinkDevice.__init__(self, wink, hass)
@property
def state(self):

View file

@ -15,18 +15,20 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Wink platform."""
import pywink
add_devices(WinkToggleDevice(switch) for switch in pywink.get_switches())
add_devices(WinkToggleDevice(switch) for switch in
pywink.get_powerstrip_outlets())
add_devices(WinkToggleDevice(switch) for switch in pywink.get_sirens())
for switch in pywink.get_switches():
add_devices([WinkToggleDevice(switch, hass)])
for switch in pywink.get_powerstrip_outlets():
add_devices([WinkToggleDevice(switch, hass)])
for switch in pywink.get_sirens():
add_devices([WinkToggleDevice(switch, hass)])
class WinkToggleDevice(WinkDevice, ToggleEntity):
"""Representation of a Wink toggle device."""
def __init__(self, wink):
def __init__(self, wink, hass):
"""Initialize the Wink device."""
WinkDevice.__init__(self, wink)
WinkDevice.__init__(self, wink, hass)
@property
def is_on(self):

View file

@ -5,17 +5,18 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/wink/
"""
import logging
import json
import voluptuous as vol
from homeassistant.helpers import discovery
from homeassistant.const import CONF_ACCESS_TOKEN, ATTR_BATTERY_LEVEL, \
CONF_EMAIL, CONF_PASSWORD
CONF_EMAIL, CONF_PASSWORD, \
EVENT_HOMEASSISTANT_START, \
EVENT_HOMEASSISTANT_STOP
from homeassistant.helpers.entity import Entity
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['python-wink==0.10.0', 'pubnub==3.8.2']
REQUIREMENTS = ['python-wink==0.10.1', 'pubnubsub-handler==0.0.5']
_LOGGER = logging.getLogger(__name__)
@ -57,13 +58,13 @@ WINK_COMPONENTS = [
def setup(hass, config):
"""Setup the Wink component."""
import pywink
from pubnubsubhandler import PubNubSubscriptionHandler
user_agent = config[DOMAIN][CONF_USER_AGENT]
user_agent = config[DOMAIN].get(CONF_USER_AGENT)
if user_agent:
pywink.set_user_agent(user_agent)
from pubnub import Pubnub
access_token = config[DOMAIN].get(CONF_ACCESS_TOKEN)
if access_token:
@ -76,49 +77,62 @@ def setup(hass, config):
pywink.set_wink_credentials(email, password, client_id,
client_secret)
global SUBSCRIPTION_HANDLER
SUBSCRIPTION_HANDLER = Pubnub(
'N/A', pywink.get_subscription_key(), ssl_on=True)
SUBSCRIPTION_HANDLER.set_heartbeat(120)
hass.data[DOMAIN] = {}
hass.data[DOMAIN]['entities'] = []
hass.data[DOMAIN]['pubnub'] = PubNubSubscriptionHandler(
pywink.get_subscription_key(),
pywink.wink_api_fetch)
def start_subscription(event):
"""Start the pubnub subscription."""
hass.data[DOMAIN]['pubnub'].subscribe()
hass.bus.listen(EVENT_HOMEASSISTANT_START, start_subscription)
def stop_subscription(event):
"""Stop the pubnub subscription."""
hass.data[DOMAIN]['pubnub'].unsubscribe()
hass.bus.listen(EVENT_HOMEASSISTANT_STOP, stop_subscription)
def force_update(call):
"""Force all devices to poll the Wink API."""
_LOGGER.info("Refreshing Wink states from API.")
for entity in hass.data[DOMAIN]['entities']:
entity.update_ha_state(True)
hass.services.register(DOMAIN, 'Refresh state from Wink', force_update)
# Load components for the devices in Wink that we support
for component in WINK_COMPONENTS:
discovery.load_platform(hass, component, DOMAIN, {}, config)
return True
class WinkDevice(Entity):
"""Representation a base Wink device."""
def __init__(self, wink):
def __init__(self, wink, hass):
"""Initialize the Wink device."""
from pubnub import Pubnub
self.wink = wink
self._battery = self.wink.battery_level
if self.wink.pubnub_channel in CHANNELS:
pubnub = Pubnub('N/A', self.wink.pubnub_key, ssl_on=True)
pubnub.set_heartbeat(120)
pubnub.subscribe(self.wink.pubnub_channel,
self._pubnub_update,
error=self._pubnub_error)
else:
CHANNELS.append(self.wink.pubnub_channel)
SUBSCRIPTION_HANDLER.subscribe(self.wink.pubnub_channel,
self._pubnub_update,
error=self._pubnub_error)
hass.data[DOMAIN]['pubnub'].add_subscription(
self.wink.pubnub_channel,
self._pubnub_update)
hass.data[DOMAIN]['entities'].append(self)
def _pubnub_update(self, message, channel):
def _pubnub_update(self, message):
try:
self.wink.pubnub_update(json.loads(message))
self.update_ha_state()
except (AttributeError, KeyError):
error = "Pubnub returned invalid json for " + self.name
logging.getLogger(__name__).error(error)
if message is None:
_LOGGER.error("Error on pubnub update for " + self.name +
" pollin API for current state")
self.update_ha_state(True)
else:
self.wink.pubnub_update(message)
self.update_ha_state()
except (ValueError, KeyError, AttributeError):
_LOGGER.error("Error in pubnub JSON for " + self.name +
" pollin API for current state")
self.update_ha_state(True)
def _pubnub_error(self, message):
_LOGGER.error("Error on pubnub update for " + self.wink.name())
@property
def unique_id(self):
"""Return the ID of this Wink device."""

View file

@ -340,7 +340,7 @@ proliphix==0.4.1
psutil==5.0.0
# homeassistant.components.wink
pubnub==3.8.2
pubnubsub-handler==0.0.5
# homeassistant.components.notify.pushbullet
pushbullet.py==0.10.0
@ -465,7 +465,7 @@ python-telegram-bot==5.2.0
python-twitch==1.3.0
# homeassistant.components.wink
python-wink==0.10.0
python-wink==0.10.1
# homeassistant.components.keyboard
# pyuserinput==0.1.11