Don't add extra entities for zwave_js controller (#67209)

* Don't add extra entities for zwave_js controller

* Revert reformat of controller_state

* fix indentation issues

* fix indentation issues
This commit is contained in:
Raman Gupta 2022-02-25 01:39:30 -05:00 committed by GitHub
parent 7842d12b75
commit ad4409bcb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 247 additions and 54 deletions

View File

@ -293,17 +293,19 @@ async def async_setup_entry( # noqa: C901
async def async_on_node_added(node: ZwaveNode) -> None:
"""Handle node added event."""
# Create a node status sensor for each device
await async_setup_platform(SENSOR_DOMAIN)
async_dispatcher_send(
hass, f"{DOMAIN}_{entry.entry_id}_add_node_status_sensor", node
)
# No need for a ping button or node status sensor for controller nodes
if not node.is_controller_node:
# Create a node status sensor for each device
await async_setup_platform(SENSOR_DOMAIN)
async_dispatcher_send(
hass, f"{DOMAIN}_{entry.entry_id}_add_node_status_sensor", node
)
# Create a ping button for each device
await async_setup_platform(BUTTON_DOMAIN)
async_dispatcher_send(
hass, f"{DOMAIN}_{entry.entry_id}_add_ping_button_entity", node
)
# Create a ping button for each device
await async_setup_platform(BUTTON_DOMAIN)
async_dispatcher_send(
hass, f"{DOMAIN}_{entry.entry_id}_add_ping_button_entity", node
)
# we only want to run discovery when the node has reached ready state,
# otherwise we'll have all kinds of missing info issues.

View File

@ -181,6 +181,12 @@ def controller_state_fixture():
return json.loads(load_fixture("zwave_js/controller_state.json"))
@pytest.fixture(name="controller_node_state", scope="session")
def controller_node_state_fixture():
"""Load the controller node state fixture data."""
return json.loads(load_fixture("zwave_js/controller_node_state.json"))
@pytest.fixture(name="version_state", scope="session")
def version_state_fixture():
"""Load the version state fixture data."""
@ -535,6 +541,14 @@ def mock_client_fixture(controller_state, version_state, log_config_state):
yield client
@pytest.fixture(name="controller_node")
def controller_node_fixture(client, controller_node_state):
"""Mock a controller node."""
node = Node(client, copy.deepcopy(controller_node_state))
client.driver.controller.nodes[node.node_id] = node
return node
@pytest.fixture(name="multisensor_6")
def multisensor_6_fixture(client, multisensor_6_state):
"""Mock a multisensor 6 node."""

View File

@ -1245,5 +1245,6 @@
"label": "Z-Wave chip hardware version"
}
}
]
],
"isControllerNode": false
}

View File

@ -616,5 +616,6 @@
"label": "Z-Wave chip hardware version"
}
}
]
],
"isControllerNode": false
}

View File

@ -3752,5 +3752,6 @@
}
],
"interviewStage": "Complete",
"deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x0371:0x0103:0x00a4:1.3"
"deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x0371:0x0103:0x00a4:1.3",
"isControllerNode": false
}

View File

@ -645,5 +645,6 @@
"label": "Z-Wave chip hardware version"
}
}
]
],
"isControllerNode": false
}

View File

@ -397,5 +397,6 @@
},
"value": 0
}
]
],
"isControllerNode": false
}

View File

@ -432,5 +432,6 @@
"1.1"
]
}
]
],
"isControllerNode": false
}

View File

@ -712,5 +712,6 @@
"label": "Z-Wave chip hardware version"
}
}
]
],
"isControllerNode": false
}

View File

@ -1440,5 +1440,6 @@
"isSecure": false
}
],
"interviewStage": "Complete"
"interviewStage": "Complete",
"isControllerNode": false
}

View File

@ -1246,5 +1246,6 @@
"isSecure": true
}
],
"interviewStage": "Complete"
"interviewStage": "Complete",
"isControllerNode": false
}

View File

@ -1173,5 +1173,6 @@
},
"value": 25.5
}
]
],
"isControllerNode": false
}

View File

@ -826,5 +826,6 @@
"version": 1,
"isSecure": false
}
]
],
"isControllerNode": false
}

View File

@ -1083,5 +1083,6 @@
"version": 3,
"isSecure": false
}
]
],
"isControllerNode": false
}

View File

@ -851,5 +851,6 @@
},
"value": false
}
]
],
"isControllerNode": false
}

View File

@ -958,5 +958,6 @@
"version": 1,
"isSecure": false
}
]
],
"isControllerNode": false
}

View File

