New config schema for supporting unique id (#40)

This commit is contained in:
Shay Levy 2022-04-02 14:04:54 +03:00 committed by GitHub
parent f2cb127dd3
commit 8ab01e7ce8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 108 additions and 44 deletions

View File

@ -6,7 +6,13 @@ import asyncio
import voluptuous as vol import voluptuous as vol
from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensorEntity from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensorEntity
from homeassistant.const import DEVICE_DEFAULT_NAME from homeassistant.const import (
CONF_NAME,
CONF_PORT,
CONF_SENSORS,
CONF_UNIQUE_ID,
DEVICE_DEFAULT_NAME,
)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -24,17 +30,34 @@ DEFAULT_BOUNCETIME = 50
DEFAULT_INVERT_LOGIC = False DEFAULT_INVERT_LOGIC = False
DEFAULT_PULL_MODE = "UP" DEFAULT_PULL_MODE = "UP"
_SENSORS_SCHEMA = vol.Schema({cv.positive_int: cv.string}) _SENSORS_LEGACY_SCHEMA = vol.Schema({cv.positive_int: cv.string})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( _SENSOR_SCHEMA = vol.Schema(
{ {
vol.Required(CONF_PORTS): _SENSORS_SCHEMA, vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_PORT): cv.positive_int,
vol.Optional(CONF_PULL_MODE, default=DEFAULT_PULL_MODE): cv.string,
vol.Optional(CONF_BOUNCETIME, default=DEFAULT_BOUNCETIME): cv.positive_int, vol.Optional(CONF_BOUNCETIME, default=DEFAULT_BOUNCETIME): cv.positive_int,
vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean, vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean,
vol.Optional(CONF_PULL_MODE, default=DEFAULT_PULL_MODE): cv.string, vol.Optional(CONF_UNIQUE_ID): cv.string,
} }
) )
PLATFORM_SCHEMA = vol.All(
PLATFORM_SCHEMA.extend(
{
vol.Exclusive(CONF_PORTS, CONF_SENSORS): _SENSORS_LEGACY_SCHEMA,
vol.Exclusive(CONF_SENSORS, CONF_SENSORS): vol.All(
cv.ensure_list, [_SENSOR_SCHEMA]
),
vol.Optional(CONF_BOUNCETIME, default=DEFAULT_BOUNCETIME): cv.positive_int,
vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean,
vol.Optional(CONF_PULL_MODE, default=DEFAULT_PULL_MODE): cv.string,
},
),
cv.has_at_least_one_key(CONF_PORTS, CONF_SENSORS),
)
def setup_platform( def setup_platform(
hass: HomeAssistant, hass: HomeAssistant,
@ -45,19 +68,38 @@ def setup_platform(
"""Set up the Raspberry PI GPIO devices.""" """Set up the Raspberry PI GPIO devices."""
setup_reload_service(hass, DOMAIN, PLATFORMS) setup_reload_service(hass, DOMAIN, PLATFORMS)
sensors = []
sensors_conf = config.get(CONF_SENSORS)
if sensors_conf is not None:
for sensor in sensors_conf:
sensors.append(
RPiGPIOBinarySensor(
sensor[CONF_NAME],
sensor[CONF_PORT],
sensor[CONF_PULL_MODE],
sensor[CONF_BOUNCETIME],
sensor[CONF_INVERT_LOGIC],
sensor.get(CONF_UNIQUE_ID),
)
)
add_entities(sensors, True)
return
pull_mode = config[CONF_PULL_MODE] pull_mode = config[CONF_PULL_MODE]
bouncetime = config[CONF_BOUNCETIME] bouncetime = config[CONF_BOUNCETIME]
invert_logic = config[CONF_INVERT_LOGIC] invert_logic = config[CONF_INVERT_LOGIC]
binary_sensors = []
ports = config[CONF_PORTS] ports = config[CONF_PORTS]
for port_num, port_name in ports.items(): for port_num, port_name in ports.items():
binary_sensors.append( sensors.append(
RPiGPIOBinarySensor( RPiGPIOBinarySensor(
port_name, port_num, pull_mode, bouncetime, invert_logic port_name, port_num, pull_mode, bouncetime, invert_logic
) )
) )
add_entities(binary_sensors, True)
add_entities(sensors, True)
class RPiGPIOBinarySensor(BinarySensorEntity): class RPiGPIOBinarySensor(BinarySensorEntity):
@ -69,9 +111,11 @@ class RPiGPIOBinarySensor(BinarySensorEntity):
self._state = await self.hass.async_add_executor_job(read_input, self._port) self._state = await self.hass.async_add_executor_job(read_input, self._port)
self.async_write_ha_state() self.async_write_ha_state()
def __init__(self, name, port, pull_mode, bouncetime, invert_logic): def __init__(self, name, port, pull_mode, bouncetime, invert_logic, unique_id=None):
"""Initialize the RPi binary sensor.""" """Initialize the RPi binary sensor."""
self._name = name or DEVICE_DEFAULT_NAME self._attr_name = name or DEVICE_DEFAULT_NAME
self._attr_unique_id = unique_id
self._attr_should_poll = False
self._port = port self._port = port
self._pull_mode = pull_mode self._pull_mode = pull_mode
self._bouncetime = bouncetime self._bouncetime = bouncetime
@ -87,16 +131,6 @@ class RPiGPIOBinarySensor(BinarySensorEntity):
edge_detect(self._port, edge_detected, self._bouncetime) edge_detect(self._port, edge_detected, self._bouncetime)
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property @property
def is_on(self): def is_on(self):
"""Return the state of the entity.""" """Return the state of the entity."""

View File

@ -6,7 +6,7 @@ from time import sleep
import voluptuous as vol import voluptuous as vol
from homeassistant.components.cover import PLATFORM_SCHEMA, CoverEntity from homeassistant.components.cover import PLATFORM_SCHEMA, CoverEntity
from homeassistant.const import CONF_COVERS, CONF_NAME from homeassistant.const import CONF_COVERS, CONF_NAME, CONF_UNIQUE_ID
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -34,6 +34,7 @@ _COVERS_SCHEMA = vol.All(
CONF_NAME: cv.string, CONF_NAME: cv.string,
CONF_RELAY_PIN: cv.positive_int, CONF_RELAY_PIN: cv.positive_int,
CONF_STATE_PIN: cv.positive_int, CONF_STATE_PIN: cv.positive_int,
vol.Optional(CONF_UNIQUE_ID): cv.string,
} }
) )
], ],
@ -76,6 +77,7 @@ def setup_platform(
relay_time, relay_time,
invert_state, invert_state,
invert_relay, invert_relay,
cover.get(CONF_UNIQUE_ID),
) )
) )
add_entities(covers) add_entities(covers)
@ -93,9 +95,11 @@ class RPiGPIOCover(CoverEntity):
relay_time, relay_time,
invert_state, invert_state,
invert_relay, invert_relay,
unique_id,
): ):
"""Initialize the cover.""" """Initialize the cover."""
self._name = name self._attr_name = name
self._attr_unique_id = unique_id
self._state = False self._state = False
self._relay_pin = relay_pin self._relay_pin = relay_pin
self._state_pin = state_pin self._state_pin = state_pin
@ -107,11 +111,6 @@ class RPiGPIOCover(CoverEntity):
setup_input(self._state_pin, self._state_pull_mode) setup_input(self._state_pin, self._state_pull_mode)
write_output(self._relay_pin, 0 if self._invert_relay else 1) write_output(self._relay_pin, 0 if self._invert_relay else 1)
@property
def name(self):
"""Return the name of the cover if any."""
return self._name
def update(self): def update(self):
"""Update the state of the cover.""" """Update the state of the cover."""
self._state = read_input(self._state_pin) self._state = read_input(self._state_pin)

