diff --git a/homeassistant/components/otbr/manifest.json b/homeassistant/components/otbr/manifest.json index f04e15a549c..94659df8547 100644 --- a/homeassistant/components/otbr/manifest.json +++ b/homeassistant/components/otbr/manifest.json @@ -8,5 +8,5 @@ "documentation": "https://www.home-assistant.io/integrations/otbr", "integration_type": "service", "iot_class": "local_polling", - "requirements": ["python-otbr-api==2.1.0"] + "requirements": ["python-otbr-api==2.2.0"] } diff --git a/homeassistant/components/otbr/util.py b/homeassistant/components/otbr/util.py index 5caebba5eb5..2d6217ea585 100644 --- a/homeassistant/components/otbr/util.py +++ b/homeassistant/components/otbr/util.py @@ -95,6 +95,11 @@ class OTBRData: """Create an active operational dataset.""" return await self.api.create_active_dataset(dataset) + @_handle_otbr_error + async def delete_active_dataset(self) -> None: + """Delete the active operational dataset.""" + return await self.api.delete_active_dataset() + @_handle_otbr_error async def set_active_dataset_tlvs(self, dataset: bytes) -> None: """Set current active operational dataset in TLVS format.""" diff --git a/homeassistant/components/otbr/websocket_api.py b/homeassistant/components/otbr/websocket_api.py index 0dcce288348..06bbca3a4ab 100644 --- a/homeassistant/components/otbr/websocket_api.py +++ b/homeassistant/components/otbr/websocket_api.py @@ -81,6 +81,12 @@ async def websocket_create_network( connection.send_error(msg["id"], "set_enabled_failed", str(exc)) return + try: + await data.delete_active_dataset() + except HomeAssistantError as exc: + connection.send_error(msg["id"], "delete_active_dataset_failed", str(exc)) + return + try: await data.create_active_dataset( python_otbr_api.ActiveDataSet( diff --git a/homeassistant/components/thread/manifest.json b/homeassistant/components/thread/manifest.json index 9a6a64481cd..0ce54496539 100644 --- a/homeassistant/components/thread/manifest.json +++ b/homeassistant/components/thread/manifest.json @@ -7,6 +7,6 @@ "documentation": "https://www.home-assistant.io/integrations/thread", "integration_type": "service", "iot_class": "local_polling", - "requirements": ["python-otbr-api==2.1.0", "pyroute2==0.7.5"], + "requirements": ["python-otbr-api==2.2.0", "pyroute2==0.7.5"], "zeroconf": ["_meshcop._udp.local."] } diff --git a/requirements_all.txt b/requirements_all.txt index 8bb4580aa61..20df7fca52b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2106,7 +2106,7 @@ python-opensky==0.0.7 # homeassistant.components.otbr # homeassistant.components.thread -python-otbr-api==2.1.0 +python-otbr-api==2.2.0 # homeassistant.components.picnic python-picnic-api==1.1.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index bc1cae28d09..36941aceeb4 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1532,7 +1532,7 @@ python-nest==4.2.0 # homeassistant.components.otbr # homeassistant.components.thread -python-otbr-api==2.1.0 +python-otbr-api==2.2.0 # homeassistant.components.picnic python-picnic-api==1.1.0 diff --git a/tests/components/otbr/test_websocket_api.py b/tests/components/otbr/test_websocket_api.py index 1feebe9c02c..65bec9e8408 100644 --- a/tests/components/otbr/test_websocket_api.py +++ b/tests/components/otbr/test_websocket_api.py @@ -84,6 +84,8 @@ async def test_create_network( with patch( "python_otbr_api.OTBR.create_active_dataset" ) as create_dataset_mock, patch( + "python_otbr_api.OTBR.delete_active_dataset" + ) as delete_dataset_mock, patch( "python_otbr_api.OTBR.set_enabled" ) as set_enabled_mock, patch( "python_otbr_api.OTBR.get_active_dataset_tlvs", return_value=DATASET_CH16 @@ -99,6 +101,7 @@ async def test_create_network( create_dataset_mock.assert_called_once_with( python_otbr_api.models.ActiveDataSet(channel=15, network_name="home-assistant") ) + delete_dataset_mock.assert_called_once_with() assert len(set_enabled_mock.mock_calls) == 2 assert set_enabled_mock.mock_calls[0][1][0] is False assert set_enabled_mock.mock_calls[1][1][0] is True @@ -151,7 +154,7 @@ async def test_create_network_fails_2( ), patch( "python_otbr_api.OTBR.create_active_dataset", side_effect=python_otbr_api.OTBRError, - ): + ), patch("python_otbr_api.OTBR.delete_active_dataset"): await websocket_client.send_json_auto_id({"type": "otbr/create_network"}) msg = await websocket_client.receive_json() @@ -171,6 +174,8 @@ async def test_create_network_fails_3( side_effect=[None, python_otbr_api.OTBRError], ), patch( "python_otbr_api.OTBR.create_active_dataset", + ), patch( + "python_otbr_api.OTBR.delete_active_dataset" ): await websocket_client.send_json_auto_id({"type": "otbr/create_network"}) msg = await websocket_client.receive_json() @@ -191,6 +196,8 @@ async def test_create_network_fails_4( ), patch( "python_otbr_api.OTBR.get_active_dataset_tlvs", side_effect=python_otbr_api.OTBRError, + ), patch( + "python_otbr_api.OTBR.delete_active_dataset" ): await websocket_client.send_json_auto_id({"type": "otbr/create_network"}) msg = await websocket_client.receive_json() @@ -208,7 +215,9 @@ async def test_create_network_fails_5( """Test create network.""" with patch("python_otbr_api.OTBR.set_enabled"), patch( "python_otbr_api.OTBR.create_active_dataset" - ), patch("python_otbr_api.OTBR.get_active_dataset_tlvs", return_value=None): + ), patch("python_otbr_api.OTBR.get_active_dataset_tlvs", return_value=None), patch( + "python_otbr_api.OTBR.delete_active_dataset" + ): await websocket_client.send_json_auto_id({"type": "otbr/create_network"}) msg = await websocket_client.receive_json() @@ -216,6 +225,26 @@ async def test_create_network_fails_5( assert msg["error"]["code"] == "get_active_dataset_tlvs_empty" +async def test_create_network_fails_6( + hass: HomeAssistant, + aioclient_mock: AiohttpClientMocker, + otbr_config_entry, + websocket_client, +) -> None: + """Test create network.""" + with patch("python_otbr_api.OTBR.set_enabled"), patch( + "python_otbr_api.OTBR.create_active_dataset" + ), patch("python_otbr_api.OTBR.get_active_dataset_tlvs", return_value=None), patch( + "python_otbr_api.OTBR.delete_active_dataset", + side_effect=python_otbr_api.OTBRError, + ): + await websocket_client.send_json_auto_id({"type": "otbr/create_network"}) + msg = await websocket_client.receive_json() + + assert not msg["success"] + assert msg["error"]["code"] == "delete_active_dataset_failed" + + async def test_set_network( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker,