This repository has been archived by the owner on Jan 3, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
deconz.py
136 lines (112 loc) · 3.86 KB
/
deconz.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
REQUIREMENTS = ['websockets==3.3', 'aiohttp==2.2.3', 'attrs==16.3.0']
import voluptuous as vol
from homeassistant.const import (EVENT_HOMEASSISTANT_STOP, STATE_ON,
STATE_OFF, CONF_API_KEY, CONF_HOST, CONF_PORT)
import logging
from homeassistant.helpers.entity import Entity
from homeassistant.components.sensor import PLATFORM_SCHEMA
import asyncio
_LOGGER = logging.getLogger('deconz')
CONF_WS_PORT = 'websocket_port'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_API_KEY): str,
vol.Required(CONF_HOST): str,
vol.Optional(CONF_PORT, default=80):
vol.All(int, vol.Range(1, 65535)),
vol.Optional(CONF_WS_PORT, default=443):
vol.All(int, vol.Range(1, 65535))
})
def lookup_device(devices, id):
for device in devices:
if device.id == id:
return device
return None
def normalize_name(name):
return '_'.join(name.split()).lower()
@asyncio.coroutine
def async_setup_platform(hass, config, add_devices, discovery_info):
import libdeconz
rest_url = 'http://%s:%d/api/' % (config[CONF_HOST], config[CONF_PORT])
ws_url = 'ws://%s:%d' % (config[CONF_HOST], config[CONF_WS_PORT])
api_key = config[CONF_API_KEY]
session = libdeconz.DeconzSession(api_key, rest_url, ws_url)
sensors = yield from session.get_sensors_async()
devices = []
for sensor in sensors:
devices.append(DeconzSensor(sensor))
add_devices(devices)
@asyncio.coroutine
def listen_events():
_LOGGER.debug('listen_events()')
while True:
_LOGGER.debug('get_event_async()')
event = yield from session.get_event_async()
device = lookup_device(devices, event.id)
if device is None:
_LOGGER.debug('device not found')
continue
_LOGGER.debug('fire event')
_LOGGER.debug(str(device))
hass.bus.async_fire('deconz_buttonevent', {
'id': event.id,
'manufacturername': device.manufacturername,
'mode': device.mode,
'modelid': device.modelid,
'name': normalize_name(device.name),
'swversion': device.swversion,
'type': device.type,
'uniqueid': device.uniqueid,
'buttonevent': event.event
})
def on_hass_stop(event):
del event
hass.async_add_job(session.close())
hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_STOP, on_hass_stop)
hass.loop.create_task(listen_events())
# TODO how do friendly_name etc come into play? Are those parsed by
# Entity somehow or do we need to fetch them ourselves?
#
# TODO update(), read from REST API again
class DeconzSensor(Entity):
def __init__(self, sensor):
self.__sensor = sensor
self.__attributes = {
'reachable': sensor.reachable,
'manufacturername': sensor.manufacturername,
'modelid': sensor.modelid,
'name': normalize_name(sensor.name),
'swversion': sensor.swversion,
'type': sensor.type,
'uniqueid': sensor.uniqueid
}
@property
def id(self):
return self.__sensor.id
@property
def reachable(self):
return self.__sensor.reachable
@property
def manufacturername(self):
return self.__sensor.manufacturername
@property
def mode(self):
return self.__sensor.mode
@property
def modelid(self):
return self.__sensor.modelid
@property
def name(self):
return normalize_name(self.__sensor.name)
@property
def swversion(self):
return self.__sensor.swversion
@property
def type(self):
return self.__sensor.type
@property
def uniqueid(self):
return self.__sensor.uniqueid
@property
def state_attributes(self):
return self.__attributes