-
Notifications
You must be signed in to change notification settings - Fork 2
Implement button in CirclePlus Device page to enable Auto-Joining #261
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
Changes from 18 commits
094df01
cef93e1
e6d46c4
652d2fa
678899f
2ca5500
10e1fa1
16d4e88
df0f1cd
b8d216d
349c385
13c3912
bacf0ca
2e65dbb
7a234ce
618759d
cb1f7d5
0bcc192
82fb6d3
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,115 @@ | ||
| """Plugwise USB Button component for HomeAssistant.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from dataclasses import dataclass | ||
| from datetime import timedelta | ||
| import logging | ||
|
|
||
| from homeassistant.components.button import ( | ||
| ButtonEntity, | ||
| ButtonEntityDescription, | ||
| ) | ||
| from homeassistant.const import EntityCategory, Platform | ||
| from homeassistant.core import HomeAssistant | ||
| from homeassistant.helpers.entity_platform import AddEntitiesCallback | ||
| from plugwise_usb.api import NodeEvent, NodeFeature | ||
|
|
||
| from .const import NODES, STICK, UNSUB_NODE_LOADED | ||
| from .coordinator import PlugwiseUSBConfigEntry, PlugwiseUSBDataUpdateCoordinator | ||
| from .entity import PlugwiseUSBEntity, PlugwiseUSBEntityDescription | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
| PARALLEL_UPDATES = 2 | ||
| SCAN_INTERVAL = timedelta(seconds=30) | ||
|
|
||
|
|
||
| @dataclass(kw_only=True) | ||
| class PlugwiseButtonEntityDescription( | ||
| PlugwiseUSBEntityDescription, ButtonEntityDescription | ||
| ): | ||
| """Describes Plugwise button entity.""" | ||
|
|
||
| async_button_fn: str = "" | ||
|
|
||
|
|
||
| BUTTON_TYPES: tuple[PlugwiseButtonEntityDescription, ...] = ( | ||
| PlugwiseButtonEntityDescription( | ||
| key="enable_auto_join", | ||
| translation_key="enable_auto_join", | ||
| entity_category=EntityCategory.CONFIG, | ||
| async_button_fn="enable_auto_join", | ||
| node_feature=NodeFeature.CIRCLEPLUS, | ||
| ), | ||
| ) | ||
|
|
||
|
|
||
| async def async_setup_entry( | ||
| _hass: HomeAssistant, | ||
| config_entry: PlugwiseUSBConfigEntry, | ||
| async_add_entities: AddEntitiesCallback, | ||
| ) -> None: | ||
| """Set up the USB buttons from a config entry.""" | ||
|
|
||
| async def async_add_button(node_event: NodeEvent, mac: str) -> None: | ||
| """Initialize DUC for button.""" | ||
| if node_event != NodeEvent.LOADED: | ||
| return | ||
| entities: list[PlugwiseUSBEntity] = [] | ||
| if (node_duc := config_entry.runtime_data[NODES].get(mac)) is not None: | ||
| _LOGGER.debug("Add button entities for %s | duc=%s", mac, node_duc.name) | ||
| entities.extend( | ||
| [ | ||
| PlugwiseUSBButtonEntity(node_duc, entity_description) | ||
| for entity_description in BUTTON_TYPES | ||
| if entity_description.node_feature in node_duc.node.features | ||
| ] | ||
| ) | ||
| if entities: | ||
| async_add_entities(entities) | ||
|
|
||
| api_stick = config_entry.runtime_data[STICK] | ||
|
|
||
| # Listen for loaded nodes | ||
| config_entry.runtime_data[Platform.BUTTON] = {} | ||
| config_entry.runtime_data[Platform.BUTTON][UNSUB_NODE_LOADED] = ( | ||
| api_stick.subscribe_to_node_events( | ||
| async_add_button, | ||
| (NodeEvent.LOADED,), | ||
| ) | ||
| ) | ||
|
|
||
| # load any current nodes | ||
| for mac, node in api_stick.nodes.items(): | ||
| if node.is_loaded: | ||
| await async_add_button(NodeEvent.LOADED, mac) | ||
|
|
||
|
|
||
| async def async_unload_entry( | ||
| _hass: HomeAssistant, | ||
| config_entry: PlugwiseUSBConfigEntry, | ||
| ) -> None: | ||
| """Unload a config entry.""" | ||
| config_entry.runtime_data[Platform.BUTTON][UNSUB_NODE_LOADED]() | ||
|
|
||
|
|
||
| class PlugwiseUSBButtonEntity(PlugwiseUSBEntity, ButtonEntity): | ||
| """Representation of a Plugwise USB Data Update Coordinator button.""" | ||
|
|
||
| def __init__( | ||
| self, | ||
| node_duc: PlugwiseUSBDataUpdateCoordinator, | ||
| entity_description: PlugwiseButtonEntityDescription, | ||
| ) -> None: | ||
| """Initialize a button entity.""" | ||
| super().__init__(node_duc, entity_description) | ||
| self.async_button_fn = getattr( | ||
| node_duc.node, entity_description.async_button_fn | ||
| ) | ||
|
|
||
| async def async_press(self) -> None: | ||
| """Button was pressed.""" | ||
| await self.async_button_fn() | ||
|
|
||
| async def async_added_to_hass(self): | ||
| """Subscribe for push updates.""" | ||
|
Comment on lines
+114
to
+115
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can be removed, there's the same function in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned on discord, the overload is required to prevent the execution of the function in entity.py as it breaks functioning of the circle+ as soon as the button is loaded.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah Ok, now I finally understand this, sorry. |
||
Uh oh!
There was an error while loading. Please reload this page.