58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
import logging
|
|
import voluptuous as vol
|
|
import homeassistant.helpers.config_validation as cv
|
|
from homeassistant.helpers.event import async_track_state_change, async_call_later
|
|
from collections import namedtuple, defaultdict
|
|
import time
|
|
from functools import partial
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
CONF_DURATION = "duration"
|
|
CONF_SWITCHES = "switches"
|
|
|
|
DOMAIN = 'long_click'
|
|
|
|
CONFIG_SCHEMA = vol.Schema({
|
|
DOMAIN: vol.Schema({
|
|
vol.Optional(CONF_DURATION, default=1.0): float,
|
|
vol.Required(CONF_SWITCHES): cv.entity_ids}
|
|
)
|
|
}, extra=vol.ALLOW_EXTRA)
|
|
|
|
ButtonInfo = namedtuple('ButtonInfo', ['cancel', 'last_on_time'])
|
|
switch_on_times = defaultdict(ButtonInfo)
|
|
|
|
|
|
def on_rising_edge(entity_id, from_state, to_state, hass, long_click_time):
|
|
async def long_press_cb(t):
|
|
hass.bus.fire('long_click', {'entity_id': entity_id})
|
|
duration = time.time() - switch_on_times[entity_id].last_on_time
|
|
assert duration >= long_click_time
|
|
del switch_on_times[entity_id]
|
|
|
|
cancel_func = async_call_later(hass, long_click_time, long_press_cb)
|
|
switch_on_times[entity_id] = ButtonInfo(cancel_func, time.time())
|
|
|
|
|
|
def on_falling_edge(entity_id, from_state, to_state, hass, long_click_time):
|
|
if entity_id in switch_on_times:
|
|
# cancel callback
|
|
switch_on_times[entity_id].cancel()
|
|
|
|
duration = time.time() - switch_on_times[entity_id].last_on_time
|
|
# in case the callback didn't fire yet, even if longer than one second
|
|
if duration < long_click_time:
|
|
hass.bus.fire('short_click', {'entity_id': entity_id})
|
|
else:
|
|
hass.bus.fire('long_click', {'entity_id': entity_id})
|
|
del switch_on_times[entity_id]
|
|
|
|
|
|
async def async_setup(hass, config):
|
|
duration = config[DOMAIN][CONF_DURATION]
|
|
async_track_state_change(hass, config[DOMAIN][CONF_SWITCHES],
|
|
partial(on_rising_edge, hass=hass, long_click_time=duration), 'off', 'on')
|
|
async_track_state_change(hass, config[DOMAIN][CONF_SWITCHES],
|
|
partial(on_falling_edge, hass=hass, long_click_time=duration), 'on', 'off')
|
|
return True
|