mirror of
https://github.com/thecode/ha-rpi_gpio.git
synced 2025-04-19 12:27:17 +00:00
Config-flow-switch (#112)
* Add config flow to rpi_gpio * remove title * fix removing entities in config_flow and in cover.py * Set config entry per port Limit PR to binary_sensor * restore original files * Add name key to give the device a name * Add switch to config flow
This commit is contained in:
parent
c87c8595fa
commit
5c5fa6f2b4
@ -20,8 +20,10 @@ from .const import (
|
||||
CONF_BOUNCETIME,
|
||||
CONF_CONFIGURED_PORTS,
|
||||
CONF_GPIO,
|
||||
CONF_INVERT_LOGIC,
|
||||
CONF_PULL_MODE,
|
||||
DEFAULT_BOUNCETIME,
|
||||
DEFAULT_INVERT_LOGIC,
|
||||
DEFAULT_PULL_MODE,
|
||||
DOMAIN,
|
||||
)
|
||||
@ -126,3 +128,11 @@ class RpiGPIO:
|
||||
callback=edge_detected,
|
||||
bouncetime=entry.options.get(CONF_BOUNCETIME, DEFAULT_BOUNCETIME),
|
||||
)
|
||||
elif entry.data[CONF_PLATFORM] == Platform.SWITCH:
|
||||
GPIO.setup(
|
||||
int(entry.data[CONF_PORT]),
|
||||
GPIO.OUT,
|
||||
initial=GPIO.HIGH
|
||||
if entry.options.get(CONF_INVERT_LOGIC, DEFAULT_INVERT_LOGIC)
|
||||
else GPIO.LOW,
|
||||
)
|
||||
|
@ -7,11 +7,9 @@ from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensor
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_NAME,
|
||||
CONF_PLATFORM,
|
||||
CONF_PORT,
|
||||
CONF_SENSORS,
|
||||
CONF_UNIQUE_ID,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
@ -87,7 +85,7 @@ async def async_setup_entry(
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up rpi_power binary sensor."""
|
||||
"""Set up rpi_gpio binary sensor."""
|
||||
rpi_gpio: RpiGPIO = hass.data[DOMAIN][CONF_GPIO]
|
||||
await hass.async_add_executor_job(rpi_gpio.setup_port, entry)
|
||||
|
||||
|
@ -84,6 +84,15 @@ def _get_options_schema(platform: Platform, options: dict[str, Any]) -> vol.Sche
|
||||
),
|
||||
}
|
||||
)
|
||||
if platform == Platform.SWITCH:
|
||||
return vol.Schema(
|
||||
{
|
||||
vol.Optional(
|
||||
CONF_INVERT_LOGIC,
|
||||
default=options.get(CONF_INVERT_LOGIC, DEFAULT_INVERT_LOGIC),
|
||||
): selector.BooleanSelector()
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _get_avaiable_ports(hass: HomeAssistant) -> list[selector.SelectOptionDict]:
|
||||
@ -114,14 +123,13 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a flow initialized by the user."""
|
||||
return self.async_show_menu(
|
||||
step_id="user",
|
||||
menu_options=["add_binary_sensor"],
|
||||
menu_options=["add_binary_sensor", "add_switch"],
|
||||
)
|
||||
|
||||
async def async_step_add_binary_sensor(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
"""Handle adding a binary sensor entry."""
|
||||
|
||||
if user_input is None:
|
||||
|
||||
return self.async_show_form(
|
||||
@ -147,12 +155,40 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
data={CONF_PLATFORM: Platform.BINARY_SENSOR, **user_input},
|
||||
)
|
||||
|
||||
async def async_step_add_switch(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
"""Handle adding a switch."""
|
||||
if user_input is None:
|
||||
return self.async_show_form(
|
||||
step_id="add_switch",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_NAME): selector.TextSelector(),
|
||||
vol.Required(CONF_PORT, default=[]): selector.SelectSelector(
|
||||
selector.SelectSelectorConfig(
|
||||
options=_get_avaiable_ports(self.hass),
|
||||
mode=selector.SelectSelectorMode.DROPDOWN,
|
||||
)
|
||||
),
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
await self.async_set_unique_id(user_input[CONF_PORT])
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
return self.async_create_entry(
|
||||
title=f"{user_input[CONF_NAME]} (GPIO {user_input[CONF_PORT]})",
|
||||
data={CONF_PLATFORM: Platform.SWITCH, **user_input},
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(
|
||||
config_entry: config_entries.ConfigEntry,
|
||||
) -> RpiGPIOOptionsFlowHandler:
|
||||
"""Options callback for AccuWeather."""
|
||||
"""Options callback for Rpi GPIO."""
|
||||
return RpiGPIOOptionsFlowHandler(config_entry)
|
||||
|
||||
|
||||
|
@ -3,9 +3,16 @@
|
||||
"step": {
|
||||
"add_binary_sensor": {
|
||||
"data": {
|
||||
"name": "[%key:common::config_flow::data::name%]",
|
||||
"port": "Select port to set as binary sensor"
|
||||
}
|
||||
},
|
||||
"add_switch": {
|
||||
"data": {
|
||||
"name": "[%key:common::config_flow::data::name%]",
|
||||
"port": "Select port to set as switch"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"menu_options": {
|
||||
"add_binary_sensor": "Add Binary sensor",
|
||||
|
@ -1,29 +1,28 @@
|
||||
"""Allows to configure a switch using RPi GPIO."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
|
||||
from homeassistant.const import (
|
||||
CONF_NAME,
|
||||
CONF_PORT,
|
||||
CONF_SWITCHES,
|
||||
CONF_UNIQUE_ID,
|
||||
DEVICE_DEFAULT_NAME,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_NAME, CONF_PORT, CONF_SWITCHES, CONF_UNIQUE_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.reload import setup_reload_service
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
from . import DOMAIN, PLATFORMS, setup_output, write_output
|
||||
|
||||
CONF_PULL_MODE = "pull_mode"
|
||||
CONF_PORTS = "ports"
|
||||
CONF_INVERT_LOGIC = "invert_logic"
|
||||
|
||||
DEFAULT_INVERT_LOGIC = False
|
||||
from . import RpiGPIO
|
||||
from .const import (
|
||||
CONF_GPIO,
|
||||
CONF_INVERT_LOGIC,
|
||||
CONF_PORTS,
|
||||
DEFAULT_INVERT_LOGIC,
|
||||
DOMAIN,
|
||||
)
|
||||
from .entity import RpiGPIOEntity
|
||||
|
||||
_SWITCHES_LEGACY_SCHEMA = vol.Schema({cv.positive_int: cv.string})
|
||||
|
||||
@ -51,68 +50,51 @@ PLATFORM_SCHEMA = vol.All(
|
||||
)
|
||||
|
||||
|
||||
def setup_platform(
|
||||
async def async_setup_platform(
|
||||
hass: HomeAssistant,
|
||||
config: ConfigType,
|
||||
add_entities: AddEntitiesCallback,
|
||||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> None:
|
||||
"""Set up the Raspberry PI GPIO devices."""
|
||||
setup_reload_service(hass, DOMAIN, PLATFORMS)
|
||||
|
||||
switches = []
|
||||
|
||||
switches_conf = config.get(CONF_SWITCHES)
|
||||
if switches_conf is not None:
|
||||
for switch in switches_conf:
|
||||
switches.append(
|
||||
RPiGPIOSwitch(
|
||||
switch[CONF_NAME],
|
||||
switch[CONF_PORT],
|
||||
switch[CONF_INVERT_LOGIC],
|
||||
switch.get(CONF_UNIQUE_ID),
|
||||
)
|
||||
)
|
||||
|
||||
add_entities(switches, True)
|
||||
return
|
||||
|
||||
invert_logic = config[CONF_INVERT_LOGIC]
|
||||
|
||||
ports = config[CONF_PORTS]
|
||||
for port, name in ports.items():
|
||||
switches.append(RPiGPIOSwitch(name, port, invert_logic))
|
||||
|
||||
add_entities(switches)
|
||||
async_create_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
"deprecated_yaml",
|
||||
breaks_in_ha_version="2022.11.0",
|
||||
is_fixable=False,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="deprecated_yaml",
|
||||
)
|
||||
|
||||
|
||||
class RPiGPIOSwitch(SwitchEntity):
|
||||
"""Representation of a Raspberry Pi GPIO."""
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up rpi_gpio switch."""
|
||||
rpi_gpio: RpiGPIO = hass.data[DOMAIN][CONF_GPIO]
|
||||
await hass.async_add_executor_job(rpi_gpio.setup_port, entry)
|
||||
|
||||
def __init__(self, name, port, invert_logic, unique_id=None):
|
||||
"""Initialize the pin."""
|
||||
self._attr_name = name or DEVICE_DEFAULT_NAME
|
||||
self._attr_unique_id = unique_id
|
||||
self._attr_should_poll = False
|
||||
self._port = port
|
||||
self._invert_logic = invert_logic
|
||||
self._state = False
|
||||
setup_output(self._port)
|
||||
write_output(self._port, 1 if self._invert_logic else 0)
|
||||
async_add_entities([RPiGPIOSwitch(hass, entry, rpi_gpio)], True)
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if device is on."""
|
||||
return self._state
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
class RPiGPIOSwitch(RpiGPIOEntity, SwitchEntity):
|
||||
"""Representation of an output port as switch."""
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Update entity."""
|
||||
self._attr_is_on = (
|
||||
await self.rpi_gpio.async_read_input(self.port) != self.invert_logic
|
||||
)
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the device on."""
|
||||
write_output(self._port, 0 if self._invert_logic else 1)
|
||||
self._state = True
|
||||
self.schedule_update_ha_state()
|
||||
await self.rpi_gpio.async_write_output(self.port, 0 if self.invert_logic else 1)
|
||||
self.async_schedule_update_ha_state(True)
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the device off."""
|
||||
write_output(self._port, 1 if self._invert_logic else 0)
|
||||
self._state = False
|
||||
self.schedule_update_ha_state()
|
||||
await self.rpi_gpio.async_write_output(self.port, 1 if self.invert_logic else 0)
|
||||
self.async_schedule_update_ha_state(True)
|
||||
|
@ -3,9 +3,16 @@
|
||||
"step": {
|
||||
"add_binary_sensor": {
|
||||
"data": {
|
||||
"name": "Name",
|
||||
"port": "Select port to set as binary sensor"
|
||||
}
|
||||
},
|
||||
"add_switch": {
|
||||
"data": {
|
||||
"name": "Name",
|
||||
"port": "Select port to set as switch"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"menu_options": {
|
||||
"add_binary_sensor": "Add Binary sensor",
|
||||
|
Loading…
x
Reference in New Issue
Block a user