mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 15:47:12 +00:00
commit
7c784b6963
@ -16,7 +16,7 @@ from homeassistant.helpers.typing import HomeAssistantType
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
from . import config_flow # noqa: F401
|
||||
from .const import CONF_KEY, CONF_UUID, TIMEOUT
|
||||
from .const import CONF_KEY, CONF_UUID, KEY_MAC, TIMEOUT
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -61,6 +61,9 @@ async def async_setup(hass, config):
|
||||
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
|
||||
"""Establish connection with Daikin."""
|
||||
conf = entry.data
|
||||
# For backwards compat, set unique ID
|
||||
if entry.unique_id is None:
|
||||
hass.config_entries.async_update_entry(entry, unique_id=conf[KEY_MAC])
|
||||
daikin_api = await daikin_api_setup(
|
||||
hass,
|
||||
conf[CONF_HOST],
|
||||
|
@ -3,5 +3,5 @@
|
||||
"name": "De Lijn",
|
||||
"documentation": "https://www.home-assistant.io/integrations/delijn",
|
||||
"codeowners": ["@bollewolle"],
|
||||
"requirements": ["pydelijn==0.5.1"]
|
||||
"requirements": ["pydelijn==0.6.0"]
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
import logging
|
||||
|
||||
from pydelijn.api import Passages
|
||||
from pydelijn.common import HttpException
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
@ -37,22 +38,23 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||
"""Create the sensor."""
|
||||
api_key = config[CONF_API_KEY]
|
||||
name = DEFAULT_NAME
|
||||
|
||||
session = async_get_clientsession(hass)
|
||||
|
||||
sensors = []
|
||||
for nextpassage in config[CONF_NEXT_DEPARTURE]:
|
||||
stop_id = nextpassage[CONF_STOP_ID]
|
||||
number_of_departures = nextpassage[CONF_NUMBER_OF_DEPARTURES]
|
||||
line = Passages(
|
||||
hass.loop, stop_id, number_of_departures, api_key, session, True
|
||||
sensors.append(
|
||||
DeLijnPublicTransportSensor(
|
||||
Passages(
|
||||
hass.loop,
|
||||
nextpassage[CONF_STOP_ID],
|
||||
nextpassage[CONF_NUMBER_OF_DEPARTURES],
|
||||
api_key,
|
||||
session,
|
||||
True,
|
||||
)
|
||||
)
|
||||
)
|
||||
await line.get_passages()
|
||||
if line.passages is None:
|
||||
_LOGGER.warning("No data received from De Lijn")
|
||||
return
|
||||
sensors.append(DeLijnPublicTransportSensor(line, name))
|
||||
|
||||
async_add_entities(sensors, True)
|
||||
|
||||
@ -60,20 +62,28 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
||||
class DeLijnPublicTransportSensor(Entity):
|
||||
"""Representation of a Ruter sensor."""
|
||||
|
||||
def __init__(self, line, name):
|
||||
def __init__(self, line):
|
||||
"""Initialize the sensor."""
|
||||
self.line = line
|
||||
self._attributes = {ATTR_ATTRIBUTION: ATTRIBUTION}
|
||||
self._name = name
|
||||
self._name = None
|
||||
self._state = None
|
||||
self._available = False
|
||||
self._available = True
|
||||
|
||||
async def async_update(self):
|
||||
"""Get the latest data from the De Lijn API."""
|
||||
await self.line.get_passages()
|
||||
if self.line.passages is None:
|
||||
_LOGGER.warning("No data received from De Lijn")
|
||||
try:
|
||||
await self.line.get_passages()
|
||||
self._name = await self.line.get_stopname()
|
||||
except HttpException:
|
||||
self._available = False
|
||||
_LOGGER.error("De Lijn http error")
|
||||
return
|
||||
|
||||
self._attributes["stopname"] = self._name
|
||||
for passage in self.line.passages:
|
||||
passage["stopname"] = self._name
|
||||
|
||||
try:
|
||||
first = self.line.passages[0]
|
||||
if first["due_at_realtime"] is not None:
|
||||
@ -81,8 +91,6 @@ class DeLijnPublicTransportSensor(Entity):
|
||||
else:
|
||||
first_passage = first["due_at_schedule"]
|
||||
self._state = first_passage
|
||||
self._name = first["stopname"]
|
||||
self._attributes["stopname"] = first["stopname"]
|
||||
self._attributes["line_number_public"] = first["line_number_public"]
|
||||
self._attributes["line_transport_type"] = first["line_transport_type"]
|
||||
self._attributes["final_destination"] = first["final_destination"]
|
||||
@ -90,8 +98,8 @@ class DeLijnPublicTransportSensor(Entity):
|
||||
self._attributes["due_at_realtime"] = first["due_at_realtime"]
|
||||
self._attributes["next_passages"] = self.line.passages
|
||||
self._available = True
|
||||
except (KeyError, IndexError) as error:
|
||||
_LOGGER.debug("Error getting data from De Lijn: %s", error)
|
||||
except (KeyError, IndexError):
|
||||
_LOGGER.error("Invalid data received from De Lijn")
|
||||
self._available = False
|
||||
|
||||
@property
|
||||
|
@ -3,7 +3,7 @@
|
||||
"name": "forked-daapd",
|
||||
"documentation": "https://www.home-assistant.io/integrations/forked-daapd",
|
||||
"codeowners": ["@uvjustin"],
|
||||
"requirements": ["pyforked-daapd==0.1.8", "pylibrespot-java==0.1.0"],
|
||||
"requirements": ["pyforked-daapd==0.1.9", "pylibrespot-java==0.1.0"],
|
||||
"config_flow": true,
|
||||
"zeroconf": ["_daap._tcp.local."]
|
||||
}
|
||||
|
@ -794,26 +794,29 @@ class ForkedDaapdUpdater:
|
||||
"queue" in update_types
|
||||
): # update queue, queue before player for async_play_media
|
||||
queue = await self._api.get_request("queue")
|
||||
update_events["queue"] = asyncio.Event()
|
||||
async_dispatcher_send(
|
||||
self.hass,
|
||||
SIGNAL_UPDATE_QUEUE.format(self._entry_id),
|
||||
queue,
|
||||
update_events["queue"],
|
||||
)
|
||||
if queue:
|
||||
update_events["queue"] = asyncio.Event()
|
||||
async_dispatcher_send(
|
||||
self.hass,
|
||||
SIGNAL_UPDATE_QUEUE.format(self._entry_id),
|
||||
queue,
|
||||
update_events["queue"],
|
||||
)
|
||||
# order of below don't matter
|
||||
if not {"outputs", "volume"}.isdisjoint(update_types): # update outputs
|
||||
outputs = (await self._api.get_request("outputs"))["outputs"]
|
||||
update_events[
|
||||
"outputs"
|
||||
] = asyncio.Event() # only for master, zones should ignore
|
||||
async_dispatcher_send(
|
||||
self.hass,
|
||||
SIGNAL_UPDATE_OUTPUTS.format(self._entry_id),
|
||||
outputs,
|
||||
update_events["outputs"],
|
||||
)
|
||||
self._add_zones(outputs)
|
||||
outputs = await self._api.get_request("outputs")
|
||||
if outputs:
|
||||
outputs = outputs["outputs"]
|
||||
update_events[
|
||||
"outputs"
|
||||
] = asyncio.Event() # only for master, zones should ignore
|
||||
async_dispatcher_send(
|
||||
self.hass,
|
||||
SIGNAL_UPDATE_OUTPUTS.format(self._entry_id),
|
||||
outputs,
|
||||
update_events["outputs"],
|
||||
)
|
||||
self._add_zones(outputs)
|
||||
if not {"database"}.isdisjoint(update_types):
|
||||
pipes, playlists = await asyncio.gather(
|
||||
self._api.get_pipes(), self._api.get_playlists()
|
||||
@ -832,17 +835,18 @@ class ForkedDaapdUpdater:
|
||||
update_types
|
||||
): # update player
|
||||
player = await self._api.get_request("player")
|
||||
update_events["player"] = asyncio.Event()
|
||||
if update_events.get("queue"):
|
||||
await update_events[
|
||||
"queue"
|
||||
].wait() # make sure queue done before player for async_play_media
|
||||
async_dispatcher_send(
|
||||
self.hass,
|
||||
SIGNAL_UPDATE_PLAYER.format(self._entry_id),
|
||||
player,
|
||||
update_events["player"],
|
||||
)
|
||||
if player:
|
||||
update_events["player"] = asyncio.Event()
|
||||
if update_events.get("queue"):
|
||||
await update_events[
|
||||
"queue"
|
||||
].wait() # make sure queue done before player for async_play_media
|
||||
async_dispatcher_send(
|
||||
self.hass,
|
||||
SIGNAL_UPDATE_PLAYER.format(self._entry_id),
|
||||
player,
|
||||
update_events["player"],
|
||||
)
|
||||
if update_events:
|
||||
await asyncio.wait(
|
||||
[event.wait() for event in update_events.values()]
|
||||
|
@ -2,7 +2,7 @@
|
||||
"domain": "frontend",
|
||||
"name": "Home Assistant Frontend",
|
||||
"documentation": "https://www.home-assistant.io/integrations/frontend",
|
||||
"requirements": ["home-assistant-frontend==20200519.0"],
|
||||
"requirements": ["home-assistant-frontend==20200519.1"],
|
||||
"dependencies": [
|
||||
"api",
|
||||
"auth",
|
||||
|
@ -627,12 +627,14 @@ class HomeKit:
|
||||
ent_cfg = self._config.setdefault(entity_id, {})
|
||||
if ent_reg_ent.device_id:
|
||||
dev_reg_ent = dev_reg.async_get(ent_reg_ent.device_id)
|
||||
if dev_reg_ent.manufacturer:
|
||||
ent_cfg[ATTR_MANUFACTURER] = dev_reg_ent.manufacturer
|
||||
if dev_reg_ent.model:
|
||||
ent_cfg[ATTR_MODEL] = dev_reg_ent.model
|
||||
if dev_reg_ent.sw_version:
|
||||
ent_cfg[ATTR_SOFTWARE_VERSION] = dev_reg_ent.sw_version
|
||||
if dev_reg_ent is not None:
|
||||
# Handle missing devices
|
||||
if dev_reg_ent.manufacturer:
|
||||
ent_cfg[ATTR_MANUFACTURER] = dev_reg_ent.manufacturer
|
||||
if dev_reg_ent.model:
|
||||
ent_cfg[ATTR_MODEL] = dev_reg_ent.model
|
||||
if dev_reg_ent.sw_version:
|
||||
ent_cfg[ATTR_SOFTWARE_VERSION] = dev_reg_ent.sw_version
|
||||
if ATTR_MANUFACTURER not in ent_cfg:
|
||||
integration = await async_get_integration(self.hass, ent_reg_ent.platform)
|
||||
ent_cfg[ATTR_INTERGRATION] = integration.name
|
||||
|
@ -111,7 +111,7 @@ class HMLight(HMDevice, LightEntity):
|
||||
):
|
||||
self._hmdevice.on(self._channel)
|
||||
|
||||
if ATTR_HS_COLOR in kwargs:
|
||||
if ATTR_HS_COLOR in kwargs and self.supported_features & SUPPORT_COLOR:
|
||||
self._hmdevice.set_hs_color(
|
||||
hue=kwargs[ATTR_HS_COLOR][0] / 360.0,
|
||||
saturation=kwargs[ATTR_HS_COLOR][1] / 100.0,
|
||||
|
@ -31,9 +31,15 @@ from .const import (
|
||||
DEVICE_REVISION,
|
||||
DEVICE_SERIAL_NUMBER,
|
||||
DOMAIN,
|
||||
FIRMWARE_BUILD,
|
||||
FIRMWARE_IN_USERDATA,
|
||||
FIRMWARE_SUB_REVISION,
|
||||
HUB_EXCEPTIONS,
|
||||
HUB_NAME,
|
||||
LEGACY_DEVICE_BUILD,
|
||||
LEGACY_DEVICE_MODEL,
|
||||
LEGACY_DEVICE_REVISION,
|
||||
LEGACY_DEVICE_SUB_REVISION,
|
||||
MAC_ADDRESS_IN_USERDATA,
|
||||
MAINPROCESSOR_IN_USERDATA_FIRMWARE,
|
||||
MODEL_IN_MAINPROCESSOR,
|
||||
@ -159,9 +165,19 @@ async def async_get_device_info(pv_request):
|
||||
resources = await userdata.get_resources()
|
||||
userdata_data = resources[USER_DATA]
|
||||
|
||||
main_processor_info = userdata_data[FIRMWARE_IN_USERDATA][
|
||||
MAINPROCESSOR_IN_USERDATA_FIRMWARE
|
||||
]
|
||||
if FIRMWARE_IN_USERDATA in userdata_data:
|
||||
main_processor_info = userdata_data[FIRMWARE_IN_USERDATA][
|
||||
MAINPROCESSOR_IN_USERDATA_FIRMWARE
|
||||
]
|
||||
else:
|
||||
# Legacy devices
|
||||
main_processor_info = {
|
||||
REVISION_IN_MAINPROCESSOR: LEGACY_DEVICE_REVISION,
|
||||
FIRMWARE_SUB_REVISION: LEGACY_DEVICE_SUB_REVISION,
|
||||
FIRMWARE_BUILD: LEGACY_DEVICE_BUILD,
|
||||
MODEL_IN_MAINPROCESSOR: LEGACY_DEVICE_MODEL,
|
||||
}
|
||||
|
||||
return {
|
||||
DEVICE_NAME: base64_to_unicode(userdata_data[HUB_NAME]),
|
||||
DEVICE_MAC_ADDRESS: userdata_data[MAC_ADDRESS_IN_USERDATA],
|
||||
|
@ -65,3 +65,8 @@ PV_ROOM_DATA = "pv_room_data"
|
||||
COORDINATOR = "coordinator"
|
||||
|
||||
HUB_EXCEPTIONS = (asyncio.TimeoutError, PvApiConnectionError)
|
||||
|
||||
LEGACY_DEVICE_SUB_REVISION = 1
|
||||
LEGACY_DEVICE_REVISION = 0
|
||||
LEGACY_DEVICE_BUILD = 0
|
||||
LEGACY_DEVICE_MODEL = "PV Hub1.0"
|
||||
|
@ -3,6 +3,5 @@
|
||||
"name": "Logbook",
|
||||
"documentation": "https://www.home-assistant.io/integrations/logbook",
|
||||
"dependencies": ["frontend", "http", "recorder"],
|
||||
"after_dependencies": ["homekit"],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -106,11 +106,6 @@ class ONVIFCameraEntity(ONVIFBaseEntity, Camera):
|
||||
|
||||
async def stream_source(self):
|
||||
"""Return the stream source."""
|
||||
if self._stream_uri is None:
|
||||
uri_no_auth = await self.device.async_get_stream_uri(self.profile)
|
||||
self._stream_uri = uri_no_auth.replace(
|
||||
"rtsp://", f"rtsp://{self.device.username}:{self.device.password}@", 1
|
||||
)
|
||||
return self._stream_uri
|
||||
|
||||
async def async_camera_image(self):
|
||||
@ -118,11 +113,6 @@ class ONVIFCameraEntity(ONVIFBaseEntity, Camera):
|
||||
image = None
|
||||
|
||||
if self.device.capabilities.snapshot:
|
||||
if self._snapshot_uri is None:
|
||||
self._snapshot_uri = await self.device.async_get_snapshot_uri(
|
||||
self.profile
|
||||
)
|
||||
|
||||
auth = None
|
||||
if self.device.username and self.device.password:
|
||||
auth = HTTPDigestAuth(self.device.username, self.device.password)
|
||||
@ -181,6 +171,16 @@ class ONVIFCameraEntity(ONVIFBaseEntity, Camera):
|
||||
finally:
|
||||
await stream.close()
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Run when entity about to be added to hass."""
|
||||
uri_no_auth = await self.device.async_get_stream_uri(self.profile)
|
||||
self._stream_uri = uri_no_auth.replace(
|
||||
"rtsp://", f"rtsp://{self.device.username}:{self.device.password}@", 1
|
||||
)
|
||||
|
||||
if self.device.capabilities.snapshot:
|
||||
self._snapshot_uri = await self.device.async_get_snapshot_uri(self.profile)
|
||||
|
||||
async def async_perform_ptz(
|
||||
self,
|
||||
distance,
|
||||
|
@ -223,7 +223,7 @@ class ONVIFDevice:
|
||||
try:
|
||||
media_service = self.device.create_media_service()
|
||||
media_capabilities = await media_service.GetServiceCapabilities()
|
||||
snapshot = media_capabilities.SnapshotUri
|
||||
snapshot = media_capabilities and media_capabilities.SnapshotUri
|
||||
except (ONVIFError, Fault):
|
||||
pass
|
||||
|
||||
@ -231,7 +231,7 @@ class ONVIFDevice:
|
||||
try:
|
||||
event_service = self.device.create_events_service()
|
||||
event_capabilities = await event_service.GetServiceCapabilities()
|
||||
pullpoint = event_capabilities.WSPullPointSupport
|
||||
pullpoint = event_capabilities and event_capabilities.WSPullPointSupport
|
||||
except (ONVIFError, Fault):
|
||||
pass
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""Constants used by Home Assistant components."""
|
||||
MAJOR_VERSION = 0
|
||||
MINOR_VERSION = 110
|
||||
PATCH_VERSION = "0"
|
||||
PATCH_VERSION = "1"
|
||||
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||
__version__ = f"{__short_version__}.{PATCH_VERSION}"
|
||||
REQUIRED_PYTHON_VER = (3, 7, 0)
|
||||
|
@ -200,14 +200,19 @@ class Store:
|
||||
|
||||
async def _async_handle_write_data(self, *_args):
|
||||
"""Handle writing the config."""
|
||||
data = self._data
|
||||
|
||||
if "data_func" in data:
|
||||
data["data"] = data.pop("data_func")()
|
||||
|
||||
self._data = None
|
||||
|
||||
async with self._write_lock:
|
||||
if self._data is None:
|
||||
# Another write already consumed the data
|
||||
return
|
||||
|
||||
data = self._data
|
||||
|
||||
if "data_func" in data:
|
||||
data["data"] = data.pop("data_func")()
|
||||
|
||||
self._data = None
|
||||
|
||||
try:
|
||||
await self.hass.async_add_executor_job(
|
||||
self._write_data, self.path, data
|
||||
|
@ -12,7 +12,7 @@ cryptography==2.9.2
|
||||
defusedxml==0.6.0
|
||||
distro==1.5.0
|
||||
hass-nabucasa==0.34.2
|
||||
home-assistant-frontend==20200519.0
|
||||
home-assistant-frontend==20200519.1
|
||||
importlib-metadata==1.6.0
|
||||
jinja2>=2.11.1
|
||||
netdisco==2.6.0
|
||||
|
@ -731,7 +731,7 @@ hole==0.5.1
|
||||
holidays==0.10.2
|
||||
|
||||
# homeassistant.components.frontend
|
||||
home-assistant-frontend==20200519.0
|
||||
home-assistant-frontend==20200519.1
|
||||
|
||||
# homeassistant.components.zwave
|
||||
homeassistant-pyozw==0.1.10
|
||||
@ -1272,7 +1272,7 @@ pydanfossair==0.1.0
|
||||
pydeconz==70
|
||||
|
||||
# homeassistant.components.delijn
|
||||
pydelijn==0.5.1
|
||||
pydelijn==0.6.0
|
||||
|
||||
# homeassistant.components.zwave
|
||||
pydispatcher==2.0.5
|
||||
@ -1332,7 +1332,7 @@ pyflunearyou==1.0.7
|
||||
pyfnip==0.2
|
||||
|
||||
# homeassistant.components.forked_daapd
|
||||
pyforked-daapd==0.1.8
|
||||
pyforked-daapd==0.1.9
|
||||
|
||||
# homeassistant.components.fritzbox
|
||||
pyfritzhome==0.4.2
|
||||
|
@ -312,7 +312,7 @@ hole==0.5.1
|
||||
holidays==0.10.2
|
||||
|
||||
# homeassistant.components.frontend
|
||||
home-assistant-frontend==20200519.0
|
||||
home-assistant-frontend==20200519.1
|
||||
|
||||
# homeassistant.components.zwave
|
||||
homeassistant-pyozw==0.1.10
|
||||
@ -554,7 +554,7 @@ pyflume==0.4.0
|
||||
pyflunearyou==1.0.7
|
||||
|
||||
# homeassistant.components.forked_daapd
|
||||
pyforked-daapd==0.1.8
|
||||
pyforked-daapd==0.1.9
|
||||
|
||||
# homeassistant.components.fritzbox
|
||||
pyfritzhome==0.4.2
|
||||
|
@ -8,6 +8,9 @@ from homeassistant.components.forked_daapd.const import (
|
||||
CONF_TTS_PAUSE_TIME,
|
||||
CONF_TTS_VOLUME,
|
||||
DOMAIN,
|
||||
SIGNAL_UPDATE_OUTPUTS,
|
||||
SIGNAL_UPDATE_PLAYER,
|
||||
SIGNAL_UPDATE_QUEUE,
|
||||
SOURCE_NAME_CLEAR,
|
||||
SOURCE_NAME_DEFAULT,
|
||||
SUPPORTED_FEATURES,
|
||||
@ -63,7 +66,7 @@ from homeassistant.const import (
|
||||
)
|
||||
|
||||
from tests.async_mock import patch
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.common import MockConfigEntry, async_mock_signal
|
||||
|
||||
TEST_MASTER_ENTITY_NAME = "media_player.forked_daapd_server"
|
||||
TEST_ZONE_ENTITY_NAMES = [
|
||||
@ -369,6 +372,32 @@ def test_master_state(hass, mock_api_object):
|
||||
assert not state.attributes[ATTR_MEDIA_SHUFFLE]
|
||||
|
||||
|
||||
async def test_no_update_when_get_request_returns_none(
|
||||
hass, config_entry, mock_api_object
|
||||
):
|
||||
"""Test when get request returns None."""
|
||||
|
||||
async def get_request_side_effect(update_type):
|
||||
return None
|
||||
|
||||
mock_api_object.get_request.side_effect = get_request_side_effect
|
||||
updater_update = mock_api_object.start_websocket_handler.call_args[0][2]
|
||||
signal_output_call = async_mock_signal(
|
||||
hass, SIGNAL_UPDATE_OUTPUTS.format(config_entry.entry_id)
|
||||
)
|
||||
signal_player_call = async_mock_signal(
|
||||
hass, SIGNAL_UPDATE_PLAYER.format(config_entry.entry_id)
|
||||
)
|
||||
signal_queue_call = async_mock_signal(
|
||||
hass, SIGNAL_UPDATE_QUEUE.format(config_entry.entry_id)
|
||||
)
|
||||
await updater_update(["outputs", "player", "queue"])
|
||||
await hass.async_block_till_done()
|
||||
assert len(signal_output_call) == 0
|
||||
assert len(signal_player_call) == 0
|
||||
assert len(signal_queue_call) == 0
|
||||
|
||||
|
||||
async def _service_call(
|
||||
hass, entity_name, service, additional_service_data=None, blocking=True
|
||||
):
|
||||
|
@ -913,3 +913,83 @@ def _write_data(path: str, data: Dict) -> None:
|
||||
if not os.path.isdir(os.path.dirname(path)):
|
||||
os.makedirs(os.path.dirname(path))
|
||||
json_util.save_json(path, data)
|
||||
|
||||
|
||||
async def test_homekit_ignored_missing_devices(
|
||||
hass, hk_driver, debounce_patcher, device_reg, entity_reg
|
||||
):
|
||||
"""Test HomeKit handles a device in the entity registry but missing from the device registry."""
|
||||
entry = await async_init_integration(hass)
|
||||
|
||||
homekit = HomeKit(
|
||||
hass,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
{},
|
||||
{"light.demo": {}},
|
||||
DEFAULT_SAFE_MODE,
|
||||
advertise_ip=None,
|
||||
interface_choice=None,
|
||||
entry_id=entry.entry_id,
|
||||
)
|
||||
homekit.driver = hk_driver
|
||||
homekit._filter = Mock(return_value=True)
|
||||
homekit.bridge = HomeBridge(hass, hk_driver, "mock_bridge")
|
||||
|
||||
config_entry = MockConfigEntry(domain="test", data={})
|
||||
config_entry.add_to_hass(hass)
|
||||
device_entry = device_reg.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
sw_version="0.16.0",
|
||||
model="Powerwall 2",
|
||||
manufacturer="Tesla",
|
||||
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
|
||||
entity_reg.async_get_or_create(
|
||||
"binary_sensor",
|
||||
"powerwall",
|
||||
"battery_charging",
|
||||
device_id=device_entry.id,
|
||||
device_class=DEVICE_CLASS_BATTERY_CHARGING,
|
||||
)
|
||||
entity_reg.async_get_or_create(
|
||||
"sensor",
|
||||
"powerwall",
|
||||
"battery",
|
||||
device_id=device_entry.id,
|
||||
device_class=DEVICE_CLASS_BATTERY,
|
||||
)
|
||||
light = entity_reg.async_get_or_create(
|
||||
"light", "powerwall", "demo", device_id=device_entry.id
|
||||
)
|
||||
|
||||
# Delete the device to make sure we fallback
|
||||
# to using the platform
|
||||
device_reg.async_remove_device(device_entry.id)
|
||||
|
||||
hass.states.async_set(light.entity_id, STATE_ON)
|
||||
|
||||
def _mock_get_accessory(*args, **kwargs):
|
||||
return [None, "acc", None]
|
||||
|
||||
with patch.object(homekit.bridge, "add_accessory"), patch(
|
||||
f"{PATH_HOMEKIT}.show_setup_message"
|
||||
), patch(f"{PATH_HOMEKIT}.get_accessory") as mock_get_acc, patch(
|
||||
"pyhap.accessory_driver.AccessoryDriver.start"
|
||||
):
|
||||
await homekit.async_start()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mock_get_acc.assert_called_with(
|
||||
hass,
|
||||
hk_driver,
|
||||
ANY,
|
||||
ANY,
|
||||
{
|
||||
"platform": "Tesla Powerwall",
|
||||
"linked_battery_charging_sensor": "binary_sensor.powerwall_battery_charging",
|
||||
"linked_battery_sensor": "sensor.powerwall_battery",
|
||||
},
|
||||
)
|
||||
|
34
tests/fixtures/hunterdouglas_powerview/userdata_v1.json
vendored
Normal file
34
tests/fixtures/hunterdouglas_powerview/userdata_v1.json
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"userData" : {
|
||||
"enableScheduledEvents" : true,
|
||||
"staticIp" : false,
|
||||
"sceneControllerCount" : 0,
|
||||
"accessPointCount" : 0,
|
||||
"shadeCount" : 5,
|
||||
"ip" : "192.168.20.9",
|
||||
"groupCount" : 9,
|
||||
"scheduledEventCount" : 0,
|
||||
"editingEnabled" : true,
|
||||
"roomCount" : 5,
|
||||
"setupCompleted" : false,
|
||||
"sceneCount" : 18,
|
||||
"sceneControllerMemberCount" : 0,
|
||||
"mask" : "255.255.255.0",
|
||||
"hubName" : "UG93ZXJWaWV3IEh1YiBHZW4gMQ==",
|
||||
"rfID" : "0x8B2A",
|
||||
"remoteConnectEnabled" : false,
|
||||
"multiSceneMemberCount" : 0,
|
||||
"rfStatus" : 0,
|
||||
"serialNumber" : "REMOVED",
|
||||
"undefinedShadeCount" : 0,
|
||||
"sceneMemberCount" : 18,
|
||||
"unassignedShadeCount" : 0,
|
||||
"multiSceneCount" : 0,
|
||||
"addressKind" : "newPrimary",
|
||||
"gateway" : "192.168.20.1",
|
||||
"localTimeDataSet" : true,
|
||||
"dns" : "192.168.20.1",
|
||||
"macAddress" : "00:00:00:00:00:eb",
|
||||
"rfIDInt" : 35626
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user