Restructure translations for entity components (#89702)

This commit is contained in:
Franck Nijhof 2023-03-16 12:16:08 +01:00 committed by GitHub
parent f55aaf7664
commit f32b7859b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 435 additions and 321 deletions

View file

@ -26,8 +26,9 @@
"armed_vacation": "{entity_name} armed vacation"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"armed": "Armed",
"disarmed": "Disarmed",
"armed_home": "Armed home",
@ -42,3 +43,4 @@
}
}
}
}

View file

@ -1,10 +1,12 @@
{
"title": "Alert",
"state": {
"entity_component": {
"_": {
"state": {
"idle": "[%key:common::state::idle%]",
"off": "Acknowledged",
"on": "[%key:common::state::active%]"
}
}
}
}

View file

@ -1,10 +1,12 @@
{
"title": "Automation",
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
},
"issues": {
"service_not_found": {

View file

@ -106,116 +106,170 @@
"turned_off": "{entity_name} turned off"
}
},
"state": {
"battery": {
"off": "Normal",
"on": "Low"
},
"battery_charging": {
"off": "Not charging",
"on": "Charging"
},
"carbon_monoxide": {
"off": "[%key:component::binary_sensor::state::gas::off%]",
"on": "[%key:component::binary_sensor::state::gas::on%]"
},
"cold": {
"off": "[%key:component::binary_sensor::state::battery::off%]",
"on": "Cold"
},
"connectivity": {
"off": "[%key:common::state::disconnected%]",
"on": "[%key:common::state::connected%]"
},
"door": {
"off": "[%key:common::state::closed%]",
"on": "[%key:common::state::open%]"
},
"garage_door": {
"off": "[%key:common::state::closed%]",
"on": "[%key:common::state::open%]"
},
"gas": {
"off": "Clear",
"on": "Detected"
},
"heat": {
"off": "[%key:component::binary_sensor::state::battery::off%]",
"on": "Hot"
},
"light": {
"off": "No light",
"on": "Light detected"
},
"lock": {
"off": "[%key:common::state::locked%]",
"on": "[%key:common::state::unlocked%]"
},
"moisture": {
"off": "Dry",
"on": "Wet"
},
"motion": {
"off": "[%key:component::binary_sensor::state::gas::off%]",
"on": "[%key:component::binary_sensor::state::gas::on%]"
},
"moving": {
"off": "Not moving",
"on": "Moving"
},
"occupancy": {
"off": "[%key:component::binary_sensor::state::gas::off%]",
"on": "[%key:component::binary_sensor::state::gas::on%]"
},
"opening": {
"off": "[%key:common::state::closed%]",
"on": "[%key:common::state::open%]"
},
"plug": {
"off": "Unplugged",
"on": "Plugged in"
},
"presence": {
"off": "[%key:component::device_tracker::state::_::not_home%]",
"on": "[%key:component::device_tracker::state::_::home%]"
},
"problem": {
"off": "OK",
"on": "Problem"
},
"running": {
"off": "Not running",
"on": "Running"
},
"safety": {
"off": "Safe",
"on": "Unsafe"
},
"smoke": {
"off": "[%key:component::binary_sensor::state::gas::off%]",
"on": "[%key:component::binary_sensor::state::gas::on%]"
},
"sound": {
"off": "[%key:component::binary_sensor::state::gas::off%]",
"on": "[%key:component::binary_sensor::state::gas::on%]"
},
"update": {
"off": "Up-to-date",
"on": "Update available"
},
"vibration": {
"off": "[%key:component::binary_sensor::state::gas::off%]",
"on": "[%key:component::binary_sensor::state::gas::on%]"
},
"window": {
"off": "[%key:common::state::closed%]",
"on": "[%key:common::state::open%]"
},
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
},
"battery": {
"state": {
"off": "Normal",
"on": "Low"
}
},
"battery_charging": {
"state": {
"off": "Not charging",
"on": "Charging"
}
},
"carbon_monoxide": {
"state": {
"off": "[%key:component::binary_sensor::entity_component::gas::state::off%]",
"on": "[key:component::binary_sensor::entity_component::gas::state::on%]"
}
},
"cold": {
"state": {
"off": "[%key:component::binary_sensor::entity_component::battery::state::off%]",
"on": "Cold"
}
},
"connectivity": {
"state": {
"off": "[%key:common::state::disconnected%]",
"on": "[%key:common::state::connected%]"
}
},
"door": {
"state": {
"off": "[%key:common::state::closed%]",
"on": "[%key:common::state::open%]"
}
},
"garage_door": {
"state": {
"off": "[%key:common::state::closed%]",
"on": "[%key:common::state::open%]"
}
},
"gas": {
"state": {
"off": "Clear",
"on": "Detected"
}
},
"heat": {
"state": {
"off": "[%key:component::binary_sensor::entity_component::battery::state::off%]",
"on": "Hot"
}
},
"light": {
"state": {
"off": "No light",
"on": "Light detected"
}
},
"lock": {
"state": {
"off": "[%key:common::state::locked%]",
"on": "[%key:common::state::unlocked%]"
}
},
"moisture": {
"state": {
"off": "Dry",
"on": "Wet"
}
},
"motion": {
"state": {
"off": "[key:component::binary_sensor::entity_component::gas::state::off%]",
"on": "[key:component::binary_sensor::entity_component::gas::state::on%]"
}
},
"moving": {
"state": {
"off": "Not moving",
"on": "Moving"
}
},
"occupancy": {
"state": {
"off": "[key:component::binary_sensor::entity_component::gas::state::off%]",
"on": "[key:component::binary_sensor::entity_component::gas::state::on%]"
}
},
"opening": {
"state": {
"off": "[%key:common::state::closed%]",
"on": "[%key:common::state::open%]"
}
},
"plug": {
"state": {
"off": "Unplugged",
"on": "Plugged in"
}
},
"presence": {
"state": {
"off": "[%key:component::device_tracker::entity_component::_::state::not_home%]",
"on": "[%key:component::device_tracker::entity_component::_::state::home%]"
}
},
"problem": {
"state": {
"off": "OK",
"on": "Problem"
}
},
"running": {
"state": {
"off": "Not running",
"on": "Running"
}
},
"safety": {
"state": {
"off": "Safe",
"on": "Unsafe"
}
},
"smoke": {
"state": {
"off": "[key:component::binary_sensor::entity_component::gas::state::off%]",
"on": "[key:component::binary_sensor::entity_component::gas::state::on%]"
}
},
"sound": {
"state": {
"off": "[key:component::binary_sensor::entity_component::gas::state::off%]",
"on": "[key:component::binary_sensor::entity_component::gas::state::on%]"
}
},
"update": {
"state": {
"off": "Up-to-date",
"on": "Update available"
}
},
"vibration": {
"state": {
"off": "[key:component::binary_sensor::entity_component::gas::state::off%]",
"on": "[key:component::binary_sensor::entity_component::gas::state::on%]"
}
},
"window": {
"state": {
"off": "[%key:common::state::closed%]",
"on": "[%key:common::state::open%]"
}
}
},
"device_class": {
"co": "carbon_monoxide",
"cold": "cold",

View file

@ -1,9 +1,11 @@
{
"title": "Calendar",
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
}
}

