-
-
Notifications
You must be signed in to change notification settings - Fork 38k
Add cover support to control4 #169417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add cover support to control4 #169417
Changes from 2 commits
0fb39b0
52adad6
4179faa
127eb78
39e476c
4fc7c92
0e441f5
c28e1d9
54be632
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,222 @@ | ||||
| """Platform for Control4 Covers (blinds and shades).""" | ||||
|
|
||||
| from __future__ import annotations | ||||
|
|
||||
| from datetime import timedelta | ||||
| import logging | ||||
| from typing import Any | ||||
|
|
||||
| from pyControl4.blind import C4Blind | ||||
| from pyControl4.error_handling import C4Exception | ||||
|
|
||||
| from homeassistant.components.cover import ( | ||||
| ATTR_POSITION, | ||||
| CoverDeviceClass, | ||||
| CoverEntity, | ||||
| CoverEntityFeature, | ||||
| ) | ||||
| from homeassistant.core import HomeAssistant | ||||
| from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback | ||||
| from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed | ||||
|
|
||||
| from . import Control4ConfigEntry, Control4RuntimeData, get_items_of_category | ||||
| from .const import CONTROL4_ENTITY_TYPE | ||||
| from .director_utils import update_variables_for_config_entry | ||||
| from .entity import Control4Entity | ||||
|
|
||||
| _LOGGER = logging.getLogger(__name__) | ||||
|
|
||||
| CONTROL4_CATEGORY = "blinds_shades" | ||||
|
|
||||
| CONTROL4_LEVEL = "Level" | ||||
| CONTROL4_FULLY_CLOSED = "Fully Closed" | ||||
| CONTROL4_FULLY_OPEN = "Fully Open" | ||||
| CONTROL4_OPENING = "Opening" | ||||
| CONTROL4_CLOSING = "Closing" | ||||
|
|
||||
| VARIABLES_OF_INTEREST = { | ||||
| CONTROL4_LEVEL, | ||||
| CONTROL4_FULLY_CLOSED, | ||||
| CONTROL4_FULLY_OPEN, | ||||
|
Comment on lines
+31
to
+38
|
||||
| CONTROL4_OPENING, | ||||
| CONTROL4_CLOSING, | ||||
| } | ||||
|
|
||||
|
|
||||
| async def async_setup_entry( | ||||
| hass: HomeAssistant, | ||||
| entry: Control4ConfigEntry, | ||||
| async_add_entities: AddConfigEntryEntitiesCallback, | ||||
| ) -> None: | ||||
| """Set up Control4 covers from a config entry.""" | ||||
| runtime_data = entry.runtime_data | ||||
|
|
||||
| async def async_update_data() -> dict[int, dict[str, Any]]: | ||||
| """Fetch data from Control4 director for blinds.""" | ||||
| try: | ||||
| return await update_variables_for_config_entry( | ||||
| hass, entry, VARIABLES_OF_INTEREST | ||||
| ) | ||||
| except C4Exception as err: | ||||
| raise UpdateFailed(f"Error communicating with API: {err}") from err | ||||
|
|
||||
| coordinator = DataUpdateCoordinator[dict[int, dict[str, Any]]]( | ||||
| hass, | ||||
| _LOGGER, | ||||
| name="cover", | ||||
| update_method=async_update_data, | ||||
| update_interval=timedelta(seconds=runtime_data.scan_interval), | ||||
| config_entry=entry, | ||||
| ) | ||||
|
|
||||
| await coordinator.async_refresh() | ||||
|
|
||||
|
|
||||
|
Comment on lines
+70
to
+71
Comment on lines
+61
to
+71
|
||||
| items_of_category = await get_items_of_category(hass, entry, CONTROL4_CATEGORY) | ||||
| entity_list = [] | ||||
| for item in items_of_category: | ||||
|
Comment on lines
+72
to
+74
|
||||
| try: | ||||
| if item["type"] != CONTROL4_ENTITY_TYPE: | ||||
| continue | ||||
| item_name = item["name"] | ||||
| item_id = item["id"] | ||||
| item_parent_id = item["parentId"] | ||||
| item_manufacturer = None | ||||
| item_device_name = None | ||||
| item_model = None | ||||
|
|
||||
| for parent_item in items_of_category: | ||||
| if parent_item["id"] == item_parent_id: | ||||
| item_manufacturer = parent_item.get("manufacturer") | ||||
| item_device_name = parent_item.get("roomName") | ||||
| item_model = parent_item.get("model") | ||||
|
Comment on lines
+72
to
+89
Comment on lines
+72
to
+89
Comment on lines
+85
to
+89
Comment on lines
+85
to
+89
|
||||
| except KeyError: | ||||
| _LOGGER.exception( | ||||
| "Unknown device properties received from Control4: %s", | ||||
| item, | ||||
| ) | ||||
| continue | ||||
|
|
||||
| if item_id not in coordinator.data: | ||||
| _LOGGER.warning( | ||||
| "Couldn't get cover state data for %s (ID: %s), skipping setup", | ||||
| item_name, | ||||
| item_id, | ||||
| ) | ||||
| continue | ||||
|
Comment on lines
+70
to
+103
|
||||
|
|
||||
| entity_list.append( | ||||
| Control4Cover( | ||||
| runtime_data, | ||||
| coordinator, | ||||
| item_name, | ||||
| item_id, | ||||
| item_device_name, | ||||
| item_manufacturer, | ||||
| item_model, | ||||
| item_parent_id, | ||||
| ) | ||||
| ) | ||||
|
|
||||
| async_add_entities(entity_list) | ||||
|
|
||||
|
|
||||
| class Control4Cover(Control4Entity, CoverEntity): | ||||
| """Control4 cover entity.""" | ||||
|
|
||||
| _attr_has_entity_name = True | ||||
| _attr_translation_key = "blind" | ||||
|
||||
| _attr_translation_key = "blind" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the unused
Control4RuntimeDataimport (or use it in type hints) to avoid failing Ruff's unused-import checks.