diff --git a/homeassistant/components/zwave_js/device_action.py b/homeassistant/components/zwave_js/device_action.py index 7e5e8c6c78d..a67bd44e533 100644 --- a/homeassistant/components/zwave_js/device_action.py +++ b/homeassistant/components/zwave_js/device_action.py @@ -241,7 +241,7 @@ async def async_call_action_from_config( hass: HomeAssistant, config: dict, variables: dict, context: Context | None ) -> None: """Execute a device action.""" - action_type = service = config.pop(CONF_TYPE) + action_type = service = config[CONF_TYPE] if action_type not in ACTION_TYPES: raise HomeAssistantError(f"Unhandled action type {action_type}") @@ -249,10 +249,10 @@ async def async_call_action_from_config( service_data = { k: v for k, v in config.items() - if k not in (ATTR_DOMAIN, CONF_SUBTYPE) and v not in (None, "") + if k not in (ATTR_DOMAIN, CONF_TYPE, CONF_SUBTYPE) and v not in (None, "") } - # Entity services (including refresh value which is a fake entity service) expects + # Entity services (including refresh value which is a fake entity service) expect # just an entity ID if action_type in ( SERVICE_REFRESH_VALUE, diff --git a/tests/components/zwave_js/test_device_action.py b/tests/components/zwave_js/test_device_action.py index 07663ce9456..657540db94d 100644 --- a/tests/components/zwave_js/test_device_action.py +++ b/tests/components/zwave_js/test_device_action.py @@ -169,6 +169,15 @@ async def test_actions( }, ) + with patch("zwave_js_server.model.node.Node.async_poll_value") as mock_call: + hass.bus.async_fire("test_event_refresh_value") + await hass.async_block_till_done() + mock_call.assert_called_once() + args = mock_call.call_args_list[0][0] + assert len(args) == 1 + assert args[0].value_id == "13-64-1-mode" + + # Call action a second time to confirm that it works (this was previously a bug) with patch("zwave_js_server.model.node.Node.async_poll_value") as mock_call: hass.bus.async_fire("test_event_refresh_value") await hass.async_block_till_done() @@ -206,6 +215,51 @@ async def test_actions( assert args[2] == 1 +async def test_actions_multiple_calls( + hass: HomeAssistant, + client: Client, + climate_radio_thermostat_ct100_plus: Node, + integration: ConfigEntry, +) -> None: + """Test actions can be called multiple times and still work.""" + node = climate_radio_thermostat_ct100_plus + device_id = get_device_id(client, node) + dev_reg = device_registry.async_get(hass) + device = dev_reg.async_get_device({device_id}) + assert device + + assert await async_setup_component( + hass, + automation.DOMAIN, + { + automation.DOMAIN: [ + { + "trigger": { + "platform": "event", + "event_type": "test_event_refresh_value", + }, + "action": { + "domain": DOMAIN, + "type": "refresh_value", + "device_id": device.id, + "entity_id": "climate.z_wave_thermostat", + }, + }, + ] + }, + ) + + # Trigger automation multiple times to confirm that it works each time + for _ in range(5): + with patch("zwave_js_server.model.node.Node.async_poll_value") as mock_call: + hass.bus.async_fire("test_event_refresh_value") + await hass.async_block_till_done() + mock_call.assert_called_once() + args = mock_call.call_args_list[0][0] + assert len(args) == 1 + assert args[0].value_id == "13-64-1-mode" + + async def test_lock_actions( hass: HomeAssistant, client: Client,