View file

@ -1,10 +1,12 @@
{
"title": "Camera",
"state": {
"entity_component": {
"_": {
"state": {
"recording": "Recording",
"streaming": "Streaming",
"idle": "[%key:common::state::idle%]"
}
}
}
}

View file

@ -15,8 +15,9 @@
"set_preset_mode": "Change preset on {entity_name}"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"heat": "Heat",
"cool": "Cool",
@ -24,10 +25,8 @@
"auto": "Auto",
"dry": "Dry",
"fan_only": "Fan only"
}
},
"state_attributes": {
"_": {
"aux_heat": { "name": "Aux heat" },
"current_humidity": { "name": "Current humidity" },
"current_temperature": { "name": "Current temperature" },
@ -104,3 +103,4 @@
}
}
}
}

View file

@ -1,9 +1,11 @@
{
"title": "Configurator",
"state": {
"entity_component": {
"_": {
"state": {
"configure": "Configure",
"configured": "Configured"
}
}
}
}

View file

@ -27,8 +27,9 @@
"tilt_position": "{entity_name} tilt position changes"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"open": "[%key:common::state::open%]",
"opening": "Opening",
"closed": "[%key:common::state::closed%]",
@ -37,3 +38,4 @@
}
}
}
}

View file

@ -10,10 +10,12 @@
"leaves": "{entity_name} leaves a zone"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"home": "[%key:common::state::home%]",
"not_home": "[%key:common::state::not_home%]"
}
}
}
}

View file

@ -16,10 +16,12 @@
"turn_off": "Turn off {entity_name}"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
}
}

View file

