core/homeassistant/components/harmony/data.py

283 lines
9.5 KiB
Python
Raw Normal View History

Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
"""Harmony data object which contains the Harmony Client."""
from __future__ import annotations
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
import asyncio
from collections.abc import Iterable
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
import logging
from aioharmony.const import ClientCallbackType, SendCommandDevice
import aioharmony.exceptions as aioexc
from aioharmony.harmonyapi import HarmonyAPI as HarmonyClient
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
2021-10-23 13:35:33 +00:00
from homeassistant.helpers.entity import DeviceInfo
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
from .const import ACTIVITY_POWER_OFF
from .subscriber import HarmonySubscriberMixin
_LOGGER = logging.getLogger(__name__)
class HarmonyData(HarmonySubscriberMixin):
"""HarmonyData registers for Harmony hub updates."""
_client: HarmonyClient
def __init__(
self, hass: HomeAssistant, address: str, name: str, unique_id: str | None
) -> None:
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
"""Initialize a data object."""
super().__init__(hass)
self._name = name
self._unique_id = unique_id
self._available = False
self._address = address
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
@property
def activities(self):
"""List of all non-poweroff activity objects."""
activity_infos = self._client.config.get("activity", [])
return [
info
for info in activity_infos
if info["label"] is not None and info["label"] != ACTIVITY_POWER_OFF
]
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
@property
def activity_names(self):
"""Names of all the remotes activities."""
activity_infos = self.activities
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
activities = [activity["label"] for activity in activity_infos]
return activities
@property
def device_names(self):
"""Names of all of the devices connected to the hub."""
device_infos = self._client.config.get("device", [])
devices = [device["label"] for device in device_infos]
return devices
@property
def name(self):
"""Return the Harmony device's name."""
return self._name
@property
def unique_id(self):
"""Return the Harmony device's unique_id."""
return self._unique_id
@property
def json_config(self):
"""Return the hub config as json."""
if self._client.config is None:
return None
return self._client.json_config
@property
def available(self) -> bool:
"""Return if connected to the hub."""
return self._available
@property
def current_activity(self) -> tuple:
"""Return the current activity tuple."""
return self._client.current_activity
2021-10-23 13:35:33 +00:00
def device_info(self, domain: str) -> DeviceInfo:
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
"""Return hub device info."""
model = "Harmony Hub"
if "ethernetStatus" in self._client.hub_config.info:
model = "Harmony Hub Pro 2400"
2021-10-23 13:35:33 +00:00
return DeviceInfo(
identifiers={(domain, self.unique_id)},
manufacturer="Logitech",
model=model,
name=self.name,
sw_version=self._client.hub_config.info.get(
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
"hubSwVersion", self._client.fw_version
),
2021-11-20 14:34:09 +00:00
configuration_url="https://www.logitech.com/en-us/my-account",
2021-10-23 13:35:33 +00:00
)
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
async def connect(self) -> None:
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
"""Connect to the Harmony Hub."""
_LOGGER.debug("%s: Connecting", self._name)
callbacks = {
"config_updated": self._config_updated,
"connect": self._connected,
"disconnect": self._disconnected,
"new_activity_starting": self._activity_starting,
"new_activity": self._activity_started,
}
self._client = HarmonyClient(
ip_address=self._address, callbacks=ClientCallbackType(**callbacks)
)
connected = False
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
try:
connected = await self._client.connect()
except (asyncio.TimeoutError, aioexc.TimeOut) as err:
await self._client.close()
raise ConfigEntryNotReady(
f"{self._name}: Connection timed-out to {self._address}:8088"
) from err
except (ValueError, AttributeError) as err:
await self._client.close()
raise ConfigEntryNotReady(
f"{self._name}: Error {err} while connected HUB at:"
f" {self._address}:8088"
) from err
if not connected:
await self._client.close()
raise ConfigEntryNotReady(
f"{self._name}: Unable to connect to HUB at: {self._address}:8088"
)
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
async def shutdown(self):
"""Close connection on shutdown."""
_LOGGER.debug("%s: Closing Harmony Hub", self._name)
try:
await self._client.close()
except aioexc.TimeOut:
_LOGGER.warning("%s: Disconnect timed-out", self._name)
async def async_start_activity(self, activity: str):
"""Start an activity from the Harmony device."""
if not activity:
_LOGGER.error("%s: No activity specified with turn_on service", self.name)
return
activity_id = None
activity_name = None
if activity.isdigit() or activity == "-1":
_LOGGER.debug("%s: Activity is numeric", self.name)
activity_name = self._client.get_activity_name(int(activity))
if activity_name:
activity_id = activity
if activity_id is None:
_LOGGER.debug("%s: Find activity ID based on name", self.name)
activity_name = str(activity)
activity_id = self._client.get_activity_id(activity_name)
if activity_id is None:
_LOGGER.error("%s: Activity %s is invalid", self.name, activity)
return
_, current_activity_name = self.current_activity
if current_activity_name == activity_name:
# Automations or HomeKit may turn the device on multiple times
# when the current activity is already active which will cause
# harmony to loose state. This behavior is unexpected as turning
# the device on when its already on isn't expected to reset state.
_LOGGER.debug(
"%s: Current activity is already %s", self.name, activity_name
)
return
await self.async_lock_start_activity()
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
try:
await self._client.start_activity(activity_id)
except aioexc.TimeOut:
_LOGGER.error("%s: Starting activity %s timed-out", self.name, activity)
self.async_unlock_start_activity()
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
async def async_power_off(self):
"""Start the PowerOff activity."""
_LOGGER.debug("%s: Turn Off", self.name)
try:
await self._client.power_off()
except aioexc.TimeOut:
_LOGGER.error("%s: Powering off timed-out", self.name)
async def async_send_command(
self,
commands: Iterable[str],
device: str,
num_repeats: int,
delay_secs: float,
hold_secs: float,
):
"""Send a list of commands to one device."""
device_id = None
if device.isdigit():
_LOGGER.debug("%s: Device %s is numeric", self.name, device)
if self._client.get_device_name(int(device)):
device_id = device
if device_id is None:
_LOGGER.debug(
"%s: Find device ID %s based on device name", self.name, device
)
device_id = self._client.get_device_id(str(device).strip())
if device_id is None:
_LOGGER.error("%s: Device %s is invalid", self.name, device)
return
_LOGGER.debug(
(
"Sending commands to device %s holding for %s seconds "
"with a delay of %s seconds"
),
Generate switches for harmony activities automatically (#42331) * Adding switch code for harmony activities * Working on-off * Removing poll code for now * Async updates for current activity * Update our state based on events * Notifications we got connected or disconnected * Remove unncessary constructor arg * Initial switch tests * Additional tests for switch transitions * Test transitions for availability * Testing switch state changes * Tests passing * Final tests * Updating manifest. * Correctly mock the return value from a call to the library * Adding new subscriber classes * Update class name and location * Got the refactor working locally. * Tests passing * Tracking state changes * Remove write_to_config_file - this appears to never be read. It was added far back in the past to account for a harmony library change, but nothing ever reads that path. Removing that side effect from tests is a pain - avoid the side effect completely. * Connection changes tested * Clean up temporary code * Update .coveragerc for harmony component Specifically exclude untested files instead of the whole module * Fix linting * test sending activity change commands by id * Improving coverage * Testing channel change commands * Splitting subscriber logic into it's own class * Improve coverage and tighten up .coveragerc * Test cleanups. * re-add config file writing for harmony remote * Create fixture for the mock harmonyclient * Reduce duplication in subscription callbacks * use async_run_job to call callbacks * Adding some tests for async behaviors with subscribers. * async_call_later for delay in marking remote unavailable * Test disconnection handling in harmony remote * Early exit if activity not specified * Use connection state mixin * Lint fix after rebase * Fix isort * super init for ConnectionStateMixin * Adding @mkeesey to harmony CODEOWNERS
2021-01-04 23:21:14 +00:00
device,
hold_secs,
delay_secs,
)
# Creating list of commands to send.
snd_cmnd_list = []
for _ in range(num_repeats):
for single_command in commands:
send_command = SendCommandDevice(
device=device_id, command=single_command, delay=hold_secs
)
snd_cmnd_list.append(send_command)
if delay_secs > 0:
snd_cmnd_list.append(float(delay_secs))
_LOGGER.debug("%s: Sending commands", self.name)
try:
result_list = await self._client.send_commands(snd_cmnd_list)
except aioexc.TimeOut:
_LOGGER.error("%s: Sending commands timed-out", self.name)
return
for result in result_list:
_LOGGER.error(
"Sending command %s to device %s failed with code %s: %s",
result.command.command,
result.command.device,
result.code,
result.msg,
)
async def change_channel(self, channel: int):
"""Change the channel using Harmony remote."""
_LOGGER.debug("%s: Changing channel to %s", self.name, channel)
try:
await self._client.change_channel(channel)
except aioexc.TimeOut:
_LOGGER.error("%s: Changing channel to %s timed-out", self.name, channel)
async def sync(self) -> bool:
"""Sync the Harmony device with the web service.
Returns True if the sync was successful.
"""
_LOGGER.debug("%s: Syncing hub with Harmony cloud", self.name)
try:
await self._client.sync()
except aioexc.TimeOut:
_LOGGER.error("%s: Syncing hub with Harmony cloud timed-out", self.name)
return False
return True