To use this custom pilight configuration, you need to possibly create the folders ./custom_components/light and simply dump the pilight.py file in there
Then you of course need to create the proper configuration as KennieNL showed in his post.
I added some functionality to be able to set a default brightness level in configuration, so that the light doesn’t always dim to full when it’s turned on.
"""
Support for lights via Pilight.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.pilight/
"""
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
import homeassistant.components.pilight as pilight
from homeassistant.components.light import (ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light, PLATFORM_SCHEMA)
from homeassistant.const import (CONF_NAME, CONF_ID, CONF_DEVICES, CONF_STATE,
CONF_PROTOCOL)
_LOGGER = logging.getLogger(__name__)
CONF_OFF_CODE = 'off_code'
CONF_OFF_CODE_RECIEVE = 'off_code_receive'
CONF_ON_CODE = 'on_code'
CONF_ON_CODE_RECIEVE = 'on_code_receive'
CONF_SYSTEMCODE = 'systemcode'
CONF_UNIT = 'unit'
CONF_UNITCODE = 'unitcode'
CONF_ECHO = 'echo'
CONF_DIMMABLE = 'dimmable'
CONF_BRIGHTNESS = 'brightness'
DEPENDENCIES = ['pilight']
COMMAND_SCHEMA = vol.Schema({
vol.Optional(CONF_PROTOCOL): cv.string,
vol.Optional('on'): cv.positive_int,
vol.Optional('off'): cv.positive_int,
vol.Optional(CONF_UNIT): cv.positive_int,
vol.Optional(CONF_UNITCODE): cv.positive_int,
vol.Optional(CONF_ID): vol.Any(cv.positive_int, cv.string),
vol.Optional(CONF_STATE): cv.string,
vol.Optional(CONF_SYSTEMCODE): cv.positive_int,
vol.Optional(CONF_BRIGHTNESS): cv.positive_int,
}, extra=vol.ALLOW_EXTRA)
RECEIVE_SCHEMA = COMMAND_SCHEMA.extend({
vol.Optional(CONF_ECHO): cv.boolean
})
SWITCHES_SCHEMA = vol.Schema({
vol.Required(CONF_ON_CODE): COMMAND_SCHEMA,
vol.Required(CONF_OFF_CODE): COMMAND_SCHEMA,
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_OFF_CODE_RECIEVE, default=[]): vol.All(cv.ensure_list,
[COMMAND_SCHEMA]),
vol.Optional(CONF_ON_CODE_RECIEVE, default=[]): vol.All(cv.ensure_list,
[COMMAND_SCHEMA]),
vol.Optional(CONF_DIMMABLE, default=False): cv.boolean,
vol.Optional(CONF_BRIGHTNESS): cv.positive_int
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_DEVICES):
vol.Schema({cv.string: SWITCHES_SCHEMA}),
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Pilight platform."""
devices = []
for dev_name, properties in config.get(CONF_DEVICES).items():
devices.append(
PilightDimmableLight(
hass,
properties.get(CONF_NAME, dev_name),
properties.get(CONF_ON_CODE),
properties.get(CONF_OFF_CODE),
properties.get(CONF_ON_CODE_RECIEVE),
properties.get(CONF_OFF_CODE_RECIEVE),
properties.get(CONF_DIMMABLE),
properties.get(CONF_BRIGHTNESS)
)
)
add_devices(devices)
class _ReceiveHandle(object):
def __init__(self, config, echo):
"""Initialize the handle."""
self.config_items = config.items()
self.echo = echo
def match(self, code):
"""Test if the received code matches the configured values.
The received values have to be a subset of the configured options.
"""
return self.config_items <= code.items()
def run(self, light, turn_on):
"""Change the state of the switch."""
light.set_state(turn_on=turn_on, send_code=self.echo)
class PilightDimmableLight(Light):
"""Representation of a Pilight light."""
def __init__(self, hass, name, code_on, code_off, code_on_receive,
code_off_receive, dimmable, brightness):
"""Initialize the light."""
self._hass = hass
self._name = name
self._state = False
self._code_on = code_on
self._code_off = code_off
self._code_on_receive = []
self._code_off_receive = []
self._brightness = brightness
self._dimmable = dimmable
for code_list, conf in ((self._code_on_receive, code_on_receive),
(self._code_off_receive, code_off_receive)):
for code in conf:
echo = code.pop(CONF_ECHO, True)
code_list.append(_ReceiveHandle(code, echo))
if any(self._code_on_receive) or any(self._code_off_receive):
hass.bus.listen(pilight.EVENT, self._handle_code)
@property
def name(self):
"""Get the name of the light."""
return self._name
@property
def brightness(self):
"""Return the brightness"""
return self._brightness
@property
def is_on(self):
"""Return true if switch is on."""
return self._state
@property
def supported_features(self):
"""Flag supported features."""
if self._dimmable:
return SUPPORT_BRIGHTNESS
else:
return None
def _handle_code(self, call):
"""Check if received code by the pilight-daemon.
If the code matches the receive on/off codes of this switch the switch
state is changed accordingly.
"""
# - True if off_code/on_code is contained in received code dict, not
# all items have to match.
# - Call turn on/off only once, even if more than one code is received
if any(self._code_on_receive):
for on_code in self._code_on_receive:
if on_code.match(call.data):
on_code.run(light=self, turn_on=True)
break
if any(self._code_off_receive):
for off_code in self._code_off_receive:
if off_code.match(call.data):
off_code.run(light=self, turn_on=False)
break
def set_state(self, turn_on, dimlevel=15, send_code=True):
"""Set the state of the switch.
This sets the state of the switch. If send_code is set to True, then
it will call the pilight.send service to actually send the codes
to the pilight daemon.
"""
if send_code:
if turn_on:
code = self._code_on
if self._dimmable:
code.update({'dimlevel':dimlevel})
self._hass.services.call(pilight.DOMAIN, pilight.SERVICE_NAME,
code, blocking=True)
else:
self._hass.services.call(pilight.DOMAIN, pilight.SERVICE_NAME,
self._code_off, blocking=True)
self._state = turn_on
self.schedule_update_ha_state()
def turn_on(self, **kwargs):
"""Turn the switch on by calling pilight.send service with on code."""
if kwargs.get(ATTR_BRIGHTNESS):
self._brightness = kwargs.get(ATTR_BRIGHTNESS)
if not self._brightness:
self._brightness = 255
# self._brightness = kwargs.get(ATTR_BRIGHTNESS, 255)
dimlevel = int(self._brightness / 17)
self.set_state(turn_on=True, dimlevel=dimlevel)
def turn_off(self, **kwargs):
"""Turn the switch on by calling pilight.send service with off code."""
self.set_state(turn_on=False)
With a configuration example:
- platform: pilight
devices:
light1:
dimmable: true
brightness: 200
on_code:
protocol: kaku_dimmer
unit: 4
id: 11111111
'on': 1
on_code_receive:
- protocol: arctech_switch
unit: 4
id: 11111111
state: 'on'
echo: false
off_code:
protocol: kaku_dimmer
unit: 4
id: 11111111
'off': 1
off_code_receive:
- protocol: arctech_switch
unit: 4
id: 11111111
state: 'off'
echo: false
Hope this works for you as well.