@ -155,18 +155,20 @@
}
}
},
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]",
"home": "[%key:component::device_tracker::state::_::home%]",
"not_home": "[%key:component::device_tracker::state::_::not_home%]",
"home": "[%key:component::device_tracker::entity_component::_::state::home%]",
"not_home": "[%key:component::device_tracker::entity_component::_::state::not_home%]",
"open": "[%key:common::state::open%]",
"closed": "[%key:common::state::closed%]",
"locked": "[%key:common::state::locked%]",
"unlocked": "[%key:common::state::unlocked%]",
"ok": "[%key:component::binary_sensor::state::problem::off%]",
"problem": "[%key:component::binary_sensor::state::problem::on%]"
"ok": "[%key:component::binary_sensor::entity_component::problem::state::off%]",
"problem": "[%key:component::binary_sensor::entity_component::problem::state::on%]"
}
}
}
}

View file

@ -20,10 +20,12 @@
"turn_off": "Turn off {entity_name}"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
}
}

View file

@ -1,9 +1,11 @@
{
"title": "Input boolean",
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
}
}

View file

@ -19,10 +19,12 @@
"turned_off": "{entity_name} turned off"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
}
}

View file

@ -15,10 +15,12 @@
"unlocked": "{entity_name} unlocked"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"locked": "[%key:common::state::locked%]",
"unlocked": "[%key:common::state::unlocked%]"
}
}
}
}

View file

@ -19,8 +19,9 @@
"changed_states": "{entity_name} changed states"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]",
"playing": "Playing",
@ -31,3 +32,4 @@
}
}
}
}

View file

@ -1,9 +1,11 @@
{
"title": "Person",
"state": {
"entity_component": {
"_": {
"state": {
"home": "[%key:common::state::home%]",
"not_home": "[%key:common::state::not_home%]"
}
}
}
}

View file

@ -1,9 +1,11 @@
{
"title": "Plant Monitor",
"state": {
"entity_component": {
"_": {
"ok": "[%key:component::binary_sensor::state::problem::off%]",
"problem": "[%key:component::binary_sensor::state::problem::on%]"
"state": {
"ok": "[%key:component::binary_sensor::entity_component::problem::state::off%]",
"problem": "[%key:component::binary_sensor::entity_component::problem::state::on%]"
}
}
}
}

View file

@ -16,10 +16,12 @@
"turned_off": "{entity_name} turned off"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
}
}

View file

@ -1,9 +1,11 @@
{
"title": "Schedule",
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
}
}

View file

@ -1,9 +1,11 @@
{
"title": "Script",
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
}
}

View file

@ -94,10 +94,12 @@
"wind_speed": "{entity_name} wind speed changes"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
}
}

View file

@ -10,10 +10,12 @@
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"above_horizon": "Above horizon",
"below_horizon": "Below horizon"
}
}
}
}

View file

@ -16,10 +16,12 @@
"turned_off": "{entity_name} turned off"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
}
}
}

View file

@ -1,9 +1,11 @@
{
"state": {
"entity_component": {
"_": {
"state": {
"active": "[%key:common::state::active%]",
"idle": "[%key:common::state::idle%]",
"paused": "[%key:common::state::paused%]"
}
}
}
}

View file

@ -14,8 +14,9 @@
"dock": "Let {entity_name} return to the dock"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"cleaning": "Cleaning",
"docked": "Docked",
"error": "Error",
@ -27,3 +28,4 @@
}
}
}
}

View file

@ -5,8 +5,9 @@
"turn_off": "Turn off {entity_name}"
}
},
"state": {
"entity_component": {
"_": {
"state": {
"off": "[%key:common::state::off%]",
"eco": "Eco",
"electric": "Electric",
@ -17,3 +18,4 @@
}
}
}
}

View file

