Skip to content

Commit a3c5add

Browse files
committed
Merge remote-tracking branch 'origin/nexia_290' into nexia_290
2 parents dc92d53 + b1ef7a7 commit a3c5add

File tree

5 files changed

+361
-18
lines changed

5 files changed

+361
-18
lines changed

homeassistant/components/home_connect/manifest.json

+14
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
"codeowners": ["@DavidMStraub", "@Diegorro98", "@MartinHjelmare"],
55
"config_flow": true,
66
"dependencies": ["application_credentials", "repairs"],
7+
"dhcp": [
8+
{
9+
"hostname": "balay-*",
10+
"macaddress": "C8D778*"
11+
},
12+
{
13+
"hostname": "(bosch|siemens)-*",
14+
"macaddress": "68A40E*"
15+
},
16+
{
17+
"hostname": "siemens-*",
18+
"macaddress": "38B4D3*"
19+
}
20+
],
721
"documentation": "https://www.home-assistant.io/integrations/home_connect",
822
"iot_class": "cloud_push",
923
"loggers": ["aiohomeconnect"],

homeassistant/components/mqtt/strings.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@
244244
"title": "Configure MQTT device \"{mqtt_device}\"",
245245
"description": "Please configure MQTT specific details for {platform} entity \"{entity}\":",
246246
"data": {
247-
"on_command_type": "ON command type",
248247
"blue_template": "Blue template",
249248
"brightness_template": "Brightness template",
250249
"command_template": "Command template",
@@ -255,6 +254,7 @@
255254
"force_update": "Force update",
256255
"green_template": "Green template",
257256
"last_reset_value_template": "Last reset value template",
257+
"on_command_type": "ON command type",
258258
"optimistic": "Optimistic",
259259
"payload_off": "Payload \"off\"",
260260
"payload_on": "Payload \"on\"",
@@ -275,19 +275,19 @@
275275
"command_template": "A [template](https://www.home-assistant.io/docs/configuration/templating/#using-command-templates-with-mqtt) to render the payload to be published at the command topic.",
276276
"command_topic": "The publishing topic that will be used to control the {platform} entity. [Learn more.]({url}#command_topic)",
277277
"color_temp_template": "[Template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract color temperature in Kelvin from the state payload value. Expected result of the template is an integer.",
278+
"force_update": "Sends update events even if the value hasn’t changed. Useful if you want to have meaningful value graphs in history. [Learn more.]({url}#force_update)",
278279
"green_template": "[Template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract green color from the state payload value. Expected result of the template is an integer from 0-255 range.",
279280
"last_reset_value_template": "Defines a [template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract the last reset. When Last reset template is set, the State class option must be Total. [Learn more.]({url}#last_reset_value_template)",
280-
"force_update": "Sends update events even if the value hasn’t changed. Useful if you want to have meaningful value graphs in history. [Learn more.]({url}#force_update)",
281281
"on_command_type": "Defines when the payload \"on\" is sent. Using \"Last\" (the default) will send any style (brightness, color, etc) topics first and then a payload \"on\" to the command topic. Using \"First\" will send the payload \"on\" and then any style topics. Using \"Brightness\" will only send brightness commands instead of the payload \"on\" to turn the light on.",
282282
"optimistic": "Flag that defines if the {platform} entity works in optimistic mode. [Learn more.]({url}#optimistic)",
283-
"payload_off": "The payload that represents the off state.",
284-
"payload_on": "The payload that represents the on state.",
283+
"payload_off": "The payload that represents the \"off\" state.",
284+
"payload_on": "The payload that represents the \"on\" state.",
285285
"qos": "The QoS value a {platform} entity should use.",
286286
"red_template": "[Template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract red color from the state payload value. Expected result of the template is an integer from 0-255 range.",
287287
"retain": "Select if values published by the {platform} entity should be retained at the MQTT broker.",
288288
"state_template": "[Template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract state from the state payload value.",
289289
"state_topic": "The MQTT topic subscribed to receive {platform} state values. [Learn more.]({url}#state_topic)",
290-
"supported_color_modes": "A list of color modes supported by the list. Possible color modes are On/Off, Brightness, Color temperature, HS, XY, RGB, RGBW, RGBWW, White. Note that if On/Off or Brightness are used, that must be the only value in the list. [Learn more.]({url}#supported_color_modes)",
290+
"supported_color_modes": "A list of color modes supported by the light. Possible color modes are On/Off, Brightness, Color temperature, HS, XY, RGB, RGBW, RGBWW, White. Note that if On/Off or Brightness are used, that must be the only value in the list. [Learn more.]({url}#supported_color_modes)",
291291
"value_template": "Defines a [template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract the {platform} entity value. [Learn more.]({url}#value_template)"
292292
},
293293
"sections": {

homeassistant/generated/dhcp.py

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/components/esphome/test_entity.py

+152
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,19 @@
1010
BinarySensorState,
1111
SensorInfo,
1212
SensorState,
13+
build_unique_id,
1314
)
15+
import pytest
1416

