-
Notifications
You must be signed in to change notification settings - Fork 36
/
switch.py
134 lines (105 loc) · 4.35 KB
/
switch.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
"""
Support for Sonoff smart home devices, such as smart switches (e.g. Sonoff
Basic), plugs (e.g. Sonoff S20), and wall switches (e.g. Sonoff Touch),
when these devices are in "LAN Mode", directly over the local network.
For more details about this platform, please refer to the documentation at
https://github.com/beveradb/sonoff-lan-mode-homeassistant
"""
import logging
import homeassistant.helpers.config_validation as cv
import voluptuous as vol
from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA)
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_ICON
REQUIREMENTS = ['pysonofflan>=0.3.0']
_LOGGER = logging.getLogger('homeassistant.components.switch.sonoff_lan_mode')
DEFAULT_NAME = 'Sonoff Switch'
DEFAULT_ICON = 'mdi:flash'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_ICON, default=DEFAULT_ICON) : cv.string
})
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the Sonoff LAN Mode Switch platform."""
host = config.get(CONF_HOST)
name = config.get(CONF_NAME)
icon = config.get(CONF_ICON)
async_add_entities([HassSonoffSwitch(hass, host, name, icon)], True)
class HassSonoffSwitch(SwitchDevice):
"""Home Assistant representation of a Sonoff LAN Mode device."""
def __init__(self, hass, host, name, icon):
from pysonofflan import SonoffSwitch
_LOGGER.setLevel(logging.DEBUG)
self._name = name
self._icon = icon
self._state = None
self._available = False
self._shared_state = {}
self._sonoff_device = SonoffSwitch(
host=host,
callback_after_update=self.device_update_callback,
shared_state=self._shared_state,
logger=_LOGGER,
loop=hass.loop,
ping_interval=145
)
_LOGGER.debug("HassSonoffSwitch __init__ finished creating "
"SonoffSwitch")
@property
def icon(self):
"""Return the icon to use in the frontend, if any."""
return self._icon
@property
def name(self):
_LOGGER.debug("HassSonoffSwitch returning _name: %s" % self._name)
return self._name
@property
def available(self) -> bool:
"""Return if switch is available."""
_LOGGER.debug("HassSonoffSwitch returning _available: %s" %
self._available)
return self._available
@property
def is_on(self):
"""Return true if switch is on."""
_LOGGER.debug("HassSonoffSwitch returning _state: %s" % self._state)
return self._state
async def turn_on(self, **kwargs):
"""Turn the switch on."""
_LOGGER.info("Sonoff LAN Mode switch %s switching on" % self._name)
await self._sonoff_device.turn_on()
async def turn_off(self, **kwargs):
"""Turn the switch off."""
_LOGGER.info("Sonoff LAN Mode switch %s switching off" % self._name)
await self._sonoff_device.turn_off()
async def device_update_callback(self, callback_self):
"""Handle state updates announced by the device itself."""
_LOGGER.info(
"Sonoff LAN Mode switch %s received updated state from "
"the device: %s, available: %s" % (self._name,
self._sonoff_device.state,
self._sonoff_device.available)
)
await self.async_update()
@property
def should_poll(self) -> bool:
return False
async def async_update(self):
"""Update the device state."""
_LOGGER.debug("HassSonoffSwitch async_update called")
try:
if self._sonoff_device.basic_info is None:
_LOGGER.debug(
"Sonoff device basic info still none, waiting for init "
"message")
return
self._available = self._sonoff_device.available
self._state = \
self._sonoff_device.state == \
self._sonoff_device.SWITCH_STATE_ON
self.async_schedule_update_ha_state()
except Exception as ex:
if self._available:
_LOGGER.warning(
"Could not read state for %s: %s", self.name, ex)