@ -1,6 +1,7 @@
{
"state": {
"entity_component": {
"_": {
"state": {
"clear-night": "Clear, night",
"cloudy": "Cloudy",
"exceptional": "Exceptional",
@ -19,3 +20,4 @@
}
}
}
}

View file

@ -255,11 +255,14 @@ class _TranslationCache:
categories.update(resource)
for category in categories:
resource_func = (
_merge_resources if category == "state" else _build_resources
)
new_resources: Mapping[str, dict[str, Any] | str]
new_resources = resource_func( # type: ignore[assignment]
if category in ("state", "entity_component"):
new_resources = _merge_resources(
translation_strings, components, category
)
else:
new_resources = _build_resources(
translation_strings, components, category
)
@ -299,7 +302,7 @@ async def async_get_translations(
components = set(integrations)
elif config_flow:
components = (await async_get_config_flows(hass)) - hass.config.components
elif category == "state":
elif category in ("state", "entity_component"):
components = set(hass.config.components)
else:
# Only 'state' supports merging, so remove platforms from selection

View file

@ -231,25 +231,6 @@ def gen_strings_schema(config: Config, integration: Integration) -> vol.Schema:
vol.Optional("trigger_type"): {str: cv.string_with_no_html},
vol.Optional("trigger_subtype"): {str: cv.string_with_no_html},
},
vol.Optional("state"): cv.schema_with_slug_keys(
cv.schema_with_slug_keys(
cv.string_with_no_html, slug_validator=translation_key_validator
),
slug_validator=vol.Any("_", cv.slug),
),
vol.Optional("state_attributes"): cv.schema_with_slug_keys(
cv.schema_with_slug_keys(
{
vol.Optional("name"): str,
vol.Optional("state"): cv.schema_with_slug_keys(
cv.string_with_no_html,
slug_validator=translation_key_validator,
),
},
slug_validator=translation_key_validator,
),
slug_validator=vol.Any("_", cv.slug),
),
vol.Optional("system_health"): {
vol.Optional("info"): cv.schema_with_slug_keys(
cv.string_with_no_html, slug_validator=translation_key_validator
@ -283,26 +264,48 @@ def gen_strings_schema(config: Config, integration: Integration) -> vol.Schema:
),
)
},
vol.Optional("entity"): {
str: {
str: {
vol.Optional("name"): cv.string_with_no_html,
vol.Optional("state_attributes"): {
str: {
vol.Optional("entity_component"): cv.schema_with_slug_keys(
{
vol.Optional("state"): cv.schema_with_slug_keys(
cv.string_with_no_html,
slug_validator=translation_key_validator,
),
vol.Optional("state_attributes"): cv.schema_with_slug_keys(
{
vol.Optional("name"): str,
vol.Optional("state"): cv.schema_with_slug_keys(
cv.string_with_no_html,
slug_validator=translation_key_validator,
),
},
slug_validator=translation_key_validator,
),
},
slug_validator=vol.Any("_", cv.slug),
),
vol.Optional("entity"): cv.schema_with_slug_keys(
cv.schema_with_slug_keys(
{
vol.Optional("name"): cv.string_with_no_html,
vol.Optional("state"): cv.schema_with_slug_keys(
cv.string_with_no_html,
slug_validator=translation_key_validator,
),
}
},
vol.Optional("state_attributes"): cv.schema_with_slug_keys(
{
vol.Optional("name"): cv.string_with_no_html,
vol.Optional("state"): cv.schema_with_slug_keys(
cv.string_with_no_html,
slug_validator=translation_key_validator,
),
}
}
},
slug_validator=translation_key_validator,
),
},
slug_validator=translation_key_validator,
),
slug_validator=cv.slug,
),
}
)

View file

@ -373,32 +373,32 @@ async def test_caching(hass: HomeAssistant) -> None:
"homeassistant.helpers.translation._merge_resources",
side_effect=translation._merge_resources,
) as mock_merge:
load1 = await translation.async_get_translations(hass, "en", "state")
load1 = await translation.async_get_translations(hass, "en", "entity_component")
assert len(mock_merge.mock_calls) == 1
load2 = await translation.async_get_translations(hass, "en", "state")
load2 = await translation.async_get_translations(hass, "en", "entity_component")
assert len(mock_merge.mock_calls) == 1
assert load1 == load2
for key in load1:
assert key.startswith("component.sensor.state.") or key.startswith(
"component.light.state."
)
assert key.startswith(
"component.sensor.entity_component._.state."
) or key.startswith("component.light.entity_component._.state.")
load_sensor_only = await translation.async_get_translations(
hass, "en", "state", integrations={"sensor"}
hass, "en", "entity_component", integrations={"sensor"}
)
assert load_sensor_only
for key in load_sensor_only:
assert key.startswith("component.sensor.state.")
assert key.startswith("component.sensor.entity_component._.state.")
load_light_only = await translation.async_get_translations(
hass, "en", "state", integrations={"light"}
hass, "en", "entity_component", integrations={"light"}
)
assert load_light_only
for key in load_light_only:
assert key.startswith("component.light.state.")
assert key.startswith("component.light.entity_component._.state.")
hass.config.components.add("media_player")