mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 17:57:11 +00:00
Reduce context switching in homekit state updates (#35147)
This commit is contained in:
parent
2e018ad841
commit
742e36ba26
@ -313,7 +313,7 @@ class HomeAccessory(Accessory):
|
|||||||
Run inside the Home Assistant event loop.
|
Run inside the Home Assistant event loop.
|
||||||
"""
|
"""
|
||||||
state = self.hass.states.get(self.entity_id)
|
state = self.hass.states.get(self.entity_id)
|
||||||
await self.async_update_state_callback(None, None, state)
|
self.async_update_state_callback(None, None, state)
|
||||||
async_track_state_change(
|
async_track_state_change(
|
||||||
self.hass, self.entity_id, self.async_update_state_callback
|
self.hass, self.entity_id, self.async_update_state_callback
|
||||||
)
|
)
|
||||||
@ -329,7 +329,9 @@ class HomeAccessory(Accessory):
|
|||||||
ATTR_BATTERY_CHARGING
|
ATTR_BATTERY_CHARGING
|
||||||
)
|
)
|
||||||
async_track_state_change(
|
async_track_state_change(
|
||||||
self.hass, self.linked_battery_sensor, self.async_update_linked_battery
|
self.hass,
|
||||||
|
self.linked_battery_sensor,
|
||||||
|
self.async_update_linked_battery_callback,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
battery_state = state.attributes.get(ATTR_BATTERY_LEVEL)
|
battery_state = state.attributes.get(ATTR_BATTERY_LEVEL)
|
||||||
@ -341,17 +343,16 @@ class HomeAccessory(Accessory):
|
|||||||
async_track_state_change(
|
async_track_state_change(
|
||||||
self.hass,
|
self.hass,
|
||||||
self.linked_battery_charging_sensor,
|
self.linked_battery_charging_sensor,
|
||||||
self.async_update_linked_battery_charging,
|
self.async_update_linked_battery_charging_callback,
|
||||||
)
|
)
|
||||||
elif battery_charging_state is None:
|
elif battery_charging_state is None:
|
||||||
battery_charging_state = state.attributes.get(ATTR_BATTERY_CHARGING)
|
battery_charging_state = state.attributes.get(ATTR_BATTERY_CHARGING)
|
||||||
|
|
||||||
if battery_state is not None or battery_charging_state is not None:
|
if battery_state is not None or battery_charging_state is not None:
|
||||||
self.hass.async_add_executor_job(
|
self.async_update_battery(battery_state, battery_charging_state)
|
||||||
self.update_battery, battery_state, battery_charging_state
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_update_state_callback(
|
@ha_callback
|
||||||
|
def async_update_state_callback(
|
||||||
self, entity_id=None, old_state=None, new_state=None
|
self, entity_id=None, old_state=None, new_state=None
|
||||||
):
|
):
|
||||||
"""Handle state change listener callback."""
|
"""Handle state change listener callback."""
|
||||||
@ -371,12 +372,11 @@ class HomeAccessory(Accessory):
|
|||||||
):
|
):
|
||||||
battery_charging_state = new_state.attributes.get(ATTR_BATTERY_CHARGING)
|
battery_charging_state = new_state.attributes.get(ATTR_BATTERY_CHARGING)
|
||||||
if battery_state is not None or battery_charging_state is not None:
|
if battery_state is not None or battery_charging_state is not None:
|
||||||
await self.hass.async_add_executor_job(
|
self.async_update_battery(battery_state, battery_charging_state)
|
||||||
self.update_battery, battery_state, battery_charging_state
|
self.async_update_state(new_state)
|
||||||
)
|
|
||||||
await self.hass.async_add_executor_job(self.update_state, new_state)
|
|
||||||
|
|
||||||
async def async_update_linked_battery(
|
@ha_callback
|
||||||
|
def async_update_linked_battery_callback(
|
||||||
self, entity_id=None, old_state=None, new_state=None
|
self, entity_id=None, old_state=None, new_state=None
|
||||||
):
|
):
|
||||||
"""Handle linked battery sensor state change listener callback."""
|
"""Handle linked battery sensor state change listener callback."""
|
||||||
@ -384,19 +384,17 @@ class HomeAccessory(Accessory):
|
|||||||
battery_charging_state = None
|
battery_charging_state = None
|
||||||
else:
|
else:
|
||||||
battery_charging_state = new_state.attributes.get(ATTR_BATTERY_CHARGING)
|
battery_charging_state = new_state.attributes.get(ATTR_BATTERY_CHARGING)
|
||||||
await self.hass.async_add_executor_job(
|
self.async_update_battery(new_state.state, battery_charging_state)
|
||||||
self.update_battery, new_state.state, battery_charging_state,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_update_linked_battery_charging(
|
@ha_callback
|
||||||
|
def async_update_linked_battery_charging_callback(
|
||||||
self, entity_id=None, old_state=None, new_state=None
|
self, entity_id=None, old_state=None, new_state=None
|
||||||
):
|
):
|
||||||
"""Handle linked battery charging sensor state change listener callback."""
|
"""Handle linked battery charging sensor state change listener callback."""
|
||||||
await self.hass.async_add_executor_job(
|
self.async_update_battery(None, new_state.state == STATE_ON)
|
||||||
self.update_battery, None, new_state.state == STATE_ON
|
|
||||||
)
|
|
||||||
|
|
||||||
def update_battery(self, battery_level, battery_charging):
|
@ha_callback
|
||||||
|
def async_update_battery(self, battery_level, battery_charging):
|
||||||
"""Update battery service if available.
|
"""Update battery service if available.
|
||||||
|
|
||||||
Only call this function if self._support_battery_level is True.
|
Only call this function if self._support_battery_level is True.
|
||||||
@ -427,7 +425,8 @@ class HomeAccessory(Accessory):
|
|||||||
"%s: Updated battery charging to %d", self.entity_id, hk_charging
|
"%s: Updated battery charging to %d", self.entity_id, hk_charging
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@ha_callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Handle state change to update HomeKit value.
|
"""Handle state change to update HomeKit value.
|
||||||
|
|
||||||
Overridden by accessory types.
|
Overridden by accessory types.
|
||||||
|
@ -12,6 +12,7 @@ from pyhap.const import CATEGORY_CAMERA
|
|||||||
|
|
||||||
from homeassistant.components.camera.const import DOMAIN as DOMAIN_CAMERA
|
from homeassistant.components.camera.const import DOMAIN as DOMAIN_CAMERA
|
||||||
from homeassistant.components.ffmpeg import DATA_FFMPEG
|
from homeassistant.components.ffmpeg import DATA_FFMPEG
|
||||||
|
from homeassistant.core import callback
|
||||||
from homeassistant.util import get_local_ip
|
from homeassistant.util import get_local_ip
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory
|
from .accessories import TYPES, HomeAccessory
|
||||||
@ -144,7 +145,8 @@ class Camera(HomeAccessory, PyhapCamera):
|
|||||||
options=options,
|
options=options,
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Handle state change to update HomeKit value."""
|
"""Handle state change to update HomeKit value."""
|
||||||
pass # pylint: disable=unnecessary-pass
|
pass # pylint: disable=unnecessary-pass
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ from homeassistant.const import (
|
|||||||
STATE_OPEN,
|
STATE_OPEN,
|
||||||
STATE_OPENING,
|
STATE_OPENING,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory, debounce
|
from .accessories import TYPES, HomeAccessory, debounce
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -92,7 +93,7 @@ class GarageDoorOpener(HomeAccessory):
|
|||||||
self.char_target_state = serv_garage_door.configure_char(
|
self.char_target_state = serv_garage_door.configure_char(
|
||||||
CHAR_TARGET_DOOR_STATE, value=0, setter_callback=self.set_state
|
CHAR_TARGET_DOOR_STATE, value=0, setter_callback=self.set_state
|
||||||
)
|
)
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def set_state(self, value):
|
def set_state(self, value):
|
||||||
"""Change garage state if call came from HomeKit."""
|
"""Change garage state if call came from HomeKit."""
|
||||||
@ -108,7 +109,8 @@ class GarageDoorOpener(HomeAccessory):
|
|||||||
self.char_current_state.set_value(HK_DOOR_CLOSING)
|
self.char_current_state.set_value(HK_DOOR_CLOSING)
|
||||||
self.call_service(DOMAIN, SERVICE_CLOSE_COVER, params)
|
self.call_service(DOMAIN, SERVICE_CLOSE_COVER, params)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update cover state after state changed."""
|
"""Update cover state after state changed."""
|
||||||
hass_state = new_state.state
|
hass_state = new_state.state
|
||||||
target_door_state = DOOR_TARGET_HASS_TO_HK.get(hass_state)
|
target_door_state = DOOR_TARGET_HASS_TO_HK.get(hass_state)
|
||||||
@ -184,7 +186,8 @@ class WindowCoveringBase(HomeAccessory):
|
|||||||
|
|
||||||
self.call_service(DOMAIN, SERVICE_SET_COVER_TILT_POSITION, params, value)
|
self.call_service(DOMAIN, SERVICE_SET_COVER_TILT_POSITION, params, value)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update cover position and tilt after state changed."""
|
"""Update cover position and tilt after state changed."""
|
||||||
# update tilt
|
# update tilt
|
||||||
current_tilt = new_state.attributes.get(ATTR_CURRENT_TILT_POSITION)
|
current_tilt = new_state.attributes.get(ATTR_CURRENT_TILT_POSITION)
|
||||||
@ -230,7 +233,7 @@ class WindowCovering(WindowCoveringBase, HomeAccessory):
|
|||||||
self.char_position_state = self.serv_cover.configure_char(
|
self.char_position_state = self.serv_cover.configure_char(
|
||||||
CHAR_POSITION_STATE, value=HK_POSITION_STOPPED
|
CHAR_POSITION_STATE, value=HK_POSITION_STOPPED
|
||||||
)
|
)
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
@debounce
|
@debounce
|
||||||
def move_cover(self, value):
|
def move_cover(self, value):
|
||||||
@ -241,7 +244,8 @@ class WindowCovering(WindowCoveringBase, HomeAccessory):
|
|||||||
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_POSITION: value}
|
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_POSITION: value}
|
||||||
self.call_service(DOMAIN, SERVICE_SET_COVER_POSITION, params, value)
|
self.call_service(DOMAIN, SERVICE_SET_COVER_POSITION, params, value)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update cover position and tilt after state changed."""
|
"""Update cover position and tilt after state changed."""
|
||||||
current_position = new_state.attributes.get(ATTR_CURRENT_POSITION)
|
current_position = new_state.attributes.get(ATTR_CURRENT_POSITION)
|
||||||
if isinstance(current_position, (float, int)):
|
if isinstance(current_position, (float, int)):
|
||||||
@ -271,7 +275,7 @@ class WindowCovering(WindowCoveringBase, HomeAccessory):
|
|||||||
if self.char_position_state.value != HK_POSITION_STOPPED:
|
if self.char_position_state.value != HK_POSITION_STOPPED:
|
||||||
self.char_position_state.set_value(HK_POSITION_STOPPED)
|
self.char_position_state.set_value(HK_POSITION_STOPPED)
|
||||||
|
|
||||||
super().update_state(new_state)
|
super().async_update_state(new_state)
|
||||||
|
|
||||||
|
|
||||||
@TYPES.register("WindowCoveringBasic")
|
@TYPES.register("WindowCoveringBasic")
|
||||||
@ -295,7 +299,7 @@ class WindowCoveringBasic(WindowCoveringBase, HomeAccessory):
|
|||||||
self.char_position_state = self.serv_cover.configure_char(
|
self.char_position_state = self.serv_cover.configure_char(
|
||||||
CHAR_POSITION_STATE, value=HK_POSITION_STOPPED
|
CHAR_POSITION_STATE, value=HK_POSITION_STOPPED
|
||||||
)
|
)
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
@debounce
|
@debounce
|
||||||
def move_cover(self, value):
|
def move_cover(self, value):
|
||||||
@ -322,7 +326,8 @@ class WindowCoveringBasic(WindowCoveringBase, HomeAccessory):
|
|||||||
self.char_current_position.set_value(position)
|
self.char_current_position.set_value(position)
|
||||||
self.char_target_position.set_value(position)
|
self.char_target_position.set_value(position)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update cover position after state changed."""
|
"""Update cover position after state changed."""
|
||||||
position_mapping = {STATE_OPEN: 100, STATE_CLOSED: 0}
|
position_mapping = {STATE_OPEN: 100, STATE_CLOSED: 0}
|
||||||
hk_position = position_mapping.get(new_state.state)
|
hk_position = position_mapping.get(new_state.state)
|
||||||
@ -341,4 +346,4 @@ class WindowCoveringBasic(WindowCoveringBase, HomeAccessory):
|
|||||||
if self.char_position_state.value != HK_POSITION_STOPPED:
|
if self.char_position_state.value != HK_POSITION_STOPPED:
|
||||||
self.char_position_state.set_value(HK_POSITION_STOPPED)
|
self.char_position_state.set_value(HK_POSITION_STOPPED)
|
||||||
|
|
||||||
super().update_state(new_state)
|
super().async_update_state(new_state)
|
||||||
|
@ -26,6 +26,7 @@ from homeassistant.const import (
|
|||||||
STATE_OFF,
|
STATE_OFF,
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory
|
from .accessories import TYPES, HomeAccessory
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -80,13 +81,13 @@ class Fan(HomeAccessory):
|
|||||||
|
|
||||||
if CHAR_ROTATION_SPEED in chars:
|
if CHAR_ROTATION_SPEED in chars:
|
||||||
# Initial value is set to 100 because 0 is a special value (off). 100 is
|
# Initial value is set to 100 because 0 is a special value (off). 100 is
|
||||||
# an arbitrary non-zero value. It is updated immediately by update_state
|
# an arbitrary non-zero value. It is updated immediately by async_update_state
|
||||||
# to set to the correct initial value.
|
# to set to the correct initial value.
|
||||||
self.char_speed = serv_fan.configure_char(CHAR_ROTATION_SPEED, value=100)
|
self.char_speed = serv_fan.configure_char(CHAR_ROTATION_SPEED, value=100)
|
||||||
|
|
||||||
if CHAR_SWING_MODE in chars:
|
if CHAR_SWING_MODE in chars:
|
||||||
self.char_swing = serv_fan.configure_char(CHAR_SWING_MODE, value=0)
|
self.char_swing = serv_fan.configure_char(CHAR_SWING_MODE, value=0)
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
serv_fan.setter_callback = self._set_chars
|
serv_fan.setter_callback = self._set_chars
|
||||||
|
|
||||||
def _set_chars(self, char_values):
|
def _set_chars(self, char_values):
|
||||||
@ -146,7 +147,8 @@ class Fan(HomeAccessory):
|
|||||||
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_SPEED: speed}
|
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_SPEED: speed}
|
||||||
self.call_service(DOMAIN, SERVICE_SET_SPEED, params, speed)
|
self.call_service(DOMAIN, SERVICE_SET_SPEED, params, speed)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update fan after state change."""
|
"""Update fan after state change."""
|
||||||
# Handle State
|
# Handle State
|
||||||
state = new_state.state
|
state = new_state.state
|
||||||
|
@ -23,6 +23,7 @@ from homeassistant.const import (
|
|||||||
STATE_OFF,
|
STATE_OFF,
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory
|
from .accessories import TYPES, HomeAccessory
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -77,7 +78,7 @@ class Light(HomeAccessory):
|
|||||||
|
|
||||||
if CHAR_BRIGHTNESS in self.chars:
|
if CHAR_BRIGHTNESS in self.chars:
|
||||||
# Initial value is set to 100 because 0 is a special value (off). 100 is
|
# Initial value is set to 100 because 0 is a special value (off). 100 is
|
||||||
# an arbitrary non-zero value. It is updated immediately by update_state
|
# an arbitrary non-zero value. It is updated immediately by async_update_state
|
||||||
# to set to the correct initial value.
|
# to set to the correct initial value.
|
||||||
self.char_brightness = serv_light.configure_char(CHAR_BRIGHTNESS, value=100)
|
self.char_brightness = serv_light.configure_char(CHAR_BRIGHTNESS, value=100)
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ class Light(HomeAccessory):
|
|||||||
if CHAR_SATURATION in self.chars:
|
if CHAR_SATURATION in self.chars:
|
||||||
self.char_saturation = serv_light.configure_char(CHAR_SATURATION, value=75)
|
self.char_saturation = serv_light.configure_char(CHAR_SATURATION, value=75)
|
||||||
|
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
serv_light.setter_callback = self._set_chars
|
serv_light.setter_callback = self._set_chars
|
||||||
|
|
||||||
@ -138,7 +139,8 @@ class Light(HomeAccessory):
|
|||||||
|
|
||||||
self.call_service(DOMAIN, service, params, ", ".join(events))
|
self.call_service(DOMAIN, service, params, ", ".join(events))
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update light after state change."""
|
"""Update light after state change."""
|
||||||
# Handle State
|
# Handle State
|
||||||
state = new_state.state
|
state = new_state.state
|
||||||
|
@ -5,6 +5,7 @@ from pyhap.const import CATEGORY_DOOR_LOCK
|
|||||||
|
|
||||||
from homeassistant.components.lock import DOMAIN, STATE_LOCKED, STATE_UNLOCKED
|
from homeassistant.components.lock import DOMAIN, STATE_LOCKED, STATE_UNLOCKED
|
||||||
from homeassistant.const import ATTR_CODE, ATTR_ENTITY_ID, STATE_UNKNOWN
|
from homeassistant.const import ATTR_CODE, ATTR_ENTITY_ID, STATE_UNKNOWN
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory
|
from .accessories import TYPES, HomeAccessory
|
||||||
from .const import CHAR_LOCK_CURRENT_STATE, CHAR_LOCK_TARGET_STATE, SERV_LOCK
|
from .const import CHAR_LOCK_CURRENT_STATE, CHAR_LOCK_TARGET_STATE, SERV_LOCK
|
||||||
@ -45,7 +46,7 @@ class Lock(HomeAccessory):
|
|||||||
value=HASS_TO_HOMEKIT[STATE_LOCKED],
|
value=HASS_TO_HOMEKIT[STATE_LOCKED],
|
||||||
setter_callback=self.set_state,
|
setter_callback=self.set_state,
|
||||||
)
|
)
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def set_state(self, value):
|
def set_state(self, value):
|
||||||
"""Set lock state to value if call came from HomeKit."""
|
"""Set lock state to value if call came from HomeKit."""
|
||||||
@ -62,7 +63,8 @@ class Lock(HomeAccessory):
|
|||||||
params[ATTR_CODE] = self._code
|
params[ATTR_CODE] = self._code
|
||||||
self.call_service(DOMAIN, service, params)
|
self.call_service(DOMAIN, service, params)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update lock after state changed."""
|
"""Update lock after state changed."""
|
||||||
hass_state = new_state.state
|
hass_state = new_state.state
|
||||||
if hass_state in HASS_TO_HOMEKIT:
|
if hass_state in HASS_TO_HOMEKIT:
|
||||||
|
@ -36,6 +36,7 @@ from homeassistant.const import (
|
|||||||
STATE_STANDBY,
|
STATE_STANDBY,
|
||||||
STATE_UNKNOWN,
|
STATE_UNKNOWN,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory
|
from .accessories import TYPES, HomeAccessory
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -150,7 +151,7 @@ class MediaPlayer(HomeAccessory):
|
|||||||
self.chars[FEATURE_TOGGLE_MUTE] = serv_toggle_mute.configure_char(
|
self.chars[FEATURE_TOGGLE_MUTE] = serv_toggle_mute.configure_char(
|
||||||
CHAR_ON, value=False, setter_callback=self.set_toggle_mute
|
CHAR_ON, value=False, setter_callback=self.set_toggle_mute
|
||||||
)
|
)
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def generate_service_name(self, mode):
|
def generate_service_name(self, mode):
|
||||||
"""Generate name for individual service."""
|
"""Generate name for individual service."""
|
||||||
@ -189,7 +190,8 @@ class MediaPlayer(HomeAccessory):
|
|||||||
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_MEDIA_VOLUME_MUTED: value}
|
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_MEDIA_VOLUME_MUTED: value}
|
||||||
self.call_service(DOMAIN, SERVICE_VOLUME_MUTE, params)
|
self.call_service(DOMAIN, SERVICE_VOLUME_MUTE, params)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update switch state after state changed."""
|
"""Update switch state after state changed."""
|
||||||
current_state = new_state.state
|
current_state = new_state.state
|
||||||
|
|
||||||
@ -321,7 +323,7 @@ class TelevisionMediaPlayer(HomeAccessory):
|
|||||||
serv_input.configure_char(CHAR_CURRENT_VISIBILITY_STATE, value=False)
|
serv_input.configure_char(CHAR_CURRENT_VISIBILITY_STATE, value=False)
|
||||||
_LOGGER.debug("%s: Added source %s.", self.entity_id, source)
|
_LOGGER.debug("%s: Added source %s.", self.entity_id, source)
|
||||||
|
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def set_on_off(self, value):
|
def set_on_off(self, value):
|
||||||
"""Move switch state to value if call came from HomeKit."""
|
"""Move switch state to value if call came from HomeKit."""
|
||||||
@ -375,7 +377,8 @@ class TelevisionMediaPlayer(HomeAccessory):
|
|||||||
params = {ATTR_ENTITY_ID: self.entity_id}
|
params = {ATTR_ENTITY_ID: self.entity_id}
|
||||||
self.call_service(DOMAIN, service, params)
|
self.call_service(DOMAIN, service, params)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update Television state after state changed."""
|
"""Update Television state after state changed."""
|
||||||
current_state = new_state.state
|
current_state = new_state.state
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ from homeassistant.const import (
|
|||||||
STATE_ALARM_DISARMED,
|
STATE_ALARM_DISARMED,
|
||||||
STATE_ALARM_TRIGGERED,
|
STATE_ALARM_TRIGGERED,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory
|
from .accessories import TYPES, HomeAccessory
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -64,7 +65,7 @@ class SecuritySystem(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def set_security_state(self, value):
|
def set_security_state(self, value):
|
||||||
"""Move security state to value if call came from HomeKit."""
|
"""Move security state to value if call came from HomeKit."""
|
||||||
@ -77,7 +78,8 @@ class SecuritySystem(HomeAccessory):
|
|||||||
params[ATTR_CODE] = self._alarm_code
|
params[ATTR_CODE] = self._alarm_code
|
||||||
self.call_service(DOMAIN, service, params)
|
self.call_service(DOMAIN, service, params)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update security state after state changed."""
|
"""Update security state after state changed."""
|
||||||
hass_state = new_state.state
|
hass_state = new_state.state
|
||||||
if hass_state in HASS_TO_HOMEKIT:
|
if hass_state in HASS_TO_HOMEKIT:
|
||||||
|
@ -10,6 +10,7 @@ from homeassistant.const import (
|
|||||||
STATE_ON,
|
STATE_ON,
|
||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory
|
from .accessories import TYPES, HomeAccessory
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -89,9 +90,10 @@ class TemperatureSensor(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update temperature after state changed."""
|
"""Update temperature after state changed."""
|
||||||
unit = new_state.attributes.get(ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS)
|
unit = new_state.attributes.get(ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS)
|
||||||
temperature = convert_to_float(new_state.state)
|
temperature = convert_to_float(new_state.state)
|
||||||
@ -118,9 +120,10 @@ class HumiditySensor(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update accessory after state change."""
|
"""Update accessory after state change."""
|
||||||
humidity = convert_to_float(new_state.state)
|
humidity = convert_to_float(new_state.state)
|
||||||
if humidity and self.char_humidity.value != humidity:
|
if humidity and self.char_humidity.value != humidity:
|
||||||
@ -145,9 +148,10 @@ class AirQualitySensor(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update accessory after state change."""
|
"""Update accessory after state change."""
|
||||||
density = convert_to_float(new_state.state)
|
density = convert_to_float(new_state.state)
|
||||||
if density:
|
if density:
|
||||||
@ -181,9 +185,10 @@ class CarbonMonoxideSensor(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update accessory after state change."""
|
"""Update accessory after state change."""
|
||||||
value = convert_to_float(new_state.state)
|
value = convert_to_float(new_state.state)
|
||||||
if value:
|
if value:
|
||||||
@ -218,9 +223,10 @@ class CarbonDioxideSensor(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update accessory after state change."""
|
"""Update accessory after state change."""
|
||||||
value = convert_to_float(new_state.state)
|
value = convert_to_float(new_state.state)
|
||||||
if value:
|
if value:
|
||||||
@ -248,9 +254,10 @@ class LightSensor(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update accessory after state change."""
|
"""Update accessory after state change."""
|
||||||
luminance = convert_to_float(new_state.state)
|
luminance = convert_to_float(new_state.state)
|
||||||
if luminance and self.char_light.value != luminance:
|
if luminance and self.char_light.value != luminance:
|
||||||
@ -281,9 +288,10 @@ class BinarySensor(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update accessory after state change."""
|
"""Update accessory after state change."""
|
||||||
state = new_state.state
|
state = new_state.state
|
||||||
detected = self.format(state in (STATE_ON, STATE_HOME))
|
detected = self.format(state in (STATE_ON, STATE_HOME))
|
||||||
|
@ -24,7 +24,7 @@ from homeassistant.const import (
|
|||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
)
|
)
|
||||||
from homeassistant.core import split_entity_id
|
from homeassistant.core import callback, split_entity_id
|
||||||
from homeassistant.helpers.event import call_later
|
from homeassistant.helpers.event import call_later
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory
|
from .accessories import TYPES, HomeAccessory
|
||||||
@ -71,7 +71,7 @@ class Outlet(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def set_state(self, value):
|
def set_state(self, value):
|
||||||
"""Move switch state to value if call came from HomeKit."""
|
"""Move switch state to value if call came from HomeKit."""
|
||||||
@ -80,7 +80,8 @@ class Outlet(HomeAccessory):
|
|||||||
service = SERVICE_TURN_ON if value else SERVICE_TURN_OFF
|
service = SERVICE_TURN_ON if value else SERVICE_TURN_OFF
|
||||||
self.call_service(DOMAIN, service, params)
|
self.call_service(DOMAIN, service, params)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update switch state after state changed."""
|
"""Update switch state after state changed."""
|
||||||
current_state = new_state.state == STATE_ON
|
current_state = new_state.state == STATE_ON
|
||||||
if self.char_on.value is not current_state:
|
if self.char_on.value is not current_state:
|
||||||
@ -106,7 +107,7 @@ class Switch(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def is_activate(self, state):
|
def is_activate(self, state):
|
||||||
"""Check if entity is activate only."""
|
"""Check if entity is activate only."""
|
||||||
@ -136,7 +137,8 @@ class Switch(HomeAccessory):
|
|||||||
if self.activate_only:
|
if self.activate_only:
|
||||||
call_later(self.hass, 1, self.reset_switch)
|
call_later(self.hass, 1, self.reset_switch)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update switch state after state changed."""
|
"""Update switch state after state changed."""
|
||||||
self.activate_only = self.is_activate(new_state)
|
self.activate_only = self.is_activate(new_state)
|
||||||
if self.activate_only:
|
if self.activate_only:
|
||||||
@ -162,7 +164,8 @@ class DockVacuum(Switch):
|
|||||||
service = SERVICE_START if value else SERVICE_RETURN_TO_BASE
|
service = SERVICE_START if value else SERVICE_RETURN_TO_BASE
|
||||||
self.call_service(VACUUM_DOMAIN, service, params)
|
self.call_service(VACUUM_DOMAIN, service, params)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update switch state after state changed."""
|
"""Update switch state after state changed."""
|
||||||
current_state = new_state.state in (STATE_CLEANING, STATE_ON)
|
current_state = new_state.state in (STATE_CLEANING, STATE_ON)
|
||||||
if self.char_on.value is not current_state:
|
if self.char_on.value is not current_state:
|
||||||
@ -191,7 +194,7 @@ class Valve(HomeAccessory):
|
|||||||
)
|
)
|
||||||
# Set the state so it is in sync on initial
|
# Set the state so it is in sync on initial
|
||||||
# GET to avoid an event storm after homekit startup
|
# GET to avoid an event storm after homekit startup
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def set_state(self, value):
|
def set_state(self, value):
|
||||||
"""Move value state to value if call came from HomeKit."""
|
"""Move value state to value if call came from HomeKit."""
|
||||||
@ -201,7 +204,8 @@ class Valve(HomeAccessory):
|
|||||||
service = SERVICE_TURN_ON if value else SERVICE_TURN_OFF
|
service = SERVICE_TURN_ON if value else SERVICE_TURN_OFF
|
||||||
self.call_service(DOMAIN, service, params)
|
self.call_service(DOMAIN, service, params)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update switch state after state changed."""
|
"""Update switch state after state changed."""
|
||||||
current_state = 1 if new_state.state == STATE_ON else 0
|
current_state = 1 if new_state.state == STATE_ON else 0
|
||||||
if self.char_active.value != current_state:
|
if self.char_active.value != current_state:
|
||||||
|
@ -51,6 +51,7 @@ from homeassistant.const import (
|
|||||||
TEMP_FAHRENHEIT,
|
TEMP_FAHRENHEIT,
|
||||||
UNIT_PERCENTAGE,
|
UNIT_PERCENTAGE,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory
|
from .accessories import TYPES, HomeAccessory
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -220,7 +221,7 @@ class Thermostat(HomeAccessory):
|
|||||||
CHAR_CURRENT_HUMIDITY, value=50
|
CHAR_CURRENT_HUMIDITY, value=50
|
||||||
)
|
)
|
||||||
|
|
||||||
self._update_state(state)
|
self._async_update_state(state)
|
||||||
|
|
||||||
serv_thermostat.setter_callback = self._set_chars
|
serv_thermostat.setter_callback = self._set_chars
|
||||||
|
|
||||||
@ -391,7 +392,8 @@ class Thermostat(HomeAccessory):
|
|||||||
DOMAIN_CLIMATE, SERVICE_SET_HUMIDITY, params, f"{value}{UNIT_PERCENTAGE}"
|
DOMAIN_CLIMATE, SERVICE_SET_HUMIDITY, params, f"{value}{UNIT_PERCENTAGE}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update thermostat state after state changed."""
|
"""Update thermostat state after state changed."""
|
||||||
if self._state_updates < 3:
|
if self._state_updates < 3:
|
||||||
# When we get the first state updates
|
# When we get the first state updates
|
||||||
@ -414,9 +416,10 @@ class Thermostat(HomeAccessory):
|
|||||||
)
|
)
|
||||||
self._state_updates += 1
|
self._state_updates += 1
|
||||||
|
|
||||||
self._update_state(new_state)
|
self._async_update_state(new_state)
|
||||||
|
|
||||||
def _update_state(self, new_state):
|
@callback
|
||||||
|
def _async_update_state(self, new_state):
|
||||||
"""Update state without rechecking the device features."""
|
"""Update state without rechecking the device features."""
|
||||||
features = new_state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
features = new_state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||||
|
|
||||||
@ -544,7 +547,7 @@ class WaterHeater(HomeAccessory):
|
|||||||
)
|
)
|
||||||
|
|
||||||
state = self.hass.states.get(self.entity_id)
|
state = self.hass.states.get(self.entity_id)
|
||||||
self.update_state(state)
|
self.async_update_state(state)
|
||||||
|
|
||||||
def get_temperature_range(self):
|
def get_temperature_range(self):
|
||||||
"""Return min and max temperature range."""
|
"""Return min and max temperature range."""
|
||||||
@ -586,7 +589,8 @@ class WaterHeater(HomeAccessory):
|
|||||||
f"{temperature}{self._unit}",
|
f"{temperature}{self._unit}",
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_state(self, new_state):
|
@callback
|
||||||
|
def async_update_state(self, new_state):
|
||||||
"""Update water_heater state after state change."""
|
"""Update water_heater state after state change."""
|
||||||
# Update current and target temperature
|
# Update current and target temperature
|
||||||
temperature = new_state.attributes.get(ATTR_TEMPERATURE)
|
temperature = new_state.attributes.get(ATTR_TEMPERATURE)
|
||||||
|
@ -100,19 +100,19 @@ async def test_home_accessory(hass, hk_driver):
|
|||||||
hass.states.async_set(entity_id, "on")
|
hass.states.async_set(entity_id, "on")
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.homekit.accessories.HomeAccessory.update_state"
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
) as mock_update_state:
|
) as mock_async_update_state:
|
||||||
await acc.run_handler()
|
await acc.run_handler()
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
mock_update_state.assert_called_with(state)
|
mock_async_update_state.assert_called_with(state)
|
||||||
|
|
||||||
hass.states.async_remove(entity_id)
|
hass.states.async_remove(entity_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert mock_update_state.call_count == 1
|
assert mock_async_update_state.call_count == 1
|
||||||
|
|
||||||
with pytest.raises(NotImplementedError):
|
with pytest.raises(NotImplementedError):
|
||||||
acc.update_state("new_state")
|
acc.async_update_state("new_state")
|
||||||
|
|
||||||
# Test model name from domain
|
# Test model name from domain
|
||||||
entity_id = "test_model.demo"
|
entity_id = "test_model.demo"
|
||||||
@ -130,52 +130,82 @@ async def test_battery_service(hass, hk_driver, caplog):
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
acc = HomeAccessory(hass, hk_driver, "Battery Service", entity_id, 2, None)
|
acc = HomeAccessory(hass, hk_driver, "Battery Service", entity_id, 2, None)
|
||||||
acc.update_state = lambda x: None
|
|
||||||
assert acc._char_battery.value == 0
|
assert acc._char_battery.value == 0
|
||||||
assert acc._char_low_battery.value == 0
|
assert acc._char_low_battery.value == 0
|
||||||
assert acc._char_charging.value == 2
|
assert acc._char_charging.value == 2
|
||||||
|
|
||||||
await acc.run_handler()
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
) as mock_async_update_state:
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
|
|
||||||
assert acc._char_battery.value == 50
|
assert acc._char_battery.value == 50
|
||||||
assert acc._char_low_battery.value == 0
|
assert acc._char_low_battery.value == 0
|
||||||
assert acc._char_charging.value == 2
|
assert acc._char_charging.value == 2
|
||||||
|
|
||||||
hass.states.async_set(entity_id, None, {ATTR_BATTERY_LEVEL: 15})
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
) as mock_async_update_state:
|
||||||
|
hass.states.async_set(entity_id, None, {ATTR_BATTERY_LEVEL: 15})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
assert acc._char_battery.value == 15
|
assert acc._char_battery.value == 15
|
||||||
assert acc._char_low_battery.value == 1
|
assert acc._char_low_battery.value == 1
|
||||||
assert acc._char_charging.value == 2
|
assert acc._char_charging.value == 2
|
||||||
|
|
||||||
hass.states.async_set(entity_id, None, {ATTR_BATTERY_LEVEL: "error"})
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
) as mock_async_update_state:
|
||||||
|
hass.states.async_set(entity_id, None, {ATTR_BATTERY_LEVEL: "error"})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
assert acc._char_battery.value == 15
|
assert acc._char_battery.value == 15
|
||||||
assert acc._char_low_battery.value == 1
|
assert acc._char_low_battery.value == 1
|
||||||
assert acc._char_charging.value == 2
|
assert acc._char_charging.value == 2
|
||||||
assert "ERROR" not in caplog.text
|
assert "ERROR" not in caplog.text
|
||||||
|
|
||||||
# Test charging
|
# Test charging
|
||||||
hass.states.async_set(
|
with patch(
|
||||||
entity_id, None, {ATTR_BATTERY_LEVEL: 10, ATTR_BATTERY_CHARGING: True}
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
)
|
) as mock_async_update_state:
|
||||||
await hass.async_block_till_done()
|
hass.states.async_set(
|
||||||
|
entity_id, None, {ATTR_BATTERY_LEVEL: 10, ATTR_BATTERY_CHARGING: True}
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
|
|
||||||
acc = HomeAccessory(hass, hk_driver, "Battery Service", entity_id, 2, None)
|
with patch(
|
||||||
acc.update_state = lambda x: None
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
assert acc._char_battery.value == 0
|
):
|
||||||
assert acc._char_low_battery.value == 0
|
acc = HomeAccessory(hass, hk_driver, "Battery Service", entity_id, 2, None)
|
||||||
assert acc._char_charging.value == 2
|
assert acc._char_battery.value == 0
|
||||||
|
assert acc._char_low_battery.value == 0
|
||||||
|
assert acc._char_charging.value == 2
|
||||||
|
|
||||||
await acc.run_handler()
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
) as mock_async_update_state:
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
assert acc._char_battery.value == 10
|
assert acc._char_battery.value == 10
|
||||||
assert acc._char_low_battery.value == 1
|
assert acc._char_low_battery.value == 1
|
||||||
assert acc._char_charging.value == 1
|
assert acc._char_charging.value == 1
|
||||||
|
|
||||||
hass.states.async_set(
|
with patch(
|
||||||
entity_id, None, {ATTR_BATTERY_LEVEL: 100, ATTR_BATTERY_CHARGING: False}
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
)
|
):
|
||||||
await hass.async_block_till_done()
|
hass.states.async_set(
|
||||||
|
entity_id, None, {ATTR_BATTERY_LEVEL: 100, ATTR_BATTERY_CHARGING: False}
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
assert acc._char_battery.value == 100
|
assert acc._char_battery.value == 100
|
||||||
assert acc._char_low_battery.value == 0
|
assert acc._char_low_battery.value == 0
|
||||||
assert acc._char_charging.value == 0
|
assert acc._char_charging.value == 0
|
||||||
@ -197,11 +227,15 @@ async def test_linked_battery_sensor(hass, hk_driver, caplog):
|
|||||||
2,
|
2,
|
||||||
{CONF_LINKED_BATTERY_SENSOR: linked_battery},
|
{CONF_LINKED_BATTERY_SENSOR: linked_battery},
|
||||||
)
|
)
|
||||||
acc.update_state = lambda x: None
|
|
||||||
assert acc.linked_battery_sensor == linked_battery
|
assert acc.linked_battery_sensor == linked_battery
|
||||||
|
|
||||||
await acc.run_handler()
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
) as mock_async_update_state:
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
assert acc._char_battery.value == 50
|
assert acc._char_battery.value == 50
|
||||||
assert acc._char_low_battery.value == 0
|
assert acc._char_low_battery.value == 0
|
||||||
assert acc._char_charging.value == 2
|
assert acc._char_charging.value == 2
|
||||||
@ -212,13 +246,19 @@ async def test_linked_battery_sensor(hass, hk_driver, caplog):
|
|||||||
assert acc._char_low_battery.value == 1
|
assert acc._char_low_battery.value == 1
|
||||||
|
|
||||||
# Ignore battery change on entity if it has linked_battery
|
# Ignore battery change on entity if it has linked_battery
|
||||||
hass.states.async_set(entity_id, "open", {ATTR_BATTERY_LEVEL: 90})
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
):
|
||||||
|
hass.states.async_set(entity_id, "open", {ATTR_BATTERY_LEVEL: 90})
|
||||||
|
await hass.async_block_till_done()
|
||||||
assert acc._char_battery.value == 10
|
assert acc._char_battery.value == 10
|
||||||
|
|
||||||
# Test none numeric state for linked_battery
|
# Test none numeric state for linked_battery
|
||||||
hass.states.async_set(linked_battery, "error", None)
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
):
|
||||||
|
hass.states.async_set(linked_battery, "error", None)
|
||||||
|
await hass.async_block_till_done()
|
||||||
assert acc._char_battery.value == 10
|
assert acc._char_battery.value == 10
|
||||||
assert "ERROR" not in caplog.text
|
assert "ERROR" not in caplog.text
|
||||||
|
|
||||||
@ -234,15 +274,20 @@ async def test_linked_battery_sensor(hass, hk_driver, caplog):
|
|||||||
2,
|
2,
|
||||||
{CONF_LINKED_BATTERY_SENSOR: linked_battery, CONF_LOW_BATTERY_THRESHOLD: 50},
|
{CONF_LINKED_BATTERY_SENSOR: linked_battery, CONF_LOW_BATTERY_THRESHOLD: 50},
|
||||||
)
|
)
|
||||||
acc.update_state = lambda x: None
|
with patch(
|
||||||
await acc.run_handler()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
await hass.async_block_till_done()
|
) as mock_async_update_state:
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
assert acc._char_battery.value == 20
|
assert acc._char_battery.value == 20
|
||||||
assert acc._char_low_battery.value == 1
|
assert acc._char_low_battery.value == 1
|
||||||
assert acc._char_charging.value == 1
|
assert acc._char_charging.value == 1
|
||||||
|
|
||||||
hass.states.async_set(linked_battery, 100, {ATTR_BATTERY_CHARGING: False})
|
hass.states.async_set(linked_battery, 100, {ATTR_BATTERY_CHARGING: False})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
assert acc._char_battery.value == 100
|
assert acc._char_battery.value == 100
|
||||||
assert acc._char_low_battery.value == 0
|
assert acc._char_low_battery.value == 0
|
||||||
assert acc._char_charging.value == 0
|
assert acc._char_charging.value == 0
|
||||||
@ -264,23 +309,37 @@ async def test_linked_battery_charging_sensor(hass, hk_driver, caplog):
|
|||||||
2,
|
2,
|
||||||
{CONF_LINKED_BATTERY_CHARGING_SENSOR: linked_battery_charging_sensor},
|
{CONF_LINKED_BATTERY_CHARGING_SENSOR: linked_battery_charging_sensor},
|
||||||
)
|
)
|
||||||
acc.update_state = lambda x: None
|
|
||||||
assert acc.linked_battery_charging_sensor == linked_battery_charging_sensor
|
assert acc.linked_battery_charging_sensor == linked_battery_charging_sensor
|
||||||
|
|
||||||
await acc.run_handler()
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
) as mock_async_update_state:
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
assert acc._char_battery.value == 100
|
assert acc._char_battery.value == 100
|
||||||
assert acc._char_low_battery.value == 0
|
assert acc._char_low_battery.value == 0
|
||||||
assert acc._char_charging.value == 1
|
assert acc._char_charging.value == 1
|
||||||
|
|
||||||
hass.states.async_set(linked_battery_charging_sensor, STATE_OFF, None)
|
with patch(
|
||||||
await acc.run_handler()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
await hass.async_block_till_done()
|
) as mock_async_update_state:
|
||||||
|
hass.states.async_set(linked_battery_charging_sensor, STATE_OFF, None)
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
assert acc._char_charging.value == 0
|
assert acc._char_charging.value == 0
|
||||||
|
|
||||||
hass.states.async_set(linked_battery_charging_sensor, STATE_ON, None)
|
with patch(
|
||||||
await acc.run_handler()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
await hass.async_block_till_done()
|
) as mock_async_update_state:
|
||||||
|
hass.states.async_set(linked_battery_charging_sensor, STATE_ON, None)
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
assert acc._char_charging.value == 1
|
assert acc._char_charging.value == 1
|
||||||
|
|
||||||
|
|
||||||
@ -307,11 +366,15 @@ async def test_linked_battery_sensor_and_linked_battery_charging_sensor(
|
|||||||
CONF_LINKED_BATTERY_CHARGING_SENSOR: linked_battery_charging_sensor,
|
CONF_LINKED_BATTERY_CHARGING_SENSOR: linked_battery_charging_sensor,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
acc.update_state = lambda x: None
|
|
||||||
assert acc.linked_battery_sensor == linked_battery
|
assert acc.linked_battery_sensor == linked_battery
|
||||||
|
|
||||||
await acc.run_handler()
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
) as mock_async_update_state:
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
assert acc._char_battery.value == 50
|
assert acc._char_battery.value == 50
|
||||||
assert acc._char_low_battery.value == 0
|
assert acc._char_low_battery.value == 0
|
||||||
assert acc._char_charging.value == 1
|
assert acc._char_charging.value == 1
|
||||||
@ -356,11 +419,15 @@ async def test_missing_linked_battery_sensor(hass, hk_driver, caplog):
|
|||||||
2,
|
2,
|
||||||
{CONF_LINKED_BATTERY_SENSOR: linked_battery},
|
{CONF_LINKED_BATTERY_SENSOR: linked_battery},
|
||||||
)
|
)
|
||||||
acc.update_state = lambda x: None
|
|
||||||
assert not acc.linked_battery_sensor
|
assert not acc.linked_battery_sensor
|
||||||
|
|
||||||
await acc.run_handler()
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
) as mock_async_update_state:
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
|
|
||||||
assert not acc.linked_battery_sensor
|
assert not acc.linked_battery_sensor
|
||||||
assert acc._char_battery is None
|
assert acc._char_battery is None
|
||||||
@ -377,15 +444,22 @@ async def test_battery_appears_after_startup(hass, hk_driver, caplog):
|
|||||||
acc = HomeAccessory(
|
acc = HomeAccessory(
|
||||||
hass, hk_driver, "Accessory without battery", entity_id, 2, None
|
hass, hk_driver, "Accessory without battery", entity_id, 2, None
|
||||||
)
|
)
|
||||||
acc.update_state = lambda x: None
|
|
||||||
assert acc._char_battery is None
|
assert acc._char_battery is None
|
||||||
|
|
||||||
await acc.run_handler()
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
) as mock_async_update_state:
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
mock_async_update_state.assert_called_with(state)
|
||||||
assert acc._char_battery is None
|
assert acc._char_battery is None
|
||||||
|
|
||||||
hass.states.async_set(entity_id, None, {ATTR_BATTERY_LEVEL: 15})
|
with patch(
|
||||||
await hass.async_block_till_done()
|
"homeassistant.components.homekit.accessories.HomeAccessory.async_update_state"
|
||||||
|
):
|
||||||
|
hass.states.async_set(entity_id, None, {ATTR_BATTERY_LEVEL: 15})
|
||||||
|
await hass.async_block_till_done()
|
||||||
assert acc._char_battery is None
|
assert acc._char_battery is None
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,27 @@ MOCK_END_POINTS_TLV = "ARAzA9UDF8xGmrZykkNqcaL2AgEAAxoBAQACDTE5Mi4xNjguMjA4LjUDA
|
|||||||
MOCK_START_STREAM_SESSION_UUID = UUID("3303d503-17cc-469a-b672-92436a71a2f6")
|
MOCK_START_STREAM_SESSION_UUID = UUID("3303d503-17cc-469a-b672-92436a71a2f6")
|
||||||
|
|
||||||
|
|
||||||
|
async def _async_start_streaming(hass, acc):
|
||||||
|
"""Start streaming a camera."""
|
||||||
|
acc.set_selected_stream_configuration(MOCK_START_STREAM_TLV)
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
|
async def _async_setup_endpoints(hass, acc):
|
||||||
|
"""Set camera endpoints."""
|
||||||
|
acc.set_endpoints(MOCK_END_POINTS_TLV)
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
|
async def _async_stop_stream(hass, acc):
|
||||||
|
"""Stop a camera stream."""
|
||||||
|
await acc.stop()
|
||||||
|
await acc.run_handler()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def run_driver(hass):
|
def run_driver(hass):
|
||||||
"""Return a custom AccessoryDriver instance for HomeKit accessory init."""
|
"""Return a custom AccessoryDriver instance for HomeKit accessory init."""
|
||||||
@ -92,9 +113,9 @@ async def test_camera_stream_source_configured(hass, run_driver, events):
|
|||||||
assert acc.aid == 2
|
assert acc.aid == 2
|
||||||
assert acc.category == 17 # Camera
|
assert acc.category == 17 # Camera
|
||||||
|
|
||||||
acc.set_endpoints(MOCK_END_POINTS_TLV)
|
await _async_setup_endpoints(hass, acc)
|
||||||
session_info = acc.sessions[MOCK_START_STREAM_SESSION_UUID]
|
|
||||||
working_ffmpeg = _get_working_mock_ffmpeg()
|
working_ffmpeg = _get_working_mock_ffmpeg()
|
||||||
|
session_info = acc.sessions[MOCK_START_STREAM_SESSION_UUID]
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
||||||
@ -103,8 +124,8 @@ async def test_camera_stream_source_configured(hass, run_driver, events):
|
|||||||
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
||||||
return_value=working_ffmpeg,
|
return_value=working_ffmpeg,
|
||||||
):
|
):
|
||||||
acc.set_selected_stream_configuration(MOCK_START_STREAM_TLV)
|
await _async_start_streaming(hass, acc)
|
||||||
await hass.async_block_till_done()
|
await _async_stop_stream(hass, acc)
|
||||||
|
|
||||||
expected_output = (
|
expected_output = (
|
||||||
"-map 0:v:0 -an -c:v libx264 -profile:v high -tune zerolatency -pix_fmt "
|
"-map 0:v:0 -an -c:v libx264 -profile:v high -tune zerolatency -pix_fmt "
|
||||||
@ -132,11 +153,10 @@ async def test_camera_stream_source_configured(hass, run_driver, events):
|
|||||||
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
||||||
return_value=working_ffmpeg,
|
return_value=working_ffmpeg,
|
||||||
):
|
):
|
||||||
acc.set_selected_stream_configuration(MOCK_START_STREAM_TLV)
|
await _async_start_streaming(hass, acc)
|
||||||
await acc.stop_stream(session_info)
|
await _async_stop_stream(hass, acc)
|
||||||
# Calling a second time should not throw
|
# Calling a second time should not throw
|
||||||
await acc.stop_stream(session_info)
|
await _async_stop_stream(hass, acc)
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
turbo_jpeg = mock_turbo_jpeg(
|
turbo_jpeg = mock_turbo_jpeg(
|
||||||
first_width=16, first_height=12, second_width=300, second_height=200
|
first_width=16, first_height=12, second_width=300, second_height=200
|
||||||
@ -195,8 +215,7 @@ async def test_camera_stream_source_configured_with_failing_ffmpeg(
|
|||||||
assert acc.aid == 2
|
assert acc.aid == 2
|
||||||
assert acc.category == 17 # Camera
|
assert acc.category == 17 # Camera
|
||||||
|
|
||||||
acc.set_endpoints(MOCK_END_POINTS_TLV)
|
await _async_setup_endpoints(hass, acc)
|
||||||
session_info = acc.sessions[MOCK_START_STREAM_SESSION_UUID]
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
||||||
@ -205,11 +224,10 @@ async def test_camera_stream_source_configured_with_failing_ffmpeg(
|
|||||||
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
||||||
return_value=_get_failing_mock_ffmpeg(),
|
return_value=_get_failing_mock_ffmpeg(),
|
||||||
):
|
):
|
||||||
acc.set_selected_stream_configuration(MOCK_START_STREAM_TLV)
|
await _async_start_streaming(hass, acc)
|
||||||
await acc.stop_stream(session_info)
|
await _async_stop_stream(hass, acc)
|
||||||
# Calling a second time should not throw
|
# Calling a second time should not throw
|
||||||
await acc.stop_stream(session_info)
|
await _async_stop_stream(hass, acc)
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
|
|
||||||
async def test_camera_stream_source_found(hass, run_driver, events):
|
async def test_camera_stream_source_found(hass, run_driver, events):
|
||||||
@ -229,8 +247,7 @@ async def test_camera_stream_source_found(hass, run_driver, events):
|
|||||||
assert acc.aid == 2
|
assert acc.aid == 2
|
||||||
assert acc.category == 17 # Camera
|
assert acc.category == 17 # Camera
|
||||||
|
|
||||||
acc.set_endpoints(MOCK_END_POINTS_TLV)
|
await _async_setup_endpoints(hass, acc)
|
||||||
session_info = acc.sessions[MOCK_START_STREAM_SESSION_UUID]
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
||||||
@ -239,9 +256,8 @@ async def test_camera_stream_source_found(hass, run_driver, events):
|
|||||||
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
||||||
return_value=_get_working_mock_ffmpeg(),
|
return_value=_get_working_mock_ffmpeg(),
|
||||||
):
|
):
|
||||||
acc.set_selected_stream_configuration(MOCK_START_STREAM_TLV)
|
await _async_start_streaming(hass, acc)
|
||||||
await acc.stop_stream(session_info)
|
await _async_stop_stream(hass, acc)
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
||||||
@ -250,9 +266,8 @@ async def test_camera_stream_source_found(hass, run_driver, events):
|
|||||||
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
||||||
return_value=_get_working_mock_ffmpeg(),
|
return_value=_get_working_mock_ffmpeg(),
|
||||||
):
|
):
|
||||||
acc.set_selected_stream_configuration(MOCK_START_STREAM_TLV)
|
await _async_start_streaming(hass, acc)
|
||||||
await acc.stop_stream(session_info)
|
await _async_stop_stream(hass, acc)
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
|
|
||||||
async def test_camera_stream_source_fails(hass, run_driver, events):
|
async def test_camera_stream_source_fails(hass, run_driver, events):
|
||||||
@ -272,8 +287,7 @@ async def test_camera_stream_source_fails(hass, run_driver, events):
|
|||||||
assert acc.aid == 2
|
assert acc.aid == 2
|
||||||
assert acc.category == 17 # Camera
|
assert acc.category == 17 # Camera
|
||||||
|
|
||||||
acc.set_endpoints(MOCK_END_POINTS_TLV)
|
await _async_setup_endpoints(hass, acc)
|
||||||
session_info = acc.sessions[MOCK_START_STREAM_SESSION_UUID]
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
||||||
@ -282,9 +296,8 @@ async def test_camera_stream_source_fails(hass, run_driver, events):
|
|||||||
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
||||||
return_value=_get_working_mock_ffmpeg(),
|
return_value=_get_working_mock_ffmpeg(),
|
||||||
):
|
):
|
||||||
acc.set_selected_stream_configuration(MOCK_START_STREAM_TLV)
|
await _async_start_streaming(hass, acc)
|
||||||
await acc.stop_stream(session_info)
|
await _async_stop_stream(hass, acc)
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
|
|
||||||
async def test_camera_with_no_stream(hass, run_driver, events):
|
async def test_camera_with_no_stream(hass, run_driver, events):
|
||||||
@ -302,9 +315,9 @@ async def test_camera_with_no_stream(hass, run_driver, events):
|
|||||||
assert acc.aid == 2
|
assert acc.aid == 2
|
||||||
assert acc.category == 17 # Camera
|
assert acc.category == 17 # Camera
|
||||||
|
|
||||||
acc.set_endpoints(MOCK_END_POINTS_TLV)
|
await _async_setup_endpoints(hass, acc)
|
||||||
acc.set_selected_stream_configuration(MOCK_START_STREAM_TLV)
|
await _async_start_streaming(hass, acc)
|
||||||
await hass.async_block_till_done()
|
await _async_stop_stream(hass, acc)
|
||||||
|
|
||||||
with pytest.raises(HomeAssistantError):
|
with pytest.raises(HomeAssistantError):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
@ -344,7 +357,7 @@ async def test_camera_stream_source_configured_and_copy_codec(hass, run_driver,
|
|||||||
assert acc.aid == 2
|
assert acc.aid == 2
|
||||||
assert acc.category == 17 # Camera
|
assert acc.category == 17 # Camera
|
||||||
|
|
||||||
acc.set_endpoints(MOCK_END_POINTS_TLV)
|
await _async_setup_endpoints(hass, acc)
|
||||||
session_info = acc.sessions[MOCK_START_STREAM_SESSION_UUID]
|
session_info = acc.sessions[MOCK_START_STREAM_SESSION_UUID]
|
||||||
|
|
||||||
working_ffmpeg = _get_working_mock_ffmpeg()
|
working_ffmpeg = _get_working_mock_ffmpeg()
|
||||||
@ -356,9 +369,8 @@ async def test_camera_stream_source_configured_and_copy_codec(hass, run_driver,
|
|||||||
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
"homeassistant.components.homekit.type_cameras.HAFFmpeg",
|
||||||
return_value=working_ffmpeg,
|
return_value=working_ffmpeg,
|
||||||
):
|
):
|
||||||
acc.set_selected_stream_configuration(MOCK_START_STREAM_TLV)
|
await _async_start_streaming(hass, acc)
|
||||||
await acc.stop_stream(session_info)
|
await _async_stop_stream(hass, acc)
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
expected_output = (
|
expected_output = (
|
||||||
"-map 0:v:0 -an -c:v copy -tune zerolatency -pix_fmt yuv420p -r 30 -b:v 299k "
|
"-map 0:v:0 -an -c:v copy -tune zerolatency -pix_fmt yuv420p -r 30 -b:v 299k "
|
||||||
|
Loading…
x
Reference in New Issue
Block a user