2015-08-02 16:05:28 +00:00
|
|
|
"""
|
|
|
|
homeassistant.components.switch.rpi_gpio
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2015-08-08 17:20:53 +00:00
|
|
|
Allows to control the GPIO pins of a Raspberry Pi.
|
2015-09-07 17:39:16 +00:00
|
|
|
|
2015-10-21 21:05:54 +00:00
|
|
|
For more details about this platform, please refer to the documentation at
|
2015-11-09 12:12:18 +00:00
|
|
|
https://home-assistant.io/components/switch.rpi_gpio/
|
2015-08-02 16:05:28 +00:00
|
|
|
"""
|
|
|
|
import logging
|
|
|
|
try:
|
|
|
|
import RPi.GPIO as GPIO
|
|
|
|
except ImportError:
|
|
|
|
GPIO = None
|
|
|
|
from homeassistant.helpers.entity import ToggleEntity
|
|
|
|
from homeassistant.const import (DEVICE_DEFAULT_NAME,
|
|
|
|
EVENT_HOMEASSISTANT_START,
|
|
|
|
EVENT_HOMEASSISTANT_STOP)
|
|
|
|
|
2015-08-26 10:03:06 +00:00
|
|
|
DEFAULT_INVERT_LOGIC = False
|
2015-08-25 22:23:51 +00:00
|
|
|
|
2015-08-30 01:39:50 +00:00
|
|
|
REQUIREMENTS = ['RPi.GPIO==0.5.11']
|
2015-08-02 16:05:28 +00:00
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
# pylint: disable=unused-argument
|
|
|
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
2015-08-08 17:20:53 +00:00
|
|
|
""" Sets up the Raspberry PI GPIO ports. """
|
2015-08-02 21:24:36 +00:00
|
|
|
if GPIO is None:
|
2015-08-08 17:20:53 +00:00
|
|
|
_LOGGER.error('RPi.GPIO not available. rpi_gpio ports ignored.')
|
2015-08-02 16:05:28 +00:00
|
|
|
return
|
2015-08-25 23:02:52 +00:00
|
|
|
# pylint: disable=no-member
|
2015-08-25 22:23:51 +00:00
|
|
|
GPIO.setmode(GPIO.BCM)
|
|
|
|
|
2015-08-02 16:05:28 +00:00
|
|
|
switches = []
|
2015-08-26 10:03:06 +00:00
|
|
|
invert_logic = config.get('invert_logic', DEFAULT_INVERT_LOGIC)
|
2015-08-02 16:05:28 +00:00
|
|
|
ports = config.get('ports')
|
|
|
|
for port_num, port_name in ports.items():
|
2015-08-26 10:03:06 +00:00
|
|
|
switches.append(RPiGPIOSwitch(port_name, port_num, invert_logic))
|
2015-08-02 16:05:28 +00:00
|
|
|
add_devices(switches)
|
|
|
|
|
|
|
|
def cleanup_gpio(event):
|
2015-08-08 17:20:53 +00:00
|
|
|
""" Stuff to do before stop home assistant. """
|
2015-08-06 07:56:02 +00:00
|
|
|
# pylint: disable=no-member
|
2015-08-02 16:05:28 +00:00
|
|
|
GPIO.cleanup()
|
|
|
|
|
|
|
|
def prepare_gpio(event):
|
2015-08-08 17:20:53 +00:00
|
|
|
""" Stuff to do when home assistant starts. """
|
2015-08-02 16:05:28 +00:00
|
|
|
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, cleanup_gpio)
|
|
|
|
|
|
|
|
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, prepare_gpio)
|
|
|
|
|
|
|
|
|
|
|
|
class RPiGPIOSwitch(ToggleEntity):
|
2015-08-08 17:20:53 +00:00
|
|
|
""" Represents a port that can be toggled using Raspberry Pi GPIO. """
|
2015-08-02 16:05:28 +00:00
|
|
|
|
2015-08-26 10:03:06 +00:00
|
|
|
def __init__(self, name, gpio, invert_logic):
|
2015-08-02 16:05:28 +00:00
|
|
|
self._name = name or DEVICE_DEFAULT_NAME
|
|
|
|
self._gpio = gpio
|
2015-08-26 10:22:06 +00:00
|
|
|
self._active_state = not invert_logic
|
|
|
|
self._state = not self._active_state
|
2015-08-06 07:56:02 +00:00
|
|
|
# pylint: disable=no-member
|
2015-08-02 21:24:36 +00:00
|
|
|
GPIO.setup(gpio, GPIO.OUT)
|
2015-08-02 16:05:28 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def name(self):
|
2015-08-08 17:20:53 +00:00
|
|
|
""" The name of the port. """
|
2015-08-02 16:05:28 +00:00
|
|
|
return self._name
|
|
|
|
|
|
|
|
@property
|
|
|
|
def should_poll(self):
|
2015-08-08 17:20:53 +00:00
|
|
|
""" No polling needed. """
|
2015-08-02 16:05:28 +00:00
|
|
|
return False
|
|
|
|
|
|
|
|
@property
|
|
|
|
def is_on(self):
|
|
|
|
""" True if device is on. """
|
|
|
|
return self._state
|
|
|
|
|
|
|
|
def turn_on(self, **kwargs):
|
|
|
|
""" Turn the device on. """
|
2015-08-26 10:03:06 +00:00
|
|
|
if self._switch(self._active_state):
|
2015-08-02 16:05:28 +00:00
|
|
|
self._state = True
|
|
|
|
self.update_ha_state()
|
|
|
|
|
|
|
|
def turn_off(self, **kwargs):
|
|
|
|
""" Turn the device off. """
|
2015-08-26 10:22:06 +00:00
|
|
|
if self._switch(not self._active_state):
|
2015-08-02 16:05:28 +00:00
|
|
|
self._state = False
|
|
|
|
self.update_ha_state()
|
|
|
|
|
|
|
|
def _switch(self, new_state):
|
2015-08-08 17:20:53 +00:00
|
|
|
""" Change the output value to Raspberry Pi GPIO port. """
|
2015-08-02 16:05:28 +00:00
|
|
|
_LOGGER.info('Setting GPIO %s to %s', self._gpio, new_state)
|
2015-08-06 07:56:02 +00:00
|
|
|
# pylint: disable=bare-except
|
2015-08-02 16:05:28 +00:00
|
|
|
try:
|
2015-08-06 07:56:02 +00:00
|
|
|
# pylint: disable=no-member
|
2015-08-02 21:24:36 +00:00
|
|
|
GPIO.output(self._gpio, 1 if new_state else 0)
|
2015-08-02 16:05:28 +00:00
|
|
|
except:
|
|
|
|
_LOGGER.error('GPIO "%s" output failed', self._gpio)
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2015-08-06 07:56:02 +00:00
|
|
|
# pylint: disable=no-self-use
|
2015-08-02 16:05:28 +00:00
|
|
|
@property
|
|
|
|
def device_state_attributes(self):
|
|
|
|
""" Returns device specific state attributes. """
|
|
|
|
return None
|
|
|
|
|
|
|
|
@property
|
|
|
|
def state_attributes(self):
|
|
|
|
""" Returns optional state attributes. """
|
|
|
|
data = {}
|
|
|
|
device_attr = self.device_state_attributes
|
|
|
|
if device_attr is not None:
|
|
|
|
data.update(device_attr)
|
|
|
|
return data
|