@ -0,0 +1,104 @@
{
"nodeId": 1,
"index": 0,
"status": 4,
"ready": true,
"isListening": true,
"isRouting": false,
"isSecure": "unknown",
"manufacturerId": 134,
"productId": 90,
"productType": 1,
"firmwareVersion": "1.2",
"deviceConfig": {
"filename": "/data/db/devices/0x0086/zw090.json",
"isEmbedded": true,
"manufacturer": "AEON Labs",
"manufacturerId": 134,
"label": "ZW090",
"description": "Z\u2010Stick Gen5 USB Controller",
"devices": [
{
"productType": 1,
"productId": 90
},
{
"productType": 257,
"productId": 90
},
{
"productType": 513,
"productId": 90
}
],
"firmwareVersion": {
"min": "0.0",
"max": "255.255"
},
"associations": {},
"paramInformation": {
"_map": {}
},
"metadata": {
"reset": "Use this procedure only in the event that the primary controller is missing or otherwise inoperable.\n\nPress and hold the Action Button on Z-Stick for 20 seconds and then release",
"manual": "https://products.z-wavealliance.org/ProductManual/File?folder=&filename=MarketCertificationFiles/1345/Z%20Stick%20Gen5%20manual%201.pdf"
}
},
"label": "ZW090",
"interviewAttempts": 0,
"endpoints": [
{
"nodeId": 1,
"index": 0,
"deviceClass": {
"basic": {
"key": 2,
"label": "Static Controller"
},
"generic": {
"key": 2,
"label": "Static Controller"
},
"specific": {
"key": 1,
"label": "PC Controller"
},
"mandatorySupportedCCs": [],
"mandatoryControlledCCs": [32]
},
"commandClasses": []
}
],
"values": [],
"isFrequentListening": false,
"maxDataRate": 40000,
"supportedDataRates": [40000],
"protocolVersion": 3,
"deviceClass": {
"basic": {
"key": 2,
"label": "Static Controller"
},
"generic": {
"key": 2,
"label": "Static Controller"
},
"specific": {
"key": 1,
"label": "PC Controller"
},
"mandatorySupportedCCs": [],
"mandatoryControlledCCs": [32]
},
"interviewStage": "Complete",
"deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x0086:0x0001:0x005a:1.2",
"statistics": {
"commandsTX": 0,
"commandsRX": 0,
"commandsDroppedRX": 0,
"commandsDroppedTX": 0,
"timeoutResponse": 0
},
"isControllerNode": true,
"keepAwake": false
}

View File

@ -494,5 +494,6 @@
}
],
"interviewStage": "Complete",
"deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x0371:0x0003:0x008d:3.1"
"deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x0371:0x0003:0x008d:3.1",
"isControllerNode": false
}

View File

@ -1129,5 +1129,6 @@
"commandsDroppedRX": 1,
"commandsDroppedTX": 0,
"timeoutResponse": 0
}
},
"isControllerNode": false
}

View File

@ -353,5 +353,6 @@
"label": "Z-Wave chip hardware version"
}
}
]
],
"isControllerNode": false
}

View File

@ -896,5 +896,6 @@
"commandsDroppedRX": 0,
"commandsDroppedTX": 0,
"timeoutResponse": 0
}
},
"isControllerNode": false
}

View File

@ -917,5 +917,6 @@
"label": "Z-Wave chip hardware version"
}
}
]
],
"isControllerNode": false
}

View File

@ -775,5 +775,6 @@
"value": 0,
"ccVersion": 3
}
]
],
"isControllerNode": false
}

View File

@ -325,6 +325,7 @@
"2.0"
]
}
]
],
"isControllerNode": false
}

View File

@ -427,5 +427,6 @@
"3.10"
]
}
]
],
"isControllerNode": false
}

View File

@ -348,5 +348,6 @@
"label": "Z-Wave chip hardware version"
}
}
]
],
"isControllerNode": false
}

View File

@ -10502,5 +10502,6 @@
"commandsDroppedRX": 0,
"commandsDroppedTX": 0,
"timeoutResponse": 2
}
},
"isControllerNode": false
}

View File

@ -346,5 +346,6 @@
"commandsDroppedRX": 0,
"commandsDroppedTX": 0,
"timeoutResponse": 2
}
},
"isControllerNode": false
}

View File

@ -351,5 +351,6 @@
"commandsDroppedTX": 0,
"timeoutResponse": 1
},
"highestSecurityClass": -1
"highestSecurityClass": -1,
"isControllerNode": false
}

View File

@ -638,5 +638,6 @@
"mandatoryControlledCCs": []
},
"interviewStage": "Complete",
"deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x0063:0x4944:0x3038:5.26"
"deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x0063:0x4944:0x3038:5.26",
"isControllerNode": false
}

View File

@ -720,5 +720,6 @@
"label": "Z-Wave chip hardware version"
}
}
]
],
"isControllerNode": false
}

View File

@ -1952,5 +1952,6 @@
}
}
}
]
],
"isControllerNode": false
}

View File