17+
from homeassistant.components.esphome import DOMAIN
1518
from homeassistant.const import (
1619
ATTR_FRIENDLY_NAME,
1720
ATTR_RESTORED,
1821
EVENT_HOMEASSISTANT_STOP,
1922
STATE_OFF,
2023
STATE_ON,
2124
STATE_UNAVAILABLE,
25+
Platform,
2226
)
2327
from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback
2428
from homeassistant.helpers import entity_registry as er
@@ -513,3 +517,151 @@ async def test_entity_without_name_device_with_friendly_name(
513517
# Make sure we have set the name to `None` as otherwise
514518
# the friendly_name will be "The Best Mixer "
515519
assert state.attributes[ATTR_FRIENDLY_NAME] == "The Best Mixer"
520+
521+
522+
@pytest.mark.usefixtures("hass_storage")
523+
async def test_entity_id_preserved_on_upgrade(
524+
hass: HomeAssistant,
525+
mock_client: APIClient,
526+
mock_esphome_device: MockESPHomeDeviceType,
527+
entity_registry: er.EntityRegistry,
528+
) -> None:
529+
"""Test entity_id is preserved on upgrade."""
530+
entity_info = [
531+
BinarySensorInfo(
532+
object_id="my",
533+
key=1,
534+
name="my",
535+
unique_id="binary_sensor_my",
536+
),
537+
]
538+
states = [
539+
BinarySensorState(key=1, state=True, missing_state=False),
540+
]
541+
user_service = []
542+
assert (
543+
build_unique_id("11:22:33:44:55:AA", entity_info[0])
544+
== "11:22:33:44:55:AA-binary_sensor-my"
545+
)
546+
547+
entry = entity_registry.async_get_or_create(
548+
Platform.BINARY_SENSOR,
549+
DOMAIN,
550+
"11:22:33:44:55:AA-binary_sensor-my",
551+
suggested_object_id="should_not_change",
552+
)
553+
assert entry.entity_id == "binary_sensor.should_not_change"
554+
await mock_esphome_device(
555+
mock_client=mock_client,
556+
entity_info=entity_info,
557+
user_service=user_service,
558+
states=states,
559+
device_info={"friendly_name": "The Best Mixer", "name": "mixer"},
560+
)
561+
state = hass.states.get("binary_sensor.should_not_change")
562+
assert state is not None
563+
564+
565+
@pytest.mark.usefixtures("hass_storage")
566+
async def test_entity_id_preserved_on_upgrade_old_format_entity_id(
567+
hass: HomeAssistant,
568+
mock_client: APIClient,
569+
mock_esphome_device: MockESPHomeDeviceType,
570+
entity_registry: er.EntityRegistry,
571+
) -> None:
572+
"""Test entity_id is preserved on upgrade from old format."""
573+
entity_info = [
574+
BinarySensorInfo(
575+
object_id="my",
576+
key=1,
577+
name="my",
578+
unique_id="binary_sensor_my",
579+
),
580+
]
581+
states = [
582+
BinarySensorState(key=1, state=True, missing_state=False),
583+
]
584+
user_service = []
585+
assert (
586+
build_unique_id("11:22:33:44:55:AA", entity_info[0])
587+
== "11:22:33:44:55:AA-binary_sensor-my"
588+
)
589+
590+
entry = entity_registry.async_get_or_create(
591+
Platform.BINARY_SENSOR,
592+
DOMAIN,
593+
"11:22:33:44:55:AA-binary_sensor-my",
594+
suggested_object_id="my",
595+
)
596+
assert entry.entity_id == "binary_sensor.my"
597+
await mock_esphome_device(
598+
mock_client=mock_client,
599+
entity_info=entity_info,
600+
user_service=user_service,
601+
states=states,
602+
device_info={"name": "mixer"},
603+
)
604+
state = hass.states.get("binary_sensor.my")
605+
assert state is not None
606+
607+
608+
async def test_entity_id_preserved_on_upgrade_when_in_storage(
609+
hass: HomeAssistant,
610+
mock_client: APIClient,
611+
hass_storage: dict[str, Any],
612+
mock_esphome_device: MockESPHomeDeviceType,
613+
entity_registry: er.EntityRegistry,
614+
) -> None:
615+
"""Test entity_id is preserved on upgrade with user defined entity_id."""
616+
entity_info = [
617+
BinarySensorInfo(
618+
object_id="my",
619+
key=1,
620+
name="my",
621+
unique_id="binary_sensor_my",
622+
),
623+
]
624+
states = [
625+
BinarySensorState(key=1, state=True, missing_state=False),
626+
]
627+
user_service = []
628+
device = await mock_esphome_device(
629+
mock_client=mock_client,
630+
entity_info=entity_info,
631+
user_service=user_service,
632+
states=states,
633+
device_info={"friendly_name": "The Best Mixer", "name": "mixer"},
634+
)
635+
state = hass.states.get("binary_sensor.mixer_my")
636+
assert state is not None
637+
# now rename the entity
638+
ent_reg_entry = entity_registry.async_get_or_create(
639+
Platform.BINARY_SENSOR,
640+
DOMAIN,
641+
"11:22:33:44:55:AA-binary_sensor-my",
642+
)
643+
entity_registry.async_update_entity(
644+
ent_reg_entry.entity_id,
645+
new_entity_id="binary_sensor.user_named",
646+
)
647+
await hass.config_entries.async_unload(device.entry.entry_id)
648+
await hass.async_block_till_done()
649+
entry = device.entry
650+
entry_id = entry.entry_id
651+
storage_key = f"esphome.{entry_id}"
652+
assert len(hass_storage[storage_key]["data"]["binary_sensor"]) == 1
653+
binary_sensor_data: dict[str, Any] = hass_storage[storage_key]["data"][
654+
"binary_sensor"
655+
][0]
656+
assert binary_sensor_data["name"] == "my"
657+
assert binary_sensor_data["object_id"] == "my"
658+
device = await mock_esphome_device(
659+
mock_client=mock_client,
660+
entity_info=entity_info,
661+
user_service=user_service,
662+
states=states,
663+
entry=entry,
664+
device_info={"friendly_name": "The Best Mixer", "name": "mixer"},
665+
)
666+
state = hass.states.get("binary_sensor.user_named")
667+
assert state is not None

0 commit comments

Comments
 (0)