Add option to disable MQTT Alarm Control Panel supported features (#98363)

* Make MQTT Alarm Control Panel features conditional

The MQTT Alarm Control Panel currently enables all features (arm home,
arm away, arm night, arm vacation, arm custom bypass) unconditionally.
This clutters the interface and can even be potentially dangerous, by
enabling modes that the remote alarm may not support.

Make all the features conditional, by adding a new "supported_features"
configuration option, comprising a list of the supported features as
options. Feature enablement seems inconsistent across the MQTT
component; this implementation is most alike to the Humidifier modes
option, but using a generic "supported_features" name that other
implementations may reuse in the future.

The default value of this new setting remains to be all features, which
while it may be overly expansive, is necessary to maintain backwards
compatibility.

* Apply suggestions from code review

* Use vol.Optional() instead of vol.Required() for "supported_features".
* Move the initialization of _attr_supported_features to _setup_from_config.

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>

* Apply suggestions from emontnemery's code review

* Use vol.In() instead of cv.multi_seelct()
* Remove superfluous _attr_supported_features initializers, already
  present in the base class.

Co-authored-by: Erik Montnemery <erik@montnemery.com>

* Add invalid config tests for the MQTT Alarm Control Panel

* Set expected_features to None in the invalid MQTT Alarm Control Panel tests

* Add another expected_features=None in the invalid tests

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>

---------

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
Faidon Liambotis 2023-08-18 09:23:48 +03:00 committed by GitHub
parent f6a9be937b
commit 9fdad592c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 110 additions and 12 deletions

View file

@ -39,6 +39,7 @@ from .const import (
CONF_QOS,
CONF_RETAIN,
CONF_STATE_TOPIC,
CONF_SUPPORTED_FEATURES,
)
from .debug_info import log_messages
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
@ -47,6 +48,15 @@ from .util import get_mqtt_data, valid_publish_topic, valid_subscribe_topic
_LOGGER = logging.getLogger(__name__)
_SUPPORTED_FEATURES = {
"arm_home": AlarmControlPanelEntityFeature.ARM_HOME,
"arm_away": AlarmControlPanelEntityFeature.ARM_AWAY,
"arm_night": AlarmControlPanelEntityFeature.ARM_NIGHT,
"arm_vacation": AlarmControlPanelEntityFeature.ARM_VACATION,
"arm_custom_bypass": AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS,
"trigger": AlarmControlPanelEntityFeature.TRIGGER,
}
CONF_CODE_ARM_REQUIRED = "code_arm_required"
CONF_CODE_DISARM_REQUIRED = "code_disarm_required"
CONF_CODE_TRIGGER_REQUIRED = "code_trigger_required"
@ -81,6 +91,9 @@ REMOTE_CODE_TEXT = "REMOTE_CODE_TEXT"
PLATFORM_SCHEMA_MODERN = MQTT_BASE_SCHEMA.extend(
{
vol.Optional(CONF_SUPPORTED_FEATURES, default=list(_SUPPORTED_FEATURES)): [
vol.In(_SUPPORTED_FEATURES)
],
vol.Optional(CONF_CODE): cv.string,
vol.Optional(CONF_CODE_ARM_REQUIRED, default=True): cv.boolean,
vol.Optional(CONF_CODE_DISARM_REQUIRED, default=True): cv.boolean,
@ -167,6 +180,9 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
config[CONF_COMMAND_TEMPLATE], entity=self
).async_render
for feature in self._config[CONF_SUPPORTED_FEATURES]:
self._attr_supported_features |= _SUPPORTED_FEATURES[feature]
def _prepare_subscribe_topics(self) -> None:
"""(Re)Subscribe to topics."""
@ -214,18 +230,6 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
"""Return the state of the device."""
return self._state
@property
def supported_features(self) -> AlarmControlPanelEntityFeature:
"""Return the list of supported features."""
return (
AlarmControlPanelEntityFeature.ARM_HOME
| AlarmControlPanelEntityFeature.ARM_AWAY
| AlarmControlPanelEntityFeature.ARM_NIGHT
| AlarmControlPanelEntityFeature.ARM_VACATION
| AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS
| AlarmControlPanelEntityFeature.TRIGGER
)
@property
def code_format(self) -> alarm.CodeFormat | None:
"""Return one or more digits/characters."""