mirror of
https://github.com/thecode/ha-rpi_gpio.git
synced 2025-04-19 12:27:17 +00:00
Add the option to have persistent switches (#266)
* Add the option to have persistent switches * update README * Make the same changes in the info.md file.
This commit is contained in:
parent
87e6bcfd9c
commit
14516ec30a
@ -154,6 +154,7 @@ switch:
|
||||
- port: 11
|
||||
name: "Fan Office"
|
||||
unique_id: "fan_office_switch_port_11"
|
||||
persistent: true
|
||||
- port: 12
|
||||
name: "Light Desk"
|
||||
unique_id: "light_desk_switch_port_12"
|
||||
@ -168,6 +169,7 @@ switch:
|
||||
| `name` | yes | | string | The name for the switch entity |
|
||||
| `unique_id` | no | | string | An ID that uniquely identifies the switch. Set this to a unique value to allow customization through the UI |
|
||||
| `invert_logic` | no | `false` | boolean | If true, inverts the output logic to ACTIVE LOW |
|
||||
| `persistent` | no | `false` | boolean | If true, the switch state will be persistent in HA and will be restored if HA restart / crash |
|
||||
|
||||
For more details about the GPIO layout, visit the Wikipedia [article](https://en.wikipedia.org/wiki/Raspberry_Pi#General_purpose_input-output_(GPIO)_connector) about the Raspberry Pi.
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
"""Allows to configure a switch using RPi GPIO."""
|
||||
from __future__ import annotations
|
||||
from typing import Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
@ -10,20 +11,24 @@ from homeassistant.const import (
|
||||
CONF_SWITCHES,
|
||||
CONF_UNIQUE_ID,
|
||||
DEVICE_DEFAULT_NAME,
|
||||
STATE_ON,
|
||||
)
|
||||
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.typing import ConfigType, DiscoveryInfoType
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
|
||||
from . import DOMAIN, PLATFORMS, setup_output, write_output
|
||||
|
||||
CONF_PULL_MODE = "pull_mode"
|
||||
CONF_PORTS = "ports"
|
||||
CONF_INVERT_LOGIC = "invert_logic"
|
||||
CONF_PERSISTENT = "persistent"
|
||||
|
||||
DEFAULT_INVERT_LOGIC = False
|
||||
DEFAULT_PERSISTENT = False
|
||||
|
||||
_SWITCHES_LEGACY_SCHEMA = vol.Schema({cv.positive_int: cv.string})
|
||||
|
||||
@ -32,6 +37,7 @@ _SWITCH_SCHEMA = vol.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_PERSISTENT, default=DEFAULT_PERSISTENT): cv.boolean,
|
||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||
}
|
||||
)
|
||||
@ -45,6 +51,7 @@ PLATFORM_SCHEMA = vol.All(
|
||||
cv.ensure_list, [_SWITCH_SCHEMA]
|
||||
),
|
||||
vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean,
|
||||
vol.Optional(CONF_PERSISTENT, default=DEFAULT_PERSISTENT): cv.boolean,
|
||||
},
|
||||
),
|
||||
cv.has_at_least_one_key(CONF_PORTS, CONF_SWITCHES),
|
||||
@ -65,31 +72,45 @@ def setup_platform(
|
||||
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),
|
||||
if switch[CONF_PERSISTENT]:
|
||||
switches.append(
|
||||
PersistentRPiGPIOSwitch(
|
||||
switch[CONF_NAME],
|
||||
switch[CONF_PORT],
|
||||
switch[CONF_INVERT_LOGIC],
|
||||
switch.get(CONF_UNIQUE_ID),
|
||||
)
|
||||
)
|
||||
else:
|
||||
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]
|
||||
persistent = config[CONF_PERSISTENT]
|
||||
|
||||
ports = config[CONF_PORTS]
|
||||
for port, name in ports.items():
|
||||
switches.append(RPiGPIOSwitch(name, port, invert_logic))
|
||||
if persistent:
|
||||
switches.append(PersistentRPiGPIOSwitch(name, port, invert_logic))
|
||||
else:
|
||||
switches.append(RPiGPIOSwitch(name, port, invert_logic))
|
||||
|
||||
add_entities(switches)
|
||||
|
||||
|
||||
class RPiGPIOSwitch(SwitchEntity):
|
||||
"""Representation of a Raspberry Pi GPIO."""
|
||||
"""Representation of a Raspberry Pi GPIO."""
|
||||
|
||||
def __init__(self, name, port, invert_logic, unique_id=None):
|
||||
def __init__(self, name, port, invert_logic, unique_id=None, skip_reset=False):
|
||||
"""Initialize the pin."""
|
||||
self._attr_name = name or DEVICE_DEFAULT_NAME
|
||||
self._attr_unique_id = unique_id
|
||||
@ -98,21 +119,42 @@ class RPiGPIOSwitch(SwitchEntity):
|
||||
self._invert_logic = invert_logic
|
||||
self._state = False
|
||||
setup_output(self._port)
|
||||
write_output(self._port, 1 if self._invert_logic else 0)
|
||||
if not skip_reset:
|
||||
write_output(self._port, 1 if self._invert_logic else 0)
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
def is_on(self) -> bool | None:
|
||||
"""Return true if device is on."""
|
||||
return self._state
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
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()
|
||||
self.async_write_ha_state()
|
||||
|
||||
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()
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class PersistentRPiGPIOSwitch(RPiGPIOSwitch, RestoreEntity):
|
||||
"""Representation of a persistent Raspberry Pi GPIO."""
|
||||
|
||||
def __init__(self, name, port, invert_logic, unique_id=None):
|
||||
"""Initialize the pin."""
|
||||
super().__init__(name, port, invert_logic, unique_id, True)
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Call when the switch is added to hass."""
|
||||
await super().async_added_to_hass()
|
||||
state = await self.async_get_last_state()
|
||||
if not state:
|
||||
return
|
||||
self._state = True if state.state == STATE_ON else False
|
||||
if self._state:
|
||||
await self.async_turn_on()
|
||||
else:
|
||||
await self.async_turn_off()
|
2
info.md
2
info.md
@ -142,6 +142,7 @@ switch:
|
||||
- port: 11
|
||||
name: "Fan Office"
|
||||
unique_id: "fan_office_switch_port_11"
|
||||
persistent: true
|
||||
- port: 12
|
||||
name: "Light Desk"
|
||||
unique_id: "light_desk_switch_port_12"
|
||||
@ -156,6 +157,7 @@ switch:
|
||||
| `name` | yes | | string | The name for the switch entity |
|
||||
| `unique_id` | no | | string | An ID that uniquely identifies the switch. Set this to a unique value to allow customization through the UI |
|
||||
| `invert_logic` | no | `false` | boolean | If true, inverts the output logic to ACTIVE LOW |
|
||||
| `persistent` | no | `false` | boolean | If true, the switch state will be persistent in HA and will be restored if HA restart / crash |
|
||||
|
||||
For more details about the GPIO layout, visit the Wikipedia [article](https://en.wikipedia.org/wiki/Raspberry_Pi#General_purpose_input-output_(GPIO)_connector) about the Raspberry Pi.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user