Consolidate SimpliSafe property services (#30567)
* Consolidate SimpliSafe property services * Code review comments * Code review comments * Ensure all services are admin services * Code review comments
This commit is contained in:
parent
123bef4f1e
commit
b585feb109
6 changed files with 96 additions and 139 deletions
|
@ -5,7 +5,7 @@ import logging
|
|||
|
||||
from simplipy import API
|
||||
from simplipy.errors import InvalidCredentialsError, SimplipyError
|
||||
from simplipy.system.v3 import LevelMap as V3Volume
|
||||
from simplipy.system.v3 import VOLUME_HIGH, VOLUME_LOW, VOLUME_MEDIUM, VOLUME_OFF
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import SOURCE_IMPORT
|
||||
|
@ -15,7 +15,6 @@ from homeassistant.const import (
|
|||
CONF_SCAN_INTERVAL,
|
||||
CONF_TOKEN,
|
||||
CONF_USERNAME,
|
||||
STATE_HOME,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
|
@ -30,7 +29,10 @@ from homeassistant.helpers.dispatcher import (
|
|||
)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.event import async_track_time_interval
|
||||
from homeassistant.helpers.service import verify_domain_control
|
||||
from homeassistant.helpers.service import (
|
||||
async_register_admin_service,
|
||||
verify_domain_control,
|
||||
)
|
||||
|
||||
from .config_flow import configured_instances
|
||||
from .const import DATA_CLIENT, DEFAULT_SCAN_INTERVAL, DOMAIN, TOPIC_UPDATE
|
||||
|
@ -41,24 +43,21 @@ CONF_ACCOUNTS = "accounts"
|
|||
|
||||
DATA_LISTENER = "listener"
|
||||
|
||||
ATTR_ARMED_LIGHT_STATE = "armed_light_state"
|
||||
ATTR_ARRIVAL_STATE = "arrival_state"
|
||||
ATTR_ALARM_DURATION = "alarm_duration"
|
||||
ATTR_ALARM_VOLUME = "alarm_volume"
|
||||
ATTR_CHIME_VOLUME = "chime_volume"
|
||||
ATTR_ENTRY_DELAY_AWAY = "entry_delay_away"
|
||||
ATTR_ENTRY_DELAY_HOME = "entry_delay_home"
|
||||
ATTR_EXIT_DELAY_AWAY = "exit_delay_away"
|
||||
ATTR_EXIT_DELAY_HOME = "exit_delay_home"
|
||||
ATTR_LIGHT = "light"
|
||||
ATTR_PIN_LABEL = "label"
|
||||
ATTR_PIN_LABEL_OR_VALUE = "label_or_pin"
|
||||
ATTR_PIN_VALUE = "pin"
|
||||
ATTR_SECONDS = "seconds"
|
||||
ATTR_SYSTEM_ID = "system_id"
|
||||
ATTR_TRANSITION = "transition"
|
||||
ATTR_VOLUME = "volume"
|
||||
ATTR_VOLUME_PROPERTY = "volume_property"
|
||||
ATTR_VOICE_PROMPT_VOLUME = "voice_prompt_volume"
|
||||
|
||||
STATE_AWAY = "away"
|
||||
STATE_ENTRY = "entry"
|
||||
STATE_EXIT = "exit"
|
||||
|
||||
VOLUME_PROPERTY_ALARM = "alarm"
|
||||
VOLUME_PROPERTY_CHIME = "chime"
|
||||
VOLUME_PROPERTY_VOICE_PROMPT = "voice_prompt"
|
||||
VOLUMES = [VOLUME_OFF, VOLUME_LOW, VOLUME_MEDIUM, VOLUME_HIGH]
|
||||
|
||||
SERVICE_BASE_SCHEMA = vol.Schema({vol.Required(ATTR_SYSTEM_ID): cv.positive_int})
|
||||
|
||||
|
@ -66,28 +65,33 @@ SERVICE_REMOVE_PIN_SCHEMA = SERVICE_BASE_SCHEMA.extend(
|
|||
{vol.Required(ATTR_PIN_LABEL_OR_VALUE): cv.string}
|
||||
)
|
||||
|
||||
SERVICE_SET_DELAY_SCHEMA = SERVICE_BASE_SCHEMA.extend(
|
||||
{
|
||||
vol.Required(ATTR_ARRIVAL_STATE): vol.In((STATE_AWAY, STATE_HOME)),
|
||||
vol.Required(ATTR_TRANSITION): vol.In((STATE_ENTRY, STATE_EXIT)),
|
||||
vol.Required(ATTR_SECONDS): cv.positive_int,
|
||||
}
|
||||
)
|
||||
|
||||
SERVICE_SET_LIGHT_SCHEMA = SERVICE_BASE_SCHEMA.extend(
|
||||
{vol.Required(ATTR_ARMED_LIGHT_STATE): cv.boolean}
|
||||
)
|
||||
|
||||
SERVICE_SET_PIN_SCHEMA = SERVICE_BASE_SCHEMA.extend(
|
||||
{vol.Required(ATTR_PIN_LABEL): cv.string, vol.Required(ATTR_PIN_VALUE): cv.string}
|
||||
)
|
||||
|
||||
SERVICE_SET_VOLUME_SCHEMA = SERVICE_BASE_SCHEMA.extend(
|
||||
SERVICE_SET_SYSTEM_PROPERTIES_SCHEMA = SERVICE_BASE_SCHEMA.extend(
|
||||
{
|
||||
vol.Required(ATTR_VOLUME_PROPERTY): vol.In(
|
||||
(VOLUME_PROPERTY_ALARM, VOLUME_PROPERTY_CHIME, VOLUME_PROPERTY_VOICE_PROMPT)
|
||||
vol.Optional(ATTR_ALARM_DURATION): vol.All(
|
||||
cv.time_period, lambda value: value.seconds, vol.Range(min=30, max=480)
|
||||
),
|
||||
vol.Optional(ATTR_ALARM_VOLUME): vol.All(vol.Coerce(int), vol.In(VOLUMES)),
|
||||
vol.Optional(ATTR_CHIME_VOLUME): vol.All(vol.Coerce(int), vol.In(VOLUMES)),
|
||||
vol.Optional(ATTR_ENTRY_DELAY_AWAY): vol.All(
|
||||
cv.time_period, lambda value: value.seconds, vol.Range(min=30, max=255)
|
||||
),
|
||||
vol.Optional(ATTR_ENTRY_DELAY_HOME): vol.All(
|
||||
cv.time_period, lambda value: value.seconds, vol.Range(max=255)
|
||||
),
|
||||
vol.Optional(ATTR_EXIT_DELAY_AWAY): vol.All(
|
||||
cv.time_period, lambda value: value.seconds, vol.Range(min=45, max=255)
|
||||
),
|
||||
vol.Optional(ATTR_EXIT_DELAY_HOME): vol.All(
|
||||
cv.time_period, lambda value: value.seconds, vol.Range(max=255)
|
||||
),
|
||||
vol.Optional(ATTR_LIGHT): cv.boolean,
|
||||
vol.Optional(ATTR_VOICE_PROMPT_VOLUME): vol.All(
|
||||
vol.Coerce(int), vol.In(VOLUMES)
|
||||
),
|
||||
vol.Required(ATTR_VOLUME): cv.string,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -246,47 +250,6 @@ async def async_setup_entry(hass, config_entry):
|
|||
_LOGGER.error("Error during service call: %s", err)
|
||||
return
|
||||
|
||||
@verify_system_exists
|
||||
@v3_only
|
||||
@_verify_domain_control
|
||||
async def set_alarm_duration(call):
|
||||
"""Set the duration of a running alarm."""
|
||||
system = systems[call.data[ATTR_SYSTEM_ID]]
|
||||
try:
|
||||
await system.set_alarm_duration(call.data[ATTR_SECONDS])
|
||||
except SimplipyError as err:
|
||||
_LOGGER.error("Error during service call: %s", err)
|
||||
return
|
||||
|
||||
@verify_system_exists
|
||||
@v3_only
|
||||
@_verify_domain_control
|
||||
async def set_delay(call):
|
||||
"""Set the delay duration for entry/exit, away/home (any combo)."""
|
||||
system = systems[call.data[ATTR_SYSTEM_ID]]
|
||||
coro = getattr(
|
||||
system,
|
||||
f"set_{call.data[ATTR_TRANSITION]}_delay_{call.data[ATTR_ARRIVAL_STATE]}",
|
||||
)
|
||||
|
||||
try:
|
||||
await coro(call.data[ATTR_SECONDS])
|
||||
except SimplipyError as err:
|
||||
_LOGGER.error("Error during service call: %s", err)
|
||||
return
|
||||
|
||||
@verify_system_exists
|
||||
@v3_only
|
||||
@_verify_domain_control
|
||||
async def set_armed_light(call):
|
||||
"""Turn the base station light on/off."""
|
||||
system = systems[call.data[ATTR_SYSTEM_ID]]
|
||||
try:
|
||||
await system.set_light(call.data[ATTR_ARMED_LIGHT_STATE])
|
||||
except SimplipyError as err:
|
||||
_LOGGER.error("Error during service call: %s", err)
|
||||
return
|
||||
|
||||
@verify_system_exists
|
||||
@_verify_domain_control
|
||||
async def set_pin(call):
|
||||
|
@ -301,30 +264,31 @@ async def async_setup_entry(hass, config_entry):
|
|||
@verify_system_exists
|
||||
@v3_only
|
||||
@_verify_domain_control
|
||||
async def set_volume_property(call):
|
||||
"""Set a volume parameter in an appropriate service call."""
|
||||
async def set_system_properties(call):
|
||||
"""Set one or more system parameters."""
|
||||
system = systems[call.data[ATTR_SYSTEM_ID]]
|
||||
try:
|
||||
volume = V3Volume[call.data[ATTR_VOLUME]]
|
||||
except KeyError:
|
||||
_LOGGER.error("Unknown volume string: %s", call.data[ATTR_VOLUME])
|
||||
return
|
||||
await system.set_properties(
|
||||
{
|
||||
prop: value
|
||||
for prop, value in call.data.items()
|
||||
if prop != ATTR_SYSTEM_ID
|
||||
}
|
||||
)
|
||||
except SimplipyError as err:
|
||||
_LOGGER.error("Error during service call: %s", err)
|
||||
return
|
||||
else:
|
||||
coro = getattr(system, f"set_{call.data[ATTR_VOLUME_PROPERTY]}_volume")
|
||||
await coro(volume)
|
||||
|
||||
for service, method, schema in [
|
||||
("remove_pin", remove_pin, SERVICE_REMOVE_PIN_SCHEMA),
|
||||
("set_alarm_duration", set_alarm_duration, SERVICE_SET_DELAY_SCHEMA),
|
||||
("set_delay", set_delay, SERVICE_SET_DELAY_SCHEMA),
|
||||
("set_armed_light", set_armed_light, SERVICE_SET_LIGHT_SCHEMA),
|
||||
("set_pin", set_pin, SERVICE_SET_PIN_SCHEMA),
|
||||
("set_volume_property", set_volume_property, SERVICE_SET_VOLUME_SCHEMA),
|
||||
(
|
||||
"set_system_properties",
|
||||
set_system_properties,
|
||||
SERVICE_SET_SYSTEM_PROPERTIES_SCHEMA,
|
||||
),
|
||||
]:
|
||||
hass.services.async_register(DOMAIN, service, method, schema=schema)
|
||||
async_register_admin_service(hass, DOMAIN, service, method, schema=schema)
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import re
|
|||
|
||||
from simplipy.entity import EntityTypes
|
||||
from simplipy.system import SystemStates
|
||||
from simplipy.system.v3 import VOLUME_HIGH, VOLUME_LOW, VOLUME_MEDIUM, VOLUME_OFF
|
||||
|
||||
from homeassistant.components.alarm_control_panel import (
|
||||
FORMAT_NUMBER,
|
||||
|
@ -48,6 +49,13 @@ ATTR_VOICE_PROMPT_VOLUME = "voice_prompt_volume"
|
|||
ATTR_WALL_POWER_LEVEL = "wall_power_level"
|
||||
ATTR_WIFI_STRENGTH = "wifi_strength"
|
||||
|
||||
VOLUME_STRING_MAP = {
|
||||
VOLUME_HIGH: "high",
|
||||
VOLUME_LOW: "low",
|
||||
VOLUME_MEDIUM: "medium",
|
||||
VOLUME_OFF: "off",
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||
"""Set up a SimpliSafe alarm control panel based on existing config."""
|
||||
|
@ -82,9 +90,9 @@ class SimpliSafeAlarm(SimpliSafeEntity, AlarmControlPanel):
|
|||
self._attrs.update(
|
||||
{
|
||||
ATTR_ALARM_DURATION: self._system.alarm_duration,
|
||||
ATTR_ALARM_VOLUME: self._system.alarm_volume.name,
|
||||
ATTR_ALARM_VOLUME: VOLUME_STRING_MAP[self._system.alarm_volume],
|
||||
ATTR_BATTERY_BACKUP_POWER_LEVEL: self._system.battery_backup_power_level,
|
||||
ATTR_CHIME_VOLUME: self._system.chime_volume.name,
|
||||
ATTR_CHIME_VOLUME: VOLUME_STRING_MAP[self._system.chime_volume],
|
||||
ATTR_ENTRY_DELAY_AWAY: self._system.entry_delay_away,
|
||||
ATTR_ENTRY_DELAY_HOME: self._system.entry_delay_home,
|
||||
ATTR_EXIT_DELAY_AWAY: self._system.exit_delay_away,
|
||||
|
@ -92,7 +100,9 @@ class SimpliSafeAlarm(SimpliSafeEntity, AlarmControlPanel):
|
|||
ATTR_GSM_STRENGTH: self._system.gsm_strength,
|
||||
ATTR_LIGHT: self._system.light,
|
||||
ATTR_RF_JAMMING: self._system.rf_jamming,
|
||||
ATTR_VOICE_PROMPT_VOLUME: self._system.voice_prompt_volume.name,
|
||||
ATTR_VOICE_PROMPT_VOLUME: VOLUME_STRING_MAP[
|
||||
self._system.voice_prompt_volume
|
||||
],
|
||||
ATTR_WALL_POWER_LEVEL: self._system.wall_power_level,
|
||||
ATTR_WIFI_STRENGTH: self._system.wifi_strength,
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "SimpliSafe",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/simplisafe",
|
||||
"requirements": ["simplisafe-python==5.3.6"],
|
||||
"requirements": ["simplisafe-python==6.0.0"],
|
||||
"dependencies": [],
|
||||
"codeowners": ["@bachya"]
|
||||
}
|
||||
|
|
|
@ -10,41 +10,6 @@ remove_pin:
|
|||
label_or_pin:
|
||||
description: The label/value to remove.
|
||||
example: Test PIN
|
||||
set_alarm_duration:
|
||||
description: "Set the duration (in seconds) of an active alarm"
|
||||
fields:
|
||||
system_id:
|
||||
description: The SimpliSafe system ID to affect
|
||||
example: 123987
|
||||
seconds:
|
||||
description: The number of seconds to sound the alarm
|
||||
example: 120
|
||||
set_delay:
|
||||
description: >
|
||||
Set a duration for how long the base station should delay when transitioning
|
||||
between states
|
||||
fields:
|
||||
system_id:
|
||||
description: The SimpliSafe system ID to affect
|
||||
example: 123987
|
||||
arrival_state:
|
||||
description: The target "arrival" state (away, home)
|
||||
example: away
|
||||
transition:
|
||||
description: The system state transition to affect (entry, exit)
|
||||
example: exit
|
||||
seconds:
|
||||
description: "The number of seconds to delay"
|
||||
example: 120
|
||||
set_light:
|
||||
description: "Turn the base station light on/off"
|
||||
fields:
|
||||
system_id:
|
||||
description: The SimpliSafe system ID to affect
|
||||
example: 123987
|
||||
armed_light_state:
|
||||
description: "True for on, False for off"
|
||||
example: "True"
|
||||
set_pin:
|
||||
description: Set/update a PIN
|
||||
fields:
|
||||
|
@ -57,15 +22,33 @@ set_pin:
|
|||
pin:
|
||||
description: The value of the PIN
|
||||
example: 1256
|
||||
set_volume_property:
|
||||
description: Set a level for one of the base station's various volumes
|
||||
set_system_properties:
|
||||
description: Set one or more system properties
|
||||
fields:
|
||||
system_id:
|
||||
description: The SimpliSafe system ID to affect
|
||||
example: 123987
|
||||
volume_property:
|
||||
description: The volume property to set (alarm, chime, voice_prompt)
|
||||
example: voice_prompt
|
||||
volume:
|
||||
description: "A volume (off, low, medium, high)"
|
||||
example: low
|
||||
alarm_duration:
|
||||
description: The length of a triggered alarm
|
||||
example: 300
|
||||
alarm_volume:
|
||||
description: The volume level of a triggered alarm
|
||||
example: 2
|
||||
chime_volume:
|
||||
description: The volume level of the door chime
|
||||
example: 2
|
||||
entry_delay_away:
|
||||
description: How long to delay when entering while "away"
|
||||
example: 45
|
||||
entry_delay_home:
|
||||
description: How long to delay when entering while "home"
|
||||
example: 45
|
||||
exit_delay_away:
|
||||
description: How long to delay when exiting while "away"
|
||||
example: 45
|
||||
exit_delay_home:
|
||||
description: How long to delay when exiting while "home"
|
||||
example: 45
|
||||
light:
|
||||
description: Whether the armed light should be visible
|
||||
example: true
|
||||
voice_prompt_volume:
|
||||
description: The volume level of the voice prompt
|
||||
example: 2
|
||||
|
|
|
@ -1819,7 +1819,7 @@ shodan==1.21.2
|
|||
simplepush==1.1.4
|
||||
|
||||
# homeassistant.components.simplisafe
|
||||
simplisafe-python==5.3.6
|
||||
simplisafe-python==6.0.0
|
||||
|
||||
# homeassistant.components.sisyphus
|
||||
sisyphus-control==2.2.1
|
||||
|
|
|
@ -582,7 +582,7 @@ samsungctl[websocket]==0.7.1
|
|||
sentry-sdk==0.13.5
|
||||
|
||||
# homeassistant.components.simplisafe
|
||||
simplisafe-python==5.3.6
|
||||
simplisafe-python==6.0.0
|
||||
|
||||
# homeassistant.components.sleepiq
|
||||
sleepyq==0.7
|
||||
|
|
Loading…
Add table
Reference in a new issue