Allow extra keys in MQTT discovery messages (#58390)

* Allow extra keys in MQTT discovery messages

* Remove extra keys
This commit is contained in:
Erik Montnemery 2021-10-25 13:47:06 +02:00 committed by GitHub
parent a8a8b532d0
commit 640a7fee9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 628 additions and 480 deletions

View File

@ -97,6 +97,8 @@ PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend(
} }
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema) ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
DISCOVERY_SCHEMA = PLATFORM_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA)
async def async_setup_platform( async def async_setup_platform(
hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None
@ -111,7 +113,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, alarm.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, alarm.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -135,7 +137,7 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
value_template = self._config.get(CONF_VALUE_TEMPLATE) value_template = self._config.get(CONF_VALUE_TEMPLATE)

View File

@ -58,6 +58,8 @@ PLATFORM_SCHEMA = mqtt.MQTT_RO_PLATFORM_SCHEMA.extend(
} }
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema) ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
DISCOVERY_SCHEMA = PLATFORM_SCHEMA.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_platform( async def async_setup_platform(
hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None
@ -72,7 +74,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, binary_sensor.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, binary_sensor.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -101,7 +103,7 @@ class MqttBinarySensor(MqttEntity, BinarySensorEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
value_template = self._config.get(CONF_VALUE_TEMPLATE) value_template = self._config.get(CONF_VALUE_TEMPLATE)

View File

@ -37,6 +37,8 @@ PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend(
} }
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema) ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
DISCOVERY_SCHEMA = PLATFORM_SCHEMA.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_platform( async def async_setup_platform(
hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None
@ -51,7 +53,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, camera.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, camera.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -76,7 +78,7 @@ class MqttCamera(MqttEntity, Camera):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
async def _subscribe_topics(self): async def _subscribe_topics(self):
"""(Re)Subscribe to topics.""" """(Re)Subscribe to topics."""

View File

@ -268,6 +268,8 @@ PLATFORM_SCHEMA = SCHEMA_BASE.extend(
} }
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema) ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
DISCOVERY_SCHEMA = PLATFORM_SCHEMA.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_platform( async def async_setup_platform(
hass: HomeAssistant, async_add_entities, config: ConfigType, discovery_info=None hass: HomeAssistant, async_add_entities, config: ConfigType, discovery_info=None
@ -282,7 +284,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, climate.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, climate.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -319,7 +321,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Handle being added to Home Assistant.""" """Handle being added to Home Assistant."""

View File

@ -142,53 +142,58 @@ def validate_options(value):
return value return value
_PLATFORM_SCHEMA_BASE = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_GET_POSITION_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_PAYLOAD_CLOSE, default=DEFAULT_PAYLOAD_CLOSE): vol.Any(
cv.string, None
),
vol.Optional(CONF_PAYLOAD_OPEN, default=DEFAULT_PAYLOAD_OPEN): vol.Any(
cv.string, None
),
vol.Optional(CONF_PAYLOAD_STOP, default=DEFAULT_PAYLOAD_STOP): vol.Any(
cv.string, None
),
vol.Optional(CONF_POSITION_CLOSED, default=DEFAULT_POSITION_CLOSED): int,
vol.Optional(CONF_POSITION_OPEN, default=DEFAULT_POSITION_OPEN): int,
vol.Optional(CONF_RETAIN, default=DEFAULT_RETAIN): cv.boolean,
vol.Optional(CONF_SET_POSITION_TEMPLATE): cv.template,
vol.Optional(CONF_SET_POSITION_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_STATE_CLOSED, default=STATE_CLOSED): cv.string,
vol.Optional(CONF_STATE_CLOSING, default=STATE_CLOSING): cv.string,
vol.Optional(CONF_STATE_OPEN, default=STATE_OPEN): cv.string,
vol.Optional(CONF_STATE_OPENING, default=STATE_OPENING): cv.string,
vol.Optional(CONF_STATE_STOPPED, default=DEFAULT_STATE_STOPPED): cv.string,
vol.Optional(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(
CONF_TILT_CLOSED_POSITION, default=DEFAULT_TILT_CLOSED_POSITION
): int,
vol.Optional(CONF_TILT_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_TILT_MAX, default=DEFAULT_TILT_MAX): int,
vol.Optional(CONF_TILT_MIN, default=DEFAULT_TILT_MIN): int,
vol.Optional(CONF_TILT_OPEN_POSITION, default=DEFAULT_TILT_OPEN_POSITION): int,
vol.Optional(
CONF_TILT_STATE_OPTIMISTIC, default=DEFAULT_TILT_OPTIMISTIC
): cv.boolean,
vol.Optional(CONF_TILT_STATUS_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_TILT_STATUS_TEMPLATE): cv.template,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_GET_POSITION_TEMPLATE): cv.template,
vol.Optional(CONF_TILT_COMMAND_TEMPLATE): cv.template,
}
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
PLATFORM_SCHEMA = vol.All( PLATFORM_SCHEMA = vol.All(
mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend( _PLATFORM_SCHEMA_BASE,
{ validate_options,
vol.Optional(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic, )
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_GET_POSITION_TOPIC): mqtt.valid_subscribe_topic, DISCOVERY_SCHEMA = vol.All(
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA),
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_PAYLOAD_CLOSE, default=DEFAULT_PAYLOAD_CLOSE): vol.Any(
cv.string, None
),
vol.Optional(CONF_PAYLOAD_OPEN, default=DEFAULT_PAYLOAD_OPEN): vol.Any(
cv.string, None
),
vol.Optional(CONF_PAYLOAD_STOP, default=DEFAULT_PAYLOAD_STOP): vol.Any(
cv.string, None
),
vol.Optional(CONF_POSITION_CLOSED, default=DEFAULT_POSITION_CLOSED): int,
vol.Optional(CONF_POSITION_OPEN, default=DEFAULT_POSITION_OPEN): int,
vol.Optional(CONF_RETAIN, default=DEFAULT_RETAIN): cv.boolean,
vol.Optional(CONF_SET_POSITION_TEMPLATE): cv.template,
vol.Optional(CONF_SET_POSITION_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_STATE_CLOSED, default=STATE_CLOSED): cv.string,
vol.Optional(CONF_STATE_CLOSING, default=STATE_CLOSING): cv.string,
vol.Optional(CONF_STATE_OPEN, default=STATE_OPEN): cv.string,
vol.Optional(CONF_STATE_OPENING, default=STATE_OPENING): cv.string,
vol.Optional(CONF_STATE_STOPPED, default=DEFAULT_STATE_STOPPED): cv.string,
vol.Optional(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(
CONF_TILT_CLOSED_POSITION, default=DEFAULT_TILT_CLOSED_POSITION
): int,
vol.Optional(CONF_TILT_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_TILT_MAX, default=DEFAULT_TILT_MAX): int,
vol.Optional(CONF_TILT_MIN, default=DEFAULT_TILT_MIN): int,
vol.Optional(
CONF_TILT_OPEN_POSITION, default=DEFAULT_TILT_OPEN_POSITION
): int,
vol.Optional(
CONF_TILT_STATE_OPTIMISTIC, default=DEFAULT_TILT_OPTIMISTIC
): cv.boolean,
vol.Optional(CONF_TILT_STATUS_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_TILT_STATUS_TEMPLATE): cv.template,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_GET_POSITION_TEMPLATE): cv.template,
vol.Optional(CONF_TILT_COMMAND_TEMPLATE): cv.template,
}
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema),
validate_options, validate_options,
) )
@ -206,7 +211,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, cover.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, cover.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -235,7 +240,7 @@ class MqttCover(MqttEntity, CoverEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
no_position = ( no_position = (

View File

@ -37,15 +37,15 @@ PLATFORM_SCHEMA_DISCOVERY = mqtt.MQTT_RO_PLATFORM_SCHEMA.extend(
} }
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema) ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
DISCOVERY_SCHEMA = PLATFORM_SCHEMA_DISCOVERY.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_entry_from_discovery(hass, config_entry, async_add_entities): async def async_setup_entry_from_discovery(hass, config_entry, async_add_entities):
"""Set up MQTT device tracker dynamically through MQTT discovery.""" """Set up MQTT device tracker dynamically through MQTT discovery."""
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper( await async_setup_entry_helper(hass, device_tracker.DOMAIN, setup, DISCOVERY_SCHEMA)
hass, device_tracker.DOMAIN, setup, PLATFORM_SCHEMA_DISCOVERY
)
async def _async_setup_entity( async def _async_setup_entity(
@ -67,7 +67,7 @@ class MqttDeviceTracker(MqttEntity, TrackerEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA_DISCOVERY return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -47,7 +47,6 @@ from .mixins import (
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
cleanup_device_registry, cleanup_device_registry,
device_info_from_config, device_info_from_config,
validate_device_has_at_least_one_identifier,
) )
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -85,7 +84,7 @@ TRIGGER_DISCOVERY_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend(
vol.Required(CONF_TYPE): cv.string, vol.Required(CONF_TYPE): cv.string,
vol.Optional(CONF_VALUE_TEMPLATE, default=None): vol.Any(None, cv.string), vol.Optional(CONF_VALUE_TEMPLATE, default=None): vol.Any(None, cv.string),
}, },
validate_device_has_at_least_one_identifier, extra=vol.REMOVE_EXTRA,
) )
DEVICE_TRIGGERS = "mqtt_device_triggers" DEVICE_TRIGGERS = "mqtt_device_triggers"

View File

@ -113,6 +113,64 @@ def valid_preset_mode_configuration(config):
return config return config
_PLATFORM_SCHEMA_BASE = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_OSCILLATION_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_OSCILLATION_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_OSCILLATION_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_OSCILLATION_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_PERCENTAGE_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_PERCENTAGE_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_PERCENTAGE_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_PERCENTAGE_VALUE_TEMPLATE): cv.template,
# CONF_PRESET_MODE_COMMAND_TOPIC and CONF_PRESET_MODES_LIST must be used together
vol.Inclusive(
CONF_PRESET_MODE_COMMAND_TOPIC, "preset_modes"
): mqtt.valid_publish_topic,
vol.Inclusive(
CONF_PRESET_MODES_LIST, "preset_modes", default=[]
): cv.ensure_list,
vol.Optional(CONF_PRESET_MODE_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_PRESET_MODE_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_PRESET_MODE_VALUE_TEMPLATE): cv.template,
vol.Optional(
CONF_SPEED_RANGE_MIN, default=DEFAULT_SPEED_RANGE_MIN
): cv.positive_int,
vol.Optional(
CONF_SPEED_RANGE_MAX, default=DEFAULT_SPEED_RANGE_MAX
): cv.positive_int,
vol.Optional(
CONF_PAYLOAD_RESET_PERCENTAGE, default=DEFAULT_PAYLOAD_RESET
): cv.string,
vol.Optional(
CONF_PAYLOAD_RESET_PRESET_MODE, default=DEFAULT_PAYLOAD_RESET
): cv.string,
vol.Optional(CONF_PAYLOAD_HIGH_SPEED, default=SPEED_HIGH): cv.string,
vol.Optional(CONF_PAYLOAD_LOW_SPEED, default=SPEED_LOW): cv.string,
vol.Optional(CONF_PAYLOAD_MEDIUM_SPEED, default=SPEED_MEDIUM): cv.string,
vol.Optional(CONF_PAYLOAD_OFF_SPEED, default=SPEED_OFF): cv.string,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
vol.Optional(
CONF_PAYLOAD_OSCILLATION_OFF, default=OSCILLATE_OFF_PAYLOAD
): cv.string,
vol.Optional(
CONF_PAYLOAD_OSCILLATION_ON, default=OSCILLATE_ON_PAYLOAD
): cv.string,
vol.Optional(CONF_SPEED_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(
CONF_SPEED_LIST,
default=[SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH],
): cv.ensure_list,
vol.Optional(CONF_SPEED_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_SPEED_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template,
}
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
PLATFORM_SCHEMA = vol.All( PLATFORM_SCHEMA = vol.All(
# CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_LIST, CONF_SPEED_STATE_TOPIC, CONF_SPEED_VALUE_TEMPLATE and # CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_LIST, CONF_SPEED_STATE_TOPIC, CONF_SPEED_VALUE_TEMPLATE and
# Speeds SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH SPEED_OFF, # Speeds SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH SPEED_OFF,
@ -124,63 +182,23 @@ PLATFORM_SCHEMA = vol.All(
cv.deprecated(CONF_SPEED_LIST), cv.deprecated(CONF_SPEED_LIST),
cv.deprecated(CONF_SPEED_STATE_TOPIC), cv.deprecated(CONF_SPEED_STATE_TOPIC),
cv.deprecated(CONF_SPEED_VALUE_TEMPLATE), cv.deprecated(CONF_SPEED_VALUE_TEMPLATE),
mqtt.MQTT_RW_PLATFORM_SCHEMA.extend( _PLATFORM_SCHEMA_BASE,
{ valid_speed_range_configuration,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, valid_preset_mode_configuration,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean, )
vol.Optional(CONF_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_OSCILLATION_COMMAND_TOPIC): mqtt.valid_publish_topic, DISCOVERY_SCHEMA = vol.All(
vol.Optional(CONF_OSCILLATION_COMMAND_TEMPLATE): cv.template, # CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_LIST, CONF_SPEED_STATE_TOPIC, CONF_SPEED_VALUE_TEMPLATE and
vol.Optional(CONF_OSCILLATION_STATE_TOPIC): mqtt.valid_subscribe_topic, # Speeds SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH SPEED_OFF,
vol.Optional(CONF_OSCILLATION_VALUE_TEMPLATE): cv.template, # are deprecated, support will be removed with release 2021.9
vol.Optional(CONF_PERCENTAGE_COMMAND_TOPIC): mqtt.valid_publish_topic, cv.deprecated(CONF_PAYLOAD_HIGH_SPEED),
vol.Optional(CONF_PERCENTAGE_COMMAND_TEMPLATE): cv.template, cv.deprecated(CONF_PAYLOAD_LOW_SPEED),
vol.Optional(CONF_PERCENTAGE_STATE_TOPIC): mqtt.valid_subscribe_topic, cv.deprecated(CONF_PAYLOAD_MEDIUM_SPEED),
vol.Optional(CONF_PERCENTAGE_VALUE_TEMPLATE): cv.template, cv.deprecated(CONF_SPEED_COMMAND_TOPIC),
# CONF_PRESET_MODE_COMMAND_TOPIC and CONF_PRESET_MODES_LIST must be used together cv.deprecated(CONF_SPEED_LIST),
vol.Inclusive( cv.deprecated(CONF_SPEED_STATE_TOPIC),
CONF_PRESET_MODE_COMMAND_TOPIC, "preset_modes" cv.deprecated(CONF_SPEED_VALUE_TEMPLATE),
): mqtt.valid_publish_topic, _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA),
vol.Inclusive(
CONF_PRESET_MODES_LIST, "preset_modes", default=[]
): cv.ensure_list,
vol.Optional(CONF_PRESET_MODE_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_PRESET_MODE_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_PRESET_MODE_VALUE_TEMPLATE): cv.template,
vol.Optional(
CONF_SPEED_RANGE_MIN, default=DEFAULT_SPEED_RANGE_MIN
): cv.positive_int,
vol.Optional(
CONF_SPEED_RANGE_MAX, default=DEFAULT_SPEED_RANGE_MAX
): cv.positive_int,
vol.Optional(
CONF_PAYLOAD_RESET_PERCENTAGE, default=DEFAULT_PAYLOAD_RESET
): cv.string,
vol.Optional(
CONF_PAYLOAD_RESET_PRESET_MODE, default=DEFAULT_PAYLOAD_RESET
): cv.string,
vol.Optional(CONF_PAYLOAD_HIGH_SPEED, default=SPEED_HIGH): cv.string,
vol.Optional(CONF_PAYLOAD_LOW_SPEED, default=SPEED_LOW): cv.string,
vol.Optional(CONF_PAYLOAD_MEDIUM_SPEED, default=SPEED_MEDIUM): cv.string,
vol.Optional(CONF_PAYLOAD_OFF_SPEED, default=SPEED_OFF): cv.string,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
vol.Optional(
CONF_PAYLOAD_OSCILLATION_OFF, default=OSCILLATE_OFF_PAYLOAD
): cv.string,
vol.Optional(
CONF_PAYLOAD_OSCILLATION_ON, default=OSCILLATE_ON_PAYLOAD
): cv.string,
vol.Optional(CONF_SPEED_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(
CONF_SPEED_LIST,
default=[SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH],
): cv.ensure_list,
vol.Optional(CONF_SPEED_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_SPEED_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template,
}
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema),
valid_speed_range_configuration, valid_speed_range_configuration,
valid_preset_mode_configuration, valid_preset_mode_configuration,
) )
@ -199,7 +217,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, fan.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, fan.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -236,7 +254,7 @@ class MqttFan(MqttEntity, FanEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -86,46 +86,52 @@ def valid_humidity_range_configuration(config):
return config return config
_PLATFORM_SCHEMA_BASE = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend(
{
# CONF_AVAIALABLE_MODES_LIST and CONF_MODE_COMMAND_TOPIC must be used together
vol.Inclusive(
CONF_AVAILABLE_MODES_LIST, "available_modes", default=[]
): cv.ensure_list,
vol.Inclusive(
CONF_MODE_COMMAND_TOPIC, "available_modes"
): mqtt.valid_publish_topic,
vol.Optional(CONF_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_DEVICE_CLASS, default=DEVICE_CLASS_HUMIDIFIER): vol.In(
[DEVICE_CLASS_HUMIDIFIER, DEVICE_CLASS_DEHUMIDIFIER]
),
vol.Optional(CONF_MODE_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_MODE_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_MODE_STATE_TEMPLATE): cv.template,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template,
vol.Required(CONF_TARGET_HUMIDITY_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_TARGET_HUMIDITY_COMMAND_TEMPLATE): cv.template,
vol.Optional(
CONF_TARGET_HUMIDITY_MAX, default=DEFAULT_MAX_HUMIDITY
): cv.positive_int,
vol.Optional(
CONF_TARGET_HUMIDITY_MIN, default=DEFAULT_MIN_HUMIDITY
): cv.positive_int,
vol.Optional(CONF_TARGET_HUMIDITY_STATE_TEMPLATE): cv.template,
vol.Optional(CONF_TARGET_HUMIDITY_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(
CONF_PAYLOAD_RESET_HUMIDITY, default=DEFAULT_PAYLOAD_RESET
): cv.string,
vol.Optional(CONF_PAYLOAD_RESET_MODE, default=DEFAULT_PAYLOAD_RESET): cv.string,
}
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
PLATFORM_SCHEMA = vol.All( PLATFORM_SCHEMA = vol.All(
mqtt.MQTT_RW_PLATFORM_SCHEMA.extend( _PLATFORM_SCHEMA_BASE,
{ valid_humidity_range_configuration,
# CONF_AVAIALABLE_MODES_LIST and CONF_MODE_COMMAND_TOPIC must be used together valid_mode_configuration,
vol.Inclusive( )
CONF_AVAILABLE_MODES_LIST, "available_modes", default=[]
): cv.ensure_list, DISCOVERY_SCHEMA = vol.All(
vol.Inclusive( _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA),
CONF_MODE_COMMAND_TOPIC, "available_modes"
): mqtt.valid_publish_topic,
vol.Optional(CONF_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_DEVICE_CLASS, default=DEVICE_CLASS_HUMIDIFIER): vol.In(
[DEVICE_CLASS_HUMIDIFIER, DEVICE_CLASS_DEHUMIDIFIER]
),
vol.Optional(CONF_MODE_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_MODE_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_MODE_STATE_TEMPLATE): cv.template,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template,
vol.Required(CONF_TARGET_HUMIDITY_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_TARGET_HUMIDITY_COMMAND_TEMPLATE): cv.template,
vol.Optional(
CONF_TARGET_HUMIDITY_MAX, default=DEFAULT_MAX_HUMIDITY
): cv.positive_int,
vol.Optional(
CONF_TARGET_HUMIDITY_MIN, default=DEFAULT_MIN_HUMIDITY
): cv.positive_int,
vol.Optional(CONF_TARGET_HUMIDITY_STATE_TEMPLATE): cv.template,
vol.Optional(CONF_TARGET_HUMIDITY_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(
CONF_PAYLOAD_RESET_HUMIDITY, default=DEFAULT_PAYLOAD_RESET
): cv.string,
vol.Optional(
CONF_PAYLOAD_RESET_MODE, default=DEFAULT_PAYLOAD_RESET
): cv.string,
}
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema),
valid_humidity_range_configuration, valid_humidity_range_configuration,
valid_mode_configuration, valid_mode_configuration,
) )
@ -144,7 +150,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, humidifier.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, humidifier.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -179,7 +185,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -11,9 +11,31 @@ from homeassistant.helpers.typing import ConfigType
from .. import DOMAIN, PLATFORMS from .. import DOMAIN, PLATFORMS
from ..mixins import async_setup_entry_helper from ..mixins import async_setup_entry_helper
from .schema import CONF_SCHEMA, MQTT_LIGHT_SCHEMA_SCHEMA from .schema import CONF_SCHEMA, MQTT_LIGHT_SCHEMA_SCHEMA
from .schema_basic import PLATFORM_SCHEMA_BASIC, async_setup_entity_basic from .schema_basic import (
from .schema_json import PLATFORM_SCHEMA_JSON, async_setup_entity_json DISCOVERY_SCHEMA_BASIC,
from .schema_template import PLATFORM_SCHEMA_TEMPLATE, async_setup_entity_template PLATFORM_SCHEMA_BASIC,
async_setup_entity_basic,
)
from .schema_json import (
DISCOVERY_SCHEMA_JSON,
PLATFORM_SCHEMA_JSON,
async_setup_entity_json,
)
from .schema_template import (
DISCOVERY_SCHEMA_TEMPLATE,
PLATFORM_SCHEMA_TEMPLATE,
async_setup_entity_template,
)
def validate_mqtt_light_discovery(value):
"""Validate MQTT light schema."""
schemas = {
"basic": DISCOVERY_SCHEMA_BASIC,
"json": DISCOVERY_SCHEMA_JSON,
"template": DISCOVERY_SCHEMA_TEMPLATE,
}
return schemas[value[CONF_SCHEMA]](value)
def validate_mqtt_light(value): def validate_mqtt_light(value):
@ -26,6 +48,12 @@ def validate_mqtt_light(value):
return schemas[value[CONF_SCHEMA]](value) return schemas[value[CONF_SCHEMA]](value)
DISCOVERY_SCHEMA = vol.All(
MQTT_LIGHT_SCHEMA_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA),
validate_mqtt_light_discovery,
)
PLATFORM_SCHEMA = vol.All( PLATFORM_SCHEMA = vol.All(
MQTT_LIGHT_SCHEMA_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA), validate_mqtt_light MQTT_LIGHT_SCHEMA_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA), validate_mqtt_light
) )
@ -44,7 +72,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, light.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, light.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(

View File

@ -152,9 +152,7 @@ VALUE_TEMPLATE_KEYS = [
CONF_XY_VALUE_TEMPLATE, CONF_XY_VALUE_TEMPLATE,
] ]
PLATFORM_SCHEMA_BASIC = vol.All( _PLATFORM_SCHEMA_BASE = (
# CONF_VALUE_TEMPLATE is deprecated, support will be removed in 2021.10
cv.deprecated(CONF_VALUE_TEMPLATE, CONF_STATE_VALUE_TEMPLATE),
mqtt.MQTT_RW_PLATFORM_SCHEMA.extend( mqtt.MQTT_RW_PLATFORM_SCHEMA.extend(
{ {
vol.Optional(CONF_BRIGHTNESS_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Optional(CONF_BRIGHTNESS_COMMAND_TOPIC): mqtt.valid_publish_topic,
@ -212,10 +210,22 @@ PLATFORM_SCHEMA_BASIC = vol.All(
vol.Optional(CONF_XY_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Optional(CONF_XY_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_XY_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_XY_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_XY_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_XY_VALUE_TEMPLATE): cv.template,
} },
) )
.extend(MQTT_ENTITY_COMMON_SCHEMA.schema) .extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
.extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema), .extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema)
)
PLATFORM_SCHEMA_BASIC = vol.All(
# CONF_VALUE_TEMPLATE is deprecated, support will be removed in 2021.10
cv.deprecated(CONF_VALUE_TEMPLATE, CONF_STATE_VALUE_TEMPLATE),
_PLATFORM_SCHEMA_BASE,
)
DISCOVERY_SCHEMA_BASIC = vol.All(
# CONF_VALUE_TEMPLATE is deprecated, support will be removed in 2021.10
cv.deprecated(CONF_VALUE_TEMPLATE, CONF_STATE_VALUE_TEMPLATE),
_PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA),
) )
@ -268,7 +278,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA_BASIC return DISCOVERY_SCHEMA_BASIC
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -102,7 +102,7 @@ def valid_color_configuration(config):
return config return config
PLATFORM_SCHEMA_JSON = vol.All( _PLATFORM_SCHEMA_BASE = (
mqtt.MQTT_RW_PLATFORM_SCHEMA.extend( mqtt.MQTT_RW_PLATFORM_SCHEMA.extend(
{ {
vol.Optional(CONF_BRIGHTNESS, default=DEFAULT_BRIGHTNESS): cv.boolean, vol.Optional(CONF_BRIGHTNESS, default=DEFAULT_BRIGHTNESS): cv.boolean,
@ -143,7 +143,16 @@ PLATFORM_SCHEMA_JSON = vol.All(
}, },
) )
.extend(MQTT_ENTITY_COMMON_SCHEMA.schema) .extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
.extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema), .extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema)
)
PLATFORM_SCHEMA_JSON = vol.All(
_PLATFORM_SCHEMA_BASE,
valid_color_configuration,
)
DISCOVERY_SCHEMA_JSON = vol.All(
_PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA),
valid_color_configuration, valid_color_configuration,
) )
@ -184,7 +193,7 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA_JSON return DISCOVERY_SCHEMA_JSON
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -84,6 +84,8 @@ PLATFORM_SCHEMA_TEMPLATE = (
.extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema) .extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema)
) )
DISCOVERY_SCHEMA_TEMPLATE = PLATFORM_SCHEMA_TEMPLATE.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_entity_template( async def async_setup_entity_template(
hass, config, async_add_entities, config_entry, discovery_data hass, config, async_add_entities, config_entry, discovery_data
@ -117,7 +119,7 @@ class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA_TEMPLATE return DISCOVERY_SCHEMA_TEMPLATE
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -49,6 +49,8 @@ PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend(
} }
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema) ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
DISCOVERY_SCHEMA = PLATFORM_SCHEMA.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_platform( async def async_setup_platform(
hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None
@ -63,7 +65,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, lock.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, lock.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -88,7 +90,7 @@ class MqttLock(MqttEntity, LockEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -59,21 +59,28 @@ def validate_config(config):
return config return config
_PLATFORM_SCHEMA_BASE = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_MAX, default=DEFAULT_MAX_VALUE): vol.Coerce(float),
vol.Optional(CONF_MIN, default=DEFAULT_MIN_VALUE): vol.Coerce(float),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_PAYLOAD_RESET, default=DEFAULT_PAYLOAD_RESET): cv.string,
vol.Optional(CONF_STEP, default=DEFAULT_STEP): vol.All(
vol.Coerce(float), vol.Range(min=1e-3)
),
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
},
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
PLATFORM_SCHEMA = vol.All( PLATFORM_SCHEMA = vol.All(
mqtt.MQTT_RW_PLATFORM_SCHEMA.extend( _PLATFORM_SCHEMA_BASE,
{ validate_config,
vol.Optional(CONF_MAX, default=DEFAULT_MAX_VALUE): vol.Coerce(float), )
vol.Optional(CONF_MIN, default=DEFAULT_MIN_VALUE): vol.Coerce(float),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, DISCOVERY_SCHEMA = vol.All(
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean, _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA),
vol.Optional(CONF_PAYLOAD_RESET, default=DEFAULT_PAYLOAD_RESET): cv.string,
vol.Optional(CONF_STEP, default=DEFAULT_STEP): vol.All(
vol.Coerce(float), vol.Range(min=1e-3)
),
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
},
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema),
validate_config, validate_config,
) )
@ -91,7 +98,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, number.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, number.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -120,7 +127,7 @@ class MqttNumber(MqttEntity, NumberEntity, RestoreEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -35,6 +35,8 @@ PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend(
} }
).extend(MQTT_AVAILABILITY_SCHEMA.schema) ).extend(MQTT_AVAILABILITY_SCHEMA.schema)
DISCOVERY_SCHEMA = PLATFORM_SCHEMA.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_platform( async def async_setup_platform(
hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None
@ -49,7 +51,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, async_add_entities, config_entry=config_entry _async_setup_entity, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, scene.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, scene.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -85,7 +87,7 @@ class MqttScene(
async def discovery_update(self, discovery_payload): async def discovery_update(self, discovery_payload):
"""Handle updated discovery message.""" """Handle updated discovery message."""
config = PLATFORM_SCHEMA(discovery_payload) config = DISCOVERY_SCHEMA(discovery_payload)
self._setup_from_config(config) self._setup_from_config(config)
await self.availability_discovery_update(config) await self.availability_discovery_update(config)
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -41,15 +41,22 @@ def validate_config(config):
return config return config
_PLATFORM_SCHEMA_BASE = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Required(CONF_OPTIONS): cv.ensure_list,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
},
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
PLATFORM_SCHEMA = vol.All( PLATFORM_SCHEMA = vol.All(
mqtt.MQTT_RW_PLATFORM_SCHEMA.extend( _PLATFORM_SCHEMA_BASE,
{ validate_config,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, )
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Required(CONF_OPTIONS): cv.ensure_list, DISCOVERY_SCHEMA = vol.All(
vol.Optional(CONF_VALUE_TEMPLATE): cv.template, _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA),
},
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema),
validate_config, validate_config,
) )
@ -67,7 +74,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, select.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, select.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -96,7 +103,7 @@ class MqttSelect(MqttEntity, SelectEntity, RestoreEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -80,20 +80,28 @@ def validate_options(conf):
return conf return conf
_PLATFORM_SCHEMA_BASE = mqtt.MQTT_RO_PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_EXPIRE_AFTER): cv.positive_int,
vol.Optional(CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE): cv.boolean,
vol.Optional(CONF_LAST_RESET_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_LAST_RESET_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_STATE_CLASS): STATE_CLASSES_SCHEMA,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
}
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
PLATFORM_SCHEMA = vol.All( PLATFORM_SCHEMA = vol.All(
cv.deprecated(CONF_LAST_RESET_TOPIC), cv.deprecated(CONF_LAST_RESET_TOPIC),
mqtt.MQTT_RO_PLATFORM_SCHEMA.extend( _PLATFORM_SCHEMA_BASE,
{ validate_options,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA, )
vol.Optional(CONF_EXPIRE_AFTER): cv.positive_int,
vol.Optional(CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE): cv.boolean, DISCOVERY_SCHEMA = vol.All(
vol.Optional(CONF_LAST_RESET_TOPIC): mqtt.valid_subscribe_topic, cv.deprecated(CONF_LAST_RESET_TOPIC),
vol.Optional(CONF_LAST_RESET_VALUE_TEMPLATE): cv.template, _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_STATE_CLASS): STATE_CLASSES_SCHEMA,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
}
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema),
validate_options, validate_options,
) )
@ -111,7 +119,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, sensor.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, sensor.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -143,7 +151,7 @@ class MqttSensor(MqttEntity, SensorEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -51,6 +51,8 @@ PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend(
} }
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema) ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
DISCOVERY_SCHEMA = PLATFORM_SCHEMA.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_platform( async def async_setup_platform(
hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None hass: HomeAssistant, config: ConfigType, async_add_entities, discovery_info=None
@ -65,7 +67,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, switch.DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, switch.DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(
@ -93,7 +95,7 @@ class MqttSwitch(MqttEntity, SwitchEntity, RestoreEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA return DISCOVERY_SCHEMA
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""

View File

@ -29,7 +29,6 @@ from .mixins import (
async_setup_entry_helper, async_setup_entry_helper,
cleanup_device_registry, cleanup_device_registry,
device_info_from_config, device_info_from_config,
validate_device_has_at_least_one_identifier,
) )
from .util import valid_subscribe_topic from .util import valid_subscribe_topic
@ -45,7 +44,7 @@ PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend(
vol.Required(CONF_TOPIC): valid_subscribe_topic, vol.Required(CONF_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
}, },
validate_device_has_at_least_one_identifier, extra=vol.REMOVE_EXTRA,
) )

View File

@ -9,8 +9,22 @@ from homeassistant.helpers.reload import async_setup_reload_service
from .. import DOMAIN as MQTT_DOMAIN, PLATFORMS from .. import DOMAIN as MQTT_DOMAIN, PLATFORMS
from ..mixins import async_setup_entry_helper from ..mixins import async_setup_entry_helper
from .schema import CONF_SCHEMA, LEGACY, MQTT_VACUUM_SCHEMA, STATE from .schema import CONF_SCHEMA, LEGACY, MQTT_VACUUM_SCHEMA, STATE
from .schema_legacy import PLATFORM_SCHEMA_LEGACY, async_setup_entity_legacy from .schema_legacy import (
from .schema_state import PLATFORM_SCHEMA_STATE, async_setup_entity_state DISCOVERY_SCHEMA_LEGACY,
PLATFORM_SCHEMA_LEGACY,
async_setup_entity_legacy,
)
from .schema_state import (
DISCOVERY_SCHEMA_STATE,
PLATFORM_SCHEMA_STATE,
async_setup_entity_state,
)
def validate_mqtt_vacuum_discovery(value):
"""Validate MQTT vacuum schema."""
schemas = {LEGACY: DISCOVERY_SCHEMA_LEGACY, STATE: DISCOVERY_SCHEMA_STATE}
return schemas[value[CONF_SCHEMA]](value)
def validate_mqtt_vacuum(value): def validate_mqtt_vacuum(value):
@ -19,6 +33,10 @@ def validate_mqtt_vacuum(value):
return schemas[value[CONF_SCHEMA]](value) return schemas[value[CONF_SCHEMA]](value)
DISCOVERY_SCHEMA = vol.All(
MQTT_VACUUM_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA), validate_mqtt_vacuum_discovery
)
PLATFORM_SCHEMA = vol.All( PLATFORM_SCHEMA = vol.All(
MQTT_VACUUM_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA), validate_mqtt_vacuum MQTT_VACUUM_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA), validate_mqtt_vacuum
) )
@ -35,7 +53,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
setup = functools.partial( setup = functools.partial(
_async_setup_entity, hass, async_add_entities, config_entry=config_entry _async_setup_entity, hass, async_add_entities, config_entry=config_entry
) )
await async_setup_entry_helper(hass, DOMAIN, setup, PLATFORM_SCHEMA) await async_setup_entry_helper(hass, DOMAIN, setup, DISCOVERY_SCHEMA)
async def _async_setup_entity( async def _async_setup_entity(

View File

@ -156,6 +156,8 @@ PLATFORM_SCHEMA_LEGACY = (
.extend(MQTT_VACUUM_SCHEMA.schema) .extend(MQTT_VACUUM_SCHEMA.schema)
) )
DISCOVERY_SCHEMA_LEGACY = PLATFORM_SCHEMA_LEGACY.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_entity_legacy( async def async_setup_entity_legacy(
hass, config, async_add_entities, config_entry, discovery_data hass, config, async_add_entities, config_entry, discovery_data
@ -185,7 +187,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA_LEGACY return DISCOVERY_SCHEMA_LEGACY
def _setup_from_config(self, config): def _setup_from_config(self, config):
supported_feature_strings = config[CONF_SUPPORTED_FEATURES] supported_feature_strings = config[CONF_SUPPORTED_FEATURES]

View File

@ -136,6 +136,9 @@ PLATFORM_SCHEMA_STATE = (
) )
DISCOVERY_SCHEMA_STATE = PLATFORM_SCHEMA_STATE.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_entity_state( async def async_setup_entity_state(
hass, config, async_add_entities, config_entry, discovery_data hass, config, async_add_entities, config_entry, discovery_data
): ):
@ -159,7 +162,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
@staticmethod @staticmethod
def config_schema(): def config_schema():
"""Return the config schema.""" """Return the config schema."""
return PLATFORM_SCHEMA_STATE return DISCOVERY_SCHEMA_STATE
def _setup_from_config(self, config): def _setup_from_config(self, config):
supported_feature_strings = config[CONF_SUPPORTED_FEATURES] supported_feature_strings = config[CONF_SUPPORTED_FEATURES]

View File

@ -625,15 +625,13 @@ async def test_discovery_update_alarm_topic_and_template(hass, mqtt_mock, caplog
([("alarm/state2", '{"state2":{"state":"triggered"}}')], "triggered", None), ([("alarm/state2", '{"state2":{"state":"triggered"}}')], "triggered", None),
] ]
data1 = json.dumps(config1)
data2 = json.dumps(config2)
await help_test_discovery_update( await help_test_discovery_update(
hass, hass,
mqtt_mock, mqtt_mock,
caplog, caplog,
alarm_control_panel.DOMAIN, alarm_control_panel.DOMAIN,
data1, config1,
data2, config2,
state_data1=state_data1, state_data1=state_data1,
state_data2=state_data2, state_data2=state_data2,
) )
@ -658,15 +656,13 @@ async def test_discovery_update_alarm_template(hass, mqtt_mock, caplog):
([("alarm/state1", '{"state2":{"state":"triggered"}}')], "triggered", None), ([("alarm/state1", '{"state2":{"state":"triggered"}}')], "triggered", None),
] ]
data1 = json.dumps(config1)
data2 = json.dumps(config2)
await help_test_discovery_update( await help_test_discovery_update(
hass, hass,
mqtt_mock, mqtt_mock,
caplog, caplog,
alarm_control_panel.DOMAIN, alarm_control_panel.DOMAIN,
data1, config1,
data2, config2,
state_data1=state_data1, state_data1=state_data1,
state_data2=state_data2, state_data2=state_data2,
) )

View File

@ -679,15 +679,13 @@ async def test_discovery_update_binary_sensor_topic_template(hass, mqtt_mock, ca
([("sensor/state2", '{"state2":{"state":"OFF"}}')], "off", None), ([("sensor/state2", '{"state2":{"state":"OFF"}}')], "off", None),
] ]
data1 = json.dumps(config1)
data2 = json.dumps(config2)
await help_test_discovery_update( await help_test_discovery_update(
hass, hass,
mqtt_mock, mqtt_mock,
caplog, caplog,
binary_sensor.DOMAIN, binary_sensor.DOMAIN,
data1, config1,
data2, config2,
state_data1=state_data1, state_data1=state_data1,
state_data2=state_data2, state_data2=state_data2,
) )
@ -714,15 +712,13 @@ async def test_discovery_update_binary_sensor_template(hass, mqtt_mock, caplog):
([("sensor/state1", '{"state2":{"state":"OFF"}}')], "off", None), ([("sensor/state1", '{"state2":{"state":"OFF"}}')], "off", None),
] ]
data1 = json.dumps(config1)
data2 = json.dumps(config2)
await help_test_discovery_update( await help_test_discovery_update(
hass, hass,
mqtt_mock, mqtt_mock,
caplog, caplog,
binary_sensor.DOMAIN, binary_sensor.DOMAIN,
data1, config1,
data2, config2,
state_data1=state_data1, state_data1=state_data1,
state_data2=state_data2, state_data2=state_data2,
) )

View File

@ -161,11 +161,11 @@ async def test_discovery_removal_camera(hass, mqtt_mock, caplog):
async def test_discovery_update_camera(hass, mqtt_mock, caplog): async def test_discovery_update_camera(hass, mqtt_mock, caplog):
"""Test update of discovered camera.""" """Test update of discovered camera."""
data1 = '{ "name": "Beer", "topic": "test_topic"}' config1 = {"name": "Beer", "topic": "test_topic"}
data2 = '{ "name": "Milk", "topic": "test_topic"}' config2 = {"name": "Milk", "topic": "test_topic"}
await help_test_discovery_update( await help_test_discovery_update(
hass, mqtt_mock, caplog, camera.DOMAIN, data1, data2 hass, mqtt_mock, caplog, camera.DOMAIN, config1, config2
) )

View File

@ -991,10 +991,10 @@ async def test_discovery_removal_climate(hass, mqtt_mock, caplog):
async def test_discovery_update_climate(hass, mqtt_mock, caplog): async def test_discovery_update_climate(hass, mqtt_mock, caplog):
"""Test update of discovered climate.""" """Test update of discovered climate."""
data1 = '{ "name": "Beer" }' config1 = {"name": "Beer"}
data2 = '{ "name": "Milk" }' config2 = {"name": "Milk"}
await help_test_discovery_update( await help_test_discovery_update(
hass, mqtt_mock, caplog, CLIMATE_DOMAIN, data1, data2 hass, mqtt_mock, caplog, CLIMATE_DOMAIN, config1, config2
) )

View File

@ -662,8 +662,8 @@ async def help_test_discovery_update(
mqtt_mock, mqtt_mock,
caplog, caplog,
domain, domain,
discovery_data1, discovery_config1,
discovery_data2, discovery_config2,
state_data1=None, state_data1=None,
state_data2=None, state_data2=None,
): ):
@ -671,6 +671,14 @@ async def help_test_discovery_update(
This is a test helper for the MqttDiscoveryUpdate mixin. This is a test helper for the MqttDiscoveryUpdate mixin.
""" """
# Add some future configuration to the configurations
config1 = copy.deepcopy(discovery_config1)
config1["some_future_option_1"] = "future_option_1"
config2 = copy.deepcopy(discovery_config2)
config2["some_future_option_2"] = "future_option_2"
discovery_data1 = json.dumps(config1)
discovery_data2 = json.dumps(config2)
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", discovery_data1) async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", discovery_data1)
await hass.async_block_till_done() await hass.async_block_till_done()

View File

@ -2401,10 +2401,10 @@ async def test_discovery_removal_cover(hass, mqtt_mock, caplog):
async def test_discovery_update_cover(hass, mqtt_mock, caplog): async def test_discovery_update_cover(hass, mqtt_mock, caplog):
"""Test update of discovered cover.""" """Test update of discovered cover."""
data1 = '{ "name": "Beer", "command_topic": "test_topic" }' config1 = {"name": "Beer", "command_topic": "test_topic"}
data2 = '{ "name": "Milk", "command_topic": "test_topic" }' config2 = {"name": "Milk", "command_topic": "test_topic"}
await help_test_discovery_update( await help_test_discovery_update(
hass, mqtt_mock, caplog, cover.DOMAIN, data1, data2 hass, mqtt_mock, caplog, cover.DOMAIN, config1, config2
) )

View File

@ -130,7 +130,7 @@ async def test_discover_bad_triggers(hass, device_reg, entity_reg, mqtt_mock):
'{ "automation_type":"trigger",' '{ "automation_type":"trigger",'
' "device":{"identifiers":["0AFFD2"]},' ' "device":{"identifiers":["0AFFD2"]},'
' "payloads": "short_press",' ' "payloads": "short_press",'
' "topic": "foobar/triggers/button1",' ' "topics": "foobar/triggers/button1",'
' "type": "button_short_press",' ' "type": "button_short_press",'
' "subtype": "button_1" }' ' "subtype": "button_1" }'
) )
@ -167,22 +167,28 @@ async def test_discover_bad_triggers(hass, device_reg, entity_reg, mqtt_mock):
async def test_update_remove_triggers(hass, device_reg, entity_reg, mqtt_mock): async def test_update_remove_triggers(hass, device_reg, entity_reg, mqtt_mock):
"""Test triggers can be updated and removed.""" """Test triggers can be updated and removed."""
data1 = ( config1 = {
'{ "automation_type":"trigger",' "automation_type": "trigger",
' "device":{"identifiers":["0AFFD2"]},' "device": {"identifiers": ["0AFFD2"]},
' "payload": "short_press",' "payload": "short_press",
' "topic": "foobar/triggers/button1",' "topic": "foobar/triggers/button1",
' "type": "button_short_press",' "type": "button_short_press",
' "subtype": "button_1" }' "subtype": "button_1",
) }
data2 = ( config1["some_future_option_1"] = "future_option_1"
'{ "automation_type":"trigger",' data1 = json.dumps(config1)
' "device":{"identifiers":["0AFFD2"]},'
' "payload": "short_press",' config2 = {
' "topic": "foobar/triggers/button1",' "automation_type": "trigger",
' "type": "button_short_press",' "device": {"identifiers": ["0AFFD2"]},
' "subtype": "button_2" }' "payload": "short_press",
) "topic": "foobar/triggers/button1",
"type": "button_short_press",
"subtype": "button_2",
}
config2["topic"] = "foobar/tag_scanned2"
data2 = json.dumps(config2)
async_fire_mqtt_message(hass, "homeassistant/device_automation/bla/config", data1) async_fire_mqtt_message(hass, "homeassistant/device_automation/bla/config", data1)
await hass.async_block_till_done() await hass.async_block_till_done()

View File

@ -1590,9 +1590,11 @@ async def test_discovery_removal_fan(hass, mqtt_mock, caplog):
async def test_discovery_update_fan(hass, mqtt_mock, caplog): async def test_discovery_update_fan(hass, mqtt_mock, caplog):
"""Test update of discovered fan.""" """Test update of discovered fan."""
data1 = '{ "name": "Beer", "command_topic": "test_topic" }' config1 = {"name": "Beer", "command_topic": "test_topic"}
data2 = '{ "name": "Milk", "command_topic": "test_topic" }' config2 = {"name": "Milk", "command_topic": "test_topic"}
await help_test_discovery_update(hass, mqtt_mock, caplog, fan.DOMAIN, data1, data2) await help_test_discovery_update(
hass, mqtt_mock, caplog, fan.DOMAIN, config1, config2
)
async def test_discovery_update_unchanged_fan(hass, mqtt_mock, caplog): async def test_discovery_update_unchanged_fan(hass, mqtt_mock, caplog):

View File

@ -975,10 +975,18 @@ async def test_discovery_removal_humidifier(hass, mqtt_mock, caplog):
async def test_discovery_update_humidifier(hass, mqtt_mock, caplog): async def test_discovery_update_humidifier(hass, mqtt_mock, caplog):
"""Test update of discovered humidifier.""" """Test update of discovered humidifier."""
data1 = '{ "name": "Beer", "command_topic": "test_topic", "target_humidity_command_topic": "test-topic2" }' config1 = {
data2 = '{ "name": "Milk", "command_topic": "test_topic", "target_humidity_command_topic": "test-topic2" }' "name": "Beer",
"command_topic": "test_topic",
"target_humidity_command_topic": "test-topic2",
}
config2 = {
"name": "Milk",
"command_topic": "test_topic",
"target_humidity_command_topic": "test-topic2",
}
await help_test_discovery_update( await help_test_discovery_update(
hass, mqtt_mock, caplog, humidifier.DOMAIN, data1, data2 hass, mqtt_mock, caplog, humidifier.DOMAIN, config1, config2
) )

View File

@ -651,10 +651,10 @@ async def test_discovery_removal_vacuum(hass, mqtt_mock, caplog):
async def test_discovery_update_vacuum(hass, mqtt_mock, caplog): async def test_discovery_update_vacuum(hass, mqtt_mock, caplog):
"""Test update of discovered vacuum.""" """Test update of discovered vacuum."""
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic" }' config1 = {"name": "Beer", " " "command_topic": "test_topic"}
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }' config2 = {"name": "Milk", " " "command_topic": "test_topic"}
await help_test_discovery_update( await help_test_discovery_update(
hass, mqtt_mock, caplog, vacuum.DOMAIN, data1, data2 hass, mqtt_mock, caplog, vacuum.DOMAIN, config1, config2
) )

View File

@ -153,7 +153,6 @@ light:
payload_off: "off" payload_off: "off"
""" """
import json
from os import path from os import path
from unittest.mock import call, patch from unittest.mock import call, patch
@ -2798,65 +2797,61 @@ async def test_discovery_deprecated(hass, mqtt_mock, caplog):
async def test_discovery_update_light_topic_and_template(hass, mqtt_mock, caplog): async def test_discovery_update_light_topic_and_template(hass, mqtt_mock, caplog):
"""Test update of discovered light.""" """Test update of discovered light."""
data1 = json.dumps( config1 = {
{ "name": "Beer",
"name": "Beer", "state_topic": "test_light_rgb/state1",
"state_topic": "test_light_rgb/state1", "command_topic": "test_light_rgb/set",
"command_topic": "test_light_rgb/set", "brightness_command_topic": "test_light_rgb/state1",
"brightness_command_topic": "test_light_rgb/state1", "rgb_command_topic": "test_light_rgb/rgb/set",
"rgb_command_topic": "test_light_rgb/rgb/set", "color_temp_command_topic": "test_light_rgb/state1",
"color_temp_command_topic": "test_light_rgb/state1", "effect_command_topic": "test_light_rgb/effect/set",
"effect_command_topic": "test_light_rgb/effect/set", "hs_command_topic": "test_light_rgb/hs/set",
"hs_command_topic": "test_light_rgb/hs/set", "white_value_command_topic": "test_light_rgb/white_value/set",
"white_value_command_topic": "test_light_rgb/white_value/set", "xy_command_topic": "test_light_rgb/xy/set",
"xy_command_topic": "test_light_rgb/xy/set", "brightness_state_topic": "test_light_rgb/state1",
"brightness_state_topic": "test_light_rgb/state1", "color_temp_state_topic": "test_light_rgb/state1",
"color_temp_state_topic": "test_light_rgb/state1", "effect_state_topic": "test_light_rgb/state1",
"effect_state_topic": "test_light_rgb/state1", "hs_state_topic": "test_light_rgb/state1",
"hs_state_topic": "test_light_rgb/state1", "rgb_state_topic": "test_light_rgb/state1",
"rgb_state_topic": "test_light_rgb/state1", "white_value_state_topic": "test_light_rgb/state1",
"white_value_state_topic": "test_light_rgb/state1", "xy_state_topic": "test_light_rgb/state1",
"xy_state_topic": "test_light_rgb/state1", "state_value_template": "{{ value_json.state1.state }}",
"state_value_template": "{{ value_json.state1.state }}", "brightness_value_template": "{{ value_json.state1.brightness }}",
"brightness_value_template": "{{ value_json.state1.brightness }}", "color_temp_value_template": "{{ value_json.state1.ct }}",
"color_temp_value_template": "{{ value_json.state1.ct }}", "effect_value_template": "{{ value_json.state1.fx }}",
"effect_value_template": "{{ value_json.state1.fx }}", "hs_value_template": "{{ value_json.state1.hs }}",
"hs_value_template": "{{ value_json.state1.hs }}", "rgb_value_template": "{{ value_json.state1.rgb }}",
"rgb_value_template": "{{ value_json.state1.rgb }}", "white_value_template": "{{ value_json.state1.white }}",
"white_value_template": "{{ value_json.state1.white }}", "xy_value_template": "{{ value_json.state1.xy }}",
"xy_value_template": "{{ value_json.state1.xy }}", }
}
)
data2 = json.dumps( config2 = {
{ "name": "Milk",
"name": "Milk", "state_topic": "test_light_rgb/state2",
"state_topic": "test_light_rgb/state2", "command_topic": "test_light_rgb/set",
"command_topic": "test_light_rgb/set", "brightness_command_topic": "test_light_rgb/state2",
"brightness_command_topic": "test_light_rgb/state2", "rgb_command_topic": "test_light_rgb/rgb/set",
"rgb_command_topic": "test_light_rgb/rgb/set", "color_temp_command_topic": "test_light_rgb/state2",
"color_temp_command_topic": "test_light_rgb/state2", "effect_command_topic": "test_light_rgb/effect/set",
"effect_command_topic": "test_light_rgb/effect/set", "hs_command_topic": "test_light_rgb/hs/set",
"hs_command_topic": "test_light_rgb/hs/set", "white_value_command_topic": "test_light_rgb/white_value/set",
"white_value_command_topic": "test_light_rgb/white_value/set", "xy_command_topic": "test_light_rgb/xy/set",
"xy_command_topic": "test_light_rgb/xy/set", "brightness_state_topic": "test_light_rgb/state2",
"brightness_state_topic": "test_light_rgb/state2", "color_temp_state_topic": "test_light_rgb/state2",
"color_temp_state_topic": "test_light_rgb/state2", "effect_state_topic": "test_light_rgb/state2",
"effect_state_topic": "test_light_rgb/state2", "hs_state_topic": "test_light_rgb/state2",
"hs_state_topic": "test_light_rgb/state2", "rgb_state_topic": "test_light_rgb/state2",
"rgb_state_topic": "test_light_rgb/state2", "white_value_state_topic": "test_light_rgb/state2",
"white_value_state_topic": "test_light_rgb/state2", "xy_state_topic": "test_light_rgb/state2",
"xy_state_topic": "test_light_rgb/state2", "state_value_template": "{{ value_json.state2.state }}",
"state_value_template": "{{ value_json.state2.state }}", "brightness_value_template": "{{ value_json.state2.brightness }}",
"brightness_value_template": "{{ value_json.state2.brightness }}", "color_temp_value_template": "{{ value_json.state2.ct }}",
"color_temp_value_template": "{{ value_json.state2.ct }}", "effect_value_template": "{{ value_json.state2.fx }}",
"effect_value_template": "{{ value_json.state2.fx }}", "hs_value_template": "{{ value_json.state2.hs }}",
"hs_value_template": "{{ value_json.state2.hs }}", "rgb_value_template": "{{ value_json.state2.rgb }}",
"rgb_value_template": "{{ value_json.state2.rgb }}", "white_value_template": "{{ value_json.state2.white }}",
"white_value_template": "{{ value_json.state2.white }}", "xy_value_template": "{{ value_json.state2.xy }}",
"xy_value_template": "{{ value_json.state2.xy }}", }
}
)
state_data1 = [ state_data1 = [
( (
[ [
@ -3054,8 +3049,8 @@ async def test_discovery_update_light_topic_and_template(hass, mqtt_mock, caplog
mqtt_mock, mqtt_mock,
caplog, caplog,
light.DOMAIN, light.DOMAIN,
data1, config1,
data2, config2,
state_data1=state_data1, state_data1=state_data1,
state_data2=state_data2, state_data2=state_data2,
) )
@ -3063,65 +3058,61 @@ async def test_discovery_update_light_topic_and_template(hass, mqtt_mock, caplog
async def test_discovery_update_light_template(hass, mqtt_mock, caplog): async def test_discovery_update_light_template(hass, mqtt_mock, caplog):
"""Test update of discovered light.""" """Test update of discovered light."""
data1 = json.dumps( config1 = {
{ "name": "Beer",
"name": "Beer", "state_topic": "test_light_rgb/state1",
"state_topic": "test_light_rgb/state1", "command_topic": "test_light_rgb/set",
"command_topic": "test_light_rgb/set", "brightness_command_topic": "test_light_rgb/state1",
"brightness_command_topic": "test_light_rgb/state1", "rgb_command_topic": "test_light_rgb/rgb/set",
"rgb_command_topic": "test_light_rgb/rgb/set", "color_temp_command_topic": "test_light_rgb/state1",
"color_temp_command_topic": "test_light_rgb/state1", "effect_command_topic": "test_light_rgb/effect/set",
"effect_command_topic": "test_light_rgb/effect/set", "hs_command_topic": "test_light_rgb/hs/set",
"hs_command_topic": "test_light_rgb/hs/set", "white_value_command_topic": "test_light_rgb/white_value/set",
"white_value_command_topic": "test_light_rgb/white_value/set", "xy_command_topic": "test_light_rgb/xy/set",
"xy_command_topic": "test_light_rgb/xy/set", "brightness_state_topic": "test_light_rgb/state1",
"brightness_state_topic": "test_light_rgb/state1", "color_temp_state_topic": "test_light_rgb/state1",
"color_temp_state_topic": "test_light_rgb/state1", "effect_state_topic": "test_light_rgb/state1",
"effect_state_topic": "test_light_rgb/state1", "hs_state_topic": "test_light_rgb/state1",
"hs_state_topic": "test_light_rgb/state1", "rgb_state_topic": "test_light_rgb/state1",
"rgb_state_topic": "test_light_rgb/state1", "white_value_state_topic": "test_light_rgb/state1",
"white_value_state_topic": "test_light_rgb/state1", "xy_state_topic": "test_light_rgb/state1",
"xy_state_topic": "test_light_rgb/state1", "state_value_template": "{{ value_json.state1.state }}",
"state_value_template": "{{ value_json.state1.state }}", "brightness_value_template": "{{ value_json.state1.brightness }}",
"brightness_value_template": "{{ value_json.state1.brightness }}", "color_temp_value_template": "{{ value_json.state1.ct }}",
"color_temp_value_template": "{{ value_json.state1.ct }}", "effect_value_template": "{{ value_json.state1.fx }}",
"effect_value_template": "{{ value_json.state1.fx }}", "hs_value_template": "{{ value_json.state1.hs }}",
"hs_value_template": "{{ value_json.state1.hs }}", "rgb_value_template": "{{ value_json.state1.rgb }}",
"rgb_value_template": "{{ value_json.state1.rgb }}", "white_value_template": "{{ value_json.state1.white }}",
"white_value_template": "{{ value_json.state1.white }}", "xy_value_template": "{{ value_json.state1.xy }}",
"xy_value_template": "{{ value_json.state1.xy }}", }
}
)
data2 = json.dumps( config2 = {
{ "name": "Milk",
"name": "Milk", "state_topic": "test_light_rgb/state1",
"state_topic": "test_light_rgb/state1", "command_topic": "test_light_rgb/set",
"command_topic": "test_light_rgb/set", "brightness_command_topic": "test_light_rgb/state1",
"brightness_command_topic": "test_light_rgb/state1", "rgb_command_topic": "test_light_rgb/rgb/set",
"rgb_command_topic": "test_light_rgb/rgb/set", "color_temp_command_topic": "test_light_rgb/state1",
"color_temp_command_topic": "test_light_rgb/state1", "effect_command_topic": "test_light_rgb/effect/set",
"effect_command_topic": "test_light_rgb/effect/set", "hs_command_topic": "test_light_rgb/hs/set",
"hs_command_topic": "test_light_rgb/hs/set", "white_value_command_topic": "test_light_rgb/white_value/set",
"white_value_command_topic": "test_light_rgb/white_value/set", "xy_command_topic": "test_light_rgb/xy/set",
"xy_command_topic": "test_light_rgb/xy/set", "brightness_state_topic": "test_light_rgb/state1",
"brightness_state_topic": "test_light_rgb/state1", "color_temp_state_topic": "test_light_rgb/state1",
"color_temp_state_topic": "test_light_rgb/state1", "effect_state_topic": "test_light_rgb/state1",
"effect_state_topic": "test_light_rgb/state1", "hs_state_topic": "test_light_rgb/state1",
"hs_state_topic": "test_light_rgb/state1", "rgb_state_topic": "test_light_rgb/state1",
"rgb_state_topic": "test_light_rgb/state1", "white_value_state_topic": "test_light_rgb/state1",
"white_value_state_topic": "test_light_rgb/state1", "xy_state_topic": "test_light_rgb/state1",
"xy_state_topic": "test_light_rgb/state1", "state_value_template": "{{ value_json.state2.state }}",
"state_value_template": "{{ value_json.state2.state }}", "brightness_value_template": "{{ value_json.state2.brightness }}",
"brightness_value_template": "{{ value_json.state2.brightness }}", "color_temp_value_template": "{{ value_json.state2.ct }}",
"color_temp_value_template": "{{ value_json.state2.ct }}", "effect_value_template": "{{ value_json.state2.fx }}",
"effect_value_template": "{{ value_json.state2.fx }}", "hs_value_template": "{{ value_json.state2.hs }}",
"hs_value_template": "{{ value_json.state2.hs }}", "rgb_value_template": "{{ value_json.state2.rgb }}",
"rgb_value_template": "{{ value_json.state2.rgb }}", "white_value_template": "{{ value_json.state2.white }}",
"white_value_template": "{{ value_json.state2.white }}", "xy_value_template": "{{ value_json.state2.xy }}",
"xy_value_template": "{{ value_json.state2.xy }}", }
}
)
state_data1 = [ state_data1 = [
( (
[ [
@ -3277,8 +3268,8 @@ async def test_discovery_update_light_template(hass, mqtt_mock, caplog):
mqtt_mock, mqtt_mock,
caplog, caplog,
light.DOMAIN, light.DOMAIN,
data1, config1,
data2, config2,
state_data1=state_data1, state_data1=state_data1,
state_data2=state_data2, state_data2=state_data2,
) )

View File

@ -1786,20 +1786,20 @@ async def test_discovery_removal(hass, mqtt_mock, caplog):
async def test_discovery_update_light(hass, mqtt_mock, caplog): async def test_discovery_update_light(hass, mqtt_mock, caplog):
"""Test update of discovered light.""" """Test update of discovered light."""
data1 = ( config1 = {
'{ "name": "Beer",' "name": "Beer",
' "schema": "json",' "schema": "json",
' "state_topic": "test_topic",' "state_topic": "test_topic",
' "command_topic": "test_topic" }' "command_topic": "test_topic",
) }
data2 = ( config2 = {
'{ "name": "Milk",' "name": "Milk",
' "schema": "json",' "schema": "json",
' "state_topic": "test_topic",' "state_topic": "test_topic",
' "command_topic": "test_topic" }' "command_topic": "test_topic",
) }
await help_test_discovery_update( await help_test_discovery_update(
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2 hass, mqtt_mock, caplog, light.DOMAIN, config1, config2
) )

View File

@ -950,24 +950,24 @@ async def test_discovery_removal(hass, mqtt_mock, caplog):
async def test_discovery_update_light(hass, mqtt_mock, caplog): async def test_discovery_update_light(hass, mqtt_mock, caplog):
"""Test update of discovered light.""" """Test update of discovered light."""
data1 = ( config1 = {
'{ "name": "Beer",' "name": "Beer",
' "schema": "template",' "schema": "template",
' "state_topic": "test_topic",' "state_topic": "test_topic",
' "command_topic": "test_topic",' "command_topic": "test_topic",
' "command_on_template": "on",' "command_on_template": "on",
' "command_off_template": "off"}' "command_off_template": "off",
) }
data2 = ( config2 = {
'{ "name": "Milk",' "name": "Milk",
' "schema": "template",' "schema": "template",
' "state_topic": "test_topic",' "state_topic": "test_topic",
' "command_topic": "test_topic",' "command_topic": "test_topic",
' "command_on_template": "on",' "command_on_template": "on",
' "command_off_template": "off"}' "command_off_template": "off",
) }
await help_test_discovery_update( await help_test_discovery_update(
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2 hass, mqtt_mock, caplog, light.DOMAIN, config1, config2
) )

View File

@ -379,19 +379,21 @@ async def test_discovery_removal_lock(hass, mqtt_mock, caplog):
async def test_discovery_update_lock(hass, mqtt_mock, caplog): async def test_discovery_update_lock(hass, mqtt_mock, caplog):
"""Test update of discovered lock.""" """Test update of discovered lock."""
data1 = ( config1 = {
'{ "name": "Beer",' "name": "Beer",
' "state_topic": "test_topic",' "state_topic": "test_topic",
' "command_topic": "command_topic",' "command_topic": "command_topic",
' "availability_topic": "availability_topic1" }' "availability_topic": "availability_topic1",
}
config2 = {
"name": "Milk",
"state_topic": "test_topic2",
"command_topic": "command_topic",
"availability_topic": "availability_topic2",
}
await help_test_discovery_update(
hass, mqtt_mock, caplog, LOCK_DOMAIN, config1, config2
) )
data2 = (
'{ "name": "Milk",'
' "state_topic": "test_topic2",'
' "command_topic": "command_topic",'
' "availability_topic": "availability_topic2" }'
)
await help_test_discovery_update(hass, mqtt_mock, caplog, LOCK_DOMAIN, data1, data2)
async def test_discovery_update_unchanged_lock(hass, mqtt_mock, caplog): async def test_discovery_update_unchanged_lock(hass, mqtt_mock, caplog):

View File

@ -344,15 +344,19 @@ async def test_discovery_removal_number(hass, mqtt_mock, caplog):
async def test_discovery_update_number(hass, mqtt_mock, caplog): async def test_discovery_update_number(hass, mqtt_mock, caplog):
"""Test update of discovered number.""" """Test update of discovered number."""
data1 = ( config1 = {
'{ "name": "Beer", "state_topic": "test-topic", "command_topic": "test-topic"}' "name": "Beer",
) "state_topic": "test-topic",
data2 = ( "command_topic": "test-topic",
'{ "name": "Milk", "state_topic": "test-topic", "command_topic": "test-topic"}' }
) config2 = {
"name": "Milk",
"state_topic": "test-topic",
"command_topic": "test-topic",
}
await help_test_discovery_update( await help_test_discovery_update(
hass, mqtt_mock, caplog, number.DOMAIN, data1, data2 hass, mqtt_mock, caplog, number.DOMAIN, config1, config2
) )

View File

@ -1,6 +1,5 @@
"""The tests for the MQTT scene platform.""" """The tests for the MQTT scene platform."""
import copy import copy
import json
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
@ -147,15 +146,13 @@ async def test_discovery_update_payload(hass, mqtt_mock, caplog):
config1["payload_on"] = "ON" config1["payload_on"] = "ON"
config2["payload_on"] = "ACTIVATE" config2["payload_on"] = "ACTIVATE"
data1 = json.dumps(config1)
data2 = json.dumps(config2)
await help_test_discovery_update( await help_test_discovery_update(
hass, hass,
mqtt_mock, mqtt_mock,
caplog, caplog,
scene.DOMAIN, scene.DOMAIN,
data1, config1,
data2, config2,
) )

View File

@ -309,11 +309,21 @@ async def test_discovery_removal_select(hass, mqtt_mock, caplog):
async def test_discovery_update_select(hass, mqtt_mock, caplog): async def test_discovery_update_select(hass, mqtt_mock, caplog):
"""Test update of discovered select.""" """Test update of discovered select."""
data1 = '{ "name": "Beer", "state_topic": "test-topic", "command_topic": "test-topic", "options": ["milk", "beer"]}' config1 = {
data2 = '{ "name": "Milk", "state_topic": "test-topic", "command_topic": "test-topic", "options": ["milk", "beer"]}' "name": "Beer",
"state_topic": "test-topic",
"command_topic": "test-topic",
"options": ["milk", "beer"],
}
config2 = {
"name": "Milk",
"state_topic": "test-topic",
"command_topic": "test-topic",
"options": ["milk", "beer"],
}
await help_test_discovery_update( await help_test_discovery_update(
hass, mqtt_mock, caplog, select.DOMAIN, data1, data2 hass, mqtt_mock, caplog, select.DOMAIN, config1, config2
) )

View File

@ -661,15 +661,13 @@ async def test_discovery_update_sensor_topic_template(hass, mqtt_mock, caplog):
([("sensor/state2", '{"state":100}')], "200", None), ([("sensor/state2", '{"state":100}')], "200", None),
] ]
data1 = json.dumps(config1)
data2 = json.dumps(config2)
await help_test_discovery_update( await help_test_discovery_update(
hass, hass,
mqtt_mock, mqtt_mock,
caplog, caplog,
sensor.DOMAIN, sensor.DOMAIN,
data1, config1,
data2, config2,
state_data1=state_data1, state_data1=state_data1,
state_data2=state_data2, state_data2=state_data2,
) )
@ -694,15 +692,13 @@ async def test_discovery_update_sensor_template(hass, mqtt_mock, caplog):
([("sensor/state1", '{"state":100}')], "200", None), ([("sensor/state1", '{"state":100}')], "200", None),
] ]
data1 = json.dumps(config1)
data2 = json.dumps(config2)
await help_test_discovery_update( await help_test_discovery_update(
hass, hass,
mqtt_mock, mqtt_mock,
caplog, caplog,
sensor.DOMAIN, sensor.DOMAIN,
data1, config1,
data2, config2,
state_data1=state_data1, state_data1=state_data1,
state_data2=state_data2, state_data2=state_data2,
) )

View File

@ -427,10 +427,10 @@ async def test_discovery_removal_vacuum(hass, mqtt_mock, caplog):
async def test_discovery_update_vacuum(hass, mqtt_mock, caplog): async def test_discovery_update_vacuum(hass, mqtt_mock, caplog):
"""Test update of discovered vacuum.""" """Test update of discovered vacuum."""
data1 = '{ "schema": "state", "name": "Beer", "command_topic": "test_topic"}' config1 = {"schema": "state", "name": "Beer", "command_topic": "test_topic"}
data2 = '{ "schema": "state", "name": "Milk", "command_topic": "test_topic"}' config2 = {"schema": "state", "name": "Milk", "command_topic": "test_topic"}
await help_test_discovery_update( await help_test_discovery_update(
hass, mqtt_mock, caplog, vacuum.DOMAIN, data1, data2 hass, mqtt_mock, caplog, vacuum.DOMAIN, config1, config2
) )

View File

@ -1,6 +1,5 @@
"""The tests for the MQTT switch platform.""" """The tests for the MQTT switch platform."""
import copy import copy
import json
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
@ -339,15 +338,13 @@ async def test_discovery_update_switch_topic_template(hass, mqtt_mock, caplog):
([("switch/state2", '{"state2":{"state":"OFF"}}')], "off", None), ([("switch/state2", '{"state2":{"state":"OFF"}}')], "off", None),
] ]
data1 = json.dumps(config1)
data2 = json.dumps(config2)
await help_test_discovery_update( await help_test_discovery_update(
hass, hass,
mqtt_mock, mqtt_mock,
caplog, caplog,
switch.DOMAIN, switch.DOMAIN,
data1, config1,
data2, config2,
state_data1=state_data1, state_data1=state_data1,
state_data2=state_data2, state_data2=state_data2,
) )
@ -374,15 +371,13 @@ async def test_discovery_update_switch_template(hass, mqtt_mock, caplog):
([("switch/state1", '{"state2":{"state":"OFF"}}')], "off", None), ([("switch/state1", '{"state2":{"state":"OFF"}}')], "off", None),
] ]
data1 = json.dumps(config1)
data2 = json.dumps(config2)
await help_test_discovery_update( await help_test_discovery_update(
hass, hass,
mqtt_mock, mqtt_mock,
caplog, caplog,
switch.DOMAIN, switch.DOMAIN,
data1, config1,
data2, config2,
state_data1=state_data1, state_data1=state_data1,
state_data2=state_data2, state_data2=state_data2,
) )

View File

@ -144,7 +144,9 @@ async def test_if_fires_on_mqtt_message_after_update_with_device(
): ):
"""Test tag scanning after update.""" """Test tag scanning after update."""
config1 = copy.deepcopy(DEFAULT_CONFIG_DEVICE) config1 = copy.deepcopy(DEFAULT_CONFIG_DEVICE)
config1["some_future_option_1"] = "future_option_1"
config2 = copy.deepcopy(DEFAULT_CONFIG_DEVICE) config2 = copy.deepcopy(DEFAULT_CONFIG_DEVICE)
config2["some_future_option_2"] = "future_option_2"
config2["topic"] = "foobar/tag_scanned2" config2["topic"] = "foobar/tag_scanned2"
async_fire_mqtt_message(hass, "homeassistant/tag/bla1/config", json.dumps(config1)) async_fire_mqtt_message(hass, "homeassistant/tag/bla1/config", json.dumps(config1))