modbus slave unique ids (#86126)

modbus slave unique ids
This commit is contained in:
GrahamJB1 2023-01-19 10:08:11 +00:00 committed by GitHub
parent 6802f3db30
commit 200d3ae845
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 8 deletions

View file

@ -10,6 +10,7 @@ from homeassistant.const import (
CONF_BINARY_SENSORS, CONF_BINARY_SENSORS,
CONF_DEVICE_CLASS, CONF_DEVICE_CLASS,
CONF_NAME, CONF_NAME,
CONF_UNIQUE_ID,
STATE_ON, STATE_ON,
) )
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
@ -138,6 +139,9 @@ class SlaveSensor(
idx += 1 idx += 1
self._attr_name = f"{entry[CONF_NAME]} {idx}" self._attr_name = f"{entry[CONF_NAME]} {idx}"
self._attr_device_class = entry.get(CONF_DEVICE_CLASS) self._attr_device_class = entry.get(CONF_DEVICE_CLASS)
self._attr_unique_id = entry.get(CONF_UNIQUE_ID)
if self._attr_unique_id:
self._attr_unique_id = f"{self._attr_unique_id}_{idx}"
self._attr_available = False self._attr_available = False
self._result_inx = idx self._result_inx = idx
super().__init__(coordinator) super().__init__(coordinator)

View file

@ -6,7 +6,12 @@ import logging
from typing import Any, Optional from typing import Any, Optional
from homeassistant.components.sensor import CONF_STATE_CLASS, SensorEntity from homeassistant.components.sensor import CONF_STATE_CLASS, SensorEntity
from homeassistant.const import CONF_NAME, CONF_SENSORS, CONF_UNIT_OF_MEASUREMENT from homeassistant.const import (
CONF_NAME,
CONF_SENSORS,
CONF_UNIQUE_ID,
CONF_UNIT_OF_MEASUREMENT,
)
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
@ -145,6 +150,9 @@ class SlaveSensor(
idx += 1 idx += 1
self._idx = idx self._idx = idx
self._attr_name = f"{entry[CONF_NAME]} {idx}" self._attr_name = f"{entry[CONF_NAME]} {idx}"
self._attr_unique_id = entry.get(CONF_UNIQUE_ID)
if self._attr_unique_id:
self._attr_unique_id = f"{self._attr_unique_id}_{idx}"
self._attr_available = False self._attr_available = False
super().__init__(coordinator) super().__init__(coordinator)

View file

@ -19,17 +19,20 @@ from homeassistant.const import (
CONF_NAME, CONF_NAME,
CONF_SCAN_INTERVAL, CONF_SCAN_INTERVAL,
CONF_SLAVE, CONF_SLAVE,
CONF_UNIQUE_ID,
STATE_OFF, STATE_OFF,
STATE_ON, STATE_ON,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
STATE_UNKNOWN, STATE_UNKNOWN,
) )
from homeassistant.core import State from homeassistant.core import State
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from .conftest import TEST_ENTITY_NAME, ReadResult, do_next_cycle from .conftest import TEST_ENTITY_NAME, ReadResult, do_next_cycle
ENTITY_ID = f"{SENSOR_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_") ENTITY_ID = f"{SENSOR_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
SLAVE_UNIQUE_ID = "ground_floor_sensor"
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -341,31 +344,31 @@ async def test_config_slave_binary_sensor(hass, mock_modbus):
"config_addon,register_words,expected, slaves", "config_addon,register_words,expected, slaves",
[ [
( (
{CONF_SLAVE_COUNT: 1}, {CONF_SLAVE_COUNT: 1, CONF_UNIQUE_ID: SLAVE_UNIQUE_ID},
[False] * 8, [False] * 8,
STATE_OFF, STATE_OFF,
[STATE_OFF], [STATE_OFF],
), ),
( (
{CONF_SLAVE_COUNT: 1}, {CONF_SLAVE_COUNT: 1, CONF_UNIQUE_ID: SLAVE_UNIQUE_ID},
[True] + [False] * 7, [True] + [False] * 7,
STATE_ON, STATE_ON,
[STATE_OFF], [STATE_OFF],
), ),
( (
{CONF_SLAVE_COUNT: 1}, {CONF_SLAVE_COUNT: 1, CONF_UNIQUE_ID: SLAVE_UNIQUE_ID},
[False, True] + [False] * 6, [False, True] + [False] * 6,
STATE_OFF, STATE_OFF,
[STATE_ON], [STATE_ON],
), ),
( (
{CONF_SLAVE_COUNT: 7}, {CONF_SLAVE_COUNT: 7, CONF_UNIQUE_ID: SLAVE_UNIQUE_ID},
[True, False] * 4, [True, False] * 4,
STATE_ON, STATE_ON,
[STATE_OFF, STATE_ON] * 3 + [STATE_OFF], [STATE_OFF, STATE_ON] * 3 + [STATE_OFF],
), ),
( (
{CONF_SLAVE_COUNT: 31}, {CONF_SLAVE_COUNT: 31, CONF_UNIQUE_ID: SLAVE_UNIQUE_ID},
[True, False] * 16, [True, False] * 16,
STATE_ON, STATE_ON,
[STATE_OFF, STATE_ON] * 15 + [STATE_OFF], [STATE_OFF, STATE_ON] * 15 + [STATE_OFF],
@ -375,10 +378,14 @@ async def test_config_slave_binary_sensor(hass, mock_modbus):
async def test_slave_binary_sensor(hass, expected, slaves, mock_do_cycle): async def test_slave_binary_sensor(hass, expected, slaves, mock_do_cycle):
"""Run test for given config.""" """Run test for given config."""
assert hass.states.get(ENTITY_ID).state == expected assert hass.states.get(ENTITY_ID).state == expected
entity_registry = er.async_get(hass)
for i in range(len(slaves)): for i, slave in enumerate(slaves):
entity_id = f"{SENSOR_DOMAIN}.{TEST_ENTITY_NAME}_{i+1}".replace(" ", "_") entity_id = f"{SENSOR_DOMAIN}.{TEST_ENTITY_NAME}_{i+1}".replace(" ", "_")
assert hass.states.get(entity_id).state == slaves[i] assert hass.states.get(entity_id).state == slave
unique_id = f"{SLAVE_UNIQUE_ID}_{i+1}"
entry = entity_registry.async_get(entity_id)
assert entry.unique_id == unique_id
async def test_no_discovery_info_binary_sensor(hass, caplog): async def test_no_discovery_info_binary_sensor(hass, caplog):

View file

@ -33,15 +33,18 @@ from homeassistant.const import (
CONF_SENSORS, CONF_SENSORS,
CONF_SLAVE, CONF_SLAVE,
CONF_STRUCTURE, CONF_STRUCTURE,
CONF_UNIQUE_ID,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
STATE_UNKNOWN, STATE_UNKNOWN,
) )
from homeassistant.core import State from homeassistant.core import State
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from .conftest import TEST_ENTITY_NAME, ReadResult, do_next_cycle from .conftest import TEST_ENTITY_NAME, ReadResult, do_next_cycle
ENTITY_ID = f"{SENSOR_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_") ENTITY_ID = f"{SENSOR_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
SLAVE_UNIQUE_ID = "ground_floor_sensor"
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -573,6 +576,7 @@ async def test_all_sensor(hass, mock_do_cycle, expected):
( (
{ {
CONF_SLAVE_COUNT: 0, CONF_SLAVE_COUNT: 0,
CONF_UNIQUE_ID: SLAVE_UNIQUE_ID,
}, },
[0x0102, 0x0304], [0x0102, 0x0304],
False, False,
@ -581,6 +585,7 @@ async def test_all_sensor(hass, mock_do_cycle, expected):
( (
{ {
CONF_SLAVE_COUNT: 1, CONF_SLAVE_COUNT: 1,
CONF_UNIQUE_ID: SLAVE_UNIQUE_ID,
}, },
[0x0102, 0x0304, 0x0403, 0x0201], [0x0102, 0x0304, 0x0403, 0x0201],
False, False,
@ -589,6 +594,7 @@ async def test_all_sensor(hass, mock_do_cycle, expected):
( (
{ {
CONF_SLAVE_COUNT: 3, CONF_SLAVE_COUNT: 3,
CONF_UNIQUE_ID: SLAVE_UNIQUE_ID,
}, },
[ [
0x0102, 0x0102,
@ -611,6 +617,7 @@ async def test_all_sensor(hass, mock_do_cycle, expected):
( (
{ {
CONF_SLAVE_COUNT: 1, CONF_SLAVE_COUNT: 1,
CONF_UNIQUE_ID: SLAVE_UNIQUE_ID,
}, },
[0x0102, 0x0304, 0x0403, 0x0201], [0x0102, 0x0304, 0x0403, 0x0201],
True, True,
@ -619,6 +626,7 @@ async def test_all_sensor(hass, mock_do_cycle, expected):
( (
{ {
CONF_SLAVE_COUNT: 1, CONF_SLAVE_COUNT: 1,
CONF_UNIQUE_ID: SLAVE_UNIQUE_ID,
}, },
[], [],
False, False,
@ -629,10 +637,14 @@ async def test_all_sensor(hass, mock_do_cycle, expected):
async def test_slave_sensor(hass, mock_do_cycle, expected): async def test_slave_sensor(hass, mock_do_cycle, expected):
"""Run test for sensor.""" """Run test for sensor."""
assert hass.states.get(ENTITY_ID).state == expected[0] assert hass.states.get(ENTITY_ID).state == expected[0]
entity_registry = er.async_get(hass)
for i in range(1, len(expected)): for i in range(1, len(expected)):
entity_id = f"{SENSOR_DOMAIN}.{TEST_ENTITY_NAME}_{i}".replace(" ", "_") entity_id = f"{SENSOR_DOMAIN}.{TEST_ENTITY_NAME}_{i}".replace(" ", "_")
assert hass.states.get(entity_id).state == expected[i] assert hass.states.get(entity_id).state == expected[i]
unique_id = f"{SLAVE_UNIQUE_ID}_{i}"
entry = entity_registry.async_get(entity_id)
assert entry.unique_id == unique_id
@pytest.mark.parametrize( @pytest.mark.parametrize(