mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 17:27:10 +00:00
Add Remote RPi Component (#23518)
* Add Remote RPi Component * Add Remote RPi Component * fix imports * Added support for setup as switch and binary_sensor * remove pylint error handling * Changed to domain config * Changed to domain config * Changed to domain config * Changed to domain config * Update __init__.py * Update manifest.json * Update requirements_all.txt * Update switch.py * Update binary_sensor.py * Changed to domain config
This commit is contained in:
parent
9438dd1cbd
commit
6e1728542e
@ -487,6 +487,7 @@ omit =
|
||||
homeassistant/components/reddit/*
|
||||
homeassistant/components/rejseplanen/sensor.py
|
||||
homeassistant/components/remember_the_milk/__init__.py
|
||||
homeassistant/components/remote_rpi_gpio/*
|
||||
homeassistant/components/rest/binary_sensor.py
|
||||
homeassistant/components/rest/notify.py
|
||||
homeassistant/components/rest/switch.py
|
||||
|
63
homeassistant/components/remote_rpi_gpio/__init__.py
Normal file
63
homeassistant/components/remote_rpi_gpio/__init__.py
Normal file
@ -0,0 +1,63 @@
|
||||
"""Support for controlling GPIO pins of a Raspberry Pi."""
|
||||
import logging
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_BOUNCETIME = 'bouncetime'
|
||||
CONF_INVERT_LOGIC = 'invert_logic'
|
||||
CONF_PULL_MODE = 'pull_mode'
|
||||
|
||||
DEFAULT_BOUNCETIME = 50
|
||||
DEFAULT_INVERT_LOGIC = False
|
||||
DEFAULT_PULL_MODE = "UP"
|
||||
|
||||
DOMAIN = 'remote_rpi_gpio'
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
"""Set up the Raspberry Pi Remote GPIO component."""
|
||||
return True
|
||||
|
||||
|
||||
def setup_output(address, port, invert_logic):
|
||||
"""Set up a GPIO as output."""
|
||||
from gpiozero import LED
|
||||
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||
|
||||
try:
|
||||
return LED(port, active_high=invert_logic,
|
||||
pin_factory=PiGPIOFactory(address))
|
||||
except (ValueError, IndexError, KeyError):
|
||||
return None
|
||||
|
||||
|
||||
def setup_input(address, port, pull_mode, bouncetime):
|
||||
"""Set up a GPIO as input."""
|
||||
from gpiozero import Button
|
||||
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||
|
||||
if pull_mode == "UP":
|
||||
pull_gpio_up = True
|
||||
elif pull_mode == "DOWN":
|
||||
pull_gpio_up = False
|
||||
|
||||
try:
|
||||
return Button(port,
|
||||
pull_up=pull_gpio_up,
|
||||
bounce_time=bouncetime,
|
||||
pin_factory=PiGPIOFactory(address))
|
||||
except (ValueError, IndexError, KeyError, IOError):
|
||||
return None
|
||||
|
||||
|
||||
def write_output(switch, value):
|
||||
"""Write a value to a GPIO."""
|
||||
if value == 1:
|
||||
switch.on()
|
||||
if value == 0:
|
||||
switch.off()
|
||||
|
||||
|
||||
def read_input(button):
|
||||
"""Read a value from a GPIO."""
|
||||
return button.is_pressed
|
106
homeassistant/components/remote_rpi_gpio/binary_sensor.py
Normal file
106
homeassistant/components/remote_rpi_gpio/binary_sensor.py
Normal file
@ -0,0 +1,106 @@
|
||||
"""Support for binary sensor using RPi GPIO."""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import requests
|
||||
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDevice, PLATFORM_SCHEMA)
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from . import (CONF_BOUNCETIME, CONF_PULL_MODE, CONF_INVERT_LOGIC,
|
||||
DEFAULT_BOUNCETIME, DEFAULT_INVERT_LOGIC, DEFAULT_PULL_MODE)
|
||||
from .. import remote_rpi_gpio
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_PORTS = 'ports'
|
||||
|
||||
_SENSORS_SCHEMA = vol.Schema({
|
||||
cv.positive_int: cv.string,
|
||||
})
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Required(CONF_PORTS): _SENSORS_SCHEMA,
|
||||
vol.Optional(CONF_INVERT_LOGIC,
|
||||
default=DEFAULT_INVERT_LOGIC): cv.boolean,
|
||||
vol.Optional(CONF_BOUNCETIME,
|
||||
default=DEFAULT_BOUNCETIME): cv.positive_int,
|
||||
vol.Optional(CONF_PULL_MODE,
|
||||
default=DEFAULT_PULL_MODE): cv.string,
|
||||
})
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Raspberry PI GPIO devices."""
|
||||
address = config['host']
|
||||
invert_logic = config[CONF_INVERT_LOGIC]
|
||||
pull_mode = config[CONF_PULL_MODE]
|
||||
ports = config['ports']
|
||||
bouncetime = config[CONF_BOUNCETIME]/1000
|
||||
|
||||
devices = []
|
||||
for port_num, port_name in ports.items():
|
||||
try:
|
||||
button = remote_rpi_gpio.setup_input(address,
|
||||
port_num,
|
||||
pull_mode,
|
||||
bouncetime)
|
||||
except (ValueError, IndexError, KeyError, IOError):
|
||||
return
|
||||
new_sensor = RemoteRPiGPIOBinarySensor(port_name, button, invert_logic)
|
||||
devices.append(new_sensor)
|
||||
|
||||
add_entities(devices, True)
|
||||
|
||||
|
||||
class RemoteRPiGPIOBinarySensor(BinarySensorDevice):
|
||||
"""Represent a binary sensor that uses a Remote Raspberry Pi GPIO."""
|
||||
|
||||
def __init__(self, name, button, invert_logic):
|
||||
"""Initialize the RPi binary sensor."""
|
||||
self._name = name
|
||||
self._invert_logic = invert_logic
|
||||
self._state = False
|
||||
self._button = button
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Run when entity about to be added to hass."""
|
||||
def read_gpio():
|
||||
"""Read state from GPIO."""
|
||||
self._state = remote_rpi_gpio.read_input(self._button)
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
self._button.when_released = read_gpio
|
||||
self._button.when_pressed = read_gpio
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return the state of the entity."""
|
||||
return self._state != self._invert_logic
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of this sensor, from DEVICE_CLASSES."""
|
||||
return
|
||||
|
||||
def update(self):
|
||||
"""Update the GPIO state."""
|
||||
try:
|
||||
self._state = remote_rpi_gpio.read_input(self._button)
|
||||
except requests.exceptions.ConnectionError:
|
||||
return
|
10
homeassistant/components/remote_rpi_gpio/manifest.json
Normal file
10
homeassistant/components/remote_rpi_gpio/manifest.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"domain": "remote_rpi_gpio",
|
||||
"name": "remote_rpi_gpio",
|
||||
"documentation": "https://www.home-assistant.io/components/remote_rpi_gpio",
|
||||
"requirements": [
|
||||
"gpiozero==1.4.1"
|
||||
],
|
||||
"dependencies": [],
|
||||
"codeowners": []
|
||||
}
|
91
homeassistant/components/remote_rpi_gpio/switch.py
Normal file
91
homeassistant/components/remote_rpi_gpio/switch.py
Normal file
@ -0,0 +1,91 @@
|
||||
"""Allows to configure a switch using RPi GPIO."""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.switch import SwitchDevice, PLATFORM_SCHEMA
|
||||
from homeassistant.const import DEVICE_DEFAULT_NAME, CONF_HOST
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from . import CONF_INVERT_LOGIC, DEFAULT_INVERT_LOGIC
|
||||
from .. import remote_rpi_gpio
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_PORTS = 'ports'
|
||||
|
||||
_SENSORS_SCHEMA = vol.Schema({
|
||||
cv.positive_int: cv.string,
|
||||
})
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Required(CONF_PORTS): _SENSORS_SCHEMA,
|
||||
vol.Optional(CONF_INVERT_LOGIC,
|
||||
default=DEFAULT_INVERT_LOGIC): cv.boolean
|
||||
})
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Remote Raspberry PI GPIO devices."""
|
||||
address = config[CONF_HOST]
|
||||
invert_logic = config[CONF_INVERT_LOGIC]
|
||||
ports = config[CONF_PORTS]
|
||||
|
||||
devices = []
|
||||
for port, name in ports.items():
|
||||
try:
|
||||
led = remote_rpi_gpio.setup_output(
|
||||
address, port, invert_logic)
|
||||
except (ValueError, IndexError, KeyError, IOError):
|
||||
return
|
||||
new_switch = RemoteRPiGPIOSwitch(name, led, invert_logic)
|
||||
devices.append(new_switch)
|
||||
|
||||
add_entities(devices)
|
||||
|
||||
|
||||
class RemoteRPiGPIOSwitch(SwitchDevice):
|
||||
"""Representation of a Remtoe Raspberry Pi GPIO."""
|
||||
|
||||
def __init__(self, name, led, invert_logic):
|
||||
"""Initialize the pin."""
|
||||
self._name = name or DEVICE_DEFAULT_NAME
|
||||
self._state = False
|
||||
self._invert_logic = invert_logic
|
||||
self._switch = led
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the switch."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def assumed_state(self):
|
||||
"""If unable to access real state of the entity."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if device is on."""
|
||||
return self._state
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn the device on."""
|
||||
remote_rpi_gpio.write_output(self._switch,
|
||||
0 if self._invert_logic else 1)
|
||||
self._state = True
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn the device off."""
|
||||
remote_rpi_gpio.write_output(self._switch,
|
||||
1 if self._invert_logic else 0)
|
||||
self._state = False
|
||||
self.schedule_update_ha_state()
|
@ -518,6 +518,9 @@ googledevices==1.0.2
|
||||
# homeassistant.components.google_travel_time
|
||||
googlemaps==2.5.1
|
||||
|
||||
# homeassistant.components.remote_rpi_gpio
|
||||
gpiozero==1.4.1
|
||||
|
||||
# homeassistant.components.gpsd
|
||||
gps3==0.33.3
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user