mirror of
https://github.com/thecode/ha-rpi_gpio.git
synced 2025-07-17 15:56:32 +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
|
- port: 11
|
||||||
name: "Fan Office"
|
name: "Fan Office"
|
||||||
unique_id: "fan_office_switch_port_11"
|
unique_id: "fan_office_switch_port_11"
|
||||||
|
persistent: true
|
||||||
- port: 12
|
- port: 12
|
||||||
name: "Light Desk"
|
name: "Light Desk"
|
||||||
unique_id: "light_desk_switch_port_12"
|
unique_id: "light_desk_switch_port_12"
|
||||||
@ -168,6 +169,7 @@ switch:
|
|||||||
| `name` | yes | | string | The name for the switch entity |
|
| `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 |
|
| `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 |
|
| `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.
|
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."""
|
"""Allows to configure a switch using RPi GPIO."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
@ -10,20 +11,24 @@ from homeassistant.const import (
|
|||||||
CONF_SWITCHES,
|
CONF_SWITCHES,
|
||||||
CONF_UNIQUE_ID,
|
CONF_UNIQUE_ID,
|
||||||
DEVICE_DEFAULT_NAME,
|
DEVICE_DEFAULT_NAME,
|
||||||
|
STATE_ON,
|
||||||
)
|
)
|
||||||
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
|
||||||
from homeassistant.helpers.reload import setup_reload_service
|
from homeassistant.helpers.reload import setup_reload_service
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
|
|
||||||
from . import DOMAIN, PLATFORMS, setup_output, write_output
|
from . import DOMAIN, PLATFORMS, setup_output, write_output
|
||||||
|
|
||||||
CONF_PULL_MODE = "pull_mode"
|
CONF_PULL_MODE = "pull_mode"
|
||||||
CONF_PORTS = "ports"
|
CONF_PORTS = "ports"
|
||||||
CONF_INVERT_LOGIC = "invert_logic"
|
CONF_INVERT_LOGIC = "invert_logic"
|
||||||
|
CONF_PERSISTENT = "persistent"
|
||||||
|
|
||||||
DEFAULT_INVERT_LOGIC = False
|
DEFAULT_INVERT_LOGIC = False
|
||||||
|
DEFAULT_PERSISTENT = False
|
||||||
|
|
||||||
_SWITCHES_LEGACY_SCHEMA = vol.Schema({cv.positive_int: cv.string})
|
_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_NAME): cv.string,
|
||||||
vol.Required(CONF_PORT): cv.positive_int,
|
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_PERSISTENT, default=DEFAULT_PERSISTENT): cv.boolean,
|
||||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -45,6 +51,7 @@ PLATFORM_SCHEMA = vol.All(
|
|||||||
cv.ensure_list, [_SWITCH_SCHEMA]
|
cv.ensure_list, [_SWITCH_SCHEMA]
|
||||||
),
|
),
|
||||||
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_PERSISTENT, default=DEFAULT_PERSISTENT): cv.boolean,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
cv.has_at_least_one_key(CONF_PORTS, CONF_SWITCHES),
|
cv.has_at_least_one_key(CONF_PORTS, CONF_SWITCHES),
|
||||||
@ -65,6 +72,16 @@ def setup_platform(
|
|||||||
switches_conf = config.get(CONF_SWITCHES)
|
switches_conf = config.get(CONF_SWITCHES)
|
||||||
if switches_conf is not None:
|
if switches_conf is not None:
|
||||||
for switch in switches_conf:
|
for switch in switches_conf:
|
||||||
|
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(
|
switches.append(
|
||||||
RPiGPIOSwitch(
|
RPiGPIOSwitch(
|
||||||
switch[CONF_NAME],
|
switch[CONF_NAME],
|
||||||
@ -78,9 +95,13 @@ def setup_platform(
|
|||||||
return
|
return
|
||||||
|
|
||||||
invert_logic = config[CONF_INVERT_LOGIC]
|
invert_logic = config[CONF_INVERT_LOGIC]
|
||||||
|
persistent = config[CONF_PERSISTENT]
|
||||||
|
|
||||||
ports = config[CONF_PORTS]
|
ports = config[CONF_PORTS]
|
||||||
for port, name in ports.items():
|
for port, name in ports.items():
|
||||||
|
if persistent:
|
||||||
|
switches.append(PersistentRPiGPIOSwitch(name, port, invert_logic))
|
||||||
|
else:
|
||||||
switches.append(RPiGPIOSwitch(name, port, invert_logic))
|
switches.append(RPiGPIOSwitch(name, port, invert_logic))
|
||||||
|
|
||||||
add_entities(switches)
|
add_entities(switches)
|
||||||
@ -89,7 +110,7 @@ def setup_platform(
|
|||||||
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, unique_id=None):
|
def __init__(self, name, port, invert_logic, unique_id=None, skip_reset=False):
|
||||||
"""Initialize the pin."""
|
"""Initialize the pin."""
|
||||||
self._attr_name = name or DEVICE_DEFAULT_NAME
|
self._attr_name = name or DEVICE_DEFAULT_NAME
|
||||||
self._attr_unique_id = unique_id
|
self._attr_unique_id = unique_id
|
||||||
@ -98,21 +119,42 @@ class RPiGPIOSwitch(SwitchEntity):
|
|||||||
self._invert_logic = invert_logic
|
self._invert_logic = invert_logic
|
||||||
self._state = False
|
self._state = False
|
||||||
setup_output(self._port)
|
setup_output(self._port)
|
||||||
|
if not skip_reset:
|
||||||
write_output(self._port, 1 if self._invert_logic else 0)
|
write_output(self._port, 1 if self._invert_logic else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self) -> bool | None:
|
||||||
"""Return true if device is on."""
|
"""Return true if device is on."""
|
||||||
return self._state
|
return self._state
|
||||||
|
|
||||||
def turn_on(self, **kwargs):
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Turn the device on."""
|
"""Turn the device on."""
|
||||||
write_output(self._port, 0 if self._invert_logic else 1)
|
write_output(self._port, 0 if self._invert_logic else 1)
|
||||||
self._state = True
|
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."""
|
"""Turn the device off."""
|
||||||
write_output(self._port, 1 if self._invert_logic else 0)
|
write_output(self._port, 1 if self._invert_logic else 0)
|
||||||
self._state = False
|
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
|
- port: 11
|
||||||
name: "Fan Office"
|
name: "Fan Office"
|
||||||
unique_id: "fan_office_switch_port_11"
|
unique_id: "fan_office_switch_port_11"
|
||||||
|
persistent: true
|
||||||
- port: 12
|
- port: 12
|
||||||
name: "Light Desk"
|
name: "Light Desk"
|
||||||
unique_id: "light_desk_switch_port_12"
|
unique_id: "light_desk_switch_port_12"
|
||||||
@ -156,6 +157,7 @@ switch:
|
|||||||
| `name` | yes | | string | The name for the switch entity |
|
| `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 |
|
| `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 |
|
| `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.
|
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