mirror of
https://github.com/home-assistant/core.git
synced 2025-11-17 15:00:12 +00:00
Rflink 433Mhz gateway platform and components (#4547)
* Initial sketches of rflink component. * Add requirement. * Properly load configuration. * Bump rflink for graceful parse errors and protocol callback. * Cleanup, documentation and linting. * More documentation, first sensor implementation (temp & hum). * Add brightness/dim support for newkaku protocol. * Use separate class for dimmables. * Make sure non-dimmable newkaku devices are turned on. * Move some code around, add switches. Support loading from config. * Fix bug in ignoring devices. * Fix initial state assumption. * Improve reliability on invalid conditions. * Allow configuration of group for new devices. * Sensor icons. * Fix parsing negative numbers. * Correct icon. * Allow sending commands serial. * Pluralize. * Allow adding sensors from config. * Fix ignoring devices and bugs in previous commit. * Share know devices so devices from configuration don't get added as lights. * Lookup unit from value_key. * Remove debug. * Start implementing event protocol in place of packet protocol. - Added first test suite for sensors. - This currently breaks light and switch. * Refactor switch component to fit new rflink changes. Add test suite. * Fix style. * Refactor and test lights. Bring coverage to 100%. * Use non-broken and production tested rflink module. * Update requirements. * Bump for logging. * Improve readability. * Do not use global variable but keep known device state in intended place. * Improve docs. * Make icon support generic. * Disable overriding icons in config, as it belongs in customization. Only keep custom icon for entities that are able to detect a icon based on the thing they represent (sensors in this case). * Implement configuration schema, overall refactor of magic values. * Fix bug in config/test wait_for_ack. * Small refactors. * Move command logic into separate class. * Convert command sending logic to class based pattern instead of using the event bus. * Start not using bus for rflink event propagation to platforms. * Do not use event bus for all entity types. * Fire an event on the bus for every switch incoming rflink command. * Resolve lint errors, remove some old code. * Known devices no longer need to be registered separately. * Log bus events. * Event callback is a..... callback. * Use full entity id for events. * Move event sending to entity. * Log incoming events. * Make firing events optional inline with rfxtrx. * Add foundation for signal repetition. * Add signal repetition config and tests. * Make plain switchable type explicitly configurable. * Enable default entity settings for automatically added entities as well. * Prevent default configuration leaking accross entities. * Make sure device defaults don't get overwritten by defaults further down. * Don't let fast state switching and repetitions turn your house into a disco. * Make repetitions more responsive. * Disable on/off fallback on dimmables as it currently doesn't play nice with repetitions. * Use rflink that allows send_command_ack to be safely cancelled. * Reduce duplication and make repeat work for non-ack. * Implement reconnection logic. * Improve reconnection logic. * Also cancel repetitions when entity state is changed due to external command. * Update requirements. * Fix linting. * Fix spelling. * Don't lie. * Fix lint. * Support for automatically creating protocol translation (fixes spaces in device names). * Returned support for dimmable and on/off entity. * Duplicate code to fix linting issues with inheritance. * Allow overriding unit of measurement from config.
This commit is contained in:
committed by
Paulus Schoutsen
parent
9925b2a8e0
commit
bbda2a72f4
141
homeassistant/components/sensor/rflink.py
Normal file
141
homeassistant/components/sensor/rflink.py
Normal file
@@ -0,0 +1,141 @@
|
||||
"""Support for Rflink sensors.
|
||||
|
||||
For more details about this platform, please refer to the documentation
|
||||
at https://home-assistant.io/components/light.rflink/
|
||||
|
||||
"""
|
||||
import asyncio
|
||||
from functools import partial
|
||||
import logging
|
||||
|
||||
from homeassistant.components import group
|
||||
from homeassistant.components.rflink import (
|
||||
CONF_ALIASSES, CONF_DEVICES, CONF_NEW_DEVICES_GROUP, DATA_DEVICE_REGISTER,
|
||||
DATA_ENTITY_LOOKUP, DOMAIN, EVENT_KEY_ID, EVENT_KEY_SENSOR, EVENT_KEY_UNIT,
|
||||
RflinkDevice, cv, vol)
|
||||
from homeassistant.const import (
|
||||
ATTR_UNIT_OF_MEASUREMENT, CONF_NAME, CONF_PLATFORM,
|
||||
CONF_UNIT_OF_MEASUREMENT)
|
||||
|
||||
DEPENDENCIES = ['rflink']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SENSOR_ICONS = {
|
||||
'humidity': 'mdi:water-percent',
|
||||
'battery': 'mdi:battery',
|
||||
'temperature': 'mdi:thermometer',
|
||||
}
|
||||
|
||||
CONF_SENSOR_TYPE = 'sensor_type'
|
||||
|
||||
PLATFORM_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_PLATFORM): DOMAIN,
|
||||
vol.Optional(CONF_NEW_DEVICES_GROUP, default=None): cv.string,
|
||||
vol.Optional(CONF_DEVICES, default={}): vol.Schema({
|
||||
cv.string: {
|
||||
vol.Optional(CONF_NAME): cv.string,
|
||||
vol.Required(CONF_SENSOR_TYPE): cv.string,
|
||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT, default=None): cv.string,
|
||||
vol.Optional(CONF_ALIASSES, default=[]):
|
||||
vol.All(cv.ensure_list, [cv.string]),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
|
||||
def lookup_unit_for_sensor_type(sensor_type):
|
||||
"""Get unit for sensor type.
|
||||
|
||||
Async friendly.
|
||||
|
||||
"""
|
||||
from rflink.parser import UNITS, PACKET_FIELDS
|
||||
field_abbrev = {v: k for k, v in PACKET_FIELDS.items()}
|
||||
|
||||
return UNITS.get(field_abbrev.get(sensor_type))
|
||||
|
||||
|
||||
def devices_from_config(domain_config, hass=None):
|
||||
"""Parse config and add rflink sensor devices."""
|
||||
devices = []
|
||||
for device_id, config in domain_config[CONF_DEVICES].items():
|
||||
if not config[ATTR_UNIT_OF_MEASUREMENT]:
|
||||
config[ATTR_UNIT_OF_MEASUREMENT] = lookup_unit_for_sensor_type(
|
||||
config[CONF_SENSOR_TYPE])
|
||||
device = RflinkSensor(device_id, hass, **config)
|
||||
devices.append(device)
|
||||
|
||||
# register entity to listen to incoming rflink events
|
||||
hass.data[DATA_ENTITY_LOOKUP][
|
||||
EVENT_KEY_SENSOR][device_id].append(device)
|
||||
return devices
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup the Rflink platform."""
|
||||
# add devices from config
|
||||
yield from async_add_devices(devices_from_config(config, hass))
|
||||
|
||||
# add new (unconfigured) devices to user desired group
|
||||
if config[CONF_NEW_DEVICES_GROUP]:
|
||||
new_devices_group = yield from group.Group.async_create_group(
|
||||
hass, config[CONF_NEW_DEVICES_GROUP], [], True)
|
||||
else:
|
||||
new_devices_group = None
|
||||
|
||||
@asyncio.coroutine
|
||||
def add_new_device(event):
|
||||
"""Check if device is known, otherwise create device entity."""
|
||||
device_id = event[EVENT_KEY_ID]
|
||||
|
||||
rflinksensor = partial(RflinkSensor, device_id, hass)
|
||||
device = rflinksensor(event[EVENT_KEY_SENSOR], event[EVENT_KEY_UNIT])
|
||||
# add device entity
|
||||
yield from async_add_devices([device])
|
||||
|
||||
# register entity to listen to incoming rflink events
|
||||
hass.data[DATA_ENTITY_LOOKUP][
|
||||
EVENT_KEY_SENSOR][device_id].append(device)
|
||||
|
||||
# make sure the event is processed by the new entity
|
||||
device.handle_event(event)
|
||||
|
||||
# maybe add to new devices group
|
||||
if new_devices_group:
|
||||
yield from new_devices_group.async_update_tracked_entity_ids(
|
||||
list(new_devices_group.tracking) + [device.entity_id])
|
||||
|
||||
hass.data[DATA_DEVICE_REGISTER][EVENT_KEY_SENSOR] = add_new_device
|
||||
|
||||
|
||||
class RflinkSensor(RflinkDevice):
|
||||
"""Representation of a Rflink sensor."""
|
||||
|
||||
def __init__(self, device_id, hass, sensor_type,
|
||||
unit_of_measurement, **kwargs):
|
||||
"""Handle sensor specific args and super init."""
|
||||
self._sensor_type = sensor_type
|
||||
self._unit_of_measurement = unit_of_measurement
|
||||
super().__init__(device_id, hass, **kwargs)
|
||||
|
||||
def _handle_event(self, event):
|
||||
"""Domain specific event handler."""
|
||||
self._state = event['value']
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return measurement unit."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return value."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return possible sensor specific icon."""
|
||||
if self._sensor_type in SENSOR_ICONS:
|
||||
return SENSOR_ICONS[self._sensor_type]
|
||||
Reference in New Issue
Block a user