-
Notifications
You must be signed in to change notification settings - Fork 4
/
rt.py
178 lines (147 loc) · 5.07 KB
/
rt.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
"""
Simple platform to control **SOME** Tuya switch devices.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/switch.tuya/
"""
import voluptuous as vol
from homeassistant.components.switch import SwitchDevice, PLATFORM_SCHEMA
from homeassistant.const import (CONF_NAME, CONF_HOST, CONF_ID, CONF_SWITCHES, CONF_FRIENDLY_NAME, CONF_ICON)
import homeassistant.helpers.config_validation as cv
from time import time
from time import sleep
from threading import Lock
REQUIREMENTS = ['pytuya==7.0.4']
CONF_DEVICE_ID = 'device_id'
CONF_LOCAL_KEY = 'local_key'
DEFAULT_ID = '1'
#ATTR_CURRENT = 'current'
#ATTR_CURRENT_CONSUMPTION = 'current_consumption'
#ATTR_VOLTAGE = 'voltage'
ATTR_TARGET = 'target'
ATTR_CURRENT = 'current'
ATTR_PROBEA = 'probea'
ATTR_PROBEB = 'probeb'
SWITCH_SCHEMA = vol.Schema({
vol.Optional(CONF_ID, default=DEFAULT_ID): cv.string,
vol.Optional(CONF_FRIENDLY_NAME): cv.string,
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_ICON): cv.icon,
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_DEVICE_ID): cv.string,
vol.Required(CONF_LOCAL_KEY): cv.string,
vol.Optional(CONF_ID, default=DEFAULT_ID): cv.string,
vol.Optional(CONF_SWITCHES, default={}):
vol.Schema({cv.slug: SWITCH_SCHEMA}),
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up of the Tuya switch."""
# import pytuya
from . import pytuya
devices = config.get(CONF_SWITCHES)
switches = []
outlet_device = TuyaCache(
pytuya.OutletDevice(
config.get(CONF_DEVICE_ID),
config.get(CONF_HOST),
config.get(CONF_LOCAL_KEY)
)
)
for object_id, device_config in devices.items():
switches.append(
TuyaDevice(
outlet_device,
device_config.get(CONF_FRIENDLY_NAME, object_id),
device_config.get(CONF_ICON),
device_config.get(CONF_ID)
)
)
name = config.get(CONF_NAME)
if name:
switches.append(
TuyaDevice(
outlet_device,
name,
config.get(CONF_ICON),
config.get(CONF_ID)
)
)
add_devices(switches)
class TuyaCache:
"""Cache wrapper for pytuya.OutletDevice"""
def __init__(self, device):
"""Initialize the cache."""
self._cached_status = ''
self._cached_status_time = 0
self._device = device
self._lock = Lock()
def __get_status(self):
for i in range(3):
try:
status = self._device.status()
return status
except ConnectionError:
if i+1 == 3:
raise ConnectionError("Failed to update status.")
def set_status(self, state, switchid):
"""Change the Tuya switch status and clear the cache."""
self._cached_status = ''
self._cached_status_time = 0
return self._device.set_status(state, switchid)
def status(self):
"""Get state of Tuya switch and cache the results."""
self._lock.acquire()
try:
now = time()
if not self._cached_status or now - self._cached_status_time > 20:
sleep(0.5)
self._cached_status = self.__get_status()
self._cached_status_time = time()
return self._cached_status
finally:
self._lock.release()
class TuyaDevice(SwitchDevice):
"""Representation of a Tuya switch."""
def __init__(self, device, name, icon, switchid):
"""Initialize the Tuya switch."""
self._device = device
self._name = name
self._state = False
self._icon = icon
self._switchid = switchid
self._status = self._device.status()
@property
def name(self):
"""Get name of Tuya switch."""
return self._name
@property
def is_on(self):
"""Check if Tuya switch is on."""
return self._state
@property
def device_state_attributes(self):
attrs = {}
try:
attrs[ATTR_TARGET] = "{}".format(self._status['dps']['102'])
attrs[ATTR_CURRENT] = "{}".format(self._status['dps']['103'])
attrs[ATTR_PROBEA] = "{}".format(self._status['dps']['105'])
attrs[ATTR_PROBEB] = "{}".format(self._status['dps']['106'])
except KeyError:
pass
return attrs
@property
def icon(self):
"""Return the icon."""
return self._icon
def turn_on(self, **kwargs):
"""Turn Tuya switch on."""
self._device.set_status(True, self._switchid)
def turn_off(self, **kwargs):
"""Turn Tuya switch off."""
self._device.set_status(False, self._switchid)
def update(self):
"""Get state of Tuya switch."""
status = self._device.status()
self._status= status
self._state = status['dps'][self._switchid]