def test_deprecated_or_removed_logger_with_config_attributes(caplog): """Test if the logger outputs the correct message if the line and file attribute is available in config.""" file: str = "configuration.yaml" line: int = 54 # test as deprecated option replacement_key = "jupiter" option_status = "is deprecated" replacement = f"'mars' option near {file}:{line} {option_status}, please replace it with '{replacement_key}'" config = OrderedDict([("mars", "blah")]) setattr(config, "__config_file__", file) setattr(config, "__line__", line) cv.deprecated("mars", replacement_key=replacement_key, default=False)(config) assert len(caplog.records) == 1 assert replacement in caplog.text caplog.clear() assert len(caplog.records) == 0 # test as removed option option_status = "has been removed" replacement = f"'mars' option near {file}:{line} {option_status}, please remove it from your configuration" config = OrderedDict([("mars", "blah")]) setattr(config, "__config_file__", file) setattr(config, "__line__", line) cv.removed("mars", default=False, raise_if_present=False)(config) assert len(caplog.records) == 1 assert replacement in caplog.text caplog.clear() assert len(caplog.records) == 0
def test_deprecated_cant_find_module(): """Test if the current module cannot be inspected.""" with patch("inspect.getmodule", return_value=None): # This used to raise. cv.deprecated( "mars", replacement_key="jupiter", default=False, ) with patch("inspect.getmodule", return_value=None): # This used to raise. cv.removed( "mars", default=False, )
def test_deprecated_or_removed_param_and_raise(caplog, schema): """ Test removed or deprecation options and fail the config validation by raising an exception. Expected behavior: - Outputs the appropriate deprecation or removed from support error if key is detected """ removed_schema = vol.All(cv.deprecated("mars", raise_if_present=True), schema) test_data = {"mars": True} with pytest.raises(vol.Invalid) as excinfo: removed_schema(test_data) assert ( "The 'mars' option is deprecated, please remove it from your configuration" in str(excinfo.value) ) assert len(caplog.records) == 0 test_data = {"venus": True} output = removed_schema(test_data.copy()) assert len(caplog.records) == 0 assert test_data == output deprecated_schema = vol.All(cv.removed("mars"), schema) test_data = {"mars": True} with pytest.raises(vol.Invalid) as excinfo: deprecated_schema(test_data) assert ( "The 'mars' option has been removed, please remove it from your configuration" in str(excinfo.value) ) assert len(caplog.records) == 0 test_data = {"venus": True} output = deprecated_schema(test_data.copy()) assert len(caplog.records) == 0 assert test_data == output
from homeassistant.helpers.aiohttp_client import async_get_clientsession import homeassistant.helpers.config_validation as cv from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC from homeassistant.helpers.entity import DeviceInfo from homeassistant.util import Throttle from .const import CONF_UUID, DOMAIN, KEY_MAC, TIMEOUT _LOGGER = logging.getLogger(__name__) PARALLEL_UPDATES = 0 MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) PLATFORMS = [Platform.CLIMATE, Platform.SENSOR, Platform.SWITCH] CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False) async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Establish connection with Daikin.""" conf = entry.data # For backwards compat, set unique ID if entry.unique_id is None or ".local" in entry.unique_id: hass.config_entries.async_update_entry(entry, unique_id=conf[KEY_MAC]) daikin_api = await daikin_api_setup( hass, conf[CONF_HOST], conf.get(CONF_API_KEY), conf.get(CONF_UUID), conf.get(CONF_PASSWORD),
_LOGGER = logging.getLogger(__name__) CONF_MAX_GPS_ACCURACY = "max_gps_accuracy" CONF_WAYPOINT_IMPORT = "waypoints" CONF_WAYPOINT_WHITELIST = "waypoint_whitelist" CONF_MQTT_TOPIC = "mqtt_topic" CONF_REGION_MAPPING = "region_mapping" CONF_EVENTS_ONLY = "events_only" BEACON_DEV_ID = "beacon" PLATFORMS = [Platform.DEVICE_TRACKER] DEFAULT_OWNTRACKS_TOPIC = "owntracks/#" CONFIG_SCHEMA = vol.All( cv.removed(CONF_WEBHOOK_ID), vol.Schema( { vol.Optional(DOMAIN, default={}): { vol.Optional(CONF_MAX_GPS_ACCURACY): vol.Coerce(float), vol.Optional(CONF_WAYPOINT_IMPORT, default=True): cv.boolean, vol.Optional(CONF_EVENTS_ONLY, default=False): cv.boolean, vol.Optional(CONF_MQTT_TOPIC, default=DEFAULT_OWNTRACKS_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_WAYPOINT_WHITELIST): vol.All(cv.ensure_list, [cv.string]), vol.Optional(CONF_SECRET): vol.Any(vol.Schema({vol.Optional(cv.string): cv.string}),
# SI Metric prefixes UNIT_PREFIXES = {None: 1, "k": 10**3, "M": 10**6, "G": 10**9, "T": 10**12} # SI Time prefixes UNIT_TIME = { TIME_SECONDS: 1, TIME_MINUTES: 60, TIME_HOURS: 60 * 60, TIME_DAYS: 24 * 60 * 60, } DEFAULT_ROUND = 3 PLATFORM_SCHEMA = vol.All( cv.removed(CONF_UNIT_OF_MEASUREMENT), PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME): cv.string, vol.Optional(CONF_UNIQUE_ID): cv.string, vol.Required(CONF_SOURCE_SENSOR): cv.entity_id, vol.Optional(CONF_ROUND_DIGITS, default=DEFAULT_ROUND): vol.Coerce(int), vol.Optional(CONF_UNIT_PREFIX, default=None): vol.In(UNIT_PREFIXES), vol.Optional(CONF_UNIT_TIME, default=TIME_HOURS): vol.In(UNIT_TIME), vol.Remove(CONF_UNIT_OF_MEASUREMENT): cv.string,
vol.Optional(CONF_TILT_STATE_OPTIMISTIC, default=DEFAULT_TILT_OPTIMISTIC): cv.boolean, vol.Optional(CONF_TILT_STATUS_TOPIC): 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_MODERN = vol.All( cv.removed("tilt_invert_state"), _PLATFORM_SCHEMA_BASE, validate_options, ) # Configuring MQTT Covers under the cover platform key is deprecated in HA Core 2022.6 PLATFORM_SCHEMA = vol.All( cv.PLATFORM_SCHEMA.extend(_PLATFORM_SCHEMA_BASE.schema), validate_options, warn_for_legacy_schema(cover.DOMAIN), ) DISCOVERY_SCHEMA = vol.All( cv.removed("tilt_invert_state"), _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA), validate_options,
.extend(MQTT_ENTITY_COMMON_SCHEMA.schema) .extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema) ) PLATFORM_SCHEMA_BASIC = vol.All( # CONF_WHITE_VALUE_* is deprecated, support will be removed in release 2022.9 cv.deprecated(CONF_WHITE_VALUE_COMMAND_TOPIC), cv.deprecated(CONF_WHITE_VALUE_SCALE), cv.deprecated(CONF_WHITE_VALUE_STATE_TOPIC), cv.deprecated(CONF_WHITE_VALUE_TEMPLATE), _PLATFORM_SCHEMA_BASE, ) DISCOVERY_SCHEMA_BASIC = vol.All( # CONF_VALUE_TEMPLATE is no longer supported, support was removed in 2022.2 cv.removed(CONF_VALUE_TEMPLATE), # CONF_WHITE_VALUE_* is deprecated, support will be removed in release 2022.9 cv.deprecated(CONF_WHITE_VALUE_COMMAND_TOPIC), cv.deprecated(CONF_WHITE_VALUE_SCALE), cv.deprecated(CONF_WHITE_VALUE_STATE_TOPIC), cv.deprecated(CONF_WHITE_VALUE_TEMPLATE), _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA), ) async def async_setup_entity_basic( hass, config, async_add_entities, config_entry, discovery_data=None ): """Set up a MQTT Light.""" async_add_entities([MqttLight(hass, config, config_entry, discovery_data)])
valid_speed_range_configuration, valid_preset_mode_configuration, warn_for_legacy_schema(fan.DOMAIN), ) PLATFORM_SCHEMA_MODERN = vol.All( _PLATFORM_SCHEMA_BASE, valid_speed_range_configuration, valid_preset_mode_configuration, ) DISCOVERY_SCHEMA = vol.All( # 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, # are no longer supported, support was removed in release 2021.12 cv.removed(CONF_PAYLOAD_HIGH_SPEED), cv.removed(CONF_PAYLOAD_LOW_SPEED), cv.removed(CONF_PAYLOAD_MEDIUM_SPEED), cv.removed(CONF_SPEED_COMMAND_TOPIC), cv.removed(CONF_SPEED_LIST), cv.removed(CONF_SPEED_STATE_TOPIC), cv.removed(CONF_SPEED_VALUE_TEMPLATE), _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA), valid_speed_range_configuration, valid_preset_mode_configuration, ) async def async_setup_platform( hass: HomeAssistant, config: ConfigType,
"wind": ATTR_CONDITION_WINDY, "fog": ATTR_CONDITION_FOG, "cloudy": ATTR_CONDITION_CLOUDY, "partly-cloudy-day": ATTR_CONDITION_PARTLYCLOUDY, "partly-cloudy-night": ATTR_CONDITION_PARTLYCLOUDY, "hail": ATTR_CONDITION_HAIL, "thunderstorm": ATTR_CONDITION_LIGHTNING, "tornado": None, } CONF_UNITS = "units" DEFAULT_NAME = "Dark Sky" PLATFORM_SCHEMA = vol.All( cv.removed(CONF_UNITS), PLATFORM_SCHEMA.extend({ vol.Required(CONF_API_KEY): cv.string, vol.Optional(CONF_LATITUDE): cv.latitude, vol.Optional(CONF_LONGITUDE): cv.longitude, vol.Optional(CONF_MODE, default="hourly"): vol.In(FORECAST_MODE), vol.Optional(CONF_UNITS): vol.In(["auto", "si", "us", "ca", "uk", "uk2"]), vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, }), )
vol.Coerce(int), }), _unsupported({ CONF_ACCOUNTS, CONF_CIRCLES, CONF_ERROR_THRESHOLD, CONF_MAX_UPDATE_WAIT, CONF_MEMBERS, CONF_PREFIX, CONF_SCAN_INTERVAL, CONF_WARNING_THRESHOLD, }), _show_as_state, ) CONFIG_SCHEMA = vol.Schema( vol.All({DOMAIN: LIFE360_SCHEMA}, cv.removed(DOMAIN, raise_if_present=False)), extra=vol.ALLOW_EXTRA, ) @dataclass class IntegData: """Integration data.""" cfg_options: dict[str, Any] | None = None # ConfigEntry.entry_id: Life360DataUpdateCoordinator coordinators: dict[str, Life360DataUpdateCoordinator] = field( init=False, default_factory=dict) # member_id: missing location reason missing_loc_reason: dict[str, MissingLocReason] = field(init=False,
cv.template, vol.Optional(CONF_TEMP_LOW_STATE_TOPIC): valid_subscribe_topic, vol.Optional(CONF_TEMP_STATE_TEMPLATE): cv.template, vol.Optional(CONF_TEMP_STATE_TOPIC): valid_subscribe_topic, vol.Optional(CONF_TEMPERATURE_UNIT): cv.temperature_unit, vol.Optional(CONF_VALUE_TEMPLATE): cv.template, }).extend(MQTT_ENTITY_COMMON_SCHEMA.schema) PLATFORM_SCHEMA_MODERN = vol.All( # Support CONF_SEND_IF_OFF is removed with release 2022.9 cv.removed(CONF_SEND_IF_OFF), # AWAY and HOLD mode topics and templates are no longer supported, support was removed with release 2022.9 cv.removed(CONF_AWAY_MODE_COMMAND_TOPIC), cv.removed(CONF_AWAY_MODE_STATE_TEMPLATE), cv.removed(CONF_AWAY_MODE_STATE_TOPIC), cv.removed(CONF_HOLD_COMMAND_TEMPLATE), cv.removed(CONF_HOLD_COMMAND_TOPIC), cv.removed(CONF_HOLD_STATE_TEMPLATE), cv.removed(CONF_HOLD_STATE_TOPIC), cv.removed(CONF_HOLD_LIST), _PLATFORM_SCHEMA_BASE, valid_preset_mode_configuration, ) # Configuring MQTT Climate under the climate platform key is deprecated in HA Core 2022.6 PLATFORM_SCHEMA = vol.All(
vol.Optional(CONF_XY_COMMAND_TOPIC): valid_publish_topic, vol.Optional(CONF_XY_STATE_TOPIC): valid_subscribe_topic, vol.Optional(CONF_XY_VALUE_TEMPLATE): cv.template, }, ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema).extend( MQTT_LIGHT_SCHEMA_SCHEMA.schema)) # The use of PLATFORM_SCHEMA is deprecated in HA Core 2022.6 PLATFORM_SCHEMA_BASIC = vol.All( cv.PLATFORM_SCHEMA.extend(_PLATFORM_SCHEMA_BASE.schema), ) DISCOVERY_SCHEMA_BASIC = vol.All( # CONF_VALUE_TEMPLATE is no longer supported, support was removed in 2022.2 cv.removed(CONF_VALUE_TEMPLATE), # CONF_WHITE_VALUE_* is no longer supported, support was removed in 2022.9 cv.removed(CONF_WHITE_VALUE_COMMAND_TOPIC), cv.removed(CONF_WHITE_VALUE_SCALE), cv.removed(CONF_WHITE_VALUE_STATE_TOPIC), cv.removed(CONF_WHITE_VALUE_TEMPLATE), _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA), ) PLATFORM_SCHEMA_MODERN_BASIC = vol.All( # CONF_VALUE_TEMPLATE is no longer supported, support was removed in 2022.2 cv.removed(CONF_VALUE_TEMPLATE), # CONF_WHITE_VALUE_* is no longer supported, support was removed in 2022.9 cv.removed(CONF_WHITE_VALUE_COMMAND_TOPIC), cv.removed(CONF_WHITE_VALUE_SCALE), cv.removed(CONF_WHITE_VALUE_STATE_TOPIC),
SensorEntity, ) from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.const import CONF_NAME, CONF_UNIT_OF_MEASUREMENT from homeassistant.core import HomeAssistant import homeassistant.helpers.config_validation as cv from homeassistant.helpers.device_registry import DeviceEntryType from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType import homeassistant.util.dt as dt_util from .const import DEFAULT_NAME, DOMAIN PLATFORM_SCHEMA = vol.All( cv.removed(CONF_UNIT_OF_MEASUREMENT, raise_if_present=False), PLATFORM_SCHEMA.extend( { vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Remove(CONF_UNIT_OF_MEASUREMENT): cv.string, }, ), ) async def async_setup_platform( hass: HomeAssistant, config: ConfigType, async_add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None:
vol.Optional(CONF_WHITE_SCALE, default=DEFAULT_WHITE_SCALE): vol.All(vol.Coerce(int), vol.Range(min=1)), vol.Optional(CONF_XY, default=DEFAULT_XY): cv.boolean, }, ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema).extend( MQTT_LIGHT_SCHEMA_SCHEMA.schema)) # Configuring MQTT Lights under the light platform key is deprecated in HA Core 2022.6 PLATFORM_SCHEMA_JSON = vol.All( cv.PLATFORM_SCHEMA.extend(_PLATFORM_SCHEMA_BASE.schema), valid_color_configuration, ) DISCOVERY_SCHEMA_JSON = vol.All( # CONF_WHITE_VALUE is no longer supported, support was removed in 2022.9 cv.removed(CONF_WHITE_VALUE), _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA), valid_color_configuration, ) PLATFORM_SCHEMA_MODERN_JSON = vol.All( # CONF_WHITE_VALUE is no longer supported, support was removed in 2022.9 cv.removed(CONF_WHITE_VALUE), _PLATFORM_SCHEMA_BASE, valid_color_configuration, ) async def async_setup_entity_json(hass, config: ConfigType, async_add_entities, config_entry, discovery_data): """Set up a MQTT JSON Light."""
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean, vol.Optional(CONF_RED_TEMPLATE): cv.template, vol.Optional(CONF_STATE_TEMPLATE): cv.template, }).extend(MQTT_ENTITY_COMMON_SCHEMA.schema).extend( MQTT_LIGHT_SCHEMA_SCHEMA.schema)) # Configuring MQTT Lights under the light platform key is deprecated in HA Core 2022.6 PLATFORM_SCHEMA_TEMPLATE = vol.All( cv.PLATFORM_SCHEMA.extend(_PLATFORM_SCHEMA_BASE.schema), ) DISCOVERY_SCHEMA_TEMPLATE = vol.All( # CONF_WHITE_VALUE_TEMPLATE is no longer supported, support was removed in 2022.9 cv.removed(CONF_WHITE_VALUE_TEMPLATE), _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA), ) PLATFORM_SCHEMA_MODERN_TEMPLATE = vol.All( # CONF_WHITE_VALUE_TEMPLATE is no longer supported, support was removed in 2022.9 cv.removed(CONF_WHITE_VALUE_TEMPLATE), _PLATFORM_SCHEMA_BASE, ) async def async_setup_entity_template(hass, config, async_add_entities, config_entry, discovery_data): """Set up a MQTT Template light.""" async_add_entities( [MqttLightTemplate(hass, config, config_entry, discovery_data)])