Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid removing zwave_js devices for non-ready nodes #59964

Merged
merged 28 commits into from Dec 27, 2021
Merged
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5630e6f
Only replace a node if the mfgr id / prod id / prod type differ
kpine Nov 14, 2021
8fb93d7
Prefer original device name for unready node
kpine Nov 14, 2021
30ec1e6
move register_node_in_dev_reg into async_setup_entry
kpine Nov 14, 2021
064fc37
simplify get_device_id_ext
kpine Nov 19, 2021
db0a1f3
Don't need hex ids
kpine Nov 19, 2021
54c6478
Revert "move register_node_in_dev_reg into async_setup_entry"
kpine Nov 20, 2021
bba258b
Revert Callable change
kpine Nov 20, 2021
b3bfe41
Revert device backup name
kpine Nov 27, 2021
e5f5e91
Add test fixtures
kpine Nov 10, 2021
d4c3e19
Update existing not ready test with new fixture data
kpine Nov 22, 2021
39e09ea
Check device properties after node added event
kpine Nov 22, 2021
06cceae
Add entity check
kpine Nov 22, 2021
b26cce3
Check for extended device id
kpine Nov 27, 2021
5232794
better device info checks
kpine Nov 27, 2021
506b2a9
Use receive_event to properly setup components
kpine Nov 27, 2021
901833c
Cleanup tests
kpine Nov 27, 2021
16a3cf8
improve test_replace_different_node
kpine Nov 27, 2021
dc7329f
improve test_replace_same_node
kpine Nov 27, 2021
0e86a4b
add test test_node_model_change
kpine Nov 28, 2021
2c553f1
Clean up long comments and strings
MartinHjelmare Dec 1, 2021
be6c406
Format
MartinHjelmare Dec 1, 2021
ec015dc
Reload integration to detect node device config changes
kpine Dec 4, 2021
7f4e5c1
update assertions
kpine Dec 4, 2021
efa60cc
Disable entities on "value removed" event
kpine Dec 19, 2021
b3523b1
Disable node status sensor on node replacement
kpine Dec 19, 2021
6c93810
Add test for disabling entities on remove value event
kpine Dec 25, 2021
8617df1
Add test for disabling node status sensor on node replacement
kpine Dec 26, 2021
f22bc41
disable entity -> remove entity
kpine Dec 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
130 changes: 130 additions & 0 deletions tests/components/zwave_js/test_init.py
Expand Up @@ -1154,3 +1154,133 @@ async def test_node_model_change(hass, zp3111, client, integration):
state = hass.states.get(custom_entity)
assert state
assert state.name == "Custom Entity Name"


async def test_disabled_entity_on_value_removed(hass, zp3111, client, integration):
"""Test that when entity primary values are removed the entity is disabled."""
MartinHjelmare marked this conversation as resolved.
Show resolved Hide resolved
er_reg = er.async_get(hass)

# re-enable this default-disabled entity
sensor_cover_entity = "sensor.4_in_1_sensor_home_security_cover_status"
er_reg.async_update_entity(entity_id=sensor_cover_entity, disabled_by=None)
await hass.async_block_till_done()

# must reload the integration when enabling an entity
await hass.config_entries.async_unload(integration.entry_id)
await hass.async_block_till_done()
assert integration.state is ConfigEntryState.NOT_LOADED
integration.add_to_hass(hass)
await hass.config_entries.async_setup(integration.entry_id)
await hass.async_block_till_done()
assert integration.state is ConfigEntryState.LOADED

state = hass.states.get(sensor_cover_entity)
assert state
assert state.state != STATE_UNAVAILABLE

# check for expected entities
binary_cover_entity = (
"binary_sensor.4_in_1_sensor_home_security_tampering_product_cover_removed"
)
state = hass.states.get(binary_cover_entity)
assert state
assert state.state != STATE_UNAVAILABLE

battery_level_entity = "sensor.4_in_1_sensor_battery_level"
state = hass.states.get(battery_level_entity)
assert state
assert state.state != STATE_UNAVAILABLE

unavailable_entities = {
state.entity_id
for state in hass.states.async_all()
if state.state == STATE_UNAVAILABLE
}

# This value ID removal does not disable any entity
MartinHjelmare marked this conversation as resolved.
Show resolved Hide resolved
event = Event(
type="value removed",
data={
"source": "node",
"event": "value removed",
"nodeId": zp3111.node_id,
"args": {
"commandClassName": "Wake Up",
"commandClass": 132,
"endpoint": 0,
"property": "wakeUpInterval",
"prevValue": 3600,
"propertyName": "wakeUpInterval",
},
},
)
client.driver.receive_event(event)
await hass.async_block_till_done()

assert all(state != STATE_UNAVAILABLE for state in hass.states.async_all())

# This value ID removal only affects the battery level entity
event = Event(
type="value removed",
data={
"source": "node",
"event": "value removed",
"nodeId": zp3111.node_id,
"args": {
"commandClassName": "Battery",
"commandClass": 128,
"endpoint": 0,
"property": "level",
"prevValue": 100,
"propertyName": "level",
},
},
)
client.driver.receive_event(event)
await hass.async_block_till_done()

state = hass.states.get(battery_level_entity)
assert state
assert state.state == STATE_UNAVAILABLE

# This value ID removal affects its multiple notification sensors
event = Event(
type="value removed",
data={
"source": "node",
"event": "value removed",
"nodeId": zp3111.node_id,
"args": {
"commandClassName": "Notification",
"commandClass": 113,
"endpoint": 0,
"property": "Home Security",
"propertyKey": "Cover status",
"prevValue": 0,
"propertyName": "Home Security",
"propertyKeyName": "Cover status",
},
},
)
client.driver.receive_event(event)
await hass.async_block_till_done()

state = hass.states.get(binary_cover_entity)
assert state
assert state.state == STATE_UNAVAILABLE

state = hass.states.get(sensor_cover_entity)
assert state
assert state.state == STATE_UNAVAILABLE

# existing entities and the entities with removed values should be unavailable
new_unavailable_entities = {
state.entity_id
for state in hass.states.async_all()
if state.state == STATE_UNAVAILABLE
}
assert (
unavailable_entities
| {battery_level_entity, binary_cover_entity, sensor_cover_entity}
== new_unavailable_entities
)