mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 17:57:11 +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/reddit/*
|
||||||
homeassistant/components/rejseplanen/sensor.py
|
homeassistant/components/rejseplanen/sensor.py
|
||||||
homeassistant/components/remember_the_milk/__init__.py
|
homeassistant/components/remember_the_milk/__init__.py
|
||||||
|
homeassistant/components/remote_rpi_gpio/*
|
||||||
homeassistant/components/rest/binary_sensor.py
|
homeassistant/components/rest/binary_sensor.py
|
||||||
homeassistant/components/rest/notify.py
|
homeassistant/components/rest/notify.py
|
||||||
homeassistant/components/rest/switch.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
|
# homeassistant.components.google_travel_time
|
||||||
googlemaps==2.5.1
|
googlemaps==2.5.1
|
||||||
|
|
||||||
|
# homeassistant.components.remote_rpi_gpio
|
||||||
|
gpiozero==1.4.1
|
||||||
|
|
||||||
# homeassistant.components.gpsd
|
# homeassistant.components.gpsd
|
||||||
gps3==0.33.3
|
gps3==0.33.3
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user