From 4e387e0c23c8950894da343048d862b5196ec1cc Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Mon, 20 Feb 2023 18:46:06 -0500 Subject: [PATCH 1/7] Add support for firmware target in zwave_js FirmwareUploadView fix --- homeassistant/components/zwave_js/api.py | 10 +++++--- .../components/zwave_js/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/zwave_js/test_api.py | 24 +++++++++++++------ 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/zwave_js/api.py b/homeassistant/components/zwave_js/api.py index ba61de3bce4af..f164a81b60e5b 100644 --- a/homeassistant/components/zwave_js/api.py +++ b/homeassistant/components/zwave_js/api.py @@ -4,7 +4,7 @@ from collections.abc import Callable import dataclasses from functools import partial, wraps -from typing import Any, Literal +from typing import Any, Literal, cast from aiohttp import web, web_exceptions, web_request import voluptuous as vol @@ -35,11 +35,11 @@ QRProvisioningInformation, ) from zwave_js_server.model.driver import Driver -from zwave_js_server.model.firmware import FirmwareUpdateData from zwave_js_server.model.log_config import LogConfig from zwave_js_server.model.log_message import LogMessage from zwave_js_server.model.node import Node, NodeStatistics from zwave_js_server.model.node.firmware import ( + NodeFirmwareUpdateData, NodeFirmwareUpdateProgress, NodeFirmwareUpdateResult, ) @@ -2066,15 +2066,19 @@ async def post(self, request: web.Request, device_id: str) -> web.Response: raise web_exceptions.HTTPBadRequest uploaded_file: web_request.FileField = data["file"] + firmware_target: int | None = None + if "target" in data: + firmware_target = int(cast(str, data["target"])) try: await update_firmware( node.client.ws_server_url, node, [ - FirmwareUpdateData( + NodeFirmwareUpdateData( uploaded_file.filename, await hass.async_add_executor_job(uploaded_file.file.read), + firmware_target=firmware_target, ) ], async_get_clientsession(hass), diff --git a/homeassistant/components/zwave_js/manifest.json b/homeassistant/components/zwave_js/manifest.json index a1367e445e919..a21f7a6f30b5e 100644 --- a/homeassistant/components/zwave_js/manifest.json +++ b/homeassistant/components/zwave_js/manifest.json @@ -8,7 +8,7 @@ "integration_type": "hub", "iot_class": "local_push", "loggers": ["zwave_js_server"], - "requirements": ["pyserial==3.5", "zwave-js-server-python==0.45.2"], + "requirements": ["pyserial==3.5", "zwave-js-server-python==0.46.0"], "usb": [ { "vid": "0658", diff --git a/requirements_all.txt b/requirements_all.txt index b8bed339eb5cb..adfef72822dd2 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2727,7 +2727,7 @@ zigpy==0.53.0 zm-py==0.5.2 # homeassistant.components.zwave_js -zwave-js-server-python==0.45.2 +zwave-js-server-python==0.46.0 # homeassistant.components.zwave_me zwave_me_ws==0.3.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 38df7c78f389b..70124fa34fa0b 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1931,7 +1931,7 @@ zigpy-znp==0.9.2 zigpy==0.53.0 # homeassistant.components.zwave_js -zwave-js-server-python==0.45.2 +zwave-js-server-python==0.46.0 # homeassistant.components.zwave_me zwave_me_ws==0.3.1 diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index 1809695643c92..e92fa5272d244 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -28,8 +28,8 @@ ProvisioningEntry, QRProvisioningInformation, ) -from zwave_js_server.model.firmware import FirmwareUpdateData from zwave_js_server.model.node import Node +from zwave_js_server.model.node.firmware import NodeFirmwareUpdateData from homeassistant.components.websocket_api import ERR_INVALID_FORMAT, ERR_NOT_FOUND from homeassistant.components.zwave_js.api import ( @@ -2893,12 +2893,17 @@ async def test_get_config_parameters( assert msg["error"]["code"] == ERR_NOT_LOADED +@pytest.mark.parametrize( + ("include_target"), + [(True), (False)], +) async def test_firmware_upload_view( hass: HomeAssistant, multisensor_6, integration, hass_client: ClientSessionGenerator, firmware_file, + include_target, ) -> None: """Test the HTTP firmware upload view.""" client = await hass_client() @@ -2909,14 +2914,19 @@ async def test_firmware_upload_view( "homeassistant.components.zwave_js.api.USER_AGENT", {"HomeAssistant": "0.0.0"}, ): + data = {"file": firmware_file} + if include_target: + data["target"] = "1" + resp = await client.post( - f"/api/zwave_js/firmware/upload/{device.id}", - data={"file": firmware_file}, - ) - assert mock_cmd.call_args[0][1:3] == ( - multisensor_6, - [FirmwareUpdateData("file", bytes(10))], + f"/api/zwave_js/firmware/upload/{device.id}", data=data ) + + update_data = NodeFirmwareUpdateData("file", bytes(10)) + if include_target: + update_data.firmware_target = 1 + + assert mock_cmd.call_args[0][1:3] == (multisensor_6, [update_data]) assert mock_cmd.call_args[1] == { "additional_user_agent_components": {"HomeAssistant": "0.0.0"}, } From 359317183b483a7a5e3b6300335c3bbbbbc1ea1f Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 21 Feb 2023 19:11:12 -0500 Subject: [PATCH 2/7] Update tests/components/zwave_js/test_api.py Co-authored-by: Martin Hjelmare --- tests/components/zwave_js/test_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index e92fa5272d244..9291bcea6ca64 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -2894,8 +2894,8 @@ async def test_get_config_parameters( @pytest.mark.parametrize( - ("include_target"), - [(True), (False)], + ("firmware_data", "expected_data"), + [({"target": "1"}, {"firmware_target": 1}), ({}, {})], ) async def test_firmware_upload_view( hass: HomeAssistant, From abc7cf15e03a5e0bdaa15d8ecd74c7e8bcd9c0be Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 21 Feb 2023 19:11:21 -0500 Subject: [PATCH 3/7] Update tests/components/zwave_js/test_api.py Co-authored-by: Martin Hjelmare --- tests/components/zwave_js/test_api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index 9291bcea6ca64..bcfcfc75adbe1 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -2903,7 +2903,8 @@ async def test_firmware_upload_view( integration, hass_client: ClientSessionGenerator, firmware_file, - include_target, + firmware_data: dict[str, Any], + expected_data: dict[str, Any], ) -> None: """Test the HTTP firmware upload view.""" client = await hass_client() From 14d5e1906490b473ef94bb3f2f5d85e570652e26 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 21 Feb 2023 19:11:26 -0500 Subject: [PATCH 4/7] Update tests/components/zwave_js/test_api.py Co-authored-by: Martin Hjelmare --- tests/components/zwave_js/test_api.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index bcfcfc75adbe1..220eff5e5c388 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -2916,8 +2916,7 @@ async def test_firmware_upload_view( {"HomeAssistant": "0.0.0"}, ): data = {"file": firmware_file} - if include_target: - data["target"] = "1" + data.update(firmware_data) resp = await client.post( f"/api/zwave_js/firmware/upload/{device.id}", data=data From 83724b927950547520b336a7654d9fcb4b299c31 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 21 Feb 2023 19:11:33 -0500 Subject: [PATCH 5/7] Update tests/components/zwave_js/test_api.py Co-authored-by: Martin Hjelmare --- tests/components/zwave_js/test_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index 220eff5e5c388..7a74d5f556867 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -2923,8 +2923,8 @@ async def test_firmware_upload_view( ) update_data = NodeFirmwareUpdateData("file", bytes(10)) - if include_target: - update_data.firmware_target = 1 + for attr, value in expected_data.items(): + setattr(update_data, attr, value) assert mock_cmd.call_args[0][1:3] == (multisensor_6, [update_data]) assert mock_cmd.call_args[1] == { From 8207b57519e074596782694ca30719630720da9e Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 21 Feb 2023 20:01:45 -0500 Subject: [PATCH 6/7] fix types --- tests/components/zwave_js/test_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index 7a74d5f556867..c83050578e4f0 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -2903,8 +2903,8 @@ async def test_firmware_upload_view( integration, hass_client: ClientSessionGenerator, firmware_file, - firmware_data: dict[str, Any], - expected_data: dict[str, Any], + firmware_data: dict[str, str], + expected_data: dict[str, int], ) -> None: """Test the HTTP firmware upload view.""" client = await hass_client() From 2d905fa94f6892616569d19bb75f411da707737a Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 21 Feb 2023 20:09:15 -0500 Subject: [PATCH 7/7] Switch back to using Any --- tests/components/zwave_js/test_api.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index c83050578e4f0..767a7301bbb14 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -2,6 +2,7 @@ from copy import deepcopy from http import HTTPStatus import json +from typing import Any from unittest.mock import patch import pytest @@ -2903,8 +2904,8 @@ async def test_firmware_upload_view( integration, hass_client: ClientSessionGenerator, firmware_file, - firmware_data: dict[str, str], - expected_data: dict[str, int], + firmware_data: dict[str, Any], + expected_data: dict[str, Any], ) -> None: """Test the HTTP firmware upload view.""" client = await hass_client()