Fix wirelesstag sensors missing for non-ASCII tag names (#172590)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Ariel Ebersberger <ariel@ebersberger.io>
This commit is contained in:
kohai-ut
2026-08-12 12:23:24 +02:00
committed by GitHub
co-authored by Claude Opus 4.8 Ariel Ebersberger
parent 40323a6688
commit f1e26b23a9
2 changed files with 96 additions and 7 deletions
@@ -19,6 +19,7 @@ from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import slugify
from . import WirelessTagPlatform
from .const import DOMAIN, SIGNAL_TAG_UPDATE, WIRELESSTAG_DATA
@@ -115,8 +116,12 @@ class WirelessTagSensor(WirelessTagBaseSensor, SensorEntity):
# I want to see entity_id as:
# sensor.wirelesstag_bedroom_temperature
# and not as sensor.bedroom for temperature and
# sensor.bedroom_2 for humidity
self.entity_id = f"sensor.{DOMAIN}_{self.underscored_name}_{self._sensor_type}"
# sensor.bedroom_2 for humidity.
# slugify ensures the entity_id stays valid for tag names containing
# accented/international or special characters.
self.entity_id = (
f"sensor.{slugify(f'{DOMAIN}_{self._tag.name}_{self._sensor_type}')}"
)
@override
async def async_added_to_hass(self) -> None:
@@ -129,11 +134,6 @@ class WirelessTagSensor(WirelessTagBaseSensor, SensorEntity):
)
)
@property
def underscored_name(self):
"""Provide name savvy to be used in entity_id name of self."""
return self.name.lower().replace(" ", "_")
@property
@override
def native_value(self):
@@ -0,0 +1,89 @@
"""Tests for the Wireless Sensor Tags sensor platform."""
from unittest.mock import MagicMock, patch
import pytest
from homeassistant.const import PERCENTAGE, UnitOfTemperature
from homeassistant.core import HomeAssistant, valid_entity_id
from homeassistant.setup import async_setup_component
CONFIG = {
"wirelesstag": {"username": "foo@bar.com", "password": "secret"},
"sensor": {
"platform": "wirelesstag",
"monitored_conditions": ["temperature", "humidity"],
},
}
def _mock_tag(name: str) -> MagicMock:
"""Return a mocked wirelesstagpy SensorTag exposing temperature and humidity."""
tag = MagicMock()
tag.uuid = "00000000-0000-0000-0000-000000000001"
tag.tag_id = 1
tag.tag_manager_mac = "ABCDEF012345"
tag.name = name
tag.allowed_sensor_types = ["temperature", "humidity"]
tag.is_alive = True
tag.battery_remaining = 0.85
tag.battery_volts = 3.0
tag.signal_strength = -60
tag.is_in_range = True
tag.power_consumption = 1.5
def _sensor(sensor_type: str) -> MagicMock:
sensor = MagicMock()
if sensor_type == "temperature":
sensor.value = 21.5
sensor.unit = UnitOfTemperature.CELSIUS
else:
sensor.value = 45.0
sensor.unit = PERCENTAGE
return sensor
tag.sensor.__getitem__.side_effect = _sensor
return tag
@pytest.mark.parametrize(
("tag_name", "expected_entity_id"),
[
pytest.param(
"Bedroom",
"sensor.wirelesstag_bedroom_temperature",
id="ascii_name",
),
pytest.param(
"Küche",
"sensor.wirelesstag_kuche_temperature",
id="non_ascii_name",
),
],
)
async def test_sensor_entity_id_is_valid(
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
tag_name: str,
expected_entity_id: str,
) -> None:
"""Test sensors get a valid entity_id even for non-ASCII tag names.
A tag named e.g. "Küche" previously produced the invalid entity_id
"sensor.wirelesstag_küche_temperature", which is rejected by Home
Assistant's entity ID validation.
"""
tag = _mock_tag(tag_name)
with patch("homeassistant.components.wirelesstag.WirelessTags") as mock_api_class:
mock_api = mock_api_class.return_value
mock_api.load_tags.return_value = {tag.uuid: tag}
assert await async_setup_component(hass, "wirelesstag", CONFIG)
await hass.async_block_till_done()
assert await async_setup_component(hass, "sensor", CONFIG)
await hass.async_block_till_done()
state = hass.states.get(expected_entity_id)
assert state is not None
assert valid_entity_id(state.entity_id)
assert "sets an invalid entity ID" not in caplog.text