From c16a18b2bd7166b3e8e588ef3494223f31ff855b Mon Sep 17 00:00:00 2001 From: Balazs Sandor Date: Fri, 8 May 2020 18:47:58 +0200 Subject: [PATCH 01/49] Update lib zigpy-cc to fix issues (#35364) --- homeassistant/components/zha/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index e49f4f1407a..2f692438935 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -6,7 +6,7 @@ "requirements": [ "bellows-homeassistant==0.15.2", "zha-quirks==0.0.38", - "zigpy-cc==0.3.1", + "zigpy-cc==0.3.2", "zigpy-deconz==0.8.1", "zigpy-homeassistant==0.19.0", "zigpy-xbee-homeassistant==0.11.0", diff --git a/requirements_all.txt b/requirements_all.txt index 804299d2e37..bdbd6e30b8b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2196,7 +2196,7 @@ zhong_hong_hvac==1.0.9 ziggo-mediabox-xl==1.1.0 # homeassistant.components.zha -zigpy-cc==0.3.1 +zigpy-cc==0.3.2 # homeassistant.components.zha zigpy-deconz==0.8.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 35f0535d77e..145eaad074d 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -833,7 +833,7 @@ zeroconf==0.25.1 zha-quirks==0.0.38 # homeassistant.components.zha -zigpy-cc==0.3.1 +zigpy-cc==0.3.2 # homeassistant.components.zha zigpy-deconz==0.8.1 From 638f37167ff07e988db9adcf82d5a8cbc0b145ad Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Wed, 13 May 2020 20:31:45 +0200 Subject: [PATCH 02/49] Bumped version to 0.110.0b0 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index ec8c29de0b7..4815638c614 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 110 -PATCH_VERSION = "0.dev0" +PATCH_VERSION = "0b0" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 0) From 0e79b47b430e9ab269edf4d0a1831c99b91a4829 Mon Sep 17 00:00:00 2001 From: Steven Looman Date: Thu, 14 May 2020 22:58:41 +0200 Subject: [PATCH 03/49] Properly handle incomplete upnp ssdp discovery (#35553) --- homeassistant/components/upnp/config_flow.py | 9 +++++++ homeassistant/components/upnp/strings.json | 3 ++- tests/components/upnp/test_config_flow.py | 28 ++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/upnp/config_flow.py b/homeassistant/components/upnp/config_flow.py index 8afd3465f07..a85e47c5919 100644 --- a/homeassistant/components/upnp/config_flow.py +++ b/homeassistant/components/upnp/config_flow.py @@ -134,6 +134,14 @@ class UpnpFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): """ _LOGGER.debug("async_step_ssdp: discovery_info: %s", discovery_info) + # Ensure complete discovery. + if ( + ssdp.ATTR_UPNP_UDN not in discovery_info + or ssdp.ATTR_SSDP_ST not in discovery_info + ): + _LOGGER.debug("Incomplete discovery, ignoring") + return self.async_abort(reason="incomplete_discovery") + # Ensure not already configuring/configured. udn = discovery_info[ssdp.ATTR_UPNP_UDN] st = discovery_info[ssdp.ATTR_SSDP_ST] # pylint: disable=invalid-name @@ -218,6 +226,7 @@ class UpnpOptionsFlowHandler(config_entries.OptionsFlow): CONFIG_ENTRY_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL ) update_interval = timedelta(seconds=update_interval_sec) + _LOGGER.debug("Updating coordinator, update_interval: %s", update_interval) coordinator.update_interval = update_interval return self.async_create_entry(title="", data=user_input) diff --git a/homeassistant/components/upnp/strings.json b/homeassistant/components/upnp/strings.json index 8936d2ec791..99e58698f2e 100644 --- a/homeassistant/components/upnp/strings.json +++ b/homeassistant/components/upnp/strings.json @@ -17,7 +17,8 @@ "abort": { "already_configured": "UPnP/IGD is already configured", "no_devices_discovered": "No UPnP/IGDs discovered", - "no_devices_found": "No UPnP/IGD devices found on the network." + "no_devices_found": "No UPnP/IGD devices found on the network.", + "incomplete_discovery": "Incomplete discovery" } } } diff --git a/tests/components/upnp/test_config_flow.py b/tests/components/upnp/test_config_flow.py index c0f5b6b4ff2..870aa13fc41 100644 --- a/tests/components/upnp/test_config_flow.py +++ b/tests/components/upnp/test_config_flow.py @@ -65,6 +65,34 @@ async def test_flow_ssdp_discovery(hass: HomeAssistantType): } +async def test_flow_ssdp_discovery_incomplete(hass: HomeAssistantType): + """Test config flow: incomplete discovery through ssdp.""" + udn = "uuid:device_1" + mock_device = MockDevice(udn) + discovery_infos = [ + { + DISCOVERY_ST: mock_device.device_type, + DISCOVERY_UDN: mock_device.udn, + DISCOVERY_LOCATION: "dummy", + } + ] + with patch.object( + Device, "async_create_device", AsyncMock(return_value=mock_device) + ), patch.object(Device, "async_discover", AsyncMock(return_value=discovery_infos)): + # Discovered via step ssdp. + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_SSDP}, + data={ + ssdp.ATTR_SSDP_ST: mock_device.device_type, + # ssdp.ATTR_UPNP_UDN: mock_device.udn, # Not provided. + "friendlyName": mock_device.name, + }, + ) + assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result["reason"] == "incomplete_discovery" + + async def test_flow_user(hass: HomeAssistantType): """Test config flow: discovered + configured through user.""" udn = "uuid:device_1" From 506dd1d423c401a8c4c56c617b17748cee700ea6 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk <11290930+bouwew@users.noreply.github.com> Date: Thu, 14 May 2020 07:03:42 +0200 Subject: [PATCH 04/49] Bump haanna to 0.15.0 (#35579) * Link to haanna v0.15.0 * Update requirements_all.txt --- homeassistant/components/plugwise/manifest.json | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/plugwise/manifest.json b/homeassistant/components/plugwise/manifest.json index 9f14f6c6e61..55e43c2a29f 100644 --- a/homeassistant/components/plugwise/manifest.json +++ b/homeassistant/components/plugwise/manifest.json @@ -3,5 +3,5 @@ "name": "Plugwise Anna", "documentation": "https://www.home-assistant.io/integrations/plugwise", "codeowners": ["@laetificat", "@CoMPaTech", "@bouwew"], - "requirements": ["haanna==0.14.3"] + "requirements": ["haanna==0.15.0"] } diff --git a/requirements_all.txt b/requirements_all.txt index 2abe1d3a6a6..f7eac178f1c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -692,7 +692,7 @@ ha-ffmpeg==2.0 ha-philipsjs==0.0.8 # homeassistant.components.plugwise -haanna==0.14.3 +haanna==0.15.0 # homeassistant.components.habitica habitipy==0.2.0 From cc431b9f14d1bb9a8a623b4a09368264e0c05a6c Mon Sep 17 00:00:00 2001 From: uvjustin <46082645+uvjustin@users.noreply.github.com> Date: Fri, 15 May 2020 01:42:00 +0800 Subject: [PATCH 05/49] Clean up forked_daapd volume saving/setting in async_play_media (#35584) * Clean up volume saving/setting in async_play_media * Set source to pipe when queued externally * Add server version requirement to error string --- .../components/forked_daapd/media_player.py | 42 +++++++++++-------- .../components/forked_daapd/strings.json | 2 +- .../forked_daapd/translations/en.json | 2 +- .../forked_daapd/test_media_player.py | 35 ++++++++++++++-- 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/homeassistant/components/forked_daapd/media_player.py b/homeassistant/components/forked_daapd/media_player.py index 8224ea68914..1b52d454def 100644 --- a/homeassistant/components/forked_daapd/media_player.py +++ b/homeassistant/components/forked_daapd/media_player.py @@ -237,7 +237,7 @@ class ForkedDaapdMaster(MediaPlayerDevice): self._track_info = defaultdict( str ) # _track info is found by matching _player data with _queue data - self._last_outputs = None # used for device on/off + self._last_outputs = [] # used for device on/off self._last_volume = DEFAULT_UNMUTE_VOLUME self._player_last_updated = None self._pipe_control_api = {} @@ -349,6 +349,13 @@ class ForkedDaapdMaster(MediaPlayerDevice): ): self._tts_requested = False self._tts_queued = True + + if ( + self._queue["count"] >= 1 + and self._queue["items"][0]["data_kind"] == "pipe" + and self._queue["items"][0]["title"] in KNOWN_PIPES + ): # if we're playing a pipe, set the source automatically so we can forward controls + self._source = f"{self._queue['items'][0]['title']} (pipe)" self._update_track_info() event.set() @@ -407,6 +414,7 @@ class ForkedDaapdMaster(MediaPlayerDevice): async def async_turn_on(self): """Restore the last on outputs state.""" # restore state + await self._api.set_volume(volume=self._last_volume * 100) if self._last_outputs: futures = [] for output in self._last_outputs: @@ -418,19 +426,16 @@ class ForkedDaapdMaster(MediaPlayerDevice): ) ) await asyncio.wait(futures) - else: - selected = [] - for output in self._outputs: - selected.append(output["id"]) - await self._api.set_enabled_outputs(selected) + else: # enable all outputs + await self._api.set_enabled_outputs( + [output["id"] for output in self._outputs] + ) async def async_turn_off(self): """Pause player and store outputs state.""" await self.async_media_pause() - if any( - [output["selected"] for output in self._outputs] - ): # only store output state if some output is selected - self._last_outputs = self._outputs + self._last_outputs = self._outputs + if any([output["selected"] for output in self._outputs]): await self._api.set_enabled_outputs([]) async def async_toggle(self): @@ -613,8 +618,12 @@ class ForkedDaapdMaster(MediaPlayerDevice): url = self._api.full_url(url) return url - async def _set_tts_volumes(self): + async def _save_and_set_tts_volumes(self): + if self.volume_level: # save master volume + self._last_volume = self.volume_level + self._last_outputs = self._outputs if self._outputs: + await self._api.set_volume(volume=self._tts_volume * 100) futures = [] for output in self._outputs: futures.append( @@ -623,7 +632,6 @@ class ForkedDaapdMaster(MediaPlayerDevice): ) ) await asyncio.wait(futures) - await self._api.set_volume(volume=self._tts_volume * 100) async def _pause_and_wait_for_callback(self): """Send pause and wait for the pause callback to be received.""" @@ -641,14 +649,12 @@ class ForkedDaapdMaster(MediaPlayerDevice): """Play a URI.""" if media_type == MEDIA_TYPE_MUSIC: saved_state = self.state # save play state - if any([output["selected"] for output in self._outputs]): # save outputs - self._last_outputs = self._outputs - await self._api.set_enabled_outputs([]) # turn off outputs + saved_mute = self.is_volume_muted sleep_future = asyncio.create_task( asyncio.sleep(self._tts_pause_time) ) # start timing now, but not exact because of fd buffer + tts latency await self._pause_and_wait_for_callback() - await self._set_tts_volumes() + await self._save_and_set_tts_volumes() # save position saved_song_position = self._player["item_progress_ms"] saved_queue = ( @@ -678,7 +684,9 @@ class ForkedDaapdMaster(MediaPlayerDevice): _LOGGER.warning("TTS request timed out") self._tts_playing_event.clear() # TTS done, return to normal - await self.async_turn_on() # restores outputs + await self.async_turn_on() # restore outputs and volumes + if saved_mute: # mute if we were muted + await self.async_mute_volume(True) if self._use_pipe_control(): # resume pipe await self._api.add_to_queue( uris=self._sources_uris[self._source], clear=True diff --git a/homeassistant/components/forked_daapd/strings.json b/homeassistant/components/forked_daapd/strings.json index ea822a5559c..33f9c7b91aa 100644 --- a/homeassistant/components/forked_daapd/strings.json +++ b/homeassistant/components/forked_daapd/strings.json @@ -16,7 +16,7 @@ "websocket_not_enabled": "forked-daapd server websocket not enabled.", "wrong_host_or_port": "Unable to connect. Please check host and port.", "wrong_password": "Incorrect password.", - "wrong_server_type": "Not a forked-daapd server.", + "wrong_server_type": "The forked-daapd integration requires a forked-daapd server with version >= 27.0.", "unknown_error": "Unknown error." }, "abort": { diff --git a/homeassistant/components/forked_daapd/translations/en.json b/homeassistant/components/forked_daapd/translations/en.json index 6fe1b006984..0c87c6624ff 100644 --- a/homeassistant/components/forked_daapd/translations/en.json +++ b/homeassistant/components/forked_daapd/translations/en.json @@ -9,7 +9,7 @@ "websocket_not_enabled": "forked-daapd server websocket not enabled.", "wrong_host_or_port": "Unable to connect. Please check host and port.", "wrong_password": "Incorrect password.", - "wrong_server_type": "Not a forked-daapd server." + "wrong_server_type": "The forked-daapd integration requires a forked-daapd server with version >= 27.0." }, "flow_title": "forked-daapd server: {name} ({host})", "step": { diff --git a/tests/components/forked_daapd/test_media_player.py b/tests/components/forked_daapd/test_media_player.py index b0bed5aba3b..8f3a6c2c139 100644 --- a/tests/components/forked_daapd/test_media_player.py +++ b/tests/components/forked_daapd/test_media_player.py @@ -111,7 +111,7 @@ SAMPLE_PLAYER_STOPPED = { "item_progress_ms": 5, } -SAMPLE_TTS_QUEUE = { +SAMPLE_QUEUE_TTS = { "version": 833, "count": 1, "items": [ @@ -127,11 +127,31 @@ SAMPLE_TTS_QUEUE = { "length_ms": 0, "track_number": 1, "media_kind": "music", + "data_kind": "url", "uri": "tts_proxy_somefile.mp3", } ], } +SAMPLE_QUEUE_PIPE = { + "version": 833, + "count": 1, + "items": [ + { + "id": 12322, + "title": "librespot-java", + "artist": "some artist", + "album": "some album", + "album_artist": "The xx", + "length_ms": 0, + "track_number": 1, + "media_kind": "music", + "data_kind": "pipe", + "uri": "pipeuri", + } + ], +} + SAMPLE_CONFIG = { "websocket_port": 3688, "version": "25.0", @@ -272,7 +292,7 @@ async def get_request_return_values_fixture(): "config": SAMPLE_CONFIG, "outputs": SAMPLE_OUTPUTS_ON, "player": SAMPLE_PLAYER_PAUSED, - "queue": SAMPLE_TTS_QUEUE, + "queue": SAMPLE_QUEUE_TTS, } @@ -630,7 +650,9 @@ async def pipe_control_api_object_fixture( return pipe_control_api.return_value -async def test_librespot_java_stuff(hass, pipe_control_api_object): +async def test_librespot_java_stuff( + hass, get_request_return_values, mock_api_object, pipe_control_api_object +): """Test options update and librespot-java stuff.""" state = hass.states.get(TEST_MASTER_ENTITY_NAME) assert state.attributes[ATTR_INPUT_SOURCE] == "librespot-java (pipe)" @@ -652,6 +674,13 @@ async def test_librespot_java_stuff(hass, pipe_control_api_object): ) state = hass.states.get(TEST_MASTER_ENTITY_NAME) assert state.attributes[ATTR_INPUT_SOURCE] == SOURCE_NAME_DEFAULT + # test pipe getting queued externally changes source + get_request_return_values["queue"] = SAMPLE_QUEUE_PIPE + updater_update = mock_api_object.start_websocket_handler.call_args[0][2] + await updater_update(["queue"]) + await hass.async_block_till_done() + state = hass.states.get(TEST_MASTER_ENTITY_NAME) + assert state.attributes[ATTR_INPUT_SOURCE] == "librespot-java (pipe)" async def test_librespot_java_play_media(hass, pipe_control_api_object): From eeaef5731f7ed36608dbd22f8a9c7f0cbe1e84af Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 14 May 2020 11:58:40 -0500 Subject: [PATCH 06/49] Fix reversed logic in zeroconf homekit pairing check (#35596) * Fix reversed logic in zeroconf homekit pairing check * s/server_info/service_info/ --- homeassistant/components/zeroconf/__init__.py | 8 +++++++- tests/components/zeroconf/test_init.py | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zeroconf/__init__.py b/homeassistant/components/zeroconf/__init__.py index 8376ed09e6c..d699160eed4 100644 --- a/homeassistant/components/zeroconf/__init__.py +++ b/homeassistant/components/zeroconf/__init__.py @@ -178,6 +178,11 @@ def setup(hass, config): return service_info = zeroconf.get_service_info(service_type, name) + if not service_info: + # Prevent the browser thread from collapsing as + # service_info can be None + return + info = info_from_service(service_info) _LOGGER.debug("Discovered new device %s %s", name, info) @@ -196,7 +201,8 @@ def setup(hass, config): and HOMEKIT_PAIRED_STATUS_FLAG in info[HOMEKIT_PROPERTIES] ): try: - if not int(info[HOMEKIT_PROPERTIES][HOMEKIT_PAIRED_STATUS_FLAG]): + # 0 means paired and not discoverable by iOS clients) + if int(info[HOMEKIT_PROPERTIES][HOMEKIT_PAIRED_STATUS_FLAG]): return except ValueError: # HomeKit pairing status unknown diff --git a/tests/components/zeroconf/test_init.py b/tests/components/zeroconf/test_init.py index 9d6d08d5b27..89c9d0c2643 100644 --- a/tests/components/zeroconf/test_init.py +++ b/tests/components/zeroconf/test_init.py @@ -18,8 +18,8 @@ PROPERTIES = { NON_ASCII_KEY: None, } -HOMEKIT_STATUS_UNPAIRED = b"0" -HOMEKIT_STATUS_PAIRED = b"1" +HOMEKIT_STATUS_UNPAIRED = b"1" +HOMEKIT_STATUS_PAIRED = b"0" @pytest.fixture From 856c0e6a152813cad9ea1d3ca53f3730ad5a2607 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 14 May 2020 03:37:14 +0200 Subject: [PATCH 07/49] Updated frontend to 20200514.0 (#35598) --- homeassistant/components/frontend/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index dad273218a0..5d4f3ce03d2 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -2,7 +2,7 @@ "domain": "frontend", "name": "Home Assistant Frontend", "documentation": "https://www.home-assistant.io/integrations/frontend", - "requirements": ["home-assistant-frontend==20200513.0"], + "requirements": ["home-assistant-frontend==20200514.0"], "dependencies": [ "api", "auth", diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index d1ed0d476c4..ae80e53a171 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -12,7 +12,7 @@ cryptography==2.9.2 defusedxml==0.6.0 distro==1.5.0 hass-nabucasa==0.34.2 -home-assistant-frontend==20200513.0 +home-assistant-frontend==20200514.0 importlib-metadata==1.6.0 jinja2>=2.11.1 netdisco==2.6.0 diff --git a/requirements_all.txt b/requirements_all.txt index f7eac178f1c..02d03372d85 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -731,7 +731,7 @@ hole==0.5.1 holidays==0.10.2 # homeassistant.components.frontend -home-assistant-frontend==20200513.0 +home-assistant-frontend==20200514.0 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index db9b2e17488..80d873d243f 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -312,7 +312,7 @@ hole==0.5.1 holidays==0.10.2 # homeassistant.components.frontend -home-assistant-frontend==20200513.0 +home-assistant-frontend==20200514.0 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 From b83adad4179aabd2c4707b014ca5c505faabb22f Mon Sep 17 00:00:00 2001 From: Jason Hunter Date: Wed, 13 May 2020 22:24:38 -0400 Subject: [PATCH 08/49] Additional checks for ONVIF event capabilities (#35599) catch any exceptions when pulling event capabilities and assume it is not supported --- homeassistant/components/onvif/device.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/onvif/device.py b/homeassistant/components/onvif/device.py index 2743ed7eca4..17a0c0c27f0 100644 --- a/homeassistant/components/onvif/device.py +++ b/homeassistant/components/onvif/device.py @@ -209,17 +209,23 @@ class ONVIFDevice: """Obtain information about the available services on the device.""" media_service = self.device.create_media_service() media_capabilities = await media_service.GetServiceCapabilities() - event_service = self.device.create_events_service() - event_capabilities = await event_service.GetServiceCapabilities() + + pullpoint = False + try: + event_service = self.device.create_events_service() + event_capabilities = await event_service.GetServiceCapabilities() + pullpoint = event_capabilities.WSPullPointSupport + except (ONVIFError, Fault): + pass + ptz = False try: self.device.get_definition("ptz") ptz = True except ONVIFError: pass - return Capabilities( - media_capabilities.SnapshotUri, event_capabilities.WSPullPointSupport, ptz - ) + + return Capabilities(media_capabilities.SnapshotUri, pullpoint, ptz) async def async_get_profiles(self) -> List[Profile]: """Obtain media profiles for this device.""" From 45d3bb7da20a477d03a45e5c0acdc2c558870f06 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Thu, 14 May 2020 16:33:57 +0200 Subject: [PATCH 09/49] Fix zwave_mqtt creating the device name (#35603) * Fix for creating the device name Creating the devicename included a typo and was missing the custom (preferred) name set by the OZW Admin tool. * update comments --- homeassistant/components/zwave_mqtt/entity.py | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/zwave_mqtt/entity.py b/homeassistant/components/zwave_mqtt/entity.py index 97c48266a2d..d64beb0ba34 100644 --- a/homeassistant/components/zwave_mqtt/entity.py +++ b/homeassistant/components/zwave_mqtt/entity.py @@ -265,15 +265,21 @@ class ZWaveDeviceEntity(Entity): def create_device_name(node: OZWNode): """Generate sensible (short) default device name from a OZWNode.""" - if node.meta_data["Name"]: - dev_name = node.meta_data["Name"] - elif node.node_product_name: - dev_name = node.node_product_name - elif node.node_device_type_string: - dev_name = node.node_device_type_string - else: - dev_name = node.specific_string - return dev_name + # Prefer custom name set by OZWAdmin if present + if node.node_name: + return node.node_name + # Prefer short devicename from metadata if present + if node.meta_data and node.meta_data.get("Name"): + return node.meta_data["Name"] + # Fallback to productname or devicetype strings + if node.node_product_name: + return node.node_product_name + if node.node_device_type_string: + return node.node_device_type_string + if node.node_specific_string: + return node.node_specific_string + # Last resort: use Node id (should never happen, but just in case) + return f"Node {node.id}" def create_device_id(node: OZWNode, node_instance: int = 1): From a930175c558af1fde6e19217b92937b1e5108d2b Mon Sep 17 00:00:00 2001 From: zacpotts <59249562+zacpotts@users.noreply.github.com> Date: Thu, 14 May 2020 11:03:53 +0100 Subject: [PATCH 10/49] Fix zwave thermostat specific device type (#35609) --- homeassistant/components/zwave/discovery_schemas.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/zwave/discovery_schemas.py b/homeassistant/components/zwave/discovery_schemas.py index 5e4b83d81e1..f8674a48a32 100644 --- a/homeassistant/components/zwave/discovery_schemas.py +++ b/homeassistant/components/zwave/discovery_schemas.py @@ -56,6 +56,7 @@ DISCOVERY_SCHEMAS = [ const.DISC_SPECIFIC_DEVICE_CLASS: [ const.SPECIFIC_TYPE_THERMOSTAT_HEATING, const.SPECIFIC_TYPE_SETPOINT_THERMOSTAT, + const.SPECIFIC_TYPE_NOT_USED, ], const.DISC_VALUES: dict( DEFAULT_VALUES_SCHEMA, From b3a0270acd6a4823fa4a892a7220228192f7791b Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 14 May 2020 19:33:14 +0200 Subject: [PATCH 11/49] Add check for HTML in translations (#35615) * Add check for HTML in translations and remove existing html * Add test --- .../components/ambiclimate/strings.json | 2 +- .../components/logi_circle/strings.json | 2 +- homeassistant/components/point/strings.json | 2 +- .../components/starline/strings.json | 2 +- homeassistant/helpers/config_validation.py | 9 ++++++ script/hassfest/translations.py | 28 +++++++++---------- tests/helpers/test_config_validation.py | 20 +++++++++++++ 7 files changed, 47 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/ambiclimate/strings.json b/homeassistant/components/ambiclimate/strings.json index 50bc8284b71..26af78f8915 100644 --- a/homeassistant/components/ambiclimate/strings.json +++ b/homeassistant/components/ambiclimate/strings.json @@ -3,7 +3,7 @@ "step": { "auth": { "title": "Authenticate Ambiclimate", - "description": "Please follow this [link]({authorization_url}) and Allow access to your Ambiclimate account, then come back and press Submit below.\n(Make sure the specified callback url is {cb_url})" + "description": "Please follow this [link]({authorization_url}) and **Allow** access to your Ambiclimate account, then come back and press **Submit** below.\n(Make sure the specified callback url is {cb_url})" } }, "create_entry": { diff --git a/homeassistant/components/logi_circle/strings.json b/homeassistant/components/logi_circle/strings.json index 347589c7881..d96f0e041a1 100644 --- a/homeassistant/components/logi_circle/strings.json +++ b/homeassistant/components/logi_circle/strings.json @@ -8,7 +8,7 @@ }, "auth": { "title": "Authenticate with Logi Circle", - "description": "Please follow the link below and Accept access to your Logi Circle account, then come back and press Submit below.\n\n[Link]({authorization_url})" + "description": "Please follow the link below and **Accept** access to your Logi Circle account, then come back and press **Submit** below.\n\n[Link]({authorization_url})" } }, "create_entry": { diff --git a/homeassistant/components/point/strings.json b/homeassistant/components/point/strings.json index b42c6cef198..194121e8e25 100644 --- a/homeassistant/components/point/strings.json +++ b/homeassistant/components/point/strings.json @@ -8,7 +8,7 @@ }, "auth": { "title": "Authenticate Point", - "description": "Please follow the link below and Accept access to your Minut account, then come back and press Submit below.\n\n[Link]({authorization_url})" + "description": "Please follow the link below and **Accept** access to your Minut account, then come back and press **Submit** below.\n\n[Link]({authorization_url})" } }, "create_entry": { diff --git a/homeassistant/components/starline/strings.json b/homeassistant/components/starline/strings.json index 919efb2f024..33e28f9a29d 100644 --- a/homeassistant/components/starline/strings.json +++ b/homeassistant/components/starline/strings.json @@ -3,7 +3,7 @@ "step": { "auth_app": { "title": "Application credentials", - "description": "Application ID and secret code from StarLine developer account", + "description": "Application ID and secret code from [StarLine developer account](https://my.starline.ru/developer)", "data": { "app_id": "App ID", "app_secret": "Secret" diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 01f737b47da..32121958b03 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -465,6 +465,15 @@ def string(value: Any) -> str: return str(value) +def string_with_no_html(value: Any) -> str: + """Validate that the value is a string without HTML.""" + value = string(value) + regex = re.compile(r"<[a-z][\s\S]*>") + if regex.search(value): + raise vol.Invalid("the string should not contain HTML") + return str(value) + + def temperature_unit(value: Any) -> str: """Validate and transform temperature unit.""" value = str(value).upper() diff --git a/script/hassfest/translations.py b/script/hassfest/translations.py index 4c7fc12fbcb..416bfbdb47e 100644 --- a/script/hassfest/translations.py +++ b/script/hassfest/translations.py @@ -91,20 +91,20 @@ def gen_data_entry_schema( """Generate a data entry schema.""" step_title_class = vol.Required if require_step_title else vol.Optional schema = { - vol.Optional("flow_title"): str, + vol.Optional("flow_title"): cv.string_with_no_html, vol.Required("step"): { str: { - step_title_class("title"): str, - vol.Optional("description"): str, - vol.Optional("data"): {str: str}, + step_title_class("title"): cv.string_with_no_html, + vol.Optional("description"): cv.string_with_no_html, + vol.Optional("data"): {str: cv.string_with_no_html}, } }, - vol.Optional("error"): {str: str}, - vol.Optional("abort"): {str: str}, - vol.Optional("create_entry"): {str: str}, + vol.Optional("error"): {str: cv.string_with_no_html}, + vol.Optional("abort"): {str: cv.string_with_no_html}, + vol.Optional("create_entry"): {str: cv.string_with_no_html}, } if flow_title == REQUIRED: - schema[vol.Required("title")] = str + schema[vol.Required("title")] = cv.string_with_no_html elif flow_title == REMOVED: schema[vol.Optional("title", msg=REMOVED_TITLE_MSG)] = partial( removed_title_validator, config, integration @@ -117,7 +117,7 @@ def gen_strings_schema(config: Config, integration: Integration): """Generate a strings schema.""" return vol.Schema( { - vol.Optional("title"): str, + vol.Optional("title"): cv.string_with_no_html, vol.Optional("config"): gen_data_entry_schema( config=config, integration=integration, @@ -131,10 +131,10 @@ def gen_strings_schema(config: Config, integration: Integration): require_step_title=False, ), vol.Optional("device_automation"): { - vol.Optional("action_type"): {str: str}, - vol.Optional("condition_type"): {str: str}, - vol.Optional("trigger_type"): {str: str}, - vol.Optional("trigger_subtype"): {str: str}, + vol.Optional("action_type"): {str: cv.string_with_no_html}, + vol.Optional("condition_type"): {str: cv.string_with_no_html}, + vol.Optional("trigger_type"): {str: cv.string_with_no_html}, + vol.Optional("trigger_subtype"): {str: cv.string_with_no_html}, }, vol.Optional("state"): cv.schema_with_slug_keys( cv.schema_with_slug_keys(str, slug_validator=lowercase_validator), @@ -203,7 +203,7 @@ def gen_platform_strings_schema(config: Config, integration: Integration): ) -ONBOARDING_SCHEMA = vol.Schema({vol.Required("area"): {str: str}}) +ONBOARDING_SCHEMA = vol.Schema({vol.Required("area"): {str: cv.string_with_no_html}}) def validate_translation_file(config: Config, integration: Integration, all_strings): diff --git a/tests/helpers/test_config_validation.py b/tests/helpers/test_config_validation.py index bee463092ff..72eb61bbacb 100644 --- a/tests/helpers/test_config_validation.py +++ b/tests/helpers/test_config_validation.py @@ -351,6 +351,26 @@ def test_string(): schema(value) +def test_string_with_no_html(): + """Test string with no html validation.""" + schema = vol.Schema(cv.string_with_no_html) + + with pytest.raises(vol.Invalid): + schema("This has HTML in it Link") + + with pytest.raises(vol.Invalid): + schema("Bold") + + for value in ( + True, + 3, + "Hello", + "**Hello**", + "This has no HTML [Link](https://home-assistant.io)", + ): + schema(value) + + def test_temperature_unit(): """Test temperature unit validation.""" schema = vol.Schema(cv.temperature_unit) From fa487c7c2f8201835618062aeaac91d063d27dc5 Mon Sep 17 00:00:00 2001 From: Anders Melchiorsen Date: Thu, 14 May 2020 17:24:26 +0200 Subject: [PATCH 12/49] Upgrade to pysonos 0.0.29 (#35617) --- homeassistant/components/sonos/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sonos/manifest.json b/homeassistant/components/sonos/manifest.json index 27631cc8045..d6bc7ff71a4 100644 --- a/homeassistant/components/sonos/manifest.json +++ b/homeassistant/components/sonos/manifest.json @@ -3,7 +3,7 @@ "name": "Sonos", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/sonos", - "requirements": ["pysonos==0.0.28"], + "requirements": ["pysonos==0.0.29"], "ssdp": [ { "st": "urn:schemas-upnp-org:device:ZonePlayer:1" diff --git a/requirements_all.txt b/requirements_all.txt index 02d03372d85..d7cba1cb0b3 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1615,7 +1615,7 @@ pysnmp==4.4.12 pysoma==0.0.10 # homeassistant.components.sonos -pysonos==0.0.28 +pysonos==0.0.29 # homeassistant.components.spc pyspcwebgw==0.4.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 80d873d243f..c072e65abc1 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -681,7 +681,7 @@ pysmartthings==0.7.1 pysoma==0.0.10 # homeassistant.components.sonos -pysonos==0.0.28 +pysonos==0.0.29 # homeassistant.components.spc pyspcwebgw==0.4.0 From bc0109256fca0345b5506ab144eb5926b19ed021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Thu, 14 May 2020 18:22:49 +0300 Subject: [PATCH 13/49] Upgrade huawei-lte-api to 1.4.12 (#35618) https://github.com/Salamek/huawei-lte-api/releases/tag/1.4.12 --- homeassistant/components/huawei_lte/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/huawei_lte/manifest.json b/homeassistant/components/huawei_lte/manifest.json index e1e91c08e9a..0660aa361f5 100644 --- a/homeassistant/components/huawei_lte/manifest.json +++ b/homeassistant/components/huawei_lte/manifest.json @@ -5,7 +5,7 @@ "documentation": "https://www.home-assistant.io/integrations/huawei_lte", "requirements": [ "getmac==0.8.2", - "huawei-lte-api==1.4.11", + "huawei-lte-api==1.4.12", "stringcase==1.2.0", "url-normalize==1.4.1" ], diff --git a/requirements_all.txt b/requirements_all.txt index d7cba1cb0b3..cad3b08d570 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -750,7 +750,7 @@ horimote==0.4.1 httplib2==0.10.3 # homeassistant.components.huawei_lte -huawei-lte-api==1.4.11 +huawei-lte-api==1.4.12 # homeassistant.components.hydrawise hydrawiser==0.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index c072e65abc1..da5694c9e36 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -328,7 +328,7 @@ homematicip==0.10.17 httplib2==0.10.3 # homeassistant.components.huawei_lte -huawei-lte-api==1.4.11 +huawei-lte-api==1.4.12 # homeassistant.components.iaqualink iaqualink==0.3.1 From 05778ad307b4ba9e8d8fcab8db9817b62d918cd5 Mon Sep 17 00:00:00 2001 From: Jason Hunter Date: Thu, 14 May 2020 11:25:58 -0400 Subject: [PATCH 14/49] additional log info and strings fix (#35622) --- homeassistant/components/onvif/event.py | 9 ++++++--- homeassistant/components/onvif/strings.json | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/onvif/event.py b/homeassistant/components/onvif/event.py index 2c56d46ad39..ee7d4349dc4 100644 --- a/homeassistant/components/onvif/event.py +++ b/homeassistant/components/onvif/event.py @@ -143,19 +143,22 @@ class EventManager: async def async_parse_messages(self, messages) -> None: """Parse notification message.""" for msg in messages: - # LOGGER.debug("ONVIF Event Message %s: %s", self.device.host, pformat(msg)) topic = msg.Topic._value_1 parser = PARSERS.get(topic) if not parser: if topic not in UNHANDLED_TOPICS: - LOGGER.info("No registered handler for event: %s", msg) + LOGGER.info( + "No registered handler for event from %s: %s", + self.unique_id, + msg, + ) UNHANDLED_TOPICS.add(topic) continue event = await parser(self.unique_id, msg) if not event: - LOGGER.warning("Unable to parse event: %s", msg) + LOGGER.warning("Unable to parse event from %s: %s", self.unique_id, msg) return self._events[event.uid] = event diff --git a/homeassistant/components/onvif/strings.json b/homeassistant/components/onvif/strings.json index b80e8b57fc7..b6ae9b98d9a 100644 --- a/homeassistant/components/onvif/strings.json +++ b/homeassistant/components/onvif/strings.json @@ -23,6 +23,7 @@ }, "manual_input": { "data": { + "name": "Name", "host": "[%key:common::config_flow::data::host%]", "port": "[%key:common::config_flow::data::port%]" }, @@ -55,4 +56,4 @@ } } } -} \ No newline at end of file +} From 618ce2ff0a2031926c83811f83ab1ad764184c9c Mon Sep 17 00:00:00 2001 From: Alexei Chetroi Date: Thu, 14 May 2020 13:50:54 -0400 Subject: [PATCH 15/49] Don't remove deprecated ZHA config option yet (#35627) --- homeassistant/components/zha/__init__.py | 2 ++ tests/components/zha/test_init.py | 25 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/homeassistant/components/zha/__init__.py b/homeassistant/components/zha/__init__.py index 4f844613336..8a23c6fc20d 100644 --- a/homeassistant/components/zha/__init__.py +++ b/homeassistant/components/zha/__init__.py @@ -44,6 +44,8 @@ ZHA_CONFIG_SCHEMA = { ), vol.Optional(CONF_ENABLE_QUIRKS, default=True): cv.boolean, vol.Optional(CONF_ZIGPY): dict, + vol.Optional(CONF_RADIO_TYPE): cv.enum(RadioType), + vol.Optional(CONF_USB_PATH): cv.string, } CONFIG_SCHEMA = vol.Schema( { diff --git a/tests/components/zha/test_init.py b/tests/components/zha/test_init.py index 963cea33bdd..f0b82231fa9 100644 --- a/tests/components/zha/test_init.py +++ b/tests/components/zha/test_init.py @@ -9,6 +9,7 @@ from homeassistant.components.zha.core.const import ( CONF_USB_PATH, DOMAIN, ) +from homeassistant.const import MAJOR_VERSION, MINOR_VERSION from homeassistant.setup import async_setup_component from tests.async_mock import AsyncMock, patch @@ -70,3 +71,27 @@ async def test_migration_from_v1_wrong_baudrate(hass, config_entry_v1): assert CONF_USB_PATH not in config_entry_v1.data assert CONF_BAUDRATE not in config_entry_v1.data[CONF_DEVICE] assert config_entry_v1.version == 2 + + +@pytest.mark.skipif( + MAJOR_VERSION != 0 or (MAJOR_VERSION == 0 and MINOR_VERSION >= 112), + reason="Not applicaable for this version", +) +@pytest.mark.parametrize( + "zha_config", + ( + {}, + {CONF_USB_PATH: "str"}, + {CONF_RADIO_TYPE: "ezsp"}, + {CONF_RADIO_TYPE: "ezsp", CONF_USB_PATH: "str"}, + ), +) +async def test_config_depreciation(hass, zha_config): + """Test config option depreciation.""" + await async_setup_component(hass, "persistent_notification", {}) + + with patch( + "homeassistant.components.zha.async_setup", return_value=True + ) as setup_mock: + assert await async_setup_component(hass, DOMAIN, {DOMAIN: zha_config}) + assert setup_mock.call_count == 1 From bcf068f66f9cf468c715e49773ca39defa06e70a Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 14 May 2020 22:56:04 +0200 Subject: [PATCH 16/49] Rename zwave_mqtt to ozw (#35631) --- .coveragerc | 8 ++++---- CODEOWNERS | 2 +- .../components/{zwave_mqtt => ozw}/__init__.py | 12 ++++++------ .../{zwave_mqtt => ozw}/binary_sensor.py | 0 .../{zwave_mqtt => ozw}/config_flow.py | 6 +++--- .../components/{zwave_mqtt => ozw}/const.py | 4 ++-- .../components/{zwave_mqtt => ozw}/discovery.py | 0 .../components/{zwave_mqtt => ozw}/entity.py | 0 .../components/{zwave_mqtt => ozw}/light.py | 0 homeassistant/components/ozw/manifest.json | 9 +++++++++ .../components/{zwave_mqtt => ozw}/sensor.py | 0 .../components/{zwave_mqtt => ozw}/services.py | 0 .../{zwave_mqtt => ozw}/services.yaml | 0 .../components/{zwave_mqtt => ozw}/strings.json | 1 - .../components/{zwave_mqtt => ozw}/switch.py | 0 .../{zwave_mqtt => ozw}/translations/ca.json | 0 .../{zwave_mqtt => ozw}/translations/de.json | 0 .../{zwave_mqtt => ozw}/translations/en.json | 0 .../{zwave_mqtt => ozw}/translations/es.json | 0 .../{zwave_mqtt => ozw}/translations/fi.json | 0 .../{zwave_mqtt => ozw}/translations/fr.json | 0 .../{zwave_mqtt => ozw}/translations/it.json | 0 .../{zwave_mqtt => ozw}/translations/ko.json | 0 .../{zwave_mqtt => ozw}/translations/lb.json | 0 .../{zwave_mqtt => ozw}/translations/nl.json | 0 .../{zwave_mqtt => ozw}/translations/no.json | 0 .../{zwave_mqtt => ozw}/translations/pl.json | 0 .../{zwave_mqtt => ozw}/translations/ru.json | 0 .../{zwave_mqtt => ozw}/translations/sl.json | 0 .../{zwave_mqtt => ozw}/translations/sv.json | 0 .../translations/zh-Hans.json | 0 .../translations/zh-Hant.json | 0 .../components/zwave_mqtt/manifest.json | 17 ----------------- homeassistant/generated/config_flows.py | 4 ++-- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/ozw/__init__.py | 1 + tests/components/{zwave_mqtt => ozw}/common.py | 8 ++++---- .../components/{zwave_mqtt => ozw}/conftest.py | 16 +++++++--------- .../{zwave_mqtt => ozw}/test_binary_sensor.py | 8 ++++---- .../{zwave_mqtt => ozw}/test_config_flow.py | 8 ++++---- .../components/{zwave_mqtt => ozw}/test_init.py | 12 ++++++------ .../{zwave_mqtt => ozw}/test_light.py | 6 +++--- .../{zwave_mqtt => ozw}/test_scenes.py | 6 +++--- .../{zwave_mqtt => ozw}/test_sensor.py | 8 ++++---- .../{zwave_mqtt => ozw}/test_switch.py | 4 ++-- tests/components/zwave_mqtt/__init__.py | 1 - .../{zwave_mqtt => ozw}/binary_sensor.json | 0 .../{zwave_mqtt => ozw}/binary_sensor_alt.json | 0 .../generic_network_dump.csv | 0 tests/fixtures/{zwave_mqtt => ozw}/light.json | 0 .../{zwave_mqtt => ozw}/light_network_dump.csv | 0 tests/fixtures/{zwave_mqtt => ozw}/sensor.json | 0 tests/fixtures/{zwave_mqtt => ozw}/switch.json | 0 54 files changed, 67 insertions(+), 78 deletions(-) rename homeassistant/components/{zwave_mqtt => ozw}/__init__.py (97%) rename homeassistant/components/{zwave_mqtt => ozw}/binary_sensor.py (100%) rename homeassistant/components/{zwave_mqtt => ozw}/config_flow.py (86%) rename homeassistant/components/{zwave_mqtt => ozw}/const.py (94%) rename homeassistant/components/{zwave_mqtt => ozw}/discovery.py (100%) rename homeassistant/components/{zwave_mqtt => ozw}/entity.py (100%) rename homeassistant/components/{zwave_mqtt => ozw}/light.py (100%) create mode 100644 homeassistant/components/ozw/manifest.json rename homeassistant/components/{zwave_mqtt => ozw}/sensor.py (100%) rename homeassistant/components/{zwave_mqtt => ozw}/services.py (100%) rename homeassistant/components/{zwave_mqtt => ozw}/services.yaml (100%) rename homeassistant/components/{zwave_mqtt => ozw}/strings.json (89%) rename homeassistant/components/{zwave_mqtt => ozw}/switch.py (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/ca.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/de.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/en.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/es.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/fi.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/fr.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/it.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/ko.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/lb.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/nl.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/no.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/pl.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/ru.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/sl.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/sv.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/zh-Hans.json (100%) rename homeassistant/components/{zwave_mqtt => ozw}/translations/zh-Hant.json (100%) delete mode 100644 homeassistant/components/zwave_mqtt/manifest.json create mode 100644 tests/components/ozw/__init__.py rename tests/components/{zwave_mqtt => ozw}/common.py (87%) rename tests/components/{zwave_mqtt => ozw}/conftest.py (80%) rename tests/components/{zwave_mqtt => ozw}/test_binary_sensor.py (89%) rename tests/components/{zwave_mqtt => ozw}/test_config_flow.py (85%) rename tests/components/{zwave_mqtt => ozw}/test_init.py (84%) rename tests/components/{zwave_mqtt => ozw}/test_light.py (96%) rename tests/components/{zwave_mqtt => ozw}/test_scenes.py (93%) rename tests/components/{zwave_mqtt => ozw}/test_sensor.py (92%) rename tests/components/{zwave_mqtt => ozw}/test_switch.py (92%) delete mode 100644 tests/components/zwave_mqtt/__init__.py rename tests/fixtures/{zwave_mqtt => ozw}/binary_sensor.json (100%) rename tests/fixtures/{zwave_mqtt => ozw}/binary_sensor_alt.json (100%) rename tests/fixtures/{zwave_mqtt => ozw}/generic_network_dump.csv (100%) rename tests/fixtures/{zwave_mqtt => ozw}/light.json (100%) rename tests/fixtures/{zwave_mqtt => ozw}/light_network_dump.csv (100%) rename tests/fixtures/{zwave_mqtt => ozw}/sensor.json (100%) rename tests/fixtures/{zwave_mqtt => ozw}/switch.json (100%) diff --git a/.coveragerc b/.coveragerc index fb4e88903b4..b468e3ef746 100644 --- a/.coveragerc +++ b/.coveragerc @@ -920,10 +920,10 @@ omit = homeassistant/components/zoneminder/* homeassistant/components/supla/* homeassistant/components/zwave/util.py - homeassistant/components/zwave_mqtt/__init__.py - homeassistant/components/zwave_mqtt/discovery.py - homeassistant/components/zwave_mqtt/entity.py - homeassistant/components/zwave_mqtt/services.py + homeassistant/components/ozw/__init__.py + homeassistant/components/ozw/discovery.py + homeassistant/components/ozw/entity.py + homeassistant/components/ozw/services.py [report] # Regexes for lines to exclude from consideration diff --git a/CODEOWNERS b/CODEOWNERS index 07c99d48b86..fd224174c90 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -293,6 +293,7 @@ homeassistant/components/openweathermap/* @fabaff homeassistant/components/opnsense/* @mtreinish homeassistant/components/orangepi_gpio/* @pascallj homeassistant/components/oru/* @bvlaicu +homeassistant/components/ozw/* @cgarwood @marcelveldt @MartinHjelmare homeassistant/components/panasonic_viera/* @joogps homeassistant/components/panel_custom/* @home-assistant/frontend homeassistant/components/panel_iframe/* @home-assistant/frontend @@ -475,7 +476,6 @@ homeassistant/components/zha/* @dmulcahey @adminiuga homeassistant/components/zone/* @home-assistant/core homeassistant/components/zoneminder/* @rohankapoorcom homeassistant/components/zwave/* @home-assistant/z-wave -homeassistant/components/zwave_mqtt/* @cgarwood @marcelveldt @MartinHjelmare # Individual files homeassistant/components/demo/weather @fabaff diff --git a/homeassistant/components/zwave_mqtt/__init__.py b/homeassistant/components/ozw/__init__.py similarity index 97% rename from homeassistant/components/zwave_mqtt/__init__.py rename to homeassistant/components/ozw/__init__.py index c391f79a542..3a7d35ddd1d 100644 --- a/homeassistant/components/zwave_mqtt/__init__.py +++ b/homeassistant/components/ozw/__init__.py @@ -1,4 +1,4 @@ -"""The zwave_mqtt integration.""" +"""The ozw integration.""" import asyncio import json import logging @@ -43,7 +43,7 @@ DATA_DEVICES = "zwave-mqtt-devices" async def async_setup(hass: HomeAssistant, config: dict): - """Initialize basic config of zwave_mqtt component.""" + """Initialize basic config of ozw component.""" if "mqtt" not in hass.config.components: _LOGGER.error("MQTT integration is not set up") return False @@ -52,9 +52,9 @@ async def async_setup(hass: HomeAssistant, config: dict): async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): - """Set up zwave_mqtt from a config entry.""" - zwave_mqtt_data = hass.data[DOMAIN][entry.entry_id] = {} - zwave_mqtt_data[DATA_UNSUBSCRIBE] = [] + """Set up ozw from a config entry.""" + ozw_data = hass.data[DOMAIN][entry.entry_id] = {} + ozw_data[DATA_UNSUBSCRIBE] = [] data_nodes = {} data_values = {} @@ -216,7 +216,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): for component in PLATFORMS ] ) - zwave_mqtt_data[DATA_UNSUBSCRIBE].append( + ozw_data[DATA_UNSUBSCRIBE].append( await mqtt.async_subscribe( hass, f"{TOPIC_OPENZWAVE}/#", async_receive_message ) diff --git a/homeassistant/components/zwave_mqtt/binary_sensor.py b/homeassistant/components/ozw/binary_sensor.py similarity index 100% rename from homeassistant/components/zwave_mqtt/binary_sensor.py rename to homeassistant/components/ozw/binary_sensor.py diff --git a/homeassistant/components/zwave_mqtt/config_flow.py b/homeassistant/components/ozw/config_flow.py similarity index 86% rename from homeassistant/components/zwave_mqtt/config_flow.py rename to homeassistant/components/ozw/config_flow.py index ff6ab21994f..8822490132c 100644 --- a/homeassistant/components/zwave_mqtt/config_flow.py +++ b/homeassistant/components/ozw/config_flow.py @@ -1,13 +1,13 @@ -"""Config flow for zwave_mqtt integration.""" +"""Config flow for ozw integration.""" from homeassistant import config_entries from .const import DOMAIN # pylint:disable=unused-import -TITLE = "Z-Wave MQTT" +TITLE = "OpenZWave" class DomainConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): - """Handle a config flow for zwave_mqtt.""" + """Handle a config flow for ozw.""" VERSION = 1 CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_PUSH diff --git a/homeassistant/components/zwave_mqtt/const.py b/homeassistant/components/ozw/const.py similarity index 94% rename from homeassistant/components/zwave_mqtt/const.py rename to homeassistant/components/ozw/const.py index 5b1f6dcbac7..59f189d124d 100644 --- a/homeassistant/components/zwave_mqtt/const.py +++ b/homeassistant/components/ozw/const.py @@ -1,10 +1,10 @@ -"""Constants for the zwave_mqtt integration.""" +"""Constants for the ozw integration.""" from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN -DOMAIN = "zwave_mqtt" +DOMAIN = "ozw" DATA_UNSUBSCRIBE = "unsubscribe" PLATFORMS = [BINARY_SENSOR_DOMAIN, LIGHT_DOMAIN, SENSOR_DOMAIN, SWITCH_DOMAIN] diff --git a/homeassistant/components/zwave_mqtt/discovery.py b/homeassistant/components/ozw/discovery.py similarity index 100% rename from homeassistant/components/zwave_mqtt/discovery.py rename to homeassistant/components/ozw/discovery.py diff --git a/homeassistant/components/zwave_mqtt/entity.py b/homeassistant/components/ozw/entity.py similarity index 100% rename from homeassistant/components/zwave_mqtt/entity.py rename to homeassistant/components/ozw/entity.py diff --git a/homeassistant/components/zwave_mqtt/light.py b/homeassistant/components/ozw/light.py similarity index 100% rename from homeassistant/components/zwave_mqtt/light.py rename to homeassistant/components/ozw/light.py diff --git a/homeassistant/components/ozw/manifest.json b/homeassistant/components/ozw/manifest.json new file mode 100644 index 00000000000..3b828845852 --- /dev/null +++ b/homeassistant/components/ozw/manifest.json @@ -0,0 +1,9 @@ +{ + "domain": "ozw", + "name": "OpenZWave (beta)", + "config_flow": true, + "documentation": "https://www.home-assistant.io/integrations/ozw", + "requirements": ["python-openzwave-mqtt==1.0.1"], + "after_dependencies": ["mqtt"], + "codeowners": ["@cgarwood", "@marcelveldt", "@MartinHjelmare"] +} diff --git a/homeassistant/components/zwave_mqtt/sensor.py b/homeassistant/components/ozw/sensor.py similarity index 100% rename from homeassistant/components/zwave_mqtt/sensor.py rename to homeassistant/components/ozw/sensor.py diff --git a/homeassistant/components/zwave_mqtt/services.py b/homeassistant/components/ozw/services.py similarity index 100% rename from homeassistant/components/zwave_mqtt/services.py rename to homeassistant/components/ozw/services.py diff --git a/homeassistant/components/zwave_mqtt/services.yaml b/homeassistant/components/ozw/services.yaml similarity index 100% rename from homeassistant/components/zwave_mqtt/services.yaml rename to homeassistant/components/ozw/services.yaml diff --git a/homeassistant/components/zwave_mqtt/strings.json b/homeassistant/components/ozw/strings.json similarity index 89% rename from homeassistant/components/zwave_mqtt/strings.json rename to homeassistant/components/ozw/strings.json index 949b545086b..dd2aad7e4ce 100644 --- a/homeassistant/components/zwave_mqtt/strings.json +++ b/homeassistant/components/ozw/strings.json @@ -1,5 +1,4 @@ { - "title": "Z-Wave over MQTT", "config": { "step": { "user": { diff --git a/homeassistant/components/zwave_mqtt/switch.py b/homeassistant/components/ozw/switch.py similarity index 100% rename from homeassistant/components/zwave_mqtt/switch.py rename to homeassistant/components/ozw/switch.py diff --git a/homeassistant/components/zwave_mqtt/translations/ca.json b/homeassistant/components/ozw/translations/ca.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/ca.json rename to homeassistant/components/ozw/translations/ca.json diff --git a/homeassistant/components/zwave_mqtt/translations/de.json b/homeassistant/components/ozw/translations/de.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/de.json rename to homeassistant/components/ozw/translations/de.json diff --git a/homeassistant/components/zwave_mqtt/translations/en.json b/homeassistant/components/ozw/translations/en.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/en.json rename to homeassistant/components/ozw/translations/en.json diff --git a/homeassistant/components/zwave_mqtt/translations/es.json b/homeassistant/components/ozw/translations/es.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/es.json rename to homeassistant/components/ozw/translations/es.json diff --git a/homeassistant/components/zwave_mqtt/translations/fi.json b/homeassistant/components/ozw/translations/fi.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/fi.json rename to homeassistant/components/ozw/translations/fi.json diff --git a/homeassistant/components/zwave_mqtt/translations/fr.json b/homeassistant/components/ozw/translations/fr.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/fr.json rename to homeassistant/components/ozw/translations/fr.json diff --git a/homeassistant/components/zwave_mqtt/translations/it.json b/homeassistant/components/ozw/translations/it.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/it.json rename to homeassistant/components/ozw/translations/it.json diff --git a/homeassistant/components/zwave_mqtt/translations/ko.json b/homeassistant/components/ozw/translations/ko.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/ko.json rename to homeassistant/components/ozw/translations/ko.json diff --git a/homeassistant/components/zwave_mqtt/translations/lb.json b/homeassistant/components/ozw/translations/lb.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/lb.json rename to homeassistant/components/ozw/translations/lb.json diff --git a/homeassistant/components/zwave_mqtt/translations/nl.json b/homeassistant/components/ozw/translations/nl.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/nl.json rename to homeassistant/components/ozw/translations/nl.json diff --git a/homeassistant/components/zwave_mqtt/translations/no.json b/homeassistant/components/ozw/translations/no.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/no.json rename to homeassistant/components/ozw/translations/no.json diff --git a/homeassistant/components/zwave_mqtt/translations/pl.json b/homeassistant/components/ozw/translations/pl.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/pl.json rename to homeassistant/components/ozw/translations/pl.json diff --git a/homeassistant/components/zwave_mqtt/translations/ru.json b/homeassistant/components/ozw/translations/ru.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/ru.json rename to homeassistant/components/ozw/translations/ru.json diff --git a/homeassistant/components/zwave_mqtt/translations/sl.json b/homeassistant/components/ozw/translations/sl.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/sl.json rename to homeassistant/components/ozw/translations/sl.json diff --git a/homeassistant/components/zwave_mqtt/translations/sv.json b/homeassistant/components/ozw/translations/sv.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/sv.json rename to homeassistant/components/ozw/translations/sv.json diff --git a/homeassistant/components/zwave_mqtt/translations/zh-Hans.json b/homeassistant/components/ozw/translations/zh-Hans.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/zh-Hans.json rename to homeassistant/components/ozw/translations/zh-Hans.json diff --git a/homeassistant/components/zwave_mqtt/translations/zh-Hant.json b/homeassistant/components/ozw/translations/zh-Hant.json similarity index 100% rename from homeassistant/components/zwave_mqtt/translations/zh-Hant.json rename to homeassistant/components/ozw/translations/zh-Hant.json diff --git a/homeassistant/components/zwave_mqtt/manifest.json b/homeassistant/components/zwave_mqtt/manifest.json deleted file mode 100644 index 8d067bf5c35..00000000000 --- a/homeassistant/components/zwave_mqtt/manifest.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "domain": "zwave_mqtt", - "name": "Z-Wave over MQTT", - "config_flow": true, - "documentation": "https://www.home-assistant.io/integrations/zwave_mqtt", - "requirements": [ - "python-openzwave-mqtt==1.0.1" - ], - "after_dependencies": [ - "mqtt" - ], - "codeowners": [ - "@cgarwood", - "@marcelveldt", - "@MartinHjelmare" - ] -} diff --git a/homeassistant/generated/config_flows.py b/homeassistant/generated/config_flows.py index 52700a17e2b..43ccb4ef6d1 100644 --- a/homeassistant/generated/config_flows.py +++ b/homeassistant/generated/config_flows.py @@ -106,6 +106,7 @@ FLOWS = [ "opentherm_gw", "openuv", "owntracks", + "ozw", "panasonic_viera", "pi_hole", "plaato", @@ -164,6 +165,5 @@ FLOWS = [ "xiaomi_miio", "zerproc", "zha", - "zwave", - "zwave_mqtt" + "zwave" ] diff --git a/requirements_all.txt b/requirements_all.txt index cad3b08d570..7833476440e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1710,7 +1710,7 @@ python-nest==4.1.0 # homeassistant.components.nmap_tracker python-nmap==0.6.1 -# homeassistant.components.zwave_mqtt +# homeassistant.components.ozw python-openzwave-mqtt==1.0.1 # homeassistant.components.qbittorrent diff --git a/requirements_test_all.txt b/requirements_test_all.txt index da5694c9e36..5b7c5561fd2 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -704,7 +704,7 @@ python-miio==0.5.0.1 # homeassistant.components.nest python-nest==4.1.0 -# homeassistant.components.zwave_mqtt +# homeassistant.components.ozw python-openzwave-mqtt==1.0.1 # homeassistant.components.songpal diff --git a/tests/components/ozw/__init__.py b/tests/components/ozw/__init__.py new file mode 100644 index 00000000000..ce419b9f55b --- /dev/null +++ b/tests/components/ozw/__init__.py @@ -0,0 +1 @@ +"""Tests for the OZW integration.""" diff --git a/tests/components/zwave_mqtt/common.py b/tests/components/ozw/common.py similarity index 87% rename from tests/components/zwave_mqtt/common.py rename to tests/components/ozw/common.py index ef85d2e5533..a71103fdf85 100644 --- a/tests/components/zwave_mqtt/common.py +++ b/tests/components/ozw/common.py @@ -2,14 +2,14 @@ import json from homeassistant import config_entries -from homeassistant.components.zwave_mqtt.const import DOMAIN +from homeassistant.components.ozw.const import DOMAIN from tests.async_mock import Mock, patch from tests.common import MockConfigEntry -async def setup_zwave(hass, entry=None, fixture=None): - """Set up Z-Wave and load a dump.""" +async def setup_ozw(hass, entry=None, fixture=None): + """Set up OZW and load a dump.""" hass.config.components.add("mqtt") if entry is None: @@ -26,7 +26,7 @@ async def setup_zwave(hass, entry=None, fixture=None): assert await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() - assert "zwave_mqtt" in hass.config.components + assert "ozw" in hass.config.components assert len(mock_subscribe.mock_calls) == 1 receive_message = mock_subscribe.mock_calls[0][1][2] diff --git a/tests/components/zwave_mqtt/conftest.py b/tests/components/ozw/conftest.py similarity index 80% rename from tests/components/zwave_mqtt/conftest.py rename to tests/components/ozw/conftest.py index 2297cee3e4e..b984172d355 100644 --- a/tests/components/zwave_mqtt/conftest.py +++ b/tests/components/ozw/conftest.py @@ -12,13 +12,13 @@ from tests.common import load_fixture @pytest.fixture(name="generic_data", scope="session") def generic_data_fixture(): """Load generic MQTT data and return it.""" - return load_fixture(f"zwave_mqtt/generic_network_dump.csv") + return load_fixture("ozw/generic_network_dump.csv") @pytest.fixture(name="light_data", scope="session") def light_data_fixture(): """Load light dimmer MQTT data and return it.""" - return load_fixture(f"zwave_mqtt/light_network_dump.csv") + return load_fixture("ozw/light_network_dump.csv") @pytest.fixture(name="sent_messages") @@ -39,7 +39,7 @@ def sent_messages_fixture(): async def light_msg_fixture(hass): """Return a mock MQTT msg with a light actuator message.""" light_json = json.loads( - await hass.async_add_executor_job(load_fixture, "zwave_mqtt/light.json") + await hass.async_add_executor_job(load_fixture, "ozw/light.json") ) message = MQTTMessage(topic=light_json["topic"], payload=light_json["payload"]) message.encode() @@ -50,7 +50,7 @@ async def light_msg_fixture(hass): async def switch_msg_fixture(hass): """Return a mock MQTT msg with a switch actuator message.""" switch_json = json.loads( - await hass.async_add_executor_job(load_fixture, "zwave_mqtt/switch.json") + await hass.async_add_executor_job(load_fixture, "ozw/switch.json") ) message = MQTTMessage(topic=switch_json["topic"], payload=switch_json["payload"]) message.encode() @@ -61,7 +61,7 @@ async def switch_msg_fixture(hass): async def sensor_msg_fixture(hass): """Return a mock MQTT msg with a sensor change message.""" sensor_json = json.loads( - await hass.async_add_executor_job(load_fixture, "zwave_mqtt/sensor.json") + await hass.async_add_executor_job(load_fixture, "ozw/sensor.json") ) message = MQTTMessage(topic=sensor_json["topic"], payload=sensor_json["payload"]) message.encode() @@ -72,7 +72,7 @@ async def sensor_msg_fixture(hass): async def binary_sensor_msg_fixture(hass): """Return a mock MQTT msg with a binary_sensor change message.""" sensor_json = json.loads( - await hass.async_add_executor_job(load_fixture, "zwave_mqtt/binary_sensor.json") + await hass.async_add_executor_job(load_fixture, "ozw/binary_sensor.json") ) message = MQTTMessage(topic=sensor_json["topic"], payload=sensor_json["payload"]) message.encode() @@ -83,9 +83,7 @@ async def binary_sensor_msg_fixture(hass): async def binary_sensor_alt_msg_fixture(hass): """Return a mock MQTT msg with a binary_sensor change message.""" sensor_json = json.loads( - await hass.async_add_executor_job( - load_fixture, "zwave_mqtt/binary_sensor_alt.json" - ) + await hass.async_add_executor_job(load_fixture, "ozw/binary_sensor_alt.json") ) message = MQTTMessage(topic=sensor_json["topic"], payload=sensor_json["payload"]) message.encode() diff --git a/tests/components/zwave_mqtt/test_binary_sensor.py b/tests/components/ozw/test_binary_sensor.py similarity index 89% rename from tests/components/zwave_mqtt/test_binary_sensor.py rename to tests/components/ozw/test_binary_sensor.py index 9e4fddbef75..62b23be0cca 100644 --- a/tests/components/zwave_mqtt/test_binary_sensor.py +++ b/tests/components/ozw/test_binary_sensor.py @@ -3,15 +3,15 @@ from homeassistant.components.binary_sensor import ( DEVICE_CLASS_MOTION, DOMAIN as BINARY_SENSOR_DOMAIN, ) -from homeassistant.components.zwave_mqtt.const import DOMAIN +from homeassistant.components.ozw.const import DOMAIN from homeassistant.const import ATTR_DEVICE_CLASS -from .common import setup_zwave +from .common import setup_ozw async def test_binary_sensor(hass, generic_data, binary_sensor_msg): """Test setting up config entry.""" - receive_msg = await setup_zwave(hass, fixture=generic_data) + receive_msg = await setup_ozw(hass, fixture=generic_data) # Test Legacy sensor (disabled by default) registry = await hass.helpers.entity_registry.async_get_registry() @@ -57,7 +57,7 @@ async def test_sensor_enabled(hass, generic_data, binary_sensor_alt_msg): ) assert entry.disabled is False - receive_msg = await setup_zwave(hass, fixture=generic_data) + receive_msg = await setup_ozw(hass, fixture=generic_data) receive_msg(binary_sensor_alt_msg) await hass.async_block_till_done() diff --git a/tests/components/zwave_mqtt/test_config_flow.py b/tests/components/ozw/test_config_flow.py similarity index 85% rename from tests/components/zwave_mqtt/test_config_flow.py rename to tests/components/ozw/test_config_flow.py index fbdf4012009..bfe3f922402 100644 --- a/tests/components/zwave_mqtt/test_config_flow.py +++ b/tests/components/ozw/test_config_flow.py @@ -1,7 +1,7 @@ """Test the Z-Wave over MQTT config flow.""" from homeassistant import config_entries, setup -from homeassistant.components.zwave_mqtt.config_flow import TITLE -from homeassistant.components.zwave_mqtt.const import DOMAIN +from homeassistant.components.ozw.config_flow import TITLE +from homeassistant.components.ozw.const import DOMAIN from tests.async_mock import patch from tests.common import MockConfigEntry @@ -18,9 +18,9 @@ async def test_user_create_entry(hass): assert result["errors"] is None with patch( - "homeassistant.components.zwave_mqtt.async_setup", return_value=True + "homeassistant.components.ozw.async_setup", return_value=True ) as mock_setup, patch( - "homeassistant.components.zwave_mqtt.async_setup_entry", return_value=True, + "homeassistant.components.ozw.async_setup_entry", return_value=True, ) as mock_setup_entry: result2 = await hass.config_entries.flow.async_configure(result["flow_id"], {}) diff --git a/tests/components/zwave_mqtt/test_init.py b/tests/components/ozw/test_init.py similarity index 84% rename from tests/components/zwave_mqtt/test_init.py rename to tests/components/ozw/test_init.py index 0b77905ab9b..9a76b4906fa 100644 --- a/tests/components/zwave_mqtt/test_init.py +++ b/tests/components/ozw/test_init.py @@ -1,18 +1,18 @@ """Test integration initialization.""" from homeassistant import config_entries -from homeassistant.components.zwave_mqtt import DOMAIN, PLATFORMS, const +from homeassistant.components.ozw import DOMAIN, PLATFORMS, const -from .common import setup_zwave +from .common import setup_ozw from tests.common import MockConfigEntry async def test_init_entry(hass, generic_data): """Test setting up config entry.""" - await setup_zwave(hass, fixture=generic_data) + await setup_ozw(hass, fixture=generic_data) # Verify integration + platform loaded. - assert "zwave_mqtt" in hass.config.components + assert "ozw" in hass.config.components for platform in PLATFORMS: assert platform in hass.config.components, platform assert f"{platform}.{DOMAIN}" in hass.config.components, f"{platform}.{DOMAIN}" @@ -32,7 +32,7 @@ async def test_unload_entry(hass, generic_data, switch_msg, caplog): entry.add_to_hass(hass) assert entry.state == config_entries.ENTRY_STATE_NOT_LOADED - receive_message = await setup_zwave(hass, entry=entry, fixture=generic_data) + receive_message = await setup_ozw(hass, entry=entry, fixture=generic_data) assert entry.state == config_entries.ENTRY_STATE_LOADED assert len(hass.states.async_entity_ids("switch")) == 1 @@ -53,7 +53,7 @@ async def test_unload_entry(hass, generic_data, switch_msg, caplog): # adding the entities. # This asserts that we have unsubscribed the entity addition signals # when unloading the integration previously. - await setup_zwave(hass, entry=entry, fixture=generic_data) + await setup_ozw(hass, entry=entry, fixture=generic_data) await hass.async_block_till_done() assert entry.state == config_entries.ENTRY_STATE_LOADED diff --git a/tests/components/zwave_mqtt/test_light.py b/tests/components/ozw/test_light.py similarity index 96% rename from tests/components/zwave_mqtt/test_light.py rename to tests/components/ozw/test_light.py index 33230cd36d9..d485ca768c5 100644 --- a/tests/components/zwave_mqtt/test_light.py +++ b/tests/components/ozw/test_light.py @@ -1,12 +1,12 @@ """Test Z-Wave Lights.""" -from homeassistant.components.zwave_mqtt.light import byte_to_zwave_brightness +from homeassistant.components.ozw.light import byte_to_zwave_brightness -from .common import setup_zwave +from .common import setup_ozw async def test_light(hass, light_data, light_msg, sent_messages): """Test setting up config entry.""" - receive_message = await setup_zwave(hass, fixture=light_data) + receive_message = await setup_ozw(hass, fixture=light_data) # Test loaded state = hass.states.get("light.led_bulb_6_multi_colour_level") diff --git a/tests/components/zwave_mqtt/test_scenes.py b/tests/components/ozw/test_scenes.py similarity index 93% rename from tests/components/zwave_mqtt/test_scenes.py rename to tests/components/ozw/test_scenes.py index 10e1f94b229..2d776b7faf4 100644 --- a/tests/components/zwave_mqtt/test_scenes.py +++ b/tests/components/ozw/test_scenes.py @@ -1,5 +1,5 @@ """Test Z-Wave (central) Scenes.""" -from .common import MQTTMessage, setup_zwave +from .common import MQTTMessage, setup_ozw from tests.common import async_capture_events @@ -7,8 +7,8 @@ from tests.common import async_capture_events async def test_scenes(hass, generic_data, sent_messages): """Test setting up config entry.""" - receive_message = await setup_zwave(hass, fixture=generic_data) - events = async_capture_events(hass, "zwave_mqtt.scene_activated") + receive_message = await setup_ozw(hass, fixture=generic_data) + events = async_capture_events(hass, "ozw.scene_activated") # Publish fake scene event on mqtt message = MQTTMessage( diff --git a/tests/components/zwave_mqtt/test_sensor.py b/tests/components/ozw/test_sensor.py similarity index 92% rename from tests/components/zwave_mqtt/test_sensor.py rename to tests/components/ozw/test_sensor.py index ab7fd26b0b6..4cc0077cdea 100644 --- a/tests/components/zwave_mqtt/test_sensor.py +++ b/tests/components/ozw/test_sensor.py @@ -1,19 +1,19 @@ """Test Z-Wave Sensors.""" +from homeassistant.components.ozw.const import DOMAIN from homeassistant.components.sensor import ( DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_POWER, DEVICE_CLASS_PRESSURE, DOMAIN as SENSOR_DOMAIN, ) -from homeassistant.components.zwave_mqtt.const import DOMAIN from homeassistant.const import ATTR_DEVICE_CLASS -from .common import setup_zwave +from .common import setup_ozw async def test_sensor(hass, generic_data): """Test setting up config entry.""" - await setup_zwave(hass, fixture=generic_data) + await setup_ozw(hass, fixture=generic_data) # Test standard sensor state = hass.states.get("sensor.smart_plug_electric_v") @@ -66,7 +66,7 @@ async def test_sensor_enabled(hass, generic_data, sensor_msg): ) assert entry.disabled is False - receive_msg = await setup_zwave(hass, fixture=generic_data) + receive_msg = await setup_ozw(hass, fixture=generic_data) receive_msg(sensor_msg) await hass.async_block_till_done() diff --git a/tests/components/zwave_mqtt/test_switch.py b/tests/components/ozw/test_switch.py similarity index 92% rename from tests/components/zwave_mqtt/test_switch.py rename to tests/components/ozw/test_switch.py index 84929dabe0a..7af331b3e0f 100644 --- a/tests/components/zwave_mqtt/test_switch.py +++ b/tests/components/ozw/test_switch.py @@ -1,10 +1,10 @@ """Test Z-Wave Switches.""" -from .common import setup_zwave +from .common import setup_ozw async def test_switch(hass, generic_data, sent_messages, switch_msg): """Test setting up config entry.""" - receive_message = await setup_zwave(hass, fixture=generic_data) + receive_message = await setup_ozw(hass, fixture=generic_data) # Test loaded state = hass.states.get("switch.smart_plug_switch") diff --git a/tests/components/zwave_mqtt/__init__.py b/tests/components/zwave_mqtt/__init__.py deleted file mode 100644 index 95d36355b29..00000000000 --- a/tests/components/zwave_mqtt/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for the Z-Wave MQTT integration.""" diff --git a/tests/fixtures/zwave_mqtt/binary_sensor.json b/tests/fixtures/ozw/binary_sensor.json similarity index 100% rename from tests/fixtures/zwave_mqtt/binary_sensor.json rename to tests/fixtures/ozw/binary_sensor.json diff --git a/tests/fixtures/zwave_mqtt/binary_sensor_alt.json b/tests/fixtures/ozw/binary_sensor_alt.json similarity index 100% rename from tests/fixtures/zwave_mqtt/binary_sensor_alt.json rename to tests/fixtures/ozw/binary_sensor_alt.json diff --git a/tests/fixtures/zwave_mqtt/generic_network_dump.csv b/tests/fixtures/ozw/generic_network_dump.csv similarity index 100% rename from tests/fixtures/zwave_mqtt/generic_network_dump.csv rename to tests/fixtures/ozw/generic_network_dump.csv diff --git a/tests/fixtures/zwave_mqtt/light.json b/tests/fixtures/ozw/light.json similarity index 100% rename from tests/fixtures/zwave_mqtt/light.json rename to tests/fixtures/ozw/light.json diff --git a/tests/fixtures/zwave_mqtt/light_network_dump.csv b/tests/fixtures/ozw/light_network_dump.csv similarity index 100% rename from tests/fixtures/zwave_mqtt/light_network_dump.csv rename to tests/fixtures/ozw/light_network_dump.csv diff --git a/tests/fixtures/zwave_mqtt/sensor.json b/tests/fixtures/ozw/sensor.json similarity index 100% rename from tests/fixtures/zwave_mqtt/sensor.json rename to tests/fixtures/ozw/sensor.json diff --git a/tests/fixtures/zwave_mqtt/switch.json b/tests/fixtures/ozw/switch.json similarity index 100% rename from tests/fixtures/zwave_mqtt/switch.json rename to tests/fixtures/ozw/switch.json From d66856dd178d7ab175b6432e332f0aacddf5e2b6 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 14 May 2020 23:48:43 +0200 Subject: [PATCH 17/49] Update translations for OZW and ONVIF --- homeassistant/components/onvif/translations/ca.json | 1 + homeassistant/components/onvif/translations/en.json | 1 + homeassistant/components/onvif/translations/es.json | 1 + homeassistant/components/onvif/translations/ko.json | 1 + homeassistant/components/onvif/translations/no.json | 1 + homeassistant/components/onvif/translations/pl.json | 10 +++++----- homeassistant/components/onvif/translations/ru.json | 1 + homeassistant/components/ozw/translations/ca.json | 3 +-- homeassistant/components/ozw/translations/de.json | 3 +-- homeassistant/components/ozw/translations/en.json | 3 +-- homeassistant/components/ozw/translations/es.json | 3 +-- homeassistant/components/ozw/translations/fr.json | 3 +-- homeassistant/components/ozw/translations/it.json | 3 +-- homeassistant/components/ozw/translations/ko.json | 3 +-- homeassistant/components/ozw/translations/lb.json | 3 +-- homeassistant/components/ozw/translations/no.json | 3 +-- homeassistant/components/ozw/translations/pl.json | 3 +-- homeassistant/components/ozw/translations/ru.json | 3 +-- homeassistant/components/ozw/translations/sl.json | 3 +-- homeassistant/components/ozw/translations/sv.json | 3 +-- homeassistant/components/ozw/translations/zh-Hant.json | 3 +-- 21 files changed, 25 insertions(+), 33 deletions(-) diff --git a/homeassistant/components/onvif/translations/ca.json b/homeassistant/components/onvif/translations/ca.json index 9d942f091d4..a0362abbb8f 100644 --- a/homeassistant/components/onvif/translations/ca.json +++ b/homeassistant/components/onvif/translations/ca.json @@ -34,6 +34,7 @@ "manual_input": { "data": { "host": "Amfitri\u00f3", + "name": "Nom", "port": "Port" }, "title": "Configura el dispositiu ONVIF" diff --git a/homeassistant/components/onvif/translations/en.json b/homeassistant/components/onvif/translations/en.json index 91828648cc0..a20b1fcb7e4 100644 --- a/homeassistant/components/onvif/translations/en.json +++ b/homeassistant/components/onvif/translations/en.json @@ -34,6 +34,7 @@ "manual_input": { "data": { "host": "Host", + "name": "Name", "port": "Port" }, "title": "Configure ONVIF device" diff --git a/homeassistant/components/onvif/translations/es.json b/homeassistant/components/onvif/translations/es.json index cf556f792bf..dd65094838d 100644 --- a/homeassistant/components/onvif/translations/es.json +++ b/homeassistant/components/onvif/translations/es.json @@ -34,6 +34,7 @@ "manual_input": { "data": { "host": "Host", + "name": "Nombre", "port": "Puerto" }, "title": "Configurar el dispositivo ONVIF" diff --git a/homeassistant/components/onvif/translations/ko.json b/homeassistant/components/onvif/translations/ko.json index 18428773bdc..9715d89f72b 100644 --- a/homeassistant/components/onvif/translations/ko.json +++ b/homeassistant/components/onvif/translations/ko.json @@ -34,6 +34,7 @@ "manual_input": { "data": { "host": "\ud638\uc2a4\ud2b8", + "name": "\uc774\ub984", "port": "\ud3ec\ud2b8" }, "title": "ONVIF \uae30\uae30 \uad6c\uc131\ud558\uae30" diff --git a/homeassistant/components/onvif/translations/no.json b/homeassistant/components/onvif/translations/no.json index 1dc8a8b4aff..5f55b264117 100644 --- a/homeassistant/components/onvif/translations/no.json +++ b/homeassistant/components/onvif/translations/no.json @@ -34,6 +34,7 @@ "manual_input": { "data": { "host": "Vert", + "name": "Navn", "port": "Port" }, "title": "Konfigurere ONVIF-enhet" diff --git a/homeassistant/components/onvif/translations/pl.json b/homeassistant/components/onvif/translations/pl.json index 213051969d8..afd4df73b66 100644 --- a/homeassistant/components/onvif/translations/pl.json +++ b/homeassistant/components/onvif/translations/pl.json @@ -1,7 +1,7 @@ { "config": { "abort": { - "already_configured": "[%key_id:common::config_flow::abort::already_configured_device%]", + "already_configured": "Urz\u0105dzenie jest ju\u017c skonfigurowane.", "already_in_progress": "Proces konfiguracji dla urz\u0105dzenia ONVIF jest ju\u017c w toku.", "no_h264": "Nie by\u0142o dost\u0119pnych \u017cadnych strumieni H264. Sprawd\u017a konfiguracj\u0119 profilu w swoim urz\u0105dzeniu.", "no_mac": "Nie mo\u017cna utworzy\u0107 unikalnego identyfikatora urz\u0105dzenia ONVIF.", @@ -13,8 +13,8 @@ "step": { "auth": { "data": { - "password": "[%key_id:common::config_flow::data::password%]", - "username": "[%key_id:common::config_flow::data::username%]" + "password": "Has\u0142o", + "username": "Nazwa u\u017cytkownika" }, "title": "Konfigurowanie uwierzytelniania" }, @@ -33,8 +33,8 @@ }, "manual_input": { "data": { - "host": "[%key_id:common::config_flow::data::host%]", - "port": "[%key_id:common::config_flow::data::port%]" + "host": "Nazwa hosta lub adres IP", + "port": "Port" }, "title": "Konfigurowanie urz\u0105dzenia ONVIF" }, diff --git a/homeassistant/components/onvif/translations/ru.json b/homeassistant/components/onvif/translations/ru.json index 20b709a4a01..84ff1775080 100644 --- a/homeassistant/components/onvif/translations/ru.json +++ b/homeassistant/components/onvif/translations/ru.json @@ -34,6 +34,7 @@ "manual_input": { "data": { "host": "\u0425\u043e\u0441\u0442", + "name": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435", "port": "\u041f\u043e\u0440\u0442" }, "title": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 ONVIF" diff --git a/homeassistant/components/ozw/translations/ca.json b/homeassistant/components/ozw/translations/ca.json index a2a4919a9c3..eba9a7e8757 100644 --- a/homeassistant/components/ozw/translations/ca.json +++ b/homeassistant/components/ozw/translations/ca.json @@ -9,6 +9,5 @@ "title": "Confirmaci\u00f3 de configuraci\u00f3" } } - }, - "title": "Z-Wave sobre MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/de.json b/homeassistant/components/ozw/translations/de.json index 5957bd57813..79393cbf865 100644 --- a/homeassistant/components/ozw/translations/de.json +++ b/homeassistant/components/ozw/translations/de.json @@ -9,6 +9,5 @@ "title": "Einrichtung best\u00e4tigen" } } - }, - "title": "Z-Wave \u00fcber MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/en.json b/homeassistant/components/ozw/translations/en.json index 4b5b44a76bb..c6a45474880 100644 --- a/homeassistant/components/ozw/translations/en.json +++ b/homeassistant/components/ozw/translations/en.json @@ -9,6 +9,5 @@ "title": "Confirm set up" } } - }, - "title": "Z-Wave over MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/es.json b/homeassistant/components/ozw/translations/es.json index eec405ed4b5..f78b62828cb 100644 --- a/homeassistant/components/ozw/translations/es.json +++ b/homeassistant/components/ozw/translations/es.json @@ -9,6 +9,5 @@ "title": "Confirmar configuraci\u00f3n" } } - }, - "title": "Z-Wave sobre MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/fr.json b/homeassistant/components/ozw/translations/fr.json index 40403973da3..dbc609b93eb 100644 --- a/homeassistant/components/ozw/translations/fr.json +++ b/homeassistant/components/ozw/translations/fr.json @@ -9,6 +9,5 @@ "title": "Confirmer la configuration" } } - }, - "title": "Z-Wave sur MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/it.json b/homeassistant/components/ozw/translations/it.json index b13b5322c8b..0b76d09cf08 100644 --- a/homeassistant/components/ozw/translations/it.json +++ b/homeassistant/components/ozw/translations/it.json @@ -9,6 +9,5 @@ "title": "Confermare la configurazione" } } - }, - "title": "Z-Wave su MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/ko.json b/homeassistant/components/ozw/translations/ko.json index 5a6346d1dd3..2412e162c3c 100644 --- a/homeassistant/components/ozw/translations/ko.json +++ b/homeassistant/components/ozw/translations/ko.json @@ -9,6 +9,5 @@ "title": "\uc124\uc815 \ub0b4\uc6a9 \ud655\uc778\ud558\uae30" } } - }, - "title": "MQTT \ub97c \ud1b5\ud55c Z-Wave" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/lb.json b/homeassistant/components/ozw/translations/lb.json index 8e579b2e399..053fe631133 100644 --- a/homeassistant/components/ozw/translations/lb.json +++ b/homeassistant/components/ozw/translations/lb.json @@ -9,6 +9,5 @@ "title": "Installatioun konfirm\u00e9ieren" } } - }, - "title": "Z-Wave iwwer MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/no.json b/homeassistant/components/ozw/translations/no.json index a89707a3ef2..1d4049978f5 100644 --- a/homeassistant/components/ozw/translations/no.json +++ b/homeassistant/components/ozw/translations/no.json @@ -9,6 +9,5 @@ "title": "Bekreft oppsett" } } - }, - "title": "" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/pl.json b/homeassistant/components/ozw/translations/pl.json index 866f7d38df6..3d57c3908a0 100644 --- a/homeassistant/components/ozw/translations/pl.json +++ b/homeassistant/components/ozw/translations/pl.json @@ -9,6 +9,5 @@ "title": "Potwierd\u017a konfiguracj\u0119" } } - }, - "title": "Z-Wave poprzez MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/ru.json b/homeassistant/components/ozw/translations/ru.json index 00d86616d46..ac968e9fdfa 100644 --- a/homeassistant/components/ozw/translations/ru.json +++ b/homeassistant/components/ozw/translations/ru.json @@ -9,6 +9,5 @@ "title": "\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438" } } - }, - "title": "Z-Wave \u0447\u0435\u0440\u0435\u0437 MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/sl.json b/homeassistant/components/ozw/translations/sl.json index 39a1ce54f7c..43c78f930f2 100644 --- a/homeassistant/components/ozw/translations/sl.json +++ b/homeassistant/components/ozw/translations/sl.json @@ -9,6 +9,5 @@ "title": "Potrdite nastavitev" } } - }, - "title": "Z-Wave \u010dez MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/sv.json b/homeassistant/components/ozw/translations/sv.json index 9a9f3e24a78..68b50437725 100644 --- a/homeassistant/components/ozw/translations/sv.json +++ b/homeassistant/components/ozw/translations/sv.json @@ -5,6 +5,5 @@ "title": "Bekr\u00e4fta inst\u00e4llningen" } } - }, - "title": "Z-Wave \u00f6ver MQTT" + } } \ No newline at end of file diff --git a/homeassistant/components/ozw/translations/zh-Hant.json b/homeassistant/components/ozw/translations/zh-Hant.json index 62b05764083..e9ad87042d2 100644 --- a/homeassistant/components/ozw/translations/zh-Hant.json +++ b/homeassistant/components/ozw/translations/zh-Hant.json @@ -9,6 +9,5 @@ "title": "\u78ba\u8a8d\u8a2d\u5b9a" } } - }, - "title": "Z-Wave over MQTT" + } } \ No newline at end of file From 20188a36de166c2868d28c8f34fb6de4b10c7a2e Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 14 May 2020 23:49:29 +0200 Subject: [PATCH 18/49] Bumped version to 0.110.0b1 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 4815638c614..e31233b7110 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 110 -PATCH_VERSION = "0b0" +PATCH_VERSION = "0b1" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 0) From 592ecd479f5a89383308337695b8c06aad38c9cf Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 14 May 2020 21:31:35 +0200 Subject: [PATCH 19/49] Updated frontend to 20200514.1 (#35632) --- homeassistant/components/frontend/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index 5d4f3ce03d2..6a1af47a9cf 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -2,7 +2,7 @@ "domain": "frontend", "name": "Home Assistant Frontend", "documentation": "https://www.home-assistant.io/integrations/frontend", - "requirements": ["home-assistant-frontend==20200514.0"], + "requirements": ["home-assistant-frontend==20200514.1"], "dependencies": [ "api", "auth", diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index ae80e53a171..b763b479fe8 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -12,7 +12,7 @@ cryptography==2.9.2 defusedxml==0.6.0 distro==1.5.0 hass-nabucasa==0.34.2 -home-assistant-frontend==20200514.0 +home-assistant-frontend==20200514.1 importlib-metadata==1.6.0 jinja2>=2.11.1 netdisco==2.6.0 diff --git a/requirements_all.txt b/requirements_all.txt index 7833476440e..39bf0eac82b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -731,7 +731,7 @@ hole==0.5.1 holidays==0.10.2 # homeassistant.components.frontend -home-assistant-frontend==20200514.0 +home-assistant-frontend==20200514.1 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 5b7c5561fd2..ef8aa7bd8e1 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -312,7 +312,7 @@ hole==0.5.1 holidays==0.10.2 # homeassistant.components.frontend -home-assistant-frontend==20200514.0 +home-assistant-frontend==20200514.1 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 From 3928fe957808bae9dc67b2c389d6ec8095e54fed Mon Sep 17 00:00:00 2001 From: Quentame Date: Fri, 15 May 2020 05:20:53 +0200 Subject: [PATCH 20/49] Bump python-synology to 0.8.1 (#35640) * Bump python-synology to 0.8.1 * Fix tests --- homeassistant/components/synology_dsm/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/synology_dsm/test_config_flow.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/synology_dsm/manifest.json b/homeassistant/components/synology_dsm/manifest.json index f57f1843f45..fcf91bb25b3 100644 --- a/homeassistant/components/synology_dsm/manifest.json +++ b/homeassistant/components/synology_dsm/manifest.json @@ -2,7 +2,7 @@ "domain": "synology_dsm", "name": "Synology DSM", "documentation": "https://www.home-assistant.io/integrations/synology_dsm", - "requirements": ["python-synology==0.8.0"], + "requirements": ["python-synology==0.8.1"], "codeowners": ["@ProtoThis", "@Quentame"], "config_flow": true, "ssdp": [ diff --git a/requirements_all.txt b/requirements_all.txt index 39bf0eac82b..9704227df98 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1726,7 +1726,7 @@ python-sochain-api==0.0.2 python-songpal==0.12 # homeassistant.components.synology_dsm -python-synology==0.8.0 +python-synology==0.8.1 # homeassistant.components.tado python-tado==0.8.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index ef8aa7bd8e1..d6827b2a259 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -711,7 +711,7 @@ python-openzwave-mqtt==1.0.1 python-songpal==0.12 # homeassistant.components.synology_dsm -python-synology==0.8.0 +python-synology==0.8.1 # homeassistant.components.tado python-tado==0.8.1 diff --git a/tests/components/synology_dsm/test_config_flow.py b/tests/components/synology_dsm/test_config_flow.py index 15a1655fbc1..f592ad90a88 100644 --- a/tests/components/synology_dsm/test_config_flow.py +++ b/tests/components/synology_dsm/test_config_flow.py @@ -309,7 +309,7 @@ async def test_connection_failed(hass: HomeAssistantType, service: MagicMock): async def test_unknown_failed(hass: HomeAssistantType, service: MagicMock): """Test when we have an unknown error.""" - service.return_value.login = Mock(side_effect=SynologyDSMException) + service.return_value.login = Mock(side_effect=SynologyDSMException(None, None)) result = await hass.config_entries.flow.async_init( DOMAIN, From 5496a8ca0527f57f1525d42deb3273515e903ed2 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 15 May 2020 09:12:26 +0200 Subject: [PATCH 21/49] Bumped version to 0.110.0b2 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index e31233b7110..39337804faf 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 110 -PATCH_VERSION = "0b1" +PATCH_VERSION = "0b2" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 0) From e8ee3c7d4d10935689e2490c50b924ddf4e5fd51 Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Sat, 16 May 2020 03:48:36 -0500 Subject: [PATCH 22/49] Prevent discovery of IPP printers lacking identifier (#35630) --- homeassistant/components/ipp/config_flow.py | 1 + homeassistant/components/ipp/strings.json | 3 +- tests/components/ipp/__init__.py | 98 ++++++++++++++---- tests/components/ipp/test_config_flow.py | 86 ++++++--------- tests/components/ipp/test_init.py | 6 +- tests/components/ipp/test_sensor.py | 4 +- .../get-printer-attributes-success-nodata.bin | Bin 0 -> 72 bytes 7 files changed, 117 insertions(+), 81 deletions(-) create mode 100644 tests/fixtures/ipp/get-printer-attributes-success-nodata.bin diff --git a/homeassistant/components/ipp/config_flow.py b/homeassistant/components/ipp/config_flow.py index 7d1c3d1b1b8..3128583f218 100644 --- a/homeassistant/components/ipp/config_flow.py +++ b/homeassistant/components/ipp/config_flow.py @@ -152,6 +152,7 @@ class IPPFlowHandler(ConfigFlow, domain=DOMAIN): _LOGGER.debug( "Unable to determine unique id from discovery info and IPP response" ) + return self.async_abort(reason="unique_id_required") await self.async_set_unique_id(unique_id) self._abort_if_unique_id_configured( diff --git a/homeassistant/components/ipp/strings.json b/homeassistant/components/ipp/strings.json index 999c868f080..09c2424151f 100644 --- a/homeassistant/components/ipp/strings.json +++ b/homeassistant/components/ipp/strings.json @@ -28,7 +28,8 @@ "connection_upgrade": "Failed to connect to printer due to connection upgrade being required.", "ipp_error": "Encountered IPP error.", "ipp_version_error": "IPP version not supported by printer.", - "parse_error": "Failed to parse response from printer." + "parse_error": "Failed to parse response from printer.", + "unique_id_required": "Device missing unique identification required for discovery." } } } diff --git a/tests/components/ipp/__init__.py b/tests/components/ipp/__init__.py index f0dc45417e1..515543f3cf5 100644 --- a/tests/components/ipp/__init__.py +++ b/tests/components/ipp/__init__.py @@ -1,6 +1,9 @@ """Tests for the IPP integration.""" import os +import aiohttp +from pyipp import IPPConnectionUpgradeRequired, IPPError + from homeassistant.components.ipp.const import CONF_BASE_PATH, CONF_UUID, DOMAIN from homeassistant.const import ( CONF_HOST, @@ -18,21 +21,25 @@ from tests.test_util.aiohttp import AiohttpClientMocker ATTR_HOSTNAME = "hostname" ATTR_PROPERTIES = "properties" +HOST = "192.168.1.31" +PORT = 631 +BASE_PATH = "/ipp/print" + IPP_ZEROCONF_SERVICE_TYPE = "_ipp._tcp.local." IPPS_ZEROCONF_SERVICE_TYPE = "_ipps._tcp.local." ZEROCONF_NAME = "EPSON XP-6000 Series" -ZEROCONF_HOST = "192.168.1.31" +ZEROCONF_HOST = HOST ZEROCONF_HOSTNAME = "EPSON123456.local." -ZEROCONF_PORT = 631 - +ZEROCONF_PORT = PORT +ZEROCONF_RP = "ipp/print" MOCK_USER_INPUT = { - CONF_HOST: "192.168.1.31", - CONF_PORT: 361, + CONF_HOST: HOST, + CONF_PORT: PORT, CONF_SSL: False, CONF_VERIFY_SSL: False, - CONF_BASE_PATH: "/ipp/print", + CONF_BASE_PATH: BASE_PATH, } MOCK_ZEROCONF_IPP_SERVICE_INFO = { @@ -41,7 +48,7 @@ MOCK_ZEROCONF_IPP_SERVICE_INFO = { CONF_HOST: ZEROCONF_HOST, ATTR_HOSTNAME: ZEROCONF_HOSTNAME, CONF_PORT: ZEROCONF_PORT, - ATTR_PROPERTIES: {"rp": "ipp/print"}, + ATTR_PROPERTIES: {"rp": ZEROCONF_RP}, } MOCK_ZEROCONF_IPPS_SERVICE_INFO = { @@ -50,7 +57,7 @@ MOCK_ZEROCONF_IPPS_SERVICE_INFO = { CONF_HOST: ZEROCONF_HOST, ATTR_HOSTNAME: ZEROCONF_HOSTNAME, CONF_PORT: ZEROCONF_PORT, - ATTR_PROPERTIES: {"rp": "ipp/print"}, + ATTR_PROPERTIES: {"rp": ZEROCONF_RP}, } @@ -61,30 +68,75 @@ def load_fixture_binary(filename): return fptr.read() +def mock_connection( + aioclient_mock: AiohttpClientMocker, + host: str = HOST, + port: int = PORT, + ssl: bool = False, + base_path: str = BASE_PATH, + conn_error: bool = False, + conn_upgrade_error: bool = False, + ipp_error: bool = False, + no_unique_id: bool = False, + parse_error: bool = False, + version_not_supported: bool = False, +): + """Mock the IPP connection.""" + scheme = "https" if ssl else "http" + ipp_url = f"{scheme}://{host}:{port}" + + if ipp_error: + aioclient_mock.post(f"{ipp_url}{base_path}", exc=IPPError) + return + + if conn_error: + aioclient_mock.post(f"{ipp_url}{base_path}", exc=aiohttp.ClientError) + return + + if conn_upgrade_error: + aioclient_mock.post(f"{ipp_url}{base_path}", exc=IPPConnectionUpgradeRequired) + return + + fixture = "ipp/get-printer-attributes.bin" + if no_unique_id: + fixture = "ipp/get-printer-attributes-success-nodata.bin" + elif version_not_supported: + fixture = "ipp/get-printer-attributes-error-0x0503.bin" + + if parse_error: + content = "BAD" + else: + content = load_fixture_binary(fixture) + + aioclient_mock.post( + f"{ipp_url}{base_path}", + content=content, + headers={"Content-Type": "application/ipp"}, + ) + + async def init_integration( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, skip_setup: bool = False, + host: str = HOST, + port: int = PORT, + ssl: bool = False, + base_path: str = BASE_PATH, uuid: str = "cfe92100-67c4-11d4-a45f-f8d027761251", unique_id: str = "cfe92100-67c4-11d4-a45f-f8d027761251", + conn_error: bool = False, ) -> MockConfigEntry: """Set up the IPP integration in Home Assistant.""" - fixture = "ipp/get-printer-attributes.bin" - aioclient_mock.post( - "http://192.168.1.31:631/ipp/print", - content=load_fixture_binary(fixture), - headers={"Content-Type": "application/ipp"}, - ) - entry = MockConfigEntry( domain=DOMAIN, unique_id=unique_id, data={ - CONF_HOST: "192.168.1.31", - CONF_PORT: 631, - CONF_SSL: False, + CONF_HOST: host, + CONF_PORT: port, + CONF_SSL: ssl, CONF_VERIFY_SSL: True, - CONF_BASE_PATH: "/ipp/print", + CONF_BASE_PATH: base_path, CONF_UUID: uuid, }, ) @@ -92,6 +144,14 @@ async def init_integration( entry.add_to_hass(hass) if not skip_setup: + mock_connection( + aioclient_mock, + host=host, + port=port, + ssl=ssl, + base_path=base_path, + conn_error=conn_error, + ) await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() diff --git a/tests/components/ipp/test_config_flow.py b/tests/components/ipp/test_config_flow.py index fb75ba9caef..0093ba57e5b 100644 --- a/tests/components/ipp/test_config_flow.py +++ b/tests/components/ipp/test_config_flow.py @@ -1,7 +1,4 @@ """Tests for the IPP config flow.""" -import aiohttp -from pyipp import IPPConnectionUpgradeRequired, IPPError - from homeassistant.components.ipp.const import CONF_BASE_PATH, CONF_UUID, DOMAIN from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF from homeassistant.const import CONF_HOST, CONF_NAME, CONF_SSL @@ -17,7 +14,7 @@ from . import ( MOCK_ZEROCONF_IPP_SERVICE_INFO, MOCK_ZEROCONF_IPPS_SERVICE_INFO, init_integration, - load_fixture_binary, + mock_connection, ) from tests.test_util.aiohttp import AiohttpClientMocker @@ -37,11 +34,7 @@ async def test_show_zeroconf_form( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test that the zeroconf confirmation form is served.""" - aioclient_mock.post( - "http://192.168.1.31:631/ipp/print", - content=load_fixture_binary("ipp/get-printer-attributes.bin"), - headers={"Content-Type": "application/ipp"}, - ) + mock_connection(aioclient_mock) discovery_info = MOCK_ZEROCONF_IPP_SERVICE_INFO.copy() result = await hass.config_entries.flow.async_init( @@ -57,7 +50,7 @@ async def test_connection_error( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we show user form on IPP connection error.""" - aioclient_mock.post("http://192.168.1.31:631/ipp/print", exc=aiohttp.ClientError) + mock_connection(aioclient_mock, conn_error=True) user_input = MOCK_USER_INPUT.copy() result = await hass.config_entries.flow.async_init( @@ -73,7 +66,7 @@ async def test_zeroconf_connection_error( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort zeroconf flow on IPP connection error.""" - aioclient_mock.post("http://192.168.1.31:631/ipp/print", exc=aiohttp.ClientError) + mock_connection(aioclient_mock, conn_error=True) discovery_info = MOCK_ZEROCONF_IPP_SERVICE_INFO.copy() result = await hass.config_entries.flow.async_init( @@ -88,7 +81,7 @@ async def test_zeroconf_confirm_connection_error( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort zeroconf flow on IPP connection error.""" - aioclient_mock.post("http://192.168.1.31:631/ipp/print", exc=aiohttp.ClientError) + mock_connection(aioclient_mock, conn_error=True) discovery_info = MOCK_ZEROCONF_IPP_SERVICE_INFO.copy() result = await hass.config_entries.flow.async_init( @@ -103,9 +96,7 @@ async def test_user_connection_upgrade_required( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we show the user form if connection upgrade required by server.""" - aioclient_mock.post( - "http://192.168.1.31:631/ipp/print", exc=IPPConnectionUpgradeRequired - ) + mock_connection(aioclient_mock, conn_upgrade_error=True) user_input = MOCK_USER_INPUT.copy() result = await hass.config_entries.flow.async_init( @@ -121,9 +112,7 @@ async def test_zeroconf_connection_upgrade_required( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort zeroconf flow on IPP connection error.""" - aioclient_mock.post( - "http://192.168.1.31:631/ipp/print", exc=IPPConnectionUpgradeRequired - ) + mock_connection(aioclient_mock, conn_upgrade_error=True) discovery_info = MOCK_ZEROCONF_IPP_SERVICE_INFO.copy() result = await hass.config_entries.flow.async_init( @@ -138,11 +127,7 @@ async def test_user_parse_error( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort user flow on IPP parse error.""" - aioclient_mock.post( - "http://192.168.1.31:631/ipp/print", - content="BAD", - headers={"Content-Type": "application/ipp"}, - ) + mock_connection(aioclient_mock, parse_error=True) user_input = MOCK_USER_INPUT.copy() result = await hass.config_entries.flow.async_init( @@ -157,11 +142,7 @@ async def test_zeroconf_parse_error( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort zeroconf flow on IPP parse error.""" - aioclient_mock.post( - "http://192.168.1.31:631/ipp/print", - content="BAD", - headers={"Content-Type": "application/ipp"}, - ) + mock_connection(aioclient_mock, parse_error=True) discovery_info = MOCK_ZEROCONF_IPP_SERVICE_INFO.copy() result = await hass.config_entries.flow.async_init( @@ -176,7 +157,7 @@ async def test_user_ipp_error( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort the user flow on IPP error.""" - aioclient_mock.post("http://192.168.1.31:631/ipp/print", exc=IPPError) + mock_connection(aioclient_mock, ipp_error=True) user_input = MOCK_USER_INPUT.copy() result = await hass.config_entries.flow.async_init( @@ -191,7 +172,7 @@ async def test_zeroconf_ipp_error( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort zeroconf flow on IPP error.""" - aioclient_mock.post("http://192.168.1.31:631/ipp/print", exc=IPPError) + mock_connection(aioclient_mock, ipp_error=True) discovery_info = MOCK_ZEROCONF_IPP_SERVICE_INFO.copy() result = await hass.config_entries.flow.async_init( @@ -206,11 +187,7 @@ async def test_user_ipp_version_error( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort user flow on IPP version not supported error.""" - aioclient_mock.post( - "http://192.168.1.31:631/ipp/print", - content=load_fixture_binary("ipp/get-printer-attributes-error-0x0503.bin"), - headers={"Content-Type": "application/ipp"}, - ) + mock_connection(aioclient_mock, version_not_supported=True) user_input = {**MOCK_USER_INPUT} result = await hass.config_entries.flow.async_init( @@ -225,11 +202,7 @@ async def test_zeroconf_ipp_version_error( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort zeroconf flow on IPP version not supported error.""" - aioclient_mock.post( - "http://192.168.1.31:631/ipp/print", - content=load_fixture_binary("ipp/get-printer-attributes-error-0x0503.bin"), - headers={"Content-Type": "application/ipp"}, - ) + mock_connection(aioclient_mock, version_not_supported=True) discovery_info = {**MOCK_ZEROCONF_IPP_SERVICE_INFO} result = await hass.config_entries.flow.async_init( @@ -291,15 +264,26 @@ async def test_zeroconf_with_uuid_device_exists_abort( assert result["reason"] == "already_configured" +async def test_zeroconf_unique_id_required_abort( + hass: HomeAssistant, aioclient_mock: AiohttpClientMocker +) -> None: + """Test we abort zeroconf flow if printer lacks unique identification.""" + mock_connection(aioclient_mock, no_unique_id=True) + + discovery_info = MOCK_ZEROCONF_IPP_SERVICE_INFO.copy() + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_ZEROCONF}, data=discovery_info, + ) + + assert result["type"] == RESULT_TYPE_ABORT + assert result["reason"] == "unique_id_required" + + async def test_full_user_flow_implementation( hass: HomeAssistant, aioclient_mock ) -> None: """Test the full manual user flow from start to finish.""" - aioclient_mock.post( - "http://192.168.1.31:631/ipp/print", - content=load_fixture_binary("ipp/get-printer-attributes.bin"), - headers={"Content-Type": "application/ipp"}, - ) + mock_connection(aioclient_mock) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, @@ -328,11 +312,7 @@ async def test_full_zeroconf_flow_implementation( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test the full manual user flow from start to finish.""" - aioclient_mock.post( - "http://192.168.1.31:631/ipp/print", - content=load_fixture_binary("ipp/get-printer-attributes.bin"), - headers={"Content-Type": "application/ipp"}, - ) + mock_connection(aioclient_mock) discovery_info = MOCK_ZEROCONF_IPP_SERVICE_INFO.copy() result = await hass.config_entries.flow.async_init( @@ -363,11 +343,7 @@ async def test_full_zeroconf_tls_flow_implementation( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test the full manual user flow from start to finish.""" - aioclient_mock.post( - "https://192.168.1.31:631/ipp/print", - content=load_fixture_binary("ipp/get-printer-attributes.bin"), - headers={"Content-Type": "application/ipp"}, - ) + mock_connection(aioclient_mock, ssl=True) discovery_info = MOCK_ZEROCONF_IPPS_SERVICE_INFO.copy() result = await hass.config_entries.flow.async_init( diff --git a/tests/components/ipp/test_init.py b/tests/components/ipp/test_init.py index 2ec11a1e937..f06be4fc8b5 100644 --- a/tests/components/ipp/test_init.py +++ b/tests/components/ipp/test_init.py @@ -1,6 +1,4 @@ """Tests for the IPP integration.""" -import aiohttp - from homeassistant.components.ipp.const import DOMAIN from homeassistant.config_entries import ( ENTRY_STATE_LOADED, @@ -17,9 +15,7 @@ async def test_config_entry_not_ready( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test the IPP configuration entry not ready.""" - aioclient_mock.post("http://192.168.1.31:631/ipp/print", exc=aiohttp.ClientError) - - entry = await init_integration(hass, aioclient_mock) + entry = await init_integration(hass, aioclient_mock, conn_error=True) assert entry.state == ENTRY_STATE_SETUP_RETRY diff --git a/tests/components/ipp/test_sensor.py b/tests/components/ipp/test_sensor.py index 51caadfceb3..1abf557c93b 100644 --- a/tests/components/ipp/test_sensor.py +++ b/tests/components/ipp/test_sensor.py @@ -8,7 +8,7 @@ from homeassistant.core import HomeAssistant from homeassistant.util import dt as dt_util from tests.async_mock import patch -from tests.components.ipp import init_integration +from tests.components.ipp import init_integration, mock_connection from tests.test_util.aiohttp import AiohttpClientMocker @@ -16,6 +16,8 @@ async def test_sensors( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test the creation and values of the IPP sensors.""" + mock_connection(aioclient_mock) + entry = await init_integration(hass, aioclient_mock, skip_setup=True) registry = await hass.helpers.entity_registry.async_get_registry() diff --git a/tests/fixtures/ipp/get-printer-attributes-success-nodata.bin b/tests/fixtures/ipp/get-printer-attributes-success-nodata.bin new file mode 100644 index 0000000000000000000000000000000000000000..e6061adaccdef6f4705bba31c5166ee7b9cefe5f GIT binary patch literal 72 zcmZQ#00PFkS&Z%sLWw0MMVU#ZC8@=_$r*`7#i=C>tfeJsx)vS`(nxZ7i6x~)i8;DC QiFxUziRq~fOsRRy0Q|TXqyPW_ literal 0 HcmV?d00001 From 2f999dd77e4bf6c3a39823ddb46d0431478ba607 Mon Sep 17 00:00:00 2001 From: Glenn Waters Date: Sat, 16 May 2020 04:43:40 -0400 Subject: [PATCH 23/49] Update Universal Powerline Bus event name (#35644) --- homeassistant/components/upb/__init__.py | 4 ++-- homeassistant/components/upb/const.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/upb/__init__.py b/homeassistant/components/upb/__init__.py index b84bab054a2..f2765ff317d 100644 --- a/homeassistant/components/upb/__init__.py +++ b/homeassistant/components/upb/__init__.py @@ -14,7 +14,7 @@ from .const import ( ATTR_COMMAND, ATTR_RATE, DOMAIN, - EVENT_UPB_LINK_CHANGED, + EVENT_UPB_SCENE_CHANGED, ) UPB_PLATFORMS = ["light", "scene"] @@ -49,7 +49,7 @@ async def async_setup_entry(hass, config_entry): return hass.bus.async_fire( - EVENT_UPB_LINK_CHANGED, + EVENT_UPB_SCENE_CHANGED, { ATTR_COMMAND: change["command"], ATTR_ADDRESS: element.addr.index, diff --git a/homeassistant/components/upb/const.py b/homeassistant/components/upb/const.py index f01af0fd39f..75d754087e4 100644 --- a/homeassistant/components/upb/const.py +++ b/homeassistant/components/upb/const.py @@ -13,7 +13,7 @@ ATTR_BRIGHTNESS_PCT = "brightness_pct" ATTR_COMMAND = "command" ATTR_RATE = "rate" CONF_NETWORK = "network" -EVENT_UPB_LINK_CHANGED = "upb.link_changed" +EVENT_UPB_SCENE_CHANGED = "upb.scene_changed" VALID_BRIGHTNESS = vol.All(vol.Coerce(int), vol.Clamp(min=0, max=255)) VALID_BRIGHTNESS_PCT = vol.All(vol.Coerce(float), vol.Range(min=0, max=100)) From 78c9411dde7b6ed7694dc4e05d45040a4da4628a Mon Sep 17 00:00:00 2001 From: Xiaonan Shen Date: Fri, 15 May 2020 03:18:43 -0700 Subject: [PATCH 24/49] Bump roombapy to 1.6.1 (#35650) * Bump roombapy to 1.6.1 * Improve roomba error handling --- homeassistant/components/roomba/irobot_base.py | 13 +++++-------- homeassistant/components/roomba/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/roomba/irobot_base.py b/homeassistant/components/roomba/irobot_base.py index 524b5a915f9..f510f4965b0 100644 --- a/homeassistant/components/roomba/irobot_base.py +++ b/homeassistant/components/roomba/irobot_base.py @@ -31,6 +31,7 @@ _LOGGER = logging.getLogger(__name__) ATTR_CLEANING_TIME = "cleaning_time" ATTR_CLEANED_AREA = "cleaned_area" ATTR_ERROR = "error" +ATTR_ERROR_CODE = "error_code" ATTR_POSITION = "position" ATTR_SOFTWARE_VERSION = "software_version" @@ -174,11 +175,6 @@ class IRobotVacuum(IRobotEntity, StateVacuumEntity): # Roomba software version software_version = state.get("softwareVer") - # Error message in plain english - error_msg = "None" - if hasattr(self.vacuum, "error_message"): - error_msg = self.vacuum.error_message - # Set properties that are to appear in the GUI state_attrs = {ATTR_SOFTWARE_VERSION: software_version} @@ -198,9 +194,10 @@ class IRobotVacuum(IRobotEntity, StateVacuumEntity): state_attrs[ATTR_CLEANING_TIME] = cleaning_time state_attrs[ATTR_CLEANED_AREA] = cleaned_area - # Skip error attr if there is none - if error_msg and error_msg != "None": - state_attrs[ATTR_ERROR] = error_msg + # Error + if self.vacuum.error_code != 0: + state_attrs[ATTR_ERROR] = self.vacuum.error_message + state_attrs[ATTR_ERROR_CODE] = self.vacuum.error_code # Not all Roombas expose position data # https://github.com/koalazak/dorita980/issues/48 diff --git a/homeassistant/components/roomba/manifest.json b/homeassistant/components/roomba/manifest.json index 45fe9133bca..3d710467b58 100644 --- a/homeassistant/components/roomba/manifest.json +++ b/homeassistant/components/roomba/manifest.json @@ -3,7 +3,7 @@ "name": "iRobot Roomba", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/roomba", - "requirements": ["roombapy==1.5.3"], + "requirements": ["roombapy==1.6.1"], "dependencies": [], "codeowners": ["@pschmitt", "@cyr-ius", "@shenxn"] } diff --git a/requirements_all.txt b/requirements_all.txt index 9704227df98..0e23f78e3ba 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1874,7 +1874,7 @@ rocketchat-API==0.6.1 rokuecp==0.4.0 # homeassistant.components.roomba -roombapy==1.5.3 +roombapy==1.6.1 # homeassistant.components.rova rova==0.1.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index d6827b2a259..3152331285d 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -765,7 +765,7 @@ ring_doorbell==0.6.0 rokuecp==0.4.0 # homeassistant.components.roomba -roombapy==1.5.3 +roombapy==1.6.1 # homeassistant.components.yamaha rxv==0.6.0 From dbd30d571d38e25e46cdf5297d1252f78ea7b53c Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 15 May 2020 12:36:02 +0200 Subject: [PATCH 25/49] Fix caldav event for calendar panel (#35653) --- homeassistant/components/caldav/calendar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/caldav/calendar.py b/homeassistant/components/caldav/calendar.py index 579755709d1..3691f704a13 100644 --- a/homeassistant/components/caldav/calendar.py +++ b/homeassistant/components/caldav/calendar.py @@ -174,7 +174,7 @@ class WebDavCalendarData: uid = vevent.uid.value data = { "uid": uid, - "title": vevent.summary.value, + "summary": vevent.summary.value, "start": self.get_hass_date(vevent.dtstart.value), "end": self.get_hass_date(self.get_end_date(vevent)), "location": self.get_attr_value(vevent, "location"), From 316d44cf3334a12392f20e366e67e9dafca7c30b Mon Sep 17 00:00:00 2001 From: Jason Hunter Date: Fri, 15 May 2020 14:05:32 -0400 Subject: [PATCH 26/49] ONVIF: Add check around media capabilities (#35667) --- homeassistant/components/onvif/device.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/onvif/device.py b/homeassistant/components/onvif/device.py index 17a0c0c27f0..c15f4bf6877 100644 --- a/homeassistant/components/onvif/device.py +++ b/homeassistant/components/onvif/device.py @@ -207,8 +207,13 @@ class ONVIFDevice: async def async_get_capabilities(self): """Obtain information about the available services on the device.""" - media_service = self.device.create_media_service() - media_capabilities = await media_service.GetServiceCapabilities() + snapshot = False + try: + media_service = self.device.create_media_service() + media_capabilities = await media_service.GetServiceCapabilities() + snapshot = media_capabilities.SnapshotUri + except (ONVIFError, Fault): + pass pullpoint = False try: @@ -225,7 +230,7 @@ class ONVIFDevice: except ONVIFError: pass - return Capabilities(media_capabilities.SnapshotUri, pullpoint, ptz) + return Capabilities(snapshot, pullpoint, ptz) async def async_get_profiles(self) -> List[Profile]: """Obtain media profiles for this device.""" From cf034ee7294cc03e9bd32b9ed48c165261b0496b Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Sat, 16 May 2020 00:12:58 +0200 Subject: [PATCH 27/49] Updated frontend to 20200515.0 (#35677) --- homeassistant/components/frontend/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index 6a1af47a9cf..f669452b92e 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -2,7 +2,7 @@ "domain": "frontend", "name": "Home Assistant Frontend", "documentation": "https://www.home-assistant.io/integrations/frontend", - "requirements": ["home-assistant-frontend==20200514.1"], + "requirements": ["home-assistant-frontend==20200515.0"], "dependencies": [ "api", "auth", diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index b763b479fe8..0e129e292af 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -12,7 +12,7 @@ cryptography==2.9.2 defusedxml==0.6.0 distro==1.5.0 hass-nabucasa==0.34.2 -home-assistant-frontend==20200514.1 +home-assistant-frontend==20200515.0 importlib-metadata==1.6.0 jinja2>=2.11.1 netdisco==2.6.0 diff --git a/requirements_all.txt b/requirements_all.txt index 0e23f78e3ba..ae58d582e38 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -731,7 +731,7 @@ hole==0.5.1 holidays==0.10.2 # homeassistant.components.frontend -home-assistant-frontend==20200514.1 +home-assistant-frontend==20200515.0 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 3152331285d..a8ab861652a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -312,7 +312,7 @@ hole==0.5.1 holidays==0.10.2 # homeassistant.components.frontend -home-assistant-frontend==20200514.1 +home-assistant-frontend==20200515.0 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 From c270d5edcf89777b44f673d4f82b13cb2bb0a290 Mon Sep 17 00:00:00 2001 From: uvjustin <46082645+uvjustin@users.noreply.github.com> Date: Sat, 16 May 2020 16:06:35 +0800 Subject: [PATCH 28/49] Change MediaPlayerDevice to MediaPlayerEntity (#35692) --- homeassistant/components/forked_daapd/media_player.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/forked_daapd/media_player.py b/homeassistant/components/forked_daapd/media_player.py index 1b52d454def..e492aa1b454 100644 --- a/homeassistant/components/forked_daapd/media_player.py +++ b/homeassistant/components/forked_daapd/media_player.py @@ -6,7 +6,7 @@ import logging from pyforked_daapd import ForkedDaapdAPI from pylibrespot_java import LibrespotJavaAPI -from homeassistant.components.media_player import MediaPlayerDevice +from homeassistant.components.media_player import MediaPlayerEntity from homeassistant.components.media_player.const import MEDIA_TYPE_MUSIC from homeassistant.const import ( CONF_HOST, @@ -116,7 +116,7 @@ async def update_listener(hass, entry): ) -class ForkedDaapdZone(MediaPlayerDevice): +class ForkedDaapdZone(MediaPlayerEntity): """Representation of a forked-daapd output.""" def __init__(self, api, output, entry_id): @@ -221,7 +221,7 @@ class ForkedDaapdZone(MediaPlayerDevice): return SUPPORTED_FEATURES_ZONE -class ForkedDaapdMaster(MediaPlayerDevice): +class ForkedDaapdMaster(MediaPlayerEntity): """Representation of the main forked-daapd device.""" def __init__( From 4a9a004de0a7b3143195c92bcea7e4d228c6219a Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sat, 16 May 2020 11:06:22 +0200 Subject: [PATCH 29/49] Bumped version to 0.110.0b3 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 39337804faf..a79d89e49c0 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 110 -PATCH_VERSION = "0b2" +PATCH_VERSION = "0b3" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 0) From 5695a63e5952c4ef0b50b4213b886dc1140634f2 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sat, 16 May 2020 13:31:15 +0200 Subject: [PATCH 30/49] Fix handling of additional data in core config storage (#35660) --- homeassistant/core.py | 25 +++++++++++++++++-------- tests/test_core.py | 17 ++++++++++++++--- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/homeassistant/core.py b/homeassistant/core.py index 929d8c74da4..34df648a4df 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -1454,10 +1454,6 @@ class Config: ) data = await store.async_load() - if data and "external_url" in data: - self._update(source=SOURCE_STORAGE, **data) - return - async def migrate_base_url(_: Event) -> None: """Migrate base_url to internal_url/external_url.""" if self.hass.config.api is None: @@ -1484,11 +1480,24 @@ class Config: external_url=network.normalize_url(str(base_url)) ) - # Try to migrate base_url to internal_url/external_url - self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, migrate_base_url) - if data: - self._update(source=SOURCE_STORAGE, **data) + # Try to migrate base_url to internal_url/external_url + if "external_url" not in data: + self.hass.bus.async_listen_once( + EVENT_HOMEASSISTANT_START, migrate_base_url + ) + + self._update( + source=SOURCE_STORAGE, + latitude=data.get("latitude"), + longitude=data.get("longitude"), + elevation=data.get("elevation"), + unit_system=data.get("unit_system"), + location_name=data.get("location_name"), + time_zone=data.get("time_zone"), + external_url=data.get("external_url", _UNDEF), + internal_url=data.get("internal_url", _UNDEF), + ) async def async_store(self) -> None: """Store [homeassistant] core config.""" diff --git a/tests/test_core.py b/tests/test_core.py index ced0b96fbed..3bc001b78b6 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1294,17 +1294,17 @@ async def test_migration_base_url(hass, hass_storage): with patch.object(hass.bus, "async_listen_once") as mock_listen: # Empty config await config.async_load() - assert len(mock_listen.mock_calls) == 1 + assert len(mock_listen.mock_calls) == 0 # With just a name stored["data"] = {"location_name": "Test Name"} await config.async_load() - assert len(mock_listen.mock_calls) == 2 + assert len(mock_listen.mock_calls) == 1 # With external url stored["data"]["external_url"] = "https://example.com" await config.async_load() - assert len(mock_listen.mock_calls) == 2 + assert len(mock_listen.mock_calls) == 1 # Test that the event listener works assert mock_listen.mock_calls[0][1][0] == EVENT_HOMEASSISTANT_START @@ -1319,3 +1319,14 @@ async def test_migration_base_url(hass, hass_storage): hass.config.api = Mock(deprecated_base_url=internal) await mock_listen.mock_calls[0][1][1](None) assert config.internal_url == internal + + +async def test_additional_data_in_core_config(hass, hass_storage): + """Test that we can handle additional data in core configuration.""" + config = ha.Config(hass) + hass_storage[ha.CORE_STORAGE_KEY] = { + "version": 1, + "data": {"location_name": "Test Name", "additional_valid_key": "value"}, + } + await config.async_load() + assert config.location_name == "Test Name" From aa176aab07dd6423216945a6c77ae10b39616d0f Mon Sep 17 00:00:00 2001 From: Alexei Chetroi Date: Sat, 16 May 2020 14:30:54 -0400 Subject: [PATCH 31/49] Bump up ZHA dependencies (#35706) --- homeassistant/components/zha/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index cd153e0d2b8..bf4176db120 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -9,7 +9,7 @@ "zha-quirks==0.0.39", "zigpy-cc==0.4.2", "zigpy-deconz==0.9.2", - "zigpy==0.20.3", + "zigpy==0.20.4", "zigpy-xbee==0.12.1", "zigpy-zigate==0.6.1" ], diff --git a/requirements_all.txt b/requirements_all.txt index ae58d582e38..d28f33d6fe1 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2263,7 +2263,7 @@ zigpy-xbee==0.12.1 zigpy-zigate==0.6.1 # homeassistant.components.zha -zigpy==0.20.3 +zigpy==0.20.4 # homeassistant.components.zoneminder zm-py==0.4.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index a8ab861652a..976f87a923c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -918,4 +918,4 @@ zigpy-xbee==0.12.1 zigpy-zigate==0.6.1 # homeassistant.components.zha -zigpy==0.20.3 +zigpy==0.20.4 From 5cb1924290b8699dccbd3d4531db48ba3bf3ef58 Mon Sep 17 00:00:00 2001 From: uvjustin <46082645+uvjustin@users.noreply.github.com> Date: Sun, 17 May 2020 21:23:44 +0800 Subject: [PATCH 32/49] Abort forked-daapd zeroconf flow if version < 27 (#35709) * Change MediaPlayerDevice to MediaPlayerEntity * Abort zeroconf if mtd-version < 27.0 --- homeassistant/components/forked_daapd/config_flow.py | 2 +- tests/components/forked_daapd/test_config_flow.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/forked_daapd/config_flow.py b/homeassistant/components/forked_daapd/config_flow.py index dda11171fe8..697c3f0c7ac 100644 --- a/homeassistant/components/forked_daapd/config_flow.py +++ b/homeassistant/components/forked_daapd/config_flow.py @@ -158,7 +158,7 @@ class ForkedDaapdFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): """Prepare configuration for a discovered forked-daapd device.""" if not ( discovery_info.get("properties") - and discovery_info["properties"].get("mtd-version") + and float(discovery_info["properties"].get("mtd-version", 0)) >= 27.0 and discovery_info["properties"].get("Machine Name") ): return self.async_abort(reason="not_forked_daapd") diff --git a/tests/components/forked_daapd/test_config_flow.py b/tests/components/forked_daapd/test_config_flow.py index b0b484d8943..b97cc07009c 100644 --- a/tests/components/forked_daapd/test_config_flow.py +++ b/tests/components/forked_daapd/test_config_flow.py @@ -103,7 +103,7 @@ async def test_zeroconf_updates_title(hass, config_entry): discovery_info = { "host": "192.168.1.1", "port": 23, - "properties": {"mtd-version": 1, "Machine Name": "zeroconf_test"}, + "properties": {"mtd-version": 27.0, "Machine Name": "zeroconf_test"}, } result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, data=discovery_info @@ -143,7 +143,7 @@ async def test_config_flow_zeroconf_valid(hass): "host": "192.168.1.1", "port": 23, "properties": { - "mtd-version": 1, + "mtd-version": 27.0, "Machine Name": "zeroconf_test", "Machine ID": "5E55EEFF", }, From e2f0520028b57959a74c449f00ad5390e46bf379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=B8yer=20Iversen?= Date: Sun, 17 May 2020 12:09:16 +0200 Subject: [PATCH 33/49] Upgrade opengarage lib to 0.1.4 (#35729) --- homeassistant/components/opengarage/manifest.json | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/opengarage/manifest.json b/homeassistant/components/opengarage/manifest.json index f15dbd6d726..8bbf8c76c42 100644 --- a/homeassistant/components/opengarage/manifest.json +++ b/homeassistant/components/opengarage/manifest.json @@ -5,5 +5,5 @@ "codeowners": [ "@danielhiversen" ], - "requirements": ["open-garage==0.1.3"] + "requirements": ["open-garage==0.1.4"] } diff --git a/requirements_all.txt b/requirements_all.txt index d28f33d6fe1..a386231a0dc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -997,7 +997,7 @@ onkyo-eiscp==1.2.7 onvif-zeep-async==0.3.0 # homeassistant.components.opengarage -open-garage==0.1.3 +open-garage==0.1.4 # homeassistant.components.opencv # opencv-python-headless==4.2.0.32 From cc5fc2baa44718a12b7a35d4d91ae5e19374345e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 17 May 2020 15:51:51 -0500 Subject: [PATCH 34/49] Ensure homekit version strings conform to spec (#35741) HomeKit requires all version strings to be in the format MAJOR.MINOR.REVISION --- homeassistant/components/homekit/accessories.py | 3 ++- homeassistant/components/homekit/util.py | 9 +++++++++ tests/components/homekit/test_util.py | 10 ++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/homekit/accessories.py b/homeassistant/components/homekit/accessories.py index 367f43d9560..3cd3c46613b 100644 --- a/homeassistant/components/homekit/accessories.py +++ b/homeassistant/components/homekit/accessories.py @@ -75,6 +75,7 @@ from .const import ( from .util import ( convert_to_float, dismiss_setup_message, + format_sw_version, show_setup_message, validate_media_player_features, ) @@ -253,7 +254,7 @@ class HomeAccessory(Accessory): else: model = domain.title() if ATTR_SOFTWARE_VERSION in self.config: - sw_version = self.config[ATTR_SOFTWARE_VERSION] + sw_version = format_sw_version(self.config[ATTR_SOFTWARE_VERSION]) else: sw_version = __version__ diff --git a/homeassistant/components/homekit/util.py b/homeassistant/components/homekit/util.py index aac0e211975..d35c463ca39 100644 --- a/homeassistant/components/homekit/util.py +++ b/homeassistant/components/homekit/util.py @@ -4,6 +4,7 @@ import io import ipaddress import logging import os +import re import secrets import socket @@ -415,6 +416,14 @@ def get_aid_storage_fullpath_for_entry_id(hass: HomeAssistant, entry_id: str): ) +def format_sw_version(version): + """Extract the version string in a format homekit can consume.""" + match = re.search(r"([0-9]+)(\.[0-9]+)?(\.[0-9]+)?", str(version).replace("-", ".")) + if match: + return match.group(0) + return None + + def migrate_filesystem_state_data_for_primary_imported_entry_id( hass: HomeAssistant, entry_id: str ): diff --git a/tests/components/homekit/test_util.py b/tests/components/homekit/test_util.py index d5ff923270b..48f0a6d270e 100644 --- a/tests/components/homekit/test_util.py +++ b/tests/components/homekit/test_util.py @@ -28,6 +28,7 @@ from homeassistant.components.homekit.util import ( density_to_air_quality, dismiss_setup_message, find_next_available_port, + format_sw_version, port_is_available, show_setup_message, temperature_to_homekit, @@ -315,3 +316,12 @@ async def test_port_is_available(hass): assert next_port assert await hass.async_add_executor_job(port_is_available, next_port) + + +async def test_format_sw_version(): + """Test format_sw_version method.""" + assert format_sw_version("soho+3.6.8+soho-release-rt120+10") == "3.6.8" + assert format_sw_version("undefined-undefined-1.6.8") == "1.6.8" + assert format_sw_version("56.0-76060") == "56.0.76060" + assert format_sw_version(3.6) == "3.6" + assert format_sw_version("unknown") is None From 99afc17b3f7c57004986baadc13ea55d16a2c066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=B8yer=20Iversen?= Date: Mon, 18 May 2020 11:00:44 +0200 Subject: [PATCH 35/49] Update mill manifest to reflect config flow (#35748) --- homeassistant/components/mill/manifest.json | 3 ++- homeassistant/generated/config_flows.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/mill/manifest.json b/homeassistant/components/mill/manifest.json index 07eec93bb65..684be0479bd 100644 --- a/homeassistant/components/mill/manifest.json +++ b/homeassistant/components/mill/manifest.json @@ -3,5 +3,6 @@ "name": "Mill", "documentation": "https://www.home-assistant.io/integrations/mill", "requirements": ["millheater==0.3.4"], - "codeowners": ["@danielhiversen"] + "codeowners": ["@danielhiversen"], + "config_flow": true } diff --git a/homeassistant/generated/config_flows.py b/homeassistant/generated/config_flows.py index 43ccb4ef6d1..154fb024112 100644 --- a/homeassistant/generated/config_flows.py +++ b/homeassistant/generated/config_flows.py @@ -89,6 +89,7 @@ FLOWS = [ "met", "meteo_france", "mikrotik", + "mill", "minecraft_server", "mobile_app", "monoprice", From 7417b3be6632efbe1a82dd2f8a40a4778b8a46f7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 18 May 2020 09:23:05 -0500 Subject: [PATCH 36/49] Handle UPS disconnects in NUT (#35758) --- homeassistant/components/nut/__init__.py | 6 ++++-- homeassistant/components/nut/sensor.py | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/nut/__init__.py b/homeassistant/components/nut/__init__.py index 99563ca65d4..5669b8a5c3b 100644 --- a/homeassistant/components/nut/__init__.py +++ b/homeassistant/components/nut/__init__.py @@ -18,7 +18,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import ( COORDINATOR, @@ -61,7 +61,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): async def async_update_data(): """Fetch data from NUT.""" async with async_timeout.timeout(10): - return await hass.async_add_executor_job(data.update) + await hass.async_add_executor_job(data.update) + if not data.status: + raise UpdateFailed("Error fetching UPS state") coordinator = DataUpdateCoordinator( hass, diff --git a/homeassistant/components/nut/sensor.py b/homeassistant/components/nut/sensor.py index 32daaaa2582..3c2144a0aee 100644 --- a/homeassistant/components/nut/sensor.py +++ b/homeassistant/components/nut/sensor.py @@ -189,6 +189,8 @@ class NUTSensor(Entity): @property def state(self): """Return entity state from ups.""" + if not self._data.status: + return None if self._type == KEY_STATUS_DISPLAY: return _format_display_state(self._data.status) return self._data.status.get(self._type) From e9f398ac2835f2f07f7926e4b5f0b861515ee0dd Mon Sep 17 00:00:00 2001 From: Fredrik Erlandsson Date: Mon, 18 May 2020 16:57:52 +0200 Subject: [PATCH 37/49] Fix daikin discovery flow (#35767) --- .../components/daikin/config_flow.py | 51 +++++++------ homeassistant/components/daikin/manifest.json | 2 +- homeassistant/components/daikin/strings.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/daikin/test_config_flow.py | 71 +++++++++++-------- 6 files changed, 74 insertions(+), 56 deletions(-) diff --git a/homeassistant/components/daikin/config_flow.py b/homeassistant/components/daikin/config_flow.py index 8dc491ac868..cd5be5cef29 100644 --- a/homeassistant/components/daikin/config_flow.py +++ b/homeassistant/components/daikin/config_flow.py @@ -15,14 +15,6 @@ from .const import CONF_KEY, CONF_UUID, KEY_IP, KEY_MAC, TIMEOUT _LOGGER = logging.getLogger(__name__) -DATA_SCHEMA = vol.Schema( - { - vol.Required(CONF_HOST): str, - vol.Optional(CONF_KEY): str, - vol.Optional(CONF_PASSWORD): str, - } -) - @config_entries.HANDLERS.register("daikin") class FlowHandler(config_entries.ConfigFlow): @@ -31,12 +23,26 @@ class FlowHandler(config_entries.ConfigFlow): VERSION = 1 CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL - def _create_entry(self, host, mac, key=None, uuid=None, password=None): + def __init__(self): + """Initialize the Daikin config flow.""" + self.host = None + + @property + def schema(self): + """Return current schema.""" + return vol.Schema( + { + vol.Required(CONF_HOST, default=self.host): str, + vol.Optional(CONF_KEY): str, + vol.Optional(CONF_PASSWORD): str, + } + ) + + async def _create_entry(self, host, mac, key=None, uuid=None, password=None): """Register new entry.""" # Check if mac already is registered - for entry in self._async_current_entries(): - if entry.data[KEY_MAC] == mac: - return self.async_abort(reason="already_configured") + await self.async_set_unique_id(mac) + self._abort_if_unique_id_configured() return self.async_create_entry( title=host, @@ -73,31 +79,31 @@ class FlowHandler(config_entries.ConfigFlow): except asyncio.TimeoutError: return self.async_show_form( step_id="user", - data_schema=DATA_SCHEMA, + data_schema=self.schema, errors={"base": "device_timeout"}, ) except web_exceptions.HTTPForbidden: return self.async_show_form( - step_id="user", data_schema=DATA_SCHEMA, errors={"base": "forbidden"}, + step_id="user", data_schema=self.schema, errors={"base": "forbidden"}, ) except ClientError: _LOGGER.exception("ClientError") return self.async_show_form( - step_id="user", data_schema=DATA_SCHEMA, errors={"base": "device_fail"}, + step_id="user", data_schema=self.schema, errors={"base": "device_fail"}, ) except Exception: # pylint: disable=broad-except _LOGGER.exception("Unexpected error creating device") return self.async_show_form( - step_id="user", data_schema=DATA_SCHEMA, errors={"base": "device_fail"}, + step_id="user", data_schema=self.schema, errors={"base": "device_fail"}, ) mac = device.mac - return self._create_entry(host, mac, key, uuid, password) + return await self._create_entry(host, mac, key, uuid, password) async def async_step_user(self, user_input=None): """User initiated config flow.""" if user_input is None: - return self.async_show_form(step_id="user", data_schema=DATA_SCHEMA,) + return self.async_show_form(step_id="user", data_schema=self.schema) return await self._create_device( user_input[CONF_HOST], user_input.get(CONF_KEY), @@ -111,7 +117,10 @@ class FlowHandler(config_entries.ConfigFlow): return await self.async_step_user() return await self._create_device(host) - async def async_step_discovery(self, user_input): + async def async_step_discovery(self, discovery_info): """Initialize step from discovery.""" - _LOGGER.info("Discovered device: %s", user_input) - return self._create_entry(user_input[KEY_IP], user_input[KEY_MAC]) + _LOGGER.debug("Discovered device: %s", discovery_info) + await self.async_set_unique_id(discovery_info[KEY_MAC]) + self._abort_if_unique_id_configured() + self.host = discovery_info[KEY_IP] + return await self.async_step_user() diff --git a/homeassistant/components/daikin/manifest.json b/homeassistant/components/daikin/manifest.json index c554e882b48..9732962de5a 100644 --- a/homeassistant/components/daikin/manifest.json +++ b/homeassistant/components/daikin/manifest.json @@ -3,7 +3,7 @@ "name": "Daikin AC", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/daikin", - "requirements": ["pydaikin==2.0.1"], + "requirements": ["pydaikin==2.0.2"], "codeowners": ["@fredrike"], "quality_scale": "platinum" } diff --git a/homeassistant/components/daikin/strings.json b/homeassistant/components/daikin/strings.json index 0286ca00c32..c60163577a6 100644 --- a/homeassistant/components/daikin/strings.json +++ b/homeassistant/components/daikin/strings.json @@ -3,7 +3,7 @@ "step": { "user": { "title": "Configure Daikin AC", - "description": "Enter IP address of your Daikin AC.", + "description": "Enter IP address of your Daikin AC.\n\nNote that [%key:common::config_flow::data::api_key%] and [%key:common::config_flow::data::password%] are used by BRP072Cxx and SKYFi devices respectively.", "data": { "host": "[%key:common::config_flow::data::host%]", "key": "[%key:common::config_flow::data::api_key%]", diff --git a/requirements_all.txt b/requirements_all.txt index a386231a0dc..effc19b575f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1263,7 +1263,7 @@ pycsspeechtts==1.0.3 # pycups==1.9.73 # homeassistant.components.daikin -pydaikin==2.0.1 +pydaikin==2.0.2 # homeassistant.components.danfoss_air pydanfossair==0.1.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 976f87a923c..c523af46c87 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -533,7 +533,7 @@ pychromecast==5.1.0 pycoolmasternet==0.0.4 # homeassistant.components.daikin -pydaikin==2.0.1 +pydaikin==2.0.2 # homeassistant.components.deconz pydeconz==70 diff --git a/tests/components/daikin/test_config_flow.py b/tests/components/daikin/test_config_flow.py index 83e13047f80..25fc8ba26f2 100644 --- a/tests/components/daikin/test_config_flow.py +++ b/tests/components/daikin/test_config_flow.py @@ -6,8 +6,8 @@ from aiohttp import ClientError from aiohttp.web_exceptions import HTTPForbidden import pytest -from homeassistant.components.daikin import config_flow from homeassistant.components.daikin.const import KEY_IP, KEY_MAC +from homeassistant.config_entries import SOURCE_DISCOVERY, SOURCE_IMPORT, SOURCE_USER from homeassistant.const import CONF_HOST from homeassistant.data_entry_flow import ( RESULT_TYPE_ABORT, @@ -22,13 +22,6 @@ MAC = "AABBCCDDEEFF" HOST = "127.0.0.1" -def init_config_flow(hass): - """Init a configuration flow.""" - flow = config_flow.FlowHandler() - flow.hass = hass - return flow - - @pytest.fixture def mock_daikin(): """Mock pydaikin.""" @@ -45,13 +38,16 @@ def mock_daikin(): async def test_user(hass, mock_daikin): """Test user config.""" - flow = init_config_flow(hass) + result = await hass.config_entries.flow.async_init( + "daikin", context={"source": SOURCE_USER}, + ) - result = await flow.async_step_user() assert result["type"] == RESULT_TYPE_FORM assert result["step_id"] == "user" - result = await flow.async_step_user({CONF_HOST: HOST}) + result = await hass.config_entries.flow.async_init( + "daikin", context={"source": SOURCE_USER}, data={CONF_HOST: HOST}, + ) assert result["type"] == RESULT_TYPE_CREATE_ENTRY assert result["title"] == HOST assert result["data"][CONF_HOST] == HOST @@ -60,34 +56,26 @@ async def test_user(hass, mock_daikin): async def test_abort_if_already_setup(hass, mock_daikin): """Test we abort if Daikin is already setup.""" - flow = init_config_flow(hass) - MockConfigEntry(domain="daikin", data={KEY_MAC: MAC}).add_to_hass(hass) + MockConfigEntry(domain="daikin", unique_id=MAC).add_to_hass(hass) + result = await hass.config_entries.flow.async_init( + "daikin", context={"source": SOURCE_USER}, data={CONF_HOST: HOST, KEY_MAC: MAC}, + ) - result = await flow.async_step_user({CONF_HOST: HOST}) assert result["type"] == RESULT_TYPE_ABORT assert result["reason"] == "already_configured" async def test_import(hass, mock_daikin): """Test import step.""" - flow = init_config_flow(hass) - - result = await flow.async_step_import({}) + result = await hass.config_entries.flow.async_init( + "daikin", context={"source": SOURCE_IMPORT}, data={}, + ) assert result["type"] == RESULT_TYPE_FORM assert result["step_id"] == "user" - result = await flow.async_step_import({CONF_HOST: HOST}) - assert result["type"] == RESULT_TYPE_CREATE_ENTRY - assert result["title"] == HOST - assert result["data"][CONF_HOST] == HOST - assert result["data"][KEY_MAC] == MAC - - -async def test_discovery(hass, mock_daikin): - """Test discovery step.""" - flow = init_config_flow(hass) - - result = await flow.async_step_discovery({KEY_IP: HOST, KEY_MAC: MAC}) + result = await hass.config_entries.flow.async_init( + "daikin", context={"source": SOURCE_IMPORT}, data={CONF_HOST: HOST}, + ) assert result["type"] == RESULT_TYPE_CREATE_ENTRY assert result["title"] == HOST assert result["data"][CONF_HOST] == HOST @@ -105,10 +93,31 @@ async def test_discovery(hass, mock_daikin): ) async def test_device_abort(hass, mock_daikin, s_effect, reason): """Test device abort.""" - flow = init_config_flow(hass) mock_daikin.factory.side_effect = s_effect - result = await flow.async_step_user({CONF_HOST: HOST}) + result = await hass.config_entries.flow.async_init( + "daikin", context={"source": SOURCE_USER}, data={CONF_HOST: HOST, KEY_MAC: MAC}, + ) assert result["type"] == RESULT_TYPE_FORM assert result["errors"] == {"base": reason} assert result["step_id"] == "user" + + +@pytest.mark.parametrize( + "source, data, unique_id", [(SOURCE_DISCOVERY, {KEY_IP: HOST, KEY_MAC: MAC}, MAC)], +) +async def test_discovery(hass, mock_daikin, source, data, unique_id): + """Test discovery/zeroconf step.""" + result = await hass.config_entries.flow.async_init( + "daikin", context={"source": source}, data=data, + ) + assert result["type"] == RESULT_TYPE_FORM + assert result["step_id"] == "user" + + MockConfigEntry(domain="daikin", unique_id=unique_id).add_to_hass(hass) + result = await hass.config_entries.flow.async_init( + "daikin", context={"source": source}, data=data, + ) + + assert result["type"] == RESULT_TYPE_ABORT + assert result["reason"] == "already_in_progress" From c61bcbf982d56008c938f0c7c1a7813d4e949a5f Mon Sep 17 00:00:00 2001 From: uvjustin <46082645+uvjustin@users.noreply.github.com> Date: Tue, 19 May 2020 03:40:39 +0800 Subject: [PATCH 38/49] Skip forked_daapd ignored entries with empty entry.data (#35772) --- homeassistant/components/forked_daapd/config_flow.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/forked_daapd/config_flow.py b/homeassistant/components/forked_daapd/config_flow.py index 697c3f0c7ac..c860e08ffc4 100644 --- a/homeassistant/components/forked_daapd/config_flow.py +++ b/homeassistant/components/forked_daapd/config_flow.py @@ -163,18 +163,18 @@ class ForkedDaapdFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): ): return self.async_abort(reason="not_forked_daapd") + await self.async_set_unique_id(discovery_info["properties"]["Machine Name"]) + self._abort_if_unique_id_configured() + # Update title and abort if we already have an entry for this host for entry in self._async_current_entries(): - if entry.data[CONF_HOST] != discovery_info["host"]: + if entry.data.get(CONF_HOST) != discovery_info["host"]: continue self.hass.config_entries.async_update_entry( entry, title=discovery_info["properties"]["Machine Name"], ) return self.async_abort(reason="already_configured") - await self.async_set_unique_id(discovery_info["properties"]["Machine Name"]) - self._abort_if_unique_id_configured() - zeroconf_data = { CONF_HOST: discovery_info["host"], CONF_PORT: int(discovery_info["port"]), From ca4433bd702bf860f5d94dc39e37a5306aa78c0b Mon Sep 17 00:00:00 2001 From: MatsNl <37705266+MatsNl@users.noreply.github.com> Date: Mon, 18 May 2020 18:12:00 +0200 Subject: [PATCH 39/49] Bump Atag dependency to 0.3.1.2 (#35776) --- homeassistant/components/atag/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/atag/manifest.json b/homeassistant/components/atag/manifest.json index b28f6875fa4..5fd77ee5155 100644 --- a/homeassistant/components/atag/manifest.json +++ b/homeassistant/components/atag/manifest.json @@ -3,6 +3,6 @@ "name": "Atag", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/atag/", - "requirements": ["pyatag==0.3.1.1"], + "requirements": ["pyatag==0.3.1.2"], "codeowners": ["@MatsNL"] } diff --git a/requirements_all.txt b/requirements_all.txt index effc19b575f..764f67b5a62 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1212,7 +1212,7 @@ pyalmond==0.0.2 pyarlo==0.2.3 # homeassistant.components.atag -pyatag==0.3.1.1 +pyatag==0.3.1.2 # homeassistant.components.netatmo pyatmo==3.3.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index c523af46c87..fef671ae909 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -515,7 +515,7 @@ pyalmond==0.0.2 pyarlo==0.2.3 # homeassistant.components.atag -pyatag==0.3.1.1 +pyatag==0.3.1.2 # homeassistant.components.netatmo pyatmo==3.3.1 From a28646bc24f760766f12be78c16c04957547751d Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 18 May 2020 21:38:25 +0200 Subject: [PATCH 40/49] Updated frontend to 20200518.0 (#35785) --- homeassistant/components/frontend/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index f669452b92e..1c33802e655 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -2,7 +2,7 @@ "domain": "frontend", "name": "Home Assistant Frontend", "documentation": "https://www.home-assistant.io/integrations/frontend", - "requirements": ["home-assistant-frontend==20200515.0"], + "requirements": ["home-assistant-frontend==20200518.0"], "dependencies": [ "api", "auth", diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 0e129e292af..4593c5bbc28 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -12,7 +12,7 @@ cryptography==2.9.2 defusedxml==0.6.0 distro==1.5.0 hass-nabucasa==0.34.2 -home-assistant-frontend==20200515.0 +home-assistant-frontend==20200518.0 importlib-metadata==1.6.0 jinja2>=2.11.1 netdisco==2.6.0 diff --git a/requirements_all.txt b/requirements_all.txt index 764f67b5a62..2763ef06efd 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -731,7 +731,7 @@ hole==0.5.1 holidays==0.10.2 # homeassistant.components.frontend -home-assistant-frontend==20200515.0 +home-assistant-frontend==20200518.0 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index fef671ae909..0cdea378a83 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -312,7 +312,7 @@ hole==0.5.1 holidays==0.10.2 # homeassistant.components.frontend -home-assistant-frontend==20200515.0 +home-assistant-frontend==20200518.0 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 From 7a72ada8b205ebd84b884bcaa838c68635425da1 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 18 May 2020 22:36:58 +0200 Subject: [PATCH 41/49] Bumped version to 0.110.0b4 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index a79d89e49c0..3e75419f7d6 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 110 -PATCH_VERSION = "0b3" +PATCH_VERSION = "0b4" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 0) From d629a551344e7d90d3239386571aa2053f650b23 Mon Sep 17 00:00:00 2001 From: Jason Hunter Date: Mon, 18 May 2020 23:02:23 -0400 Subject: [PATCH 42/49] Fix ONVIF subscription renewal (#35792) * fix subscription renewal * catch ValueError for #35762 --- homeassistant/components/onvif/device.py | 16 ++++++++++++++-- homeassistant/components/onvif/event.py | 3 ++- homeassistant/components/onvif/parsers.py | 6 +++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/onvif/device.py b/homeassistant/components/onvif/device.py index c15f4bf6877..8e69e148da3 100644 --- a/homeassistant/components/onvif/device.py +++ b/homeassistant/components/onvif/device.py @@ -54,6 +54,8 @@ class ONVIFDevice: self.profiles: List[Profile] = [] self.max_resolution: int = 0 + self._dt_diff_seconds: int = 0 + @property def name(self) -> str: """Return the name of this device.""" @@ -100,6 +102,16 @@ class ONVIFDevice: if self.capabilities.ptz: self.device.create_ptz_service() + if self._dt_diff_seconds > 300 and self.capabilities.events: + self.capabilities.events = False + LOGGER.warning( + "The system clock on '%s' is more than 5 minutes off. " + "Although this device supports events, they will be " + "disabled until the device clock is fixed as we will " + "not be able to renew the subscription.", + self.name, + ) + if self.capabilities.events: self.events = EventManager( self.hass, self.device, self.config_entry.unique_id @@ -179,9 +191,9 @@ class ONVIFDevice: ) dt_diff = cam_date - system_date - dt_diff_seconds = dt_diff.total_seconds() + self._dt_diff_seconds = dt_diff.total_seconds() - if dt_diff_seconds > 5: + if self._dt_diff_seconds > 5: LOGGER.warning( "The date/time on the device (UTC) is '%s', " "which is different from the system '%s', " diff --git a/homeassistant/components/onvif/event.py b/homeassistant/components/onvif/event.py index ee7d4349dc4..888fe5bd92b 100644 --- a/homeassistant/components/onvif/event.py +++ b/homeassistant/components/onvif/event.py @@ -104,7 +104,8 @@ class EventManager: if not self._subscription: return - await self._subscription.Renew(dt_util.utcnow() + dt.timedelta(minutes=10)) + termination_time = (dt_util.utcnow() + dt.timedelta(minutes=30)).isoformat() + await self._subscription.Renew(termination_time) async def async_pull_messages(self, _now: dt = None) -> None: """Pull messages from device.""" diff --git a/homeassistant/components/onvif/parsers.py b/homeassistant/components/onvif/parsers.py index 4fd4ffd2891..438601106b5 100644 --- a/homeassistant/components/onvif/parsers.py +++ b/homeassistant/components/onvif/parsers.py @@ -308,7 +308,7 @@ async def async_parse_last_reboot(uid: str, msg) -> Event: dt_util.parse_datetime(msg.Message._value_1.Data.SimpleItem[0].Value) ), ) - except (AttributeError, KeyError): + except (AttributeError, KeyError, ValueError): return None @@ -331,7 +331,7 @@ async def async_parse_last_reset(uid: str, msg) -> Event: ), entity_enabled=False, ) - except (AttributeError, KeyError): + except (AttributeError, KeyError, ValueError): return None @@ -354,5 +354,5 @@ async def async_parse_last_clock_sync(uid: str, msg) -> Event: ), entity_enabled=False, ) - except (AttributeError, KeyError): + except (AttributeError, KeyError, ValueError): return None From 7433fa92650f02dd6b9357fca57a8ae0e1e27e16 Mon Sep 17 00:00:00 2001 From: Anders Melchiorsen Date: Tue, 19 May 2020 08:58:51 +0200 Subject: [PATCH 43/49] Upgrade pysonos to 0.0.30 (#35793) --- homeassistant/components/sonos/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sonos/manifest.json b/homeassistant/components/sonos/manifest.json index d6bc7ff71a4..e5ce9ede290 100644 --- a/homeassistant/components/sonos/manifest.json +++ b/homeassistant/components/sonos/manifest.json @@ -3,7 +3,7 @@ "name": "Sonos", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/sonos", - "requirements": ["pysonos==0.0.29"], + "requirements": ["pysonos==0.0.30"], "ssdp": [ { "st": "urn:schemas-upnp-org:device:ZonePlayer:1" diff --git a/requirements_all.txt b/requirements_all.txt index 2763ef06efd..fc133c18651 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1615,7 +1615,7 @@ pysnmp==4.4.12 pysoma==0.0.10 # homeassistant.components.sonos -pysonos==0.0.29 +pysonos==0.0.30 # homeassistant.components.spc pyspcwebgw==0.4.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 0cdea378a83..d51246a2941 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -681,7 +681,7 @@ pysmartthings==0.7.1 pysoma==0.0.10 # homeassistant.components.sonos -pysonos==0.0.29 +pysonos==0.0.30 # homeassistant.components.spc pyspcwebgw==0.4.0 From 0cb5ccd49235e5b6ce9189d48970f79b34915b88 Mon Sep 17 00:00:00 2001 From: uvjustin <46082645+uvjustin@users.noreply.github.com> Date: Tue, 19 May 2020 21:17:02 +0800 Subject: [PATCH 44/49] Change version check in forked-daapd zeroconf step (#35796) --- .../components/forked_daapd/config_flow.py | 3 ++- .../forked_daapd/test_config_flow.py | 27 +++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/forked_daapd/config_flow.py b/homeassistant/components/forked_daapd/config_flow.py index c860e08ffc4..07eaaf4c3fe 100644 --- a/homeassistant/components/forked_daapd/config_flow.py +++ b/homeassistant/components/forked_daapd/config_flow.py @@ -158,7 +158,8 @@ class ForkedDaapdFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): """Prepare configuration for a discovered forked-daapd device.""" if not ( discovery_info.get("properties") - and float(discovery_info["properties"].get("mtd-version", 0)) >= 27.0 + and int(discovery_info["properties"].get("mtd-version", "0").split(".")[0]) + >= 27 and discovery_info["properties"].get("Machine Name") ): return self.async_abort(reason="not_forked_daapd") diff --git a/tests/components/forked_daapd/test_config_flow.py b/tests/components/forked_daapd/test_config_flow.py index b97cc07009c..3dc62bae8bd 100644 --- a/tests/components/forked_daapd/test_config_flow.py +++ b/tests/components/forked_daapd/test_config_flow.py @@ -103,7 +103,7 @@ async def test_zeroconf_updates_title(hass, config_entry): discovery_info = { "host": "192.168.1.1", "port": 23, - "properties": {"mtd-version": 27.0, "Machine Name": "zeroconf_test"}, + "properties": {"mtd-version": "27.0", "Machine Name": "zeroconf_test"}, } result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, data=discovery_info @@ -129,12 +129,35 @@ async def test_config_flow_no_websocket(hass, config_entry): async def test_config_flow_zeroconf_invalid(hass): """Test that an invalid zeroconf entry doesn't work.""" + # test with no discovery properties discovery_info = {"host": "127.0.0.1", "port": 23} result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, data=discovery_info ) # doesn't create the entry, tries to show form but gets abort assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert result["reason"] == "not_forked_daapd" + # test with forked-daapd version < 27 + discovery_info = { + "host": "127.0.0.1", + "port": 23, + "properties": {"mtd-version": "26.3", "Machine Name": "forked-daapd"}, + } + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_ZEROCONF}, data=discovery_info + ) # doesn't create the entry, tries to show form but gets abort + assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result["reason"] == "not_forked_daapd" + # test with verbose mtd-version from Firefly + discovery_info = { + "host": "127.0.0.1", + "port": 23, + "properties": {"mtd-version": "0.2.4.1", "Machine Name": "firefly"}, + } + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_ZEROCONF}, data=discovery_info + ) # doesn't create the entry, tries to show form but gets abort + assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result["reason"] == "not_forked_daapd" async def test_config_flow_zeroconf_valid(hass): @@ -143,7 +166,7 @@ async def test_config_flow_zeroconf_valid(hass): "host": "192.168.1.1", "port": 23, "properties": { - "mtd-version": 27.0, + "mtd-version": "27.0", "Machine Name": "zeroconf_test", "Machine ID": "5E55EEFF", }, From af34d130b679caba645445c39de7497822989e2c Mon Sep 17 00:00:00 2001 From: Alexei Chetroi Date: Tue, 19 May 2020 06:50:05 -0400 Subject: [PATCH 45/49] Bump up ZHA dependencies. (#35797) --- homeassistant/components/zha/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index bf4176db120..ef96d6efef1 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -4,7 +4,7 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/zha", "requirements": [ - "bellows==0.16.1", + "bellows==0.16.2", "pyserial==3.4", "zha-quirks==0.0.39", "zigpy-cc==0.4.2", diff --git a/requirements_all.txt b/requirements_all.txt index fc133c18651..e709f5e8ab3 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -333,7 +333,7 @@ beautifulsoup4==4.9.0 beewi_smartclim==0.0.7 # homeassistant.components.zha -bellows==0.16.1 +bellows==0.16.2 # homeassistant.components.bmw_connected_drive bimmer_connected==0.7.5 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index d51246a2941..6d2310967f3 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -147,7 +147,7 @@ axis==25 base36==0.1.1 # homeassistant.components.zha -bellows==0.16.1 +bellows==0.16.2 # homeassistant.components.blebox blebox_uniapi==1.3.2 From 39ce0635002e0d78b4bbb8bad25d8de7d01241a2 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 19 May 2020 19:07:15 +0200 Subject: [PATCH 46/49] Updated frontend to 20200519.0 (#35813) --- homeassistant/components/frontend/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index 1c33802e655..563e71c2eec 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -2,7 +2,7 @@ "domain": "frontend", "name": "Home Assistant Frontend", "documentation": "https://www.home-assistant.io/integrations/frontend", - "requirements": ["home-assistant-frontend==20200518.0"], + "requirements": ["home-assistant-frontend==20200519.0"], "dependencies": [ "api", "auth", diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 4593c5bbc28..c59502846b6 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -12,7 +12,7 @@ cryptography==2.9.2 defusedxml==0.6.0 distro==1.5.0 hass-nabucasa==0.34.2 -home-assistant-frontend==20200518.0 +home-assistant-frontend==20200519.0 importlib-metadata==1.6.0 jinja2>=2.11.1 netdisco==2.6.0 diff --git a/requirements_all.txt b/requirements_all.txt index e709f5e8ab3..f51773815dc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -731,7 +731,7 @@ hole==0.5.1 holidays==0.10.2 # homeassistant.components.frontend -home-assistant-frontend==20200518.0 +home-assistant-frontend==20200519.0 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 6d2310967f3..b7748649a36 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -312,7 +312,7 @@ hole==0.5.1 holidays==0.10.2 # homeassistant.components.frontend -home-assistant-frontend==20200518.0 +home-assistant-frontend==20200519.0 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 From d81a19b5a2b738695c524945ebde4cd4ffc77e63 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 19 May 2020 20:21:58 +0200 Subject: [PATCH 47/49] Bumped version to 0.110.0b5 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 3e75419f7d6..9fb6d492b57 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 110 -PATCH_VERSION = "0b4" +PATCH_VERSION = "0b5" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 0) From 57bcb4743dc2abbfbb90d36f3d948987c248a69e Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Tue, 19 May 2020 23:57:41 +0200 Subject: [PATCH 48/49] UniFi - Fix disabled entities being enabled after a restart (#35819) * Async remove call removed too much, resulting in disabled entities coming back after a restart * Calling super().async_remove is no longer needed, changed to self.async_remove * Yes, they should be sets... --- .../components/unifi/device_tracker.py | 8 ++-- homeassistant/components/unifi/sensor.py | 2 +- homeassistant/components/unifi/switch.py | 4 +- .../components/unifi/unifi_entity_base.py | 38 +++++++++---------- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/homeassistant/components/unifi/device_tracker.py b/homeassistant/components/unifi/device_tracker.py index 15c0ee7d4a7..ebad63acb4e 100644 --- a/homeassistant/components/unifi/device_tracker.py +++ b/homeassistant/components/unifi/device_tracker.py @@ -244,17 +244,17 @@ class UniFiClientTracker(UniFiClient, ScannerEntity): async def options_updated(self) -> None: """Config entry options are updated, remove entity if option is disabled.""" if not self.controller.option_track_clients: - await self.async_remove() + await self.remove_item({self.client.mac}) elif self.is_wired: if not self.controller.option_track_wired_clients: - await self.async_remove() + await self.remove_item({self.client.mac}) elif ( self.controller.option_ssid_filter and self.client.essid not in self.controller.option_ssid_filter ): - await self.async_remove() + await self.remove_item({self.client.mac}) class UniFiDeviceTracker(UniFiBase, ScannerEntity): @@ -383,4 +383,4 @@ class UniFiDeviceTracker(UniFiBase, ScannerEntity): async def options_updated(self) -> None: """Config entry options are updated, remove entity if option is disabled.""" if not self.controller.option_track_devices: - await self.async_remove() + await self.remove_item({self.device.mac}) diff --git a/homeassistant/components/unifi/sensor.py b/homeassistant/components/unifi/sensor.py index cf3cc2b1b5a..8fdb0ac1461 100644 --- a/homeassistant/components/unifi/sensor.py +++ b/homeassistant/components/unifi/sensor.py @@ -73,7 +73,7 @@ class UniFiBandwidthSensor(UniFiClient): async def options_updated(self) -> None: """Config entry options are updated, remove entity if option is disabled.""" if not self.controller.option_allow_bandwidth_sensors: - await self.async_remove() + await self.remove_item({self.client.mac}) class UniFiRxBandwidthSensor(UniFiBandwidthSensor): diff --git a/homeassistant/components/unifi/switch.py b/homeassistant/components/unifi/switch.py index a216daaf9bb..1b9f7147a9a 100644 --- a/homeassistant/components/unifi/switch.py +++ b/homeassistant/components/unifi/switch.py @@ -239,7 +239,7 @@ class UniFiPOEClientSwitch(UniFiClient, SwitchEntity, RestoreEntity): async def options_updated(self) -> None: """Config entry options are updated, remove entity if option is disabled.""" if not self.controller.option_poe_clients: - await self.async_remove() + await self.remove_item({self.client.mac}) class UniFiBlockClientSwitch(UniFiClient, SwitchEntity): @@ -287,4 +287,4 @@ class UniFiBlockClientSwitch(UniFiClient, SwitchEntity): async def options_updated(self) -> None: """Config entry options are updated, remove entity if option is disabled.""" if self.client.mac not in self.controller.option_block_clients: - await self.async_remove() + await self.remove_item({self.client.mac}) diff --git a/homeassistant/components/unifi/unifi_entity_base.py b/homeassistant/components/unifi/unifi_entity_base.py index 6fbc18f75d3..46a7123e4c9 100644 --- a/homeassistant/components/unifi/unifi_entity_base.py +++ b/homeassistant/components/unifi/unifi_entity_base.py @@ -43,18 +43,33 @@ class UniFiBase(Entity): self._item.remove_callback(self.async_update_callback) self.controller.entities[self.DOMAIN][self.TYPE].remove(self._item.mac) - async def async_remove(self): - """Clean up when removing entity. + @callback + def async_update_callback(self) -> None: + """Update the entity's state.""" + LOGGER.debug( + "Updating %s entity %s (%s)", self.TYPE, self.entity_id, self._item.mac + ) + self.async_write_ha_state() + + async def options_updated(self) -> None: + """Config entry options are updated, remove entity if option is disabled.""" + raise NotImplementedError + + async def remove_item(self, mac_addresses: set) -> None: + """Remove entity if MAC is part of set. Remove entity if no entry in entity registry exist. Remove entity registry entry if no entry in device registry exist. Remove device registry entry if there is only one linked entity (this entity). Remove entity registry entry if there are more than one entity linked to the device registry entry. """ + if self._item.mac not in mac_addresses: + return + entity_registry = await self.hass.helpers.entity_registry.async_get_registry() entity_entry = entity_registry.async_get(self.entity_id) if not entity_entry: - await super().async_remove() + await self.async_remove() return device_registry = await self.hass.helpers.device_registry.async_get_registry() @@ -69,23 +84,6 @@ class UniFiBase(Entity): entity_registry.async_remove(self.entity_id) - @callback - def async_update_callback(self) -> None: - """Update the entity's state.""" - LOGGER.debug( - "Updating %s entity %s (%s)", self.TYPE, self.entity_id, self._item.mac - ) - self.async_write_ha_state() - - async def options_updated(self) -> None: - """Config entry options are updated, remove entity if option is disabled.""" - raise NotImplementedError - - async def remove_item(self, mac_addresses: set) -> None: - """Remove entity if MAC is part of set.""" - if self._item.mac in mac_addresses: - await self.async_remove() - @property def should_poll(self) -> bool: """No polling needed.""" From f3e5d03384452f64cf5f73b2382ba0e8651c580f Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Wed, 20 May 2020 08:57:01 +0200 Subject: [PATCH 49/49] Bumped version to 0.110.0 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 9fb6d492b57..e7eddca36e0 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 110 -PATCH_VERSION = "0b5" +PATCH_VERSION = "0" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 0)