diff --git a/.coveragerc b/.coveragerc index 69755cb8a62..babb263d730 100644 --- a/.coveragerc +++ b/.coveragerc @@ -172,6 +172,7 @@ omit = homeassistant/components/switch/orvibo.py homeassistant/components/switch/pulseaudio_loopback.py homeassistant/components/switch/rest.py + homeassistant/components/switch/rpi_rf.py homeassistant/components/switch/transmission.py homeassistant/components/switch/wake_on_lan.py homeassistant/components/thermostat/eq3btsmart.py diff --git a/homeassistant/components/switch/rpi_rf.py b/homeassistant/components/switch/rpi_rf.py new file mode 100644 index 00000000000..2b090af0320 --- /dev/null +++ b/homeassistant/components/switch/rpi_rf.py @@ -0,0 +1,103 @@ +""" +Allows to configure a switch using a 433MHz module via GPIO on a Raspberry Pi. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/switch.rpi_rf/ +""" + +import logging + +from homeassistant.components.switch import SwitchDevice + +REQUIREMENTS = ['rpi-rf==0.9.5'] + +_LOGGER = logging.getLogger(__name__) + + +# pylint: disable=unused-argument +def setup_platform(hass, config, add_devices_callback, discovery_info=None): + """Find and return switches controlled by a generic RF device via GPIO.""" + import rpi_rf + + gpio = config.get('gpio') + if not gpio: + _LOGGER.error("No GPIO specified") + return False + + rfdevice = rpi_rf.RFDevice(gpio) + + switches = config.get('switches', {}) + devices = [] + for dev_name, properties in switches.items(): + if not properties.get('code_on'): + _LOGGER.error("%s: code_on not specified", dev_name) + continue + if not properties.get('code_off'): + _LOGGER.error("%s: code_off not specified", dev_name) + continue + + devices.append( + RPiRFSwitch( + hass, + properties.get('name', dev_name), + rfdevice, + properties.get('protocol', None), + properties.get('pulselength', None), + properties.get('code_on'), + properties.get('code_off'))) + if devices: + rfdevice.enable_tx() + + add_devices_callback(devices) + + +class RPiRFSwitch(SwitchDevice): + """Representation of a GPIO RF switch.""" + + # pylint: disable=too-many-arguments, too-many-instance-attributes + def __init__(self, hass, name, rfdevice, protocol, pulselength, + code_on, code_off): + """Initialize the switch.""" + self._hass = hass + self._name = name + self._state = False + self._rfdevice = rfdevice + self._protocol = protocol + self._pulselength = pulselength + self._code_on = code_on + self._code_off = code_off + + @property + def should_poll(self): + """No polling needed.""" + return False + + @property + def name(self): + """Return the name of the switch.""" + return self._name + + @property + def is_on(self): + """Return true if device is on.""" + return self._state + + def _send_code(self, code, protocol, pulselength): + """Send the code with a specified pulselength.""" + _LOGGER.info('Sending code: %s', code) + res = self._rfdevice.tx_code(code, protocol, pulselength) + if not res: + _LOGGER.error('Sending code %s failed', code) + return res + + def turn_on(self): + """Turn the switch on.""" + if self._send_code(self._code_on, self._protocol, self._pulselength): + self._state = True + self.update_ha_state() + + def turn_off(self): + """Turn the switch off.""" + if self._send_code(self._code_off, self._protocol, self._pulselength): + self._state = False + self.update_ha_state() diff --git a/requirements_all.txt b/requirements_all.txt index 7159a612313..b51b8082290 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -269,6 +269,9 @@ pywemo==0.4.2 # homeassistant.components.thermostat.radiotherm radiotherm==1.2 +# homeassistant.components.switch.rpi_rf +rpi-rf==0.9.5 + # homeassistant.components.media_player.yamaha rxv==0.1.11