Skip to content

Commit

Permalink
Merge pull request #22 from nalin29/master
Browse files Browse the repository at this point in the history
add media player via room api
  • Loading branch information
lawtancool authored Sep 3, 2024
2 parents ec50ba8 + 2f61928 commit ca5b1f8
Show file tree
Hide file tree
Showing 7 changed files with 611 additions and 2 deletions.
69 changes: 69 additions & 0 deletions custom_components/control4/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import asyncio
import json
import logging
from typing import Any
import random

from aiohttp import client_exceptions
Expand All @@ -19,12 +20,17 @@
CONF_TOKEN,
CONF_USERNAME,
Platform,
CONF_SCAN_INTERVAL,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client, device_registry as dr
from homeassistant.helpers.entity import DeviceInfo, Entity
from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)

from .const import (
CONF_ACCOUNT,
Expand All @@ -42,11 +48,13 @@
CONF_DIRECTOR_MODEL,
CONF_DIRECTOR_SW_VERSION,
CONF_WEBSOCKET,
CONF_UI_CONFIGURATION,
DEFAULT_ALARM_AWAY_MODE,
DEFAULT_ALARM_CUSTOM_BYPASS_MODE,
DEFAULT_ALARM_HOME_MODE,
DEFAULT_ALARM_NIGHT_MODE,
DEFAULT_ALARM_VACATION_MODE,
DEFAULT_SCAN_INTERVAL,
DOMAIN,
RETRY_BACKOFF_MAX_SEC,
SCHEDULE_REFRESH_ADVANCE_SEC,
Expand All @@ -60,6 +68,7 @@
Platform.ALARM_CONTROL_PANEL,
Platform.BINARY_SENSOR,
Platform.LOCK,
Platform.MEDIA_PLAYER,
]


Expand Down Expand Up @@ -110,6 +119,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
director_all_items = json.loads(director_all_items)
entry_data[CONF_DIRECTOR_ALL_ITEMS] = director_all_items

entry_data[CONF_UI_CONFIGURATION] = json.loads(
await entry_data[CONF_DIRECTOR].getUiConfiguration()
)

# Load options from config entry
entry_data[CONF_SCAN_INTERVAL] = entry.options.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
)

# Load options from config entry
entry_data[CONF_ALARM_AWAY_MODE] = entry.options.get(
CONF_ALARM_AWAY_MODE, DEFAULT_ALARM_AWAY_MODE
Expand Down Expand Up @@ -450,3 +468,54 @@ def device_info(self) -> DeviceInfo:
def extra_state_attributes(self) -> dict:
"""Return Extra state attributes."""
return self._extra_state_attributes


class Control4CoordinatorEntity(CoordinatorEntity[Any]):
"""Base entity for Control4."""

def __init__(
self,
entry_data: dict,
coordinator: DataUpdateCoordinator[Any],
name: str | None,
idx: int,
device_name: str | None,
device_manufacturer: str | None,
device_model: str | None,
device_id: int,
device_area: str,
device_attributes: dict,
) -> None:
"""Initialize a Control4 entity."""
super().__init__(coordinator)
self.entry_data = entry_data
self._attr_name = name
self._attr_unique_id = str(idx)
self._idx = idx
self._controller_unique_id = entry_data[CONF_CONTROLLER_UNIQUE_ID]
self._device_name = device_name
self._device_manufacturer = device_manufacturer
self._device_model = device_model
self._device_id = device_id
self._device_area = device_area
self._extra_state_attributes = device_attributes
self._extra_state_attributes["item id"] = idx
self._extra_state_attributes["parent item id"] = device_id

@property
def device_info(self) -> DeviceInfo:
"""Return info of parent Control4 device of entity."""
return DeviceInfo(
identifiers={(DOMAIN, str(self._device_id))},
manufacturer=self._device_manufacturer,
model=self._device_model,
name=self._device_name,
via_device=(DOMAIN, self._controller_unique_id),
suggested_area=self._device_area,
)

@property
def extra_state_attributes(self) -> dict:
"""Return Extra state attributes."""
self._extra_state_attributes.update(self.coordinator.data[self._idx])
return self._extra_state_attributes
17 changes: 15 additions & 2 deletions custom_components/control4/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@
import voluptuous as vol

from homeassistant import config_entries, exceptions
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
CONF_USERNAME,
CONF_SCAN_INTERVAL,
)
from homeassistant.core import callback
from homeassistant.helpers import aiohttp_client
from homeassistant.helpers import aiohttp_client, config_validation as cv
from homeassistant.helpers.device_registry import format_mac

from .const import (
Expand All @@ -27,7 +32,9 @@
DEFAULT_ALARM_HOME_MODE,
DEFAULT_ALARM_NIGHT_MODE,
DEFAULT_ALARM_VACATION_MODE,
DEFAULT_SCAN_INTERVAL,
DOMAIN,
MIN_SCAN_INTERVAL,
)

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -196,6 +203,12 @@ async def async_step_init(self, user_input=None):
_LOGGER.debug(self.entry_data[CONF_ALARM_ARM_STATES])
data_schema = vol.Schema(
{
vol.Optional(
CONF_SCAN_INTERVAL,
default=self.config_entry.options.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
),
): vol.All(cv.positive_int, vol.Clamp(min=MIN_SCAN_INTERVAL)),
vol.Optional(
CONF_ALARM_AWAY_MODE,
default=self.config_entry.options.get(
Expand Down
4 changes: 4 additions & 0 deletions custom_components/control4/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
CONF_DIRECTOR_ALL_ITEMS = "director_all_items"
CONF_CONTROLLER_UNIQUE_ID = "controller_unique_id"
CONF_ALARM_ARM_STATES = "alarm_arm_states"
CONF_UI_CONFIGURATION = "ui_configuration"

DEFAULT_SCAN_INTERVAL = 5
MIN_SCAN_INTERVAL = 1

CONF_CONFIG_LISTENER = "config_listener"

Expand Down
14 changes: 14 additions & 0 deletions custom_components/control4/director_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from typing import Any
from collections import defaultdict
from collections.abc import Set

from .const import CONF_DIRECTOR, DOMAIN

Expand All @@ -19,3 +22,14 @@ async def director_get_entry_variables(
result[item["varName"]] = item["value"]

return result

async def update_variables_for_config_entry(
hass: HomeAssistant, entry: ConfigEntry, variable_names: Set[str]
) -> dict[int, dict[str, Any]]:
"""Retrieve data from the Control4 director."""
director = hass.data[DOMAIN][entry.entry_id][CONF_DIRECTOR]
data = await director.getAllItemVariableValue(variable_names)
result_dict: defaultdict[int, dict[str, Any]] = defaultdict(dict)
for item in data:
result_dict[item["id"]][item["varName"]] = item["value"]
return dict(result_dict)
Loading

0 comments on commit ca5b1f8

Please sign in to comment.