Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ omit =
homeassistant/components/openweathermap/sensor.py
homeassistant/components/openweathermap/weather.py
homeassistant/components/opple/light.py
homeassistant/components/orangepi_gpio/*
homeassistant/components/orvibo/switch.py
homeassistant/components/osramlightify/light.py
homeassistant/components/otp/sensor.py
Expand Down
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ homeassistant/components/ohmconnect/* @robbiet480
homeassistant/components/onboarding/* @home-assistant/core
homeassistant/components/openuv/* @bachya
homeassistant/components/openweathermap/* @fabaff
homeassistant/components/orangepi_gpio/* @pascallj
homeassistant/components/owlet/* @oblogic7
homeassistant/components/panel_custom/* @home-assistant/core
homeassistant/components/panel_iframe/* @home-assistant/core
Expand Down
81 changes: 81 additions & 0 deletions homeassistant/components/orangepi_gpio/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""Support for controlling GPIO pins of a Orange Pi."""
import logging

from homeassistant.const import (
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)

_LOGGER = logging.getLogger(__name__)

CONF_PINMODE = 'pinmode'
Comment thread
pascallj marked this conversation as resolved.
DOMAIN = 'orangepi_gpio'
PINMODES = ['pc', 'zeroplus', 'zeroplus2', 'deo', 'neocore2']


def setup(hass, config):
"""Set up the Orange Pi GPIO component."""
from OPi import GPIO

def cleanup_gpio(event):
"""Stuff to do before stopping."""
GPIO.cleanup()

def prepare_gpio(event):
"""Stuff to do when home assistant starts."""
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, cleanup_gpio)

hass.bus.listen_once(EVENT_HOMEASSISTANT_START, prepare_gpio)
return True


def setup_mode(mode):
"""Set GPIO pin mode."""
from OPi import GPIO

if mode == 'pc':
import orangepi.pc
GPIO.setmode(orangepi.pc.BOARD)
elif mode == 'zeroplus':
import orangepi.zeroplus
GPIO.setmode(orangepi.zeroplus.BOARD)
elif mode == 'zeroplus2':
import orangepi.zeroplus
GPIO.setmode(orangepi.zeroplus2.BOARD)
elif mode == 'duo':
import nanopi.duo
GPIO.setmode(nanopi.duo.BOARD)
elif mode == 'neocore2':
import nanopi.neocore2
GPIO.setmode(nanopi.neocore2.BOARD)


def setup_output(port):
"""Set up a GPIO as output."""
from OPi import GPIO
GPIO.setup(port, GPIO.OUT)


def setup_input(port):
"""Set up a GPIO as input."""
from OPi import GPIO
GPIO.setup(port, GPIO.IN)


def write_output(port, value):
"""Write a value to a GPIO."""
from OPi import GPIO
GPIO.output(port, value)


def read_input(port):
"""Read a value from a GPIO."""
from OPi import GPIO
return GPIO.input(port)


def edge_detect(port, event_callback):
"""Add detection for RISING and FALLING events."""
from OPi import GPIO
GPIO.add_event_detect(
port,
GPIO.BOTH,
callback=event_callback)
68 changes: 68 additions & 0 deletions homeassistant/components/orangepi_gpio/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Support for binary sensor using Orange Pi GPIO."""
import logging

from homeassistant.components import orangepi_gpio
Comment thread
pascallj marked this conversation as resolved.
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.const import DEVICE_DEFAULT_NAME

from . import CONF_PINMODE
from .const import CONF_INVERT_LOGIC, CONF_PORTS, PORT_SCHEMA

_LOGGER = logging.getLogger(__name__)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(PORT_SCHEMA)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we know that more platforms are likely incoming, it would be better to have all config under the integrating component section, and set up platforms via discovery helper. See the netgear_lte component for example.



def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Orange Pi GPIO devices."""
pinmode = config[CONF_PINMODE]
orangepi_gpio.setup_mode(pinmode)

invert_logic = config[CONF_INVERT_LOGIC]

binary_sensors = []
ports = config[CONF_PORTS]
for port_num, port_name in ports.items():
binary_sensors.append(OPiGPIOBinarySensor(
port_name, port_num, invert_logic))
add_entities(binary_sensors, True)


class OPiGPIOBinarySensor(BinarySensorDevice):
"""Represent a binary sensor that uses Orange Pi GPIO."""

def __init__(self, name, port, invert_logic):
"""Initialize the Orange Pi binary sensor."""
self._name = name or DEVICE_DEFAULT_NAME
self._port = port
self._invert_logic = invert_logic
self._state = None

orangepi_gpio.setup_input(self._port)
Comment thread
pascallj marked this conversation as resolved.

def read_gpio(port):
"""Read state from GPIO."""
self._state = orangepi_gpio.read_input(self._port)
self.schedule_update_ha_state()

orangepi_gpio.edge_detect(self._port, read_gpio)
Comment thread
pascallj marked this conversation as resolved.

@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

def update(self):
"""Update the GPIO state."""
self._state = orangepi_gpio.read_input(self._port)
21 changes: 21 additions & 0 deletions homeassistant/components/orangepi_gpio/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Constants for Orange Pi GPIO."""
import voluptuous as vol

from homeassistant.helpers import config_validation as cv

from . import CONF_PINMODE, PINMODES

CONF_INVERT_LOGIC = 'invert_logic'
CONF_PORTS = 'ports'

DEFAULT_INVERT_LOGIC = False

_SENSORS_SCHEMA = vol.Schema({
cv.positive_int: cv.string,
})

PORT_SCHEMA = {
vol.Required(CONF_PORTS): _SENSORS_SCHEMA,
vol.Required(CONF_PINMODE): vol.In(PINMODES),
vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean,
}
12 changes: 12 additions & 0 deletions homeassistant/components/orangepi_gpio/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"domain": "orangepi_gpio",
"name": "Orangepi GPIO",
"documentation": "https://www.home-assistant.io/components/orangepi_gpio",
"requirements": [
"OPi.GPIO==0.3.6"
],
"dependencies": [],
"codeowners": [
"@pascallj"
]
}
3 changes: 3 additions & 0 deletions requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ HAP-python==2.4.2
# homeassistant.components.mastodon
Mastodon.py==1.3.1

# homeassistant.components.orangepi_gpio
OPi.GPIO==0.3.6

# homeassistant.components.github
PyGithub==1.43.5

Expand Down