View File

@ -4,7 +4,13 @@ from __future__ import annotations
import voluptuous as vol import voluptuous as vol
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
from homeassistant.const import DEVICE_DEFAULT_NAME from homeassistant.const import (
CONF_NAME,
CONF_PORT,
CONF_SWITCHES,
CONF_UNIQUE_ID,
DEVICE_DEFAULT_NAME,
)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -19,16 +25,32 @@ CONF_INVERT_LOGIC = "invert_logic"
DEFAULT_INVERT_LOGIC = False DEFAULT_INVERT_LOGIC = False
_SWITCHES_SCHEMA = vol.Schema({cv.positive_int: cv.string}) _SWITCHES_LEGACY_SCHEMA = vol.Schema({cv.positive_int: cv.string})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( _SWITCH_SCHEMA = vol.Schema(
{ {
vol.Required(CONF_PORTS): _SWITCHES_SCHEMA, vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_PORT): cv.positive_int,
vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean, vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean,
vol.Optional(CONF_UNIQUE_ID): cv.string,
} }
) )
PLATFORM_SCHEMA = vol.All(
PLATFORM_SCHEMA.extend(
{
vol.Exclusive(CONF_PORTS, CONF_SWITCHES): _SWITCHES_LEGACY_SCHEMA,
vol.Exclusive(CONF_SWITCHES, CONF_SWITCHES): vol.All(
cv.ensure_list, [_SWITCH_SCHEMA]
),
vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean,
},
),
cv.has_at_least_one_key(CONF_PORTS, CONF_SWITCHES),
)
def setup_platform( def setup_platform(
hass: HomeAssistant, hass: HomeAssistant,
config: ConfigType, config: ConfigType,
@ -38,37 +60,46 @@ def setup_platform(
"""Set up the Raspberry PI GPIO devices.""" """Set up the Raspberry PI GPIO devices."""
setup_reload_service(hass, DOMAIN, PLATFORMS) 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] invert_logic = config[CONF_INVERT_LOGIC]
switches = []
ports = config[CONF_PORTS] ports = config[CONF_PORTS]
for port, name in ports.items(): for port, name in ports.items():
switches.append(RPiGPIOSwitch(name, port, invert_logic)) switches.append(RPiGPIOSwitch(name, port, invert_logic))
add_entities(switches) add_entities(switches)
class RPiGPIOSwitch(SwitchEntity): class RPiGPIOSwitch(SwitchEntity):
"""Representation of a Raspberry Pi GPIO.""" """Representation of a Raspberry Pi GPIO."""
def __init__(self, name, port, invert_logic): def __init__(self, name, port, invert_logic, unique_id=None):
"""Initialize the pin.""" """Initialize the pin."""
self._name = name or DEVICE_DEFAULT_NAME self._attr_name = name or DEVICE_DEFAULT_NAME
self._attr_unique_id = unique_id
self._attr_should_poll = False
self._port = port self._port = port
self._invert_logic = invert_logic self._invert_logic = invert_logic
self._state = False self._state = False
setup_output(self._port) setup_output(self._port)
write_output(self._port, 1 if self._invert_logic else 0) write_output(self._port, 1 if self._invert_logic else 0)
@property
def name(self):
"""Return the name of the switch."""
return self._name
@property
def should_poll(self):
"""No polling needed."""
return False
@property @property
def is_on(self): def is_on(self):
"""Return true if device is on.""" """Return true if device is on."""