mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 20:27:08 +00:00
Merge pull request #42824 from home-assistant/rc
This commit is contained in:
commit
d156e95f8a
@ -3,6 +3,6 @@
|
|||||||
"name": "AirVisual",
|
"name": "AirVisual",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/airvisual",
|
"documentation": "https://www.home-assistant.io/integrations/airvisual",
|
||||||
"requirements": ["pyairvisual==5.0.3"],
|
"requirements": ["pyairvisual==5.0.4"],
|
||||||
"codeowners": ["@bachya"]
|
"codeowners": ["@bachya"]
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "bmw_connected_drive",
|
"domain": "bmw_connected_drive",
|
||||||
"name": "BMW Connected Drive",
|
"name": "BMW Connected Drive",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/bmw_connected_drive",
|
"documentation": "https://www.home-assistant.io/integrations/bmw_connected_drive",
|
||||||
"requirements": ["bimmer_connected==0.7.8"],
|
"requirements": ["bimmer_connected==0.7.11"],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": ["@gerard33", "@rikroe"]
|
"codeowners": ["@gerard33", "@rikroe"]
|
||||||
}
|
}
|
||||||
|
@ -431,7 +431,7 @@ class EvoBroker:
|
|||||||
return
|
return
|
||||||
|
|
||||||
if refresh:
|
if refresh:
|
||||||
self.hass.helpers.event.async_call_later(1, self.async_update())
|
self.hass.helpers.event.async_call_later(1, self.async_update)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
name = f"{cube.room_by_id(device.room_id).name} {device.name}"
|
name = f"{cube.room_by_id(device.room_id).name} {device.name}"
|
||||||
|
|
||||||
# Only add Window Shutters
|
# Only add Window Shutters
|
||||||
if cube.is_windowshutter(device):
|
if device.is_windowshutter():
|
||||||
devices.append(MaxCubeShutter(handler, name, device.rf_address))
|
devices.append(MaxCubeShutter(handler, name, device.rf_address))
|
||||||
|
|
||||||
if devices:
|
if devices:
|
||||||
|
@ -70,7 +70,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
for device in cube.devices:
|
for device in cube.devices:
|
||||||
name = f"{cube.room_by_id(device.room_id).name} {device.name}"
|
name = f"{cube.room_by_id(device.room_id).name} {device.name}"
|
||||||
|
|
||||||
if cube.is_thermostat(device) or cube.is_wallthermostat(device):
|
if device.is_thermostat() or device.is_wallthermostat():
|
||||||
devices.append(MaxCubeClimate(handler, name, device.rf_address))
|
devices.append(MaxCubeClimate(handler, name, device.rf_address))
|
||||||
|
|
||||||
if devices:
|
if devices:
|
||||||
@ -180,11 +180,11 @@ class MaxCubeClimate(ClimateEntity):
|
|||||||
device = cube.device_by_rf(self._rf_address)
|
device = cube.device_by_rf(self._rf_address)
|
||||||
valve = 0
|
valve = 0
|
||||||
|
|
||||||
if cube.is_thermostat(device):
|
if device.is_thermostat():
|
||||||
valve = device.valve_position
|
valve = device.valve_position
|
||||||
elif cube.is_wallthermostat(device):
|
elif device.is_wallthermostat():
|
||||||
for device in cube.devices_by_room(cube.room_by_id(device.room_id)):
|
for device in cube.devices_by_room(cube.room_by_id(device.room_id)):
|
||||||
if cube.is_thermostat(device) and device.valve_position > 0:
|
if device.is_thermostat() and device.valve_position > 0:
|
||||||
valve = device.valve_position
|
valve = device.valve_position
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@ -287,7 +287,7 @@ class MaxCubeClimate(ClimateEntity):
|
|||||||
cube = self._cubehandle.cube
|
cube = self._cubehandle.cube
|
||||||
device = cube.device_by_rf(self._rf_address)
|
device = cube.device_by_rf(self._rf_address)
|
||||||
|
|
||||||
if not cube.is_thermostat(device):
|
if not device.is_thermostat():
|
||||||
return {}
|
return {}
|
||||||
return {ATTR_VALVE_POSITION: device.valve_position}
|
return {ATTR_VALVE_POSITION: device.valve_position}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Netatmo",
|
"name": "Netatmo",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/netatmo",
|
"documentation": "https://www.home-assistant.io/integrations/netatmo",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"pyatmo==4.1.0"
|
"pyatmo==4.2.0"
|
||||||
],
|
],
|
||||||
"after_dependencies": [
|
"after_dependencies": [
|
||||||
"cloud",
|
"cloud",
|
||||||
|
@ -84,7 +84,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
|
|
||||||
if resource_template is not None:
|
if resource_template is not None:
|
||||||
resource_template.hass = hass
|
resource_template.hass = hass
|
||||||
resource = resource_template.render(parse_result=False)
|
resource = resource_template.async_render(parse_result=False)
|
||||||
|
|
||||||
if value_template is not None:
|
if value_template is not None:
|
||||||
value_template.hass = hass
|
value_template.hass = hass
|
||||||
@ -189,6 +189,6 @@ class RestBinarySensor(BinarySensorEntity):
|
|||||||
async def async_update(self):
|
async def async_update(self):
|
||||||
"""Get the latest data from REST API and updates the state."""
|
"""Get the latest data from REST API and updates the state."""
|
||||||
if self._resource_template is not None:
|
if self._resource_template is not None:
|
||||||
self.rest.set_url(self._resource_template.render(parse_result=False))
|
self.rest.set_url(self._resource_template.async_render(parse_result=False))
|
||||||
|
|
||||||
await self.rest.async_update()
|
await self.rest.async_update()
|
||||||
|
@ -103,7 +103,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
|
|
||||||
if resource_template is not None:
|
if resource_template is not None:
|
||||||
resource_template.hass = hass
|
resource_template.hass = hass
|
||||||
resource = resource_template.render(parse_result=False)
|
resource = resource_template.async_render(parse_result=False)
|
||||||
|
|
||||||
if username and password:
|
if username and password:
|
||||||
if config.get(CONF_AUTHENTICATION) == HTTP_DIGEST_AUTHENTICATION:
|
if config.get(CONF_AUTHENTICATION) == HTTP_DIGEST_AUTHENTICATION:
|
||||||
@ -202,7 +202,7 @@ class RestSensor(Entity):
|
|||||||
async def async_update(self):
|
async def async_update(self):
|
||||||
"""Get the latest data from REST API and update the state."""
|
"""Get the latest data from REST API and update the state."""
|
||||||
if self._resource_template is not None:
|
if self._resource_template is not None:
|
||||||
self.rest.set_url(self._resource_template.render(parse_result=False))
|
self.rest.set_url(self._resource_template.async_render(parse_result=False))
|
||||||
|
|
||||||
await self.rest.async_update()
|
await self.rest.async_update()
|
||||||
|
|
||||||
|
@ -360,10 +360,14 @@ class OptionsFlow(config_entries.OptionsFlow):
|
|||||||
"""Check if device can be replaced with selected device."""
|
"""Check if device can be replaced with selected device."""
|
||||||
device_data = self._get_device_data(entry_id)
|
device_data = self._get_device_data(entry_id)
|
||||||
event_code = device_data[CONF_EVENT_CODE]
|
event_code = device_data[CONF_EVENT_CODE]
|
||||||
|
|
||||||
|
if event_code is not None:
|
||||||
rfx_obj = get_rfx_object(event_code)
|
rfx_obj = get_rfx_object(event_code)
|
||||||
if (
|
if (
|
||||||
rfx_obj.device.packettype == self._selected_device_object.device.packettype
|
rfx_obj.device.packettype
|
||||||
and rfx_obj.device.subtype == self._selected_device_object.device.subtype
|
== self._selected_device_object.device.packettype
|
||||||
|
and rfx_obj.device.subtype
|
||||||
|
== self._selected_device_object.device.subtype
|
||||||
and self._selected_device_event_code != event_code
|
and self._selected_device_event_code != event_code
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
|
@ -159,7 +159,7 @@ class SimpliSafeAlarm(SimpliSafeEntity, AlarmControlPanelEntity):
|
|||||||
try:
|
try:
|
||||||
await self._system.set_off()
|
await self._system.set_off()
|
||||||
except SimplipyError as err:
|
except SimplipyError as err:
|
||||||
LOGGER.error('Error while disarming "%s": %s', self._system.name, err)
|
LOGGER.error('Error while disarming "%s": %s', self._system.system_id, err)
|
||||||
return
|
return
|
||||||
|
|
||||||
self._state = STATE_ALARM_DISARMED
|
self._state = STATE_ALARM_DISARMED
|
||||||
@ -172,7 +172,9 @@ class SimpliSafeAlarm(SimpliSafeEntity, AlarmControlPanelEntity):
|
|||||||
try:
|
try:
|
||||||
await self._system.set_home()
|
await self._system.set_home()
|
||||||
except SimplipyError as err:
|
except SimplipyError as err:
|
||||||
LOGGER.error('Error while arming "%s" (home): %s', self._system.name, err)
|
LOGGER.error(
|
||||||
|
'Error while arming "%s" (home): %s', self._system.system_id, err
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
self._state = STATE_ALARM_ARMED_HOME
|
self._state = STATE_ALARM_ARMED_HOME
|
||||||
@ -185,7 +187,9 @@ class SimpliSafeAlarm(SimpliSafeEntity, AlarmControlPanelEntity):
|
|||||||
try:
|
try:
|
||||||
await self._system.set_away()
|
await self._system.set_away()
|
||||||
except SimplipyError as err:
|
except SimplipyError as err:
|
||||||
LOGGER.error('Error while arming "%s" (away): %s', self._system.name, err)
|
LOGGER.error(
|
||||||
|
'Error while arming "%s" (away): %s', self._system.system_id, err
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
self._state = STATE_ALARM_ARMING
|
self._state = STATE_ALARM_ARMING
|
||||||
|
@ -258,10 +258,9 @@ class SynoApi:
|
|||||||
self._entry.data[CONF_PASSWORD],
|
self._entry.data[CONF_PASSWORD],
|
||||||
self._entry.data[CONF_SSL],
|
self._entry.data[CONF_SSL],
|
||||||
timeout=self._entry.options.get(CONF_TIMEOUT),
|
timeout=self._entry.options.get(CONF_TIMEOUT),
|
||||||
|
device_token=self._entry.data.get("device_token"),
|
||||||
)
|
)
|
||||||
await self._hass.async_add_executor_job(
|
await self._hass.async_add_executor_job(self.dsm.login)
|
||||||
self.dsm.login, self._entry.data.get("device_token")
|
|
||||||
)
|
|
||||||
|
|
||||||
self._with_surveillance_station = bool(
|
self._with_surveillance_station = bool(
|
||||||
self.dsm.apis.get(SynoSurveillanceStation.CAMERA_API_KEY)
|
self.dsm.apis.get(SynoSurveillanceStation.CAMERA_API_KEY)
|
||||||
|
@ -128,6 +128,11 @@ class TasmotaLight(
|
|||||||
white_value = float(attributes["white_value"])
|
white_value = float(attributes["white_value"])
|
||||||
percent_white = white_value / TASMOTA_BRIGHTNESS_MAX
|
percent_white = white_value / TASMOTA_BRIGHTNESS_MAX
|
||||||
self._white_value = percent_white * 255
|
self._white_value = percent_white * 255
|
||||||
|
if self._white_value == 0:
|
||||||
|
self._color_temp = None
|
||||||
|
self._white_value = None
|
||||||
|
if self._white_value is not None and self._white_value > 0:
|
||||||
|
self._hs = None
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -348,6 +348,8 @@ class VizioConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
"""Handle zeroconf discovery."""
|
"""Handle zeroconf discovery."""
|
||||||
assert self.hass
|
assert self.hass
|
||||||
|
|
||||||
|
# If host already has port, no need to add it again
|
||||||
|
if ":" not in discovery_info[CONF_HOST]:
|
||||||
discovery_info[
|
discovery_info[
|
||||||
CONF_HOST
|
CONF_HOST
|
||||||
] = f"{discovery_info[CONF_HOST]}:{discovery_info[CONF_PORT]}"
|
] = f"{discovery_info[CONF_HOST]}:{discovery_info[CONF_PORT]}"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Constants used by Home Assistant components."""
|
"""Constants used by Home Assistant components."""
|
||||||
MAJOR_VERSION = 0
|
MAJOR_VERSION = 0
|
||||||
MINOR_VERSION = 117
|
MINOR_VERSION = 117
|
||||||
PATCH_VERSION = "2"
|
PATCH_VERSION = "3"
|
||||||
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||||
__version__ = f"{__short_version__}.{PATCH_VERSION}"
|
__version__ = f"{__short_version__}.{PATCH_VERSION}"
|
||||||
REQUIRED_PYTHON_VER = (3, 7, 1)
|
REQUIRED_PYTHON_VER = (3, 7, 1)
|
||||||
|
@ -8,7 +8,7 @@ attrs==19.3.0
|
|||||||
bcrypt==3.1.7
|
bcrypt==3.1.7
|
||||||
certifi>=2020.6.20
|
certifi>=2020.6.20
|
||||||
ciso8601==2.1.3
|
ciso8601==2.1.3
|
||||||
cryptography==3.2.0
|
cryptography==3.2
|
||||||
defusedxml==0.6.0
|
defusedxml==0.6.0
|
||||||
distro==1.5.0
|
distro==1.5.0
|
||||||
emoji==0.5.4
|
emoji==0.5.4
|
||||||
|
@ -12,7 +12,7 @@ httpx==0.16.1
|
|||||||
importlib-metadata==1.6.0;python_version<'3.8'
|
importlib-metadata==1.6.0;python_version<'3.8'
|
||||||
jinja2>=2.11.2
|
jinja2>=2.11.2
|
||||||
PyJWT==1.7.1
|
PyJWT==1.7.1
|
||||||
cryptography==3.2.0
|
cryptography==3.2
|
||||||
pip>=8.0.3
|
pip>=8.0.3
|
||||||
python-slugify==4.0.1
|
python-slugify==4.0.1
|
||||||
pytz>=2020.1
|
pytz>=2020.1
|
||||||
|
@ -342,7 +342,7 @@ beautifulsoup4==4.9.1
|
|||||||
bellows==0.20.3
|
bellows==0.20.3
|
||||||
|
|
||||||
# homeassistant.components.bmw_connected_drive
|
# homeassistant.components.bmw_connected_drive
|
||||||
bimmer_connected==0.7.8
|
bimmer_connected==0.7.11
|
||||||
|
|
||||||
# homeassistant.components.bizkaibus
|
# homeassistant.components.bizkaibus
|
||||||
bizkaibus==0.1.1
|
bizkaibus==0.1.1
|
||||||
@ -1252,7 +1252,7 @@ pyaehw4a1==0.3.9
|
|||||||
pyaftership==0.1.2
|
pyaftership==0.1.2
|
||||||
|
|
||||||
# homeassistant.components.airvisual
|
# homeassistant.components.airvisual
|
||||||
pyairvisual==5.0.3
|
pyairvisual==5.0.4
|
||||||
|
|
||||||
# homeassistant.components.almond
|
# homeassistant.components.almond
|
||||||
pyalmond==0.0.2
|
pyalmond==0.0.2
|
||||||
@ -1264,7 +1264,7 @@ pyarlo==0.2.3
|
|||||||
pyatag==0.3.4.4
|
pyatag==0.3.4.4
|
||||||
|
|
||||||
# homeassistant.components.netatmo
|
# homeassistant.components.netatmo
|
||||||
pyatmo==4.1.0
|
pyatmo==4.2.0
|
||||||
|
|
||||||
# homeassistant.components.atome
|
# homeassistant.components.atome
|
||||||
pyatome==0.1.1
|
pyatome==0.1.1
|
||||||
|
@ -615,7 +615,7 @@ py_nextbusnext==0.1.4
|
|||||||
pyaehw4a1==0.3.9
|
pyaehw4a1==0.3.9
|
||||||
|
|
||||||
# homeassistant.components.airvisual
|
# homeassistant.components.airvisual
|
||||||
pyairvisual==5.0.3
|
pyairvisual==5.0.4
|
||||||
|
|
||||||
# homeassistant.components.almond
|
# homeassistant.components.almond
|
||||||
pyalmond==0.0.2
|
pyalmond==0.0.2
|
||||||
@ -627,7 +627,7 @@ pyarlo==0.2.3
|
|||||||
pyatag==0.3.4.4
|
pyatag==0.3.4.4
|
||||||
|
|
||||||
# homeassistant.components.netatmo
|
# homeassistant.components.netatmo
|
||||||
pyatmo==4.1.0
|
pyatmo==4.2.0
|
||||||
|
|
||||||
# homeassistant.components.blackbird
|
# homeassistant.components.blackbird
|
||||||
pyblackbird==0.5
|
pyblackbird==0.5
|
||||||
|
2
setup.py
2
setup.py
@ -44,7 +44,7 @@ REQUIRES = [
|
|||||||
"jinja2>=2.11.2",
|
"jinja2>=2.11.2",
|
||||||
"PyJWT==1.7.1",
|
"PyJWT==1.7.1",
|
||||||
# PyJWT has loose dependency. We want the latest one.
|
# PyJWT has loose dependency. We want the latest one.
|
||||||
"cryptography==3.2.0",
|
"cryptography==3.2",
|
||||||
"pip>=8.0.3",
|
"pip>=8.0.3",
|
||||||
"python-slugify==4.0.1",
|
"python-slugify==4.0.1",
|
||||||
"pytz>=2020.1",
|
"pytz>=2020.1",
|
||||||
|
@ -116,7 +116,7 @@ async def test_setup_minimum_resource_template(hass):
|
|||||||
{
|
{
|
||||||
"binary_sensor": {
|
"binary_sensor": {
|
||||||
"platform": "rest",
|
"platform": "rest",
|
||||||
"resource_template": "http://localhost",
|
"resource_template": "{% set url = 'http://localhost' %}{{ url }}",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -102,7 +102,7 @@ async def test_setup_minimum_resource_template(hass):
|
|||||||
{
|
{
|
||||||
"sensor": {
|
"sensor": {
|
||||||
"platform": "rest",
|
"platform": "rest",
|
||||||
"resource_template": "http://localhost",
|
"resource_template": "{% set url = 'http://localhost' %}{{ url }}",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -432,6 +432,8 @@ async def test_controlling_state_via_mqtt_rgbww(hass, mqtt_mock, setup_tasmota):
|
|||||||
state = hass.states.get("light.test")
|
state = hass.states.get("light.test")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes.get("white_value") == 127.5
|
assert state.attributes.get("white_value") == 127.5
|
||||||
|
# Setting white > 0 should clear the color
|
||||||
|
assert not state.attributes.get("rgb_color")
|
||||||
|
|
||||||
async_fire_mqtt_message(
|
async_fire_mqtt_message(
|
||||||
hass, "tasmota_49A3BC/tele/STATE", '{"POWER":"ON","CT":300}'
|
hass, "tasmota_49A3BC/tele/STATE", '{"POWER":"ON","CT":300}'
|
||||||
@ -440,6 +442,15 @@ async def test_controlling_state_via_mqtt_rgbww(hass, mqtt_mock, setup_tasmota):
|
|||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes.get("color_temp") == 300
|
assert state.attributes.get("color_temp") == 300
|
||||||
|
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass, "tasmota_49A3BC/tele/STATE", '{"POWER":"ON","White":0}'
|
||||||
|
)
|
||||||
|
state = hass.states.get("light.test")
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
# Setting white to 0 should clear the white_value and color_temp
|
||||||
|
assert not state.attributes.get("white_value")
|
||||||
|
assert not state.attributes.get("color_temp")
|
||||||
|
|
||||||
async_fire_mqtt_message(
|
async_fire_mqtt_message(
|
||||||
hass, "tasmota_49A3BC/tele/STATE", '{"POWER":"ON","Scheme":3}'
|
hass, "tasmota_49A3BC/tele/STATE", '{"POWER":"ON","Scheme":3}'
|
||||||
)
|
)
|
||||||
|
@ -27,6 +27,7 @@ from homeassistant.const import (
|
|||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_PIN,
|
CONF_PIN,
|
||||||
|
CONF_PORT,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.typing import HomeAssistantType
|
from homeassistant.helpers.typing import HomeAssistantType
|
||||||
|
|
||||||
@ -777,6 +778,35 @@ async def test_zeroconf_flow_already_configured(
|
|||||||
assert result["reason"] == "already_configured"
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_zeroconf_flow_with_port_in_host(
|
||||||
|
hass: HomeAssistantType,
|
||||||
|
vizio_connect: pytest.fixture,
|
||||||
|
vizio_bypass_setup: pytest.fixture,
|
||||||
|
vizio_guess_device_type: pytest.fixture,
|
||||||
|
) -> None:
|
||||||
|
"""Test entity is already configured during zeroconf setup when port is in host."""
|
||||||
|
entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
data=MOCK_SPEAKER_CONFIG,
|
||||||
|
options={CONF_VOLUME_STEP: VOLUME_STEP},
|
||||||
|
unique_id=UNIQUE_ID,
|
||||||
|
)
|
||||||
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
# Try rediscovering same device, this time with port already in host
|
||||||
|
discovery_info = MOCK_ZEROCONF_SERVICE_INFO.copy()
|
||||||
|
discovery_info[
|
||||||
|
CONF_HOST
|
||||||
|
] = f"{discovery_info[CONF_HOST]}:{discovery_info[CONF_PORT]}"
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": SOURCE_ZEROCONF}, data=discovery_info
|
||||||
|
)
|
||||||
|
|
||||||
|
# Flow should abort because device is already setup
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
async def test_zeroconf_dupe_fail(
|
async def test_zeroconf_dupe_fail(
|
||||||
hass: HomeAssistantType,
|
hass: HomeAssistantType,
|
||||||
vizio_connect: pytest.fixture,
|
vizio_connect: pytest.fixture,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user