@ -685,5 +685,6 @@
"version": 1,
"isSecure": false
}
]
],
"isControllerNode": false
}

View File

@ -446,5 +446,6 @@
"label": "Z-Wave chip hardware version"
}
}
]
],
"isControllerNode": false
}

View File

@ -2915,5 +2915,6 @@
"version": 1,
"isSecure": true
}
]
],
"isControllerNode": false
}

View File

@ -564,5 +564,6 @@
"commandsDroppedRX": 0,
"commandsDroppedTX": 0,
"timeoutResponse": 0
}
},
"isControllerNode": false
}

View File

@ -2103,5 +2103,6 @@
},
"value": 0
}
]
],
"isControllerNode": false
}

View File

@ -250,7 +250,8 @@
"label": "Dimming duration"
}
}
]
],
"isControllerNode": false
},
"result": {}
}

View File

@ -1275,5 +1275,6 @@
"label": "Dimming duration"
}
}
]
],
"isControllerNode": false
}

View File

@ -410,5 +410,6 @@
"version": 3,
"isSecure": false
}
]
],
"isControllerNode": false
}

View File

@ -258,5 +258,6 @@
"2.0"
]
}
]
],
"isControllerNode": false
}

View File

@ -429,5 +429,6 @@
"version": 1,
"isSecure": false
}
]
],
"isControllerNode": false
}

View File

@ -694,5 +694,6 @@
"label": "Z-Wave chip hardware version"
}
}
]
],
"isControllerNode": false
}

View File

@ -2803,5 +2803,6 @@
"version": 1,
"isSecure": true
}
]
],
"isControllerNode": false
}

View File

@ -64,5 +64,6 @@
"commandsDroppedRX": 0,
"commandsDroppedTX": 0,
"timeoutResponse": 0
}
},
"isControllerNode": false
}

View File

@ -702,5 +702,6 @@
"commandsDroppedTX": 0,
"timeoutResponse": 0
},
"highestSecurityClass": -1
"highestSecurityClass": -1,
"isControllerNode": false
}

View File

@ -1,13 +1,16 @@
"""Test the Z-Wave JS button entities."""
from homeassistant.components.button.const import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
from homeassistant.components.zwave_js.const import DOMAIN, SERVICE_REFRESH_VALUE
from homeassistant.components.zwave_js.helpers import get_valueless_base_unique_id
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.helpers.entity_registry import async_get
async def test_ping_entity(
hass,
client,
climate_radio_thermostat_ct100_plus_different_endpoints,
controller_node,
integration,
caplog,
):
@ -44,3 +47,13 @@ async def test_ping_entity(
)
assert "There is no value to refresh for this entity" in caplog.text
# Assert a node ping button entity is not created for the controller
node = client.driver.controller.nodes[1]
assert node.is_controller_node
assert (
async_get(hass).async_get_entity_id(
DOMAIN, "sensor", f"{get_valueless_base_unique_id(client, node)}.ping"
)
is None
)

View File

@ -934,6 +934,7 @@ async def test_replace_same_node(
"commandsDroppedTX": 0,
"timeoutResponse": 0,
},
"isControllerNode": False,
},
"result": {},
},
@ -1052,6 +1053,7 @@ async def test_replace_different_node(
"commandsDroppedTX": 0,
"timeoutResponse": 0,
},
"isControllerNode": False,
},
"result": {},
},

View File

@ -18,6 +18,7 @@ from homeassistant.components.zwave_js.const import (
SERVICE_REFRESH_VALUE,
SERVICE_RESET_METER,
)
from homeassistant.components.zwave_js.helpers import get_valueless_base_unique_id
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_ENTITY_ID,
@ -155,7 +156,9 @@ async def test_config_parameter_sensor(hass, lock_id_lock_as_id150, integration)
assert entity_entry.disabled
async def test_node_status_sensor(hass, client, lock_id_lock_as_id150, integration):
async def test_node_status_sensor(
hass, client, controller_node, lock_id_lock_as_id150, integration
):
"""Test node status sensor is created and gets updated on node state changes."""
NODE_STATUS_ENTITY = "sensor.z_wave_module_for_id_lock_150_and_101_node_status"
node = lock_id_lock_as_id150
@ -201,6 +204,18 @@ async def test_node_status_sensor(hass, client, lock_id_lock_as_id150, integrati
await client.disconnect()
assert hass.states.get(NODE_STATUS_ENTITY).state != STATE_UNAVAILABLE
# Assert a node status sensor entity is not created for the controller
node = client.driver.controller.nodes[1]
assert node.is_controller_node
assert (
ent_reg.async_get_entity_id(
DOMAIN,
"sensor",
f"{get_valueless_base_unique_id(client, node)}.node_status",
)
is None
)
async def test_node_status_sensor_not_ready(
hass,