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:
Rami Mosleh 2022-10-05 16:12:35 +03:00 committed by GitHub
parent c87c8595fa
commit 5c5fa6f2b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 112 additions and 72 deletions

View File

@ -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,
)

View File

@ -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)

View File

@ -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)

View File

@ -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",

View File

@ -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)

View File

@ -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",