mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Bump aioesphomeapi to 36.0.1 (#148991)
This commit is contained in:
parent
4c99fe9ae5
commit
916b4368dd
@ -295,23 +295,7 @@ class RuntimeEntryData:
|
||||
needed_platforms.add(Platform.BINARY_SENSOR)
|
||||
needed_platforms.add(Platform.SELECT)
|
||||
|
||||
ent_reg = er.async_get(hass)
|
||||
registry_get_entity = ent_reg.async_get_entity_id
|
||||
for info in infos:
|
||||
platform = INFO_TYPE_TO_PLATFORM[type(info)]
|
||||
needed_platforms.add(platform)
|
||||
# If the unique id is in the old format, migrate it
|
||||
# except if they downgraded and upgraded, there might be a duplicate
|
||||
# so we want to keep the one that was already there.
|
||||
if (
|
||||
(old_unique_id := info.unique_id)
|
||||
and (old_entry := registry_get_entity(platform, DOMAIN, old_unique_id))
|
||||
and (new_unique_id := build_device_unique_id(mac, info))
|
||||
!= old_unique_id
|
||||
and not registry_get_entity(platform, DOMAIN, new_unique_id)
|
||||
):
|
||||
ent_reg.async_update_entity(old_entry, new_unique_id=new_unique_id)
|
||||
|
||||
needed_platforms.update(INFO_TYPE_TO_PLATFORM[type(info)] for info in infos)
|
||||
await self._ensure_platforms_loaded(hass, entry, needed_platforms)
|
||||
|
||||
# Make a dict of the EntityInfo by type and send
|
||||
|
@ -17,7 +17,7 @@
|
||||
"mqtt": ["esphome/discover/#"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": [
|
||||
"aioesphomeapi==35.0.0",
|
||||
"aioesphomeapi==36.0.1",
|
||||
"esphome-dashboard-api==1.3.0",
|
||||
"bleak-esphome==3.1.0"
|
||||
],
|
||||
|
2
requirements_all.txt
generated
2
requirements_all.txt
generated
@ -247,7 +247,7 @@ aioelectricitymaps==0.4.0
|
||||
aioemonitor==1.0.5
|
||||
|
||||
# homeassistant.components.esphome
|
||||
aioesphomeapi==35.0.0
|
||||
aioesphomeapi==36.0.1
|
||||
|
||||
# homeassistant.components.flo
|
||||
aioflo==2021.11.0
|
||||
|
2
requirements_test_all.txt
generated
2
requirements_test_all.txt
generated
@ -235,7 +235,7 @@ aioelectricitymaps==0.4.0
|
||||
aioemonitor==1.0.5
|
||||
|
||||
# homeassistant.components.esphome
|
||||
aioesphomeapi==35.0.0
|
||||
aioesphomeapi==36.0.1
|
||||
|
||||
# homeassistant.components.flo
|
||||
aioflo==2021.11.0
|
||||
|
@ -40,7 +40,6 @@ async def test_generic_alarm_control_panel_requires_code(
|
||||
object_id="myalarm_control_panel",
|
||||
key=1,
|
||||
name="my alarm_control_panel",
|
||||
unique_id="my_alarm_control_panel",
|
||||
supported_features=EspHomeACPFeatures.ARM_AWAY
|
||||
| EspHomeACPFeatures.ARM_CUSTOM_BYPASS
|
||||
| EspHomeACPFeatures.ARM_HOME
|
||||
@ -173,7 +172,6 @@ async def test_generic_alarm_control_panel_no_code(
|
||||
object_id="myalarm_control_panel",
|
||||
key=1,
|
||||
name="my alarm_control_panel",
|
||||
unique_id="my_alarm_control_panel",
|
||||
supported_features=EspHomeACPFeatures.ARM_AWAY
|
||||
| EspHomeACPFeatures.ARM_CUSTOM_BYPASS
|
||||
| EspHomeACPFeatures.ARM_HOME
|
||||
@ -219,7 +217,6 @@ async def test_generic_alarm_control_panel_missing_state(
|
||||
object_id="myalarm_control_panel",
|
||||
key=1,
|
||||
name="my alarm_control_panel",
|
||||
unique_id="my_alarm_control_panel",
|
||||
supported_features=EspHomeACPFeatures.ARM_AWAY
|
||||
| EspHomeACPFeatures.ARM_CUSTOM_BYPASS
|
||||
| EspHomeACPFeatures.ARM_HOME
|
||||
|
@ -953,7 +953,6 @@ async def test_tts_format_from_media_player(
|
||||
object_id="mymedia_player",
|
||||
key=1,
|
||||
name="my media_player",
|
||||
unique_id="my_media_player",
|
||||
supports_pause=True,
|
||||
supported_formats=[
|
||||
MediaPlayerSupportedFormat(
|
||||
@ -1020,7 +1019,6 @@ async def test_tts_minimal_format_from_media_player(
|
||||
object_id="mymedia_player",
|
||||
key=1,
|
||||
name="my media_player",
|
||||
unique_id="my_media_player",
|
||||
supports_pause=True,
|
||||
supported_formats=[
|
||||
MediaPlayerSupportedFormat(
|
||||
@ -1156,7 +1154,6 @@ async def test_announce_media_id(
|
||||
object_id="mymedia_player",
|
||||
key=1,
|
||||
name="my media_player",
|
||||
unique_id="my_media_player",
|
||||
supports_pause=True,
|
||||
supported_formats=[
|
||||
MediaPlayerSupportedFormat(
|
||||
@ -1437,7 +1434,6 @@ async def test_start_conversation_media_id(
|
||||
object_id="mymedia_player",
|
||||
key=1,
|
||||
name="my media_player",
|
||||
unique_id="my_media_player",
|
||||
supports_pause=True,
|
||||
supported_formats=[
|
||||
MediaPlayerSupportedFormat(
|
||||
|
@ -24,7 +24,6 @@ async def test_binary_sensor_generic_entity(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
)
|
||||
]
|
||||
esphome_state, hass_state = binary_state
|
||||
@ -52,7 +51,6 @@ async def test_status_binary_sensor(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
is_status_binary_sensor=True,
|
||||
)
|
||||
]
|
||||
@ -80,7 +78,6 @@ async def test_binary_sensor_missing_state(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
)
|
||||
]
|
||||
states = [BinarySensorState(key=1, state=True, missing_state=True)]
|
||||
@ -107,7 +104,6 @@ async def test_binary_sensor_has_state_false(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
)
|
||||
]
|
||||
states = []
|
||||
@ -152,14 +148,12 @@ async def test_binary_sensors_same_key_different_device_id(
|
||||
object_id="sensor",
|
||||
key=1,
|
||||
name="Motion",
|
||||
unique_id="motion_1",
|
||||
device_id=11111111,
|
||||
),
|
||||
BinarySensorInfo(
|
||||
object_id="sensor",
|
||||
key=1,
|
||||
name="Motion",
|
||||
unique_id="motion_2",
|
||||
device_id=22222222,
|
||||
),
|
||||
]
|
||||
@ -235,14 +229,12 @@ async def test_binary_sensor_main_and_sub_device_same_key(
|
||||
object_id="main_sensor",
|
||||
key=1,
|
||||
name="Main Sensor",
|
||||
unique_id="main_1",
|
||||
device_id=0, # Main device
|
||||
),
|
||||
BinarySensorInfo(
|
||||
object_id="sub_sensor",
|
||||
key=1,
|
||||
name="Sub Sensor",
|
||||
unique_id="sub_1",
|
||||
device_id=11111111,
|
||||
),
|
||||
]
|
||||
|
@ -18,7 +18,6 @@ async def test_button_generic_entity(
|
||||
object_id="mybutton",
|
||||
key=1,
|
||||
name="my button",
|
||||
unique_id="my_button",
|
||||
)
|
||||
]
|
||||
states = []
|
||||
|
@ -30,7 +30,6 @@ async def test_camera_single_image(
|
||||
object_id="mycamera",
|
||||
key=1,
|
||||
name="my camera",
|
||||
unique_id="my_camera",
|
||||
)
|
||||
]
|
||||
states = []
|
||||
@ -75,7 +74,6 @@ async def test_camera_single_image_unavailable_before_requested(
|
||||
object_id="mycamera",
|
||||
key=1,
|
||||
name="my camera",
|
||||
unique_id="my_camera",
|
||||
)
|
||||
]
|
||||
states = []
|
||||
@ -113,7 +111,6 @@ async def test_camera_single_image_unavailable_during_request(
|
||||
object_id="mycamera",
|
||||
key=1,
|
||||
name="my camera",
|
||||
unique_id="my_camera",
|
||||
)
|
||||
]
|
||||
states = []
|
||||
@ -155,7 +152,6 @@ async def test_camera_stream(
|
||||
object_id="mycamera",
|
||||
key=1,
|
||||
name="my camera",
|
||||
unique_id="my_camera",
|
||||
)
|
||||
]
|
||||
states = []
|
||||
@ -212,7 +208,6 @@ async def test_camera_stream_unavailable(
|
||||
object_id="mycamera",
|
||||
key=1,
|
||||
name="my camera",
|
||||
unique_id="my_camera",
|
||||
)
|
||||
]
|
||||
states = []
|
||||
@ -249,7 +244,6 @@ async def test_camera_stream_with_disconnection(
|
||||
object_id="mycamera",
|
||||
key=1,
|
||||
name="my camera",
|
||||
unique_id="my_camera",
|
||||
)
|
||||
]
|
||||
states = []
|
||||
|
@ -58,7 +58,6 @@ async def test_climate_entity(
|
||||
object_id="myclimate",
|
||||
key=1,
|
||||
name="my climate",
|
||||
unique_id="my_climate",
|
||||
supports_current_temperature=True,
|
||||
supports_action=True,
|
||||
visual_min_temperature=10.0,
|
||||
@ -110,7 +109,6 @@ async def test_climate_entity_with_step_and_two_point(
|
||||
object_id="myclimate",
|
||||
key=1,
|
||||
name="my climate",
|
||||
unique_id="my_climate",
|
||||
supports_current_temperature=True,
|
||||
supports_two_point_target_temperature=True,
|
||||
visual_target_temperature_step=2,
|
||||
@ -187,7 +185,6 @@ async def test_climate_entity_with_step_and_target_temp(
|
||||
object_id="myclimate",
|
||||
key=1,
|
||||
name="my climate",
|
||||
unique_id="my_climate",
|
||||
supports_current_temperature=True,
|
||||
visual_target_temperature_step=2,
|
||||
visual_current_temperature_step=2,
|
||||
@ -345,7 +342,6 @@ async def test_climate_entity_with_humidity(
|
||||
object_id="myclimate",
|
||||
key=1,
|
||||
name="my climate",
|
||||
unique_id="my_climate",
|
||||
supports_current_temperature=True,
|
||||
supports_two_point_target_temperature=True,
|
||||
supports_action=True,
|
||||
@ -409,7 +405,6 @@ async def test_climate_entity_with_inf_value(
|
||||
object_id="myclimate",
|
||||
key=1,
|
||||
name="my climate",
|
||||
unique_id="my_climate",
|
||||
supports_current_temperature=True,
|
||||
supports_two_point_target_temperature=True,
|
||||
supports_action=True,
|
||||
@ -465,7 +460,6 @@ async def test_climate_entity_attributes(
|
||||
object_id="myclimate",
|
||||
key=1,
|
||||
name="my climate",
|
||||
unique_id="my_climate",
|
||||
supports_current_temperature=True,
|
||||
visual_target_temperature_step=2,
|
||||
visual_current_temperature_step=2,
|
||||
@ -520,7 +514,6 @@ async def test_climate_entity_attribute_current_temperature_unsupported(
|
||||
object_id="myclimate",
|
||||
key=1,
|
||||
name="my climate",
|
||||
unique_id="my_climate",
|
||||
supports_current_temperature=False,
|
||||
)
|
||||
]
|
||||
|
@ -41,7 +41,6 @@ async def test_cover_entity(
|
||||
object_id="mycover",
|
||||
key=1,
|
||||
name="my cover",
|
||||
unique_id="my_cover",
|
||||
supports_position=True,
|
||||
supports_tilt=True,
|
||||
supports_stop=True,
|
||||
@ -169,7 +168,6 @@ async def test_cover_entity_without_position(
|
||||
object_id="mycover",
|
||||
key=1,
|
||||
name="my cover",
|
||||
unique_id="my_cover",
|
||||
supports_position=False,
|
||||
supports_tilt=False,
|
||||
supports_stop=False,
|
||||
|
@ -26,7 +26,6 @@ async def test_generic_date_entity(
|
||||
object_id="mydate",
|
||||
key=1,
|
||||
name="my date",
|
||||
unique_id="my_date",
|
||||
)
|
||||
]
|
||||
states = [DateState(key=1, year=2024, month=12, day=31)]
|
||||
@ -62,7 +61,6 @@ async def test_generic_date_missing_state(
|
||||
object_id="mydate",
|
||||
key=1,
|
||||
name="my date",
|
||||
unique_id="my_date",
|
||||
)
|
||||
]
|
||||
states = [DateState(key=1, missing_state=True)]
|
||||
|
@ -26,7 +26,6 @@ async def test_generic_datetime_entity(
|
||||
object_id="mydatetime",
|
||||
key=1,
|
||||
name="my datetime",
|
||||
unique_id="my_datetime",
|
||||
)
|
||||
]
|
||||
states = [DateTimeState(key=1, epoch_seconds=1713270896)]
|
||||
@ -65,7 +64,6 @@ async def test_generic_datetime_missing_state(
|
||||
object_id="mydatetime",
|
||||
key=1,
|
||||
name="my datetime",
|
||||
unique_id="my_datetime",
|
||||
)
|
||||
]
|
||||
states = [DateTimeState(key=1, missing_state=True)]
|
||||
|
@ -51,13 +51,11 @@ async def test_entities_removed(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
),
|
||||
BinarySensorInfo(
|
||||
object_id="mybinary_sensor_to_be_removed",
|
||||
key=2,
|
||||
name="my binary_sensor to be removed",
|
||||
unique_id="mybinary_sensor_to_be_removed",
|
||||
),
|
||||
]
|
||||
states = [
|
||||
@ -100,7 +98,6 @@ async def test_entities_removed(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
),
|
||||
]
|
||||
states = [
|
||||
@ -140,13 +137,11 @@ async def test_entities_removed_after_reload(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
),
|
||||
BinarySensorInfo(
|
||||
object_id="mybinary_sensor_to_be_removed",
|
||||
key=2,
|
||||
name="my binary_sensor to be removed",
|
||||
unique_id="mybinary_sensor_to_be_removed",
|
||||
),
|
||||
]
|
||||
states = [
|
||||
@ -214,7 +209,6 @@ async def test_entities_removed_after_reload(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
),
|
||||
]
|
||||
mock_device.client.list_entities_services = AsyncMock(
|
||||
@ -267,7 +261,6 @@ async def test_entities_for_entire_platform_removed(
|
||||
object_id="mybinary_sensor_to_be_removed",
|
||||
key=1,
|
||||
name="my binary_sensor to be removed",
|
||||
unique_id="mybinary_sensor_to_be_removed",
|
||||
),
|
||||
]
|
||||
states = [
|
||||
@ -325,7 +318,6 @@ async def test_entity_info_object_ids(
|
||||
object_id="object_id_is_used",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
)
|
||||
]
|
||||
states = []
|
||||
@ -350,13 +342,11 @@ async def test_deep_sleep_device(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
),
|
||||
SensorInfo(
|
||||
object_id="my_sensor",
|
||||
key=3,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
),
|
||||
]
|
||||
states = [
|
||||
@ -456,7 +446,6 @@ async def test_esphome_device_without_friendly_name(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
),
|
||||
]
|
||||
states = [
|
||||
@ -486,7 +475,6 @@ async def test_entity_without_name_device_with_friendly_name(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="",
|
||||
unique_id="my_binary_sensor",
|
||||
),
|
||||
]
|
||||
states = [
|
||||
@ -519,7 +507,6 @@ async def test_entity_id_preserved_on_upgrade(
|
||||
object_id="my",
|
||||
key=1,
|
||||
name="my",
|
||||
unique_id="binary_sensor_my",
|
||||
),
|
||||
]
|
||||
states = [
|
||||
@ -560,7 +547,6 @@ async def test_entity_id_preserved_on_upgrade_old_format_entity_id(
|
||||
object_id="my",
|
||||
key=1,
|
||||
name="my",
|
||||
unique_id="binary_sensor_my",
|
||||
),
|
||||
]
|
||||
states = [
|
||||
@ -601,7 +587,6 @@ async def test_entity_id_preserved_on_upgrade_when_in_storage(
|
||||
object_id="my",
|
||||
key=1,
|
||||
name="my",
|
||||
unique_id="binary_sensor_my",
|
||||
),
|
||||
]
|
||||
states = [
|
||||
@ -660,7 +645,6 @@ async def test_deep_sleep_added_after_setup(
|
||||
object_id="test",
|
||||
key=1,
|
||||
name="test",
|
||||
unique_id="test",
|
||||
),
|
||||
],
|
||||
states=[
|
||||
@ -732,7 +716,6 @@ async def test_entity_assignment_to_sub_device(
|
||||
object_id="main_sensor",
|
||||
key=1,
|
||||
name="Main Sensor",
|
||||
unique_id="main_sensor",
|
||||
device_id=0,
|
||||
),
|
||||
# Entity for sub device 1
|
||||
@ -740,7 +723,6 @@ async def test_entity_assignment_to_sub_device(
|
||||
object_id="motion",
|
||||
key=2,
|
||||
name="Motion",
|
||||
unique_id="motion",
|
||||
device_id=11111111,
|
||||
),
|
||||
# Entity for sub device 2
|
||||
@ -748,7 +730,6 @@ async def test_entity_assignment_to_sub_device(
|
||||
object_id="door",
|
||||
key=3,
|
||||
name="Door",
|
||||
unique_id="door",
|
||||
device_id=22222222,
|
||||
),
|
||||
]
|
||||
@ -932,7 +913,6 @@ async def test_entity_switches_between_devices(
|
||||
object_id="sensor",
|
||||
key=1,
|
||||
name="Test Sensor",
|
||||
unique_id="sensor",
|
||||
# device_id omitted - entity belongs to main device
|
||||
),
|
||||
]
|
||||
@ -964,7 +944,6 @@ async def test_entity_switches_between_devices(
|
||||
object_id="sensor",
|
||||
key=1,
|
||||
name="Test Sensor",
|
||||
unique_id="sensor",
|
||||
device_id=11111111, # Now on sub device 1
|
||||
),
|
||||
]
|
||||
@ -993,7 +972,6 @@ async def test_entity_switches_between_devices(
|
||||
object_id="sensor",
|
||||
key=1,
|
||||
name="Test Sensor",
|
||||
unique_id="sensor",
|
||||
device_id=22222222, # Now on sub device 2
|
||||
),
|
||||
]
|
||||
@ -1020,7 +998,6 @@ async def test_entity_switches_between_devices(
|
||||
object_id="sensor",
|
||||
key=1,
|
||||
name="Test Sensor",
|
||||
unique_id="sensor",
|
||||
# device_id omitted - back to main device
|
||||
),
|
||||
]
|
||||
@ -1063,7 +1040,6 @@ async def test_entity_id_uses_sub_device_name(
|
||||
object_id="main_sensor",
|
||||
key=1,
|
||||
name="Main Sensor",
|
||||
unique_id="main_sensor",
|
||||
device_id=0,
|
||||
),
|
||||
# Entity for sub device 1
|
||||
@ -1071,7 +1047,6 @@ async def test_entity_id_uses_sub_device_name(
|
||||
object_id="motion",
|
||||
key=2,
|
||||
name="Motion",
|
||||
unique_id="motion",
|
||||
device_id=11111111,
|
||||
),
|
||||
# Entity for sub device 2
|
||||
@ -1079,7 +1054,6 @@ async def test_entity_id_uses_sub_device_name(
|
||||
object_id="door",
|
||||
key=3,
|
||||
name="Door",
|
||||
unique_id="door",
|
||||
device_id=22222222,
|
||||
),
|
||||
# Entity without name on sub device
|
||||
@ -1087,7 +1061,6 @@ async def test_entity_id_uses_sub_device_name(
|
||||
object_id="sensor_no_name",
|
||||
key=4,
|
||||
name="",
|
||||
unique_id="sensor_no_name",
|
||||
device_id=11111111,
|
||||
),
|
||||
]
|
||||
@ -1147,7 +1120,6 @@ async def test_entity_id_with_empty_sub_device_name(
|
||||
object_id="sensor",
|
||||
key=1,
|
||||
name="Sensor",
|
||||
unique_id="sensor",
|
||||
device_id=11111111,
|
||||
),
|
||||
]
|
||||
@ -1187,8 +1159,7 @@ async def test_unique_id_migration_when_entity_moves_between_devices(
|
||||
BinarySensorInfo(
|
||||
object_id="temperature",
|
||||
key=1,
|
||||
name="Temperature",
|
||||
unique_id="unused", # This field is not used by the integration
|
||||
name="Temperature", # This field is not used by the integration
|
||||
device_id=0, # Main device
|
||||
),
|
||||
]
|
||||
@ -1250,8 +1221,7 @@ async def test_unique_id_migration_when_entity_moves_between_devices(
|
||||
BinarySensorInfo(
|
||||
object_id="temperature", # Same object_id
|
||||
key=1, # Same key - this is what identifies the entity
|
||||
name="Temperature",
|
||||
unique_id="unused", # This field is not used
|
||||
name="Temperature", # This field is not used
|
||||
device_id=22222222, # Now on sub-device
|
||||
),
|
||||
]
|
||||
@ -1312,7 +1282,6 @@ async def test_unique_id_migration_sub_device_to_main_device(
|
||||
object_id="temperature",
|
||||
key=1,
|
||||
name="Temperature",
|
||||
unique_id="unused",
|
||||
device_id=22222222, # On sub-device
|
||||
),
|
||||
]
|
||||
@ -1347,7 +1316,6 @@ async def test_unique_id_migration_sub_device_to_main_device(
|
||||
object_id="temperature",
|
||||
key=1,
|
||||
name="Temperature",
|
||||
unique_id="unused",
|
||||
device_id=0, # Now on main device
|
||||
),
|
||||
]
|
||||
@ -1407,7 +1375,6 @@ async def test_unique_id_migration_between_sub_devices(
|
||||
object_id="temperature",
|
||||
key=1,
|
||||
name="Temperature",
|
||||
unique_id="unused",
|
||||
device_id=22222222, # On kitchen_controller
|
||||
),
|
||||
]
|
||||
@ -1442,7 +1409,6 @@ async def test_unique_id_migration_between_sub_devices(
|
||||
object_id="temperature",
|
||||
key=1,
|
||||
name="Temperature",
|
||||
unique_id="unused",
|
||||
device_id=33333333, # Now on bedroom_controller
|
||||
),
|
||||
]
|
||||
@ -1501,7 +1467,6 @@ async def test_entity_device_id_rename_in_yaml(
|
||||
object_id="sensor",
|
||||
key=1,
|
||||
name="Sensor",
|
||||
unique_id="unused",
|
||||
device_id=11111111,
|
||||
),
|
||||
]
|
||||
@ -1563,7 +1528,6 @@ async def test_entity_device_id_rename_in_yaml(
|
||||
object_id="sensor", # Same object_id
|
||||
key=1, # Same key
|
||||
name="Sensor",
|
||||
unique_id="unused",
|
||||
device_id=99999999, # New device_id after rename
|
||||
),
|
||||
]
|
||||
@ -1636,8 +1600,7 @@ async def test_entity_with_unicode_name(
|
||||
BinarySensorInfo(
|
||||
object_id=sanitized_object_id, # ESPHome sends the sanitized version
|
||||
key=1,
|
||||
name=unicode_name, # But also sends the original Unicode name
|
||||
unique_id="unicode_sensor",
|
||||
name=unicode_name, # But also sends the original Unicode name,
|
||||
)
|
||||
]
|
||||
states = [BinarySensorState(key=1, state=True)]
|
||||
@ -1677,8 +1640,7 @@ async def test_entity_without_name_uses_device_name_only(
|
||||
BinarySensorInfo(
|
||||
object_id="some_sanitized_id",
|
||||
key=1,
|
||||
name="", # Empty name
|
||||
unique_id="no_name_sensor",
|
||||
name="", # Empty name,
|
||||
)
|
||||
]
|
||||
states = [BinarySensorState(key=1, state=True)]
|
||||
|
@ -15,49 +15,6 @@ from homeassistant.helpers import entity_registry as er
|
||||
from .conftest import MockGenericDeviceEntryType
|
||||
|
||||
|
||||
async def test_migrate_entity_unique_id(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
mock_client: APIClient,
|
||||
mock_generic_device_entry: MockGenericDeviceEntryType,
|
||||
) -> None:
|
||||
"""Test a generic sensor entity unique id migration."""
|
||||
entity_registry.async_get_or_create(
|
||||
"sensor",
|
||||
"esphome",
|
||||
"my_sensor",
|
||||
suggested_object_id="old_sensor",
|
||||
disabled_by=None,
|
||||
)
|
||||
entity_info = [
|
||||
SensorInfo(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
entity_category=ESPHomeEntityCategory.DIAGNOSTIC,
|
||||
icon="mdi:leaf",
|
||||
)
|
||||
]
|
||||
states = [SensorState(key=1, state=50)]
|
||||
user_service = []
|
||||
await mock_generic_device_entry(
|
||||
mock_client=mock_client,
|
||||
entity_info=entity_info,
|
||||
user_service=user_service,
|
||||
states=states,
|
||||
)
|
||||
state = hass.states.get("sensor.old_sensor")
|
||||
assert state is not None
|
||||
assert state.state == "50"
|
||||
entry = entity_registry.async_get("sensor.old_sensor")
|
||||
assert entry is not None
|
||||
assert entity_registry.async_get_entity_id("sensor", "esphome", "my_sensor") is None
|
||||
# Note that ESPHome includes the EntityInfo type in the unique id
|
||||
# as this is not a 1:1 mapping to the entity platform (ie. text_sensor)
|
||||
assert entry.unique_id == "11:22:33:44:55:AA-sensor-mysensor"
|
||||
|
||||
|
||||
async def test_migrate_entity_unique_id_downgrade_upgrade(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
@ -84,7 +41,6 @@ async def test_migrate_entity_unique_id_downgrade_upgrade(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
entity_category=ESPHomeEntityCategory.DIAGNOSTIC,
|
||||
icon="mdi:leaf",
|
||||
)
|
||||
|
@ -20,7 +20,6 @@ async def test_generic_event_entity(
|
||||
object_id="myevent",
|
||||
key=1,
|
||||
name="my event",
|
||||
unique_id="my_event",
|
||||
event_types=["type1", "type2"],
|
||||
device_class=EventDeviceClass.BUTTON,
|
||||
)
|
||||
|
@ -44,7 +44,6 @@ async def test_fan_entity_with_all_features_old_api(
|
||||
object_id="myfan",
|
||||
key=1,
|
||||
name="my fan",
|
||||
unique_id="my_fan",
|
||||
supports_direction=True,
|
||||
supports_speed=True,
|
||||
supports_oscillation=True,
|
||||
@ -147,7 +146,6 @@ async def test_fan_entity_with_all_features_new_api(
|
||||
object_id="myfan",
|
||||
key=1,
|
||||
name="my fan",
|
||||
unique_id="my_fan",
|
||||
supported_speed_count=4,
|
||||
supports_direction=True,
|
||||
supports_speed=True,
|
||||
@ -317,7 +315,6 @@ async def test_fan_entity_with_no_features_new_api(
|
||||
object_id="myfan",
|
||||
key=1,
|
||||
name="my fan",
|
||||
unique_id="my_fan",
|
||||
supports_direction=False,
|
||||
supports_speed=False,
|
||||
supports_oscillation=False,
|
||||
|
@ -56,7 +56,6 @@ async def test_light_on_off(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[ESPColorMode.ON_OFF],
|
||||
@ -98,7 +97,6 @@ async def test_light_brightness(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[LightColorCapability.BRIGHTNESS],
|
||||
@ -226,7 +224,6 @@ async def test_light_legacy_brightness(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[LightColorCapability.BRIGHTNESS, 2],
|
||||
@ -282,7 +279,6 @@ async def test_light_brightness_on_off(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[ESPColorMode.ON_OFF, ESPColorMode.BRIGHTNESS],
|
||||
@ -358,7 +354,6 @@ async def test_light_legacy_white_converted_to_brightness(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[
|
||||
@ -423,7 +418,6 @@ async def test_light_legacy_white_with_rgb(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[color_mode, color_mode_2],
|
||||
@ -478,7 +472,6 @@ async def test_light_brightness_on_off_with_unknown_color_mode(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[
|
||||
@ -555,7 +548,6 @@ async def test_light_on_and_brightness(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[
|
||||
@ -607,7 +599,6 @@ async def test_rgb_color_temp_light(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=color_modes,
|
||||
@ -698,7 +689,6 @@ async def test_light_rgb(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
supported_color_modes=[
|
||||
LightColorCapability.RGB
|
||||
| LightColorCapability.ON_OFF
|
||||
@ -821,7 +811,6 @@ async def test_light_rgbw(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
supported_color_modes=[
|
||||
LightColorCapability.RGB
|
||||
| LightColorCapability.WHITE
|
||||
@ -991,7 +980,6 @@ async def test_light_rgbww_with_cold_warm_white_support(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[
|
||||
@ -1200,7 +1188,6 @@ async def test_light_rgbww_without_cold_warm_white_support(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[
|
||||
@ -1439,7 +1426,6 @@ async def test_light_color_temp(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153.846161,
|
||||
max_mireds=370.370361,
|
||||
supported_color_modes=[
|
||||
@ -1514,7 +1500,6 @@ async def test_light_color_temp_no_mireds_set(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=0,
|
||||
max_mireds=0,
|
||||
supported_color_modes=[
|
||||
@ -1610,7 +1595,6 @@ async def test_light_color_temp_legacy(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153.846161,
|
||||
max_mireds=370.370361,
|
||||
supported_color_modes=[
|
||||
@ -1695,7 +1679,6 @@ async def test_light_rgb_legacy(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153.846161,
|
||||
max_mireds=370.370361,
|
||||
supported_color_modes=[
|
||||
@ -1795,7 +1778,6 @@ async def test_light_effects(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
effects=["effect1", "effect2"],
|
||||
@ -1859,7 +1841,6 @@ async def test_only_cold_warm_white_support(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[color_modes],
|
||||
@ -1955,7 +1936,6 @@ async def test_light_no_color_modes(
|
||||
object_id="mylight",
|
||||
key=1,
|
||||
name="my light",
|
||||
unique_id="my_light",
|
||||
min_mireds=153,
|
||||
max_mireds=400,
|
||||
supported_color_modes=[color_mode],
|
||||
|
@ -34,7 +34,6 @@ async def test_lock_entity_no_open(
|
||||
object_id="mylock",
|
||||
key=1,
|
||||
name="my lock",
|
||||
unique_id="my_lock",
|
||||
supports_open=False,
|
||||
requires_code=False,
|
||||
)
|
||||
@ -72,7 +71,6 @@ async def test_lock_entity_start_locked(
|
||||
object_id="mylock",
|
||||
key=1,
|
||||
name="my lock",
|
||||
unique_id="my_lock",
|
||||
)
|
||||
]
|
||||
states = [LockEntityState(key=1, state=ESPHomeLockState.LOCKED)]
|
||||
@ -99,7 +97,6 @@ async def test_lock_entity_supports_open(
|
||||
object_id="mylock",
|
||||
key=1,
|
||||
name="my lock",
|
||||
unique_id="my_lock",
|
||||
supports_open=True,
|
||||
requires_code=True,
|
||||
)
|
||||
|
@ -55,7 +55,6 @@ async def test_media_player_entity(
|
||||
object_id="mymedia_player",
|
||||
key=1,
|
||||
name="my media_player",
|
||||
unique_id="my_media_player",
|
||||
supports_pause=True,
|
||||
)
|
||||
]
|
||||
@ -202,7 +201,6 @@ async def test_media_player_entity_with_source(
|
||||
object_id="mymedia_player",
|
||||
key=1,
|
||||
name="my media_player",
|
||||
unique_id="my_media_player",
|
||||
supports_pause=True,
|
||||
)
|
||||
]
|
||||
@ -318,7 +316,6 @@ async def test_media_player_proxy(
|
||||
object_id="mymedia_player",
|
||||
key=1,
|
||||
name="my media_player",
|
||||
unique_id="my_media_player",
|
||||
supports_pause=True,
|
||||
supported_formats=[
|
||||
MediaPlayerSupportedFormat(
|
||||
@ -477,7 +474,6 @@ async def test_media_player_formats_reload_preserves_data(
|
||||
object_id="test_media_player",
|
||||
key=1,
|
||||
name="Test Media Player",
|
||||
unique_id="test_unique_id",
|
||||
supports_pause=True,
|
||||
supported_formats=supported_formats,
|
||||
)
|
||||
|
@ -35,7 +35,6 @@ async def test_generic_number_entity(
|
||||
object_id="mynumber",
|
||||
key=1,
|
||||
name="my number",
|
||||
unique_id="my_number",
|
||||
max_value=100,
|
||||
min_value=0,
|
||||
step=1,
|
||||
@ -75,7 +74,6 @@ async def test_generic_number_nan(
|
||||
object_id="mynumber",
|
||||
key=1,
|
||||
name="my number",
|
||||
unique_id="my_number",
|
||||
max_value=100,
|
||||
min_value=0,
|
||||
step=1,
|
||||
@ -107,7 +105,6 @@ async def test_generic_number_with_unit_of_measurement_as_empty_string(
|
||||
object_id="mynumber",
|
||||
key=1,
|
||||
name="my number",
|
||||
unique_id="my_number",
|
||||
max_value=100,
|
||||
min_value=0,
|
||||
step=1,
|
||||
@ -140,7 +137,6 @@ async def test_generic_number_entity_set_when_disconnected(
|
||||
object_id="mynumber",
|
||||
key=1,
|
||||
name="my number",
|
||||
unique_id="my_number",
|
||||
max_value=100,
|
||||
min_value=0,
|
||||
step=1,
|
||||
|
@ -133,7 +133,6 @@ async def test_device_conflict_migration(
|
||||
object_id="mybinary_sensor",
|
||||
key=1,
|
||||
name="my binary_sensor",
|
||||
unique_id="my_binary_sensor",
|
||||
is_status_binary_sensor=True,
|
||||
)
|
||||
]
|
||||
|
@ -67,7 +67,6 @@ async def test_select_generic_entity(
|
||||
object_id="myselect",
|
||||
key=1,
|
||||
name="my select",
|
||||
unique_id="my_select",
|
||||
options=["a", "b"],
|
||||
)
|
||||
]
|
||||
|
@ -54,7 +54,6 @@ async def test_generic_numeric_sensor(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
)
|
||||
]
|
||||
states = [SensorState(key=1, state=50)]
|
||||
@ -110,7 +109,6 @@ async def test_generic_numeric_sensor_with_entity_category_and_icon(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
entity_category=ESPHomeEntityCategory.DIAGNOSTIC,
|
||||
icon="mdi:leaf",
|
||||
)
|
||||
@ -147,7 +145,6 @@ async def test_generic_numeric_sensor_state_class_measurement(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
state_class=ESPHomeSensorStateClass.MEASUREMENT,
|
||||
device_class="power",
|
||||
unit_of_measurement="W",
|
||||
@ -184,7 +181,6 @@ async def test_generic_numeric_sensor_device_class_timestamp(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
device_class="timestamp",
|
||||
)
|
||||
]
|
||||
@ -212,7 +208,6 @@ async def test_generic_numeric_sensor_legacy_last_reset_convert(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
legacy_last_reset_type=LastResetType.AUTO,
|
||||
state_class=ESPHomeSensorStateClass.MEASUREMENT,
|
||||
)
|
||||
@ -242,7 +237,6 @@ async def test_generic_numeric_sensor_no_state(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
)
|
||||
]
|
||||
states = []
|
||||
@ -269,7 +263,6 @@ async def test_generic_numeric_sensor_nan_state(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
)
|
||||
]
|
||||
states = [SensorState(key=1, state=math.nan, missing_state=False)]
|
||||
@ -296,7 +289,6 @@ async def test_generic_numeric_sensor_missing_state(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
)
|
||||
]
|
||||
states = [SensorState(key=1, state=True, missing_state=True)]
|
||||
@ -323,7 +315,6 @@ async def test_generic_text_sensor(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
)
|
||||
]
|
||||
states = [TextSensorState(key=1, state="i am a teapot")]
|
||||
@ -350,7 +341,6 @@ async def test_generic_text_sensor_missing_state(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
)
|
||||
]
|
||||
states = [TextSensorState(key=1, state=True, missing_state=True)]
|
||||
@ -377,7 +367,6 @@ async def test_generic_text_sensor_device_class_timestamp(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
device_class=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
]
|
||||
@ -406,7 +395,6 @@ async def test_generic_text_sensor_device_class_date(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
device_class=SensorDeviceClass.DATE,
|
||||
)
|
||||
]
|
||||
@ -435,7 +423,6 @@ async def test_generic_numeric_sensor_empty_string_uom(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
unit_of_measurement="",
|
||||
)
|
||||
]
|
||||
@ -493,7 +480,6 @@ async def test_suggested_display_precision_by_device_class(
|
||||
object_id="mysensor",
|
||||
key=1,
|
||||
name="my sensor",
|
||||
unique_id="my_sensor",
|
||||
accuracy_decimals=expected_precision,
|
||||
device_class=device_class.value,
|
||||
unit_of_measurement=unit_of_measurement,
|
||||
|
@ -26,7 +26,6 @@ async def test_switch_generic_entity(
|
||||
object_id="myswitch",
|
||||
key=1,
|
||||
name="my switch",
|
||||
unique_id="my_switch",
|
||||
)
|
||||
]
|
||||
states = [SwitchState(key=1, state=True)]
|
||||
@ -78,14 +77,12 @@ async def test_switch_sub_device_non_zero_device_id(
|
||||
object_id="main_switch",
|
||||
key=1,
|
||||
name="Main Switch",
|
||||
unique_id="main_switch_1",
|
||||
device_id=0, # Main device
|
||||
),
|
||||
SwitchInfo(
|
||||
object_id="sub_switch",
|
||||
key=2,
|
||||
name="Sub Switch",
|
||||
unique_id="sub_switch_1",
|
||||
device_id=11111111, # Sub-device
|
||||
),
|
||||
]
|
||||
|
@ -26,7 +26,6 @@ async def test_generic_text_entity(
|
||||
object_id="mytext",
|
||||
key=1,
|
||||
name="my text",
|
||||
unique_id="my_text",
|
||||
max_length=100,
|
||||
min_length=0,
|
||||
pattern=None,
|
||||
@ -66,7 +65,6 @@ async def test_generic_text_entity_no_state(
|
||||
object_id="mytext",
|
||||
key=1,
|
||||
name="my text",
|
||||
unique_id="my_text",
|
||||
max_length=100,
|
||||
min_length=0,
|
||||
pattern=None,
|
||||
@ -97,7 +95,6 @@ async def test_generic_text_entity_missing_state(
|
||||
object_id="mytext",
|
||||
key=1,
|
||||
name="my text",
|
||||
unique_id="my_text",
|
||||
max_length=100,
|
||||
min_length=0,
|
||||
pattern=None,
|
||||
|
@ -26,7 +26,6 @@ async def test_generic_time_entity(
|
||||
object_id="mytime",
|
||||
key=1,
|
||||
name="my time",
|
||||
unique_id="my_time",
|
||||
)
|
||||
]
|
||||
states = [TimeState(key=1, hour=12, minute=34, second=56)]
|
||||
@ -62,7 +61,6 @@ async def test_generic_time_missing_state(
|
||||
object_id="mytime",
|
||||
key=1,
|
||||
name="my time",
|
||||
unique_id="my_time",
|
||||
)
|
||||
]
|
||||
states = [TimeState(key=1, missing_state=True)]
|
||||
|
@ -436,7 +436,6 @@ async def test_generic_device_update_entity(
|
||||
object_id="myupdate",
|
||||
key=1,
|
||||
name="my update",
|
||||
unique_id="my_update",
|
||||
)
|
||||
]
|
||||
states = [
|
||||
@ -470,7 +469,6 @@ async def test_generic_device_update_entity_has_update(
|
||||
object_id="myupdate",
|
||||
key=1,
|
||||
name="my update",
|
||||
unique_id="my_update",
|
||||
)
|
||||
]
|
||||
states = [
|
||||
@ -561,7 +559,6 @@ async def test_update_entity_release_notes(
|
||||
object_id="myupdate",
|
||||
key=1,
|
||||
name="my update",
|
||||
unique_id="my_update",
|
||||
)
|
||||
]
|
||||
|
||||
|
@ -36,7 +36,6 @@ async def test_valve_entity(
|
||||
object_id="myvalve",
|
||||
key=1,
|
||||
name="my valve",
|
||||
unique_id="my_valve",
|
||||
supports_position=True,
|
||||
supports_stop=True,
|
||||
)
|
||||
@ -134,7 +133,6 @@ async def test_valve_entity_without_position(
|
||||
object_id="myvalve",
|
||||
key=1,
|
||||
name="my valve",
|
||||
unique_id="my_valve",
|
||||
supports_position=False,
|
||||
supports_stop=False,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user