diff --git a/CHANGELOG.md b/CHANGELOG.md index da696fcf..ecfe2c8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,18 @@ ## Versions from 0.4x +### v0.55.10 - 2025-08-29 + +- Final fix for unavailable buttons via plugwise_usb [v0.44.13](https://github.com/plugwise/python-plugwise-usb/releases/tag/v0.44.13) +- Add debug-logging per platform and per entity + ### v0.55.9 - 2025-08-25 - Add select for Scan sensitivity - Add button for Scan light calibration - Fix disabled buttons for all non-plus devices - Shorten/correct logger-messages to use `node_duc.node.name` +- Link to plugwise_usb [v0.44.12](https://github.com/plugwise/python-plugwise-usb/releases/tag/v0.44.12) ### v0.55.8 - 2025-08-15 diff --git a/custom_components/plugwise_usb/binary_sensor.py b/custom_components/plugwise_usb/binary_sensor.py index 0f33e787..13533e3d 100644 --- a/custom_components/plugwise_usb/binary_sensor.py +++ b/custom_components/plugwise_usb/binary_sensor.py @@ -77,16 +77,16 @@ async def async_add_binary_sensor(node_event: NodeEvent, mac: str) -> None: return entities: list[PlugwiseUSBEntity] = [] if (node_duc := config_entry.runtime_data[NODES].get(mac)) is not None: - _LOGGER.debug( - "Add binary_sensor entities for node %s", node_duc.node.name - ) - entities.extend( - [ - PlugwiseUSBBinarySensor(node_duc, entity_description) - for entity_description in BINARY_SENSOR_TYPES - if entity_description.node_feature in node_duc.node.features - ] - ) + for entity_description in BINARY_SENSOR_TYPES: + if entity_description.node_feature not in node_duc.node.features: + continue + entities.append(PlugwiseUSBBinarySensor(node_duc, entity_description)) + _LOGGER.debug( + "Add %s binary sensor for node %s", + entity_description.translation_key, + node_duc.node.name, + ) + if entities: async_add_entities(entities) @@ -105,7 +105,8 @@ async def async_add_binary_sensor(node_event: NodeEvent, mac: str) -> None: for mac, node in api_stick.nodes.items(): if node.is_loaded: await async_add_binary_sensor(NodeEvent.LOADED, mac) - + else: + _LOGGER.debug("Adding binary_sensor(s) for node %s failed, not loaded", mac) async def async_unload_entry( _hass: HomeAssistant, diff --git a/custom_components/plugwise_usb/button.py b/custom_components/plugwise_usb/button.py index 4e0d0438..4151e205 100644 --- a/custom_components/plugwise_usb/button.py +++ b/custom_components/plugwise_usb/button.py @@ -10,7 +10,7 @@ from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory, Platform -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import NODES, STICK, UNSUB_NODE_LOADED @@ -58,7 +58,7 @@ class PlugwiseButtonEntityDescription( translation_key="calibrate_light", entity_category=EntityCategory.CONFIG, async_button_fn="scan_calibrate_light", - node_feature=NodeFeature.MOTION, + node_feature=NodeFeature.MOTION_CONFIG, ), ) @@ -76,14 +76,15 @@ async def async_add_button(node_event: NodeEvent, mac: str) -> None: return entities: list[PlugwiseUSBEntity] = [] if (node_duc := config_entry.runtime_data[NODES].get(mac)) is not None: - _LOGGER.debug("Add button entities for node %s", node_duc.node.name) - entities.extend( - [ - PlugwiseUSBButtonEntity(node_duc, entity_description) - for entity_description in BUTTON_TYPES - if entity_description.node_feature in node_duc.node.features - ] - ) + for entity_description in BUTTON_TYPES: + if entity_description.node_feature not in node_duc.node.features: + continue + entities.append(PlugwiseUSBButtonEntity(node_duc, entity_description)) + _LOGGER.debug( + "Add %s button for node %s", + entity_description.translation_key, + node_duc.node.name, + ) if entities: async_add_entities(entities) @@ -102,6 +103,8 @@ async def async_add_button(node_event: NodeEvent, mac: str) -> None: for mac, node in api_stick.nodes.items(): if node.is_loaded: await async_add_button(NodeEvent.LOADED, mac) + else: + _LOGGER.debug("Adding button(s) for node %s failed, not loaded", mac) async def async_unload_entry( @@ -126,13 +129,6 @@ def __init__( node_duc.node, entity_description.async_button_fn ) - @callback - def _handle_coordinator_update(self) -> None: - """Handle updated data from the coordinator.""" - 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.""" diff --git a/custom_components/plugwise_usb/const.py b/custom_components/plugwise_usb/const.py index 19f9fd3e..86ee2036 100644 --- a/custom_components/plugwise_usb/const.py +++ b/custom_components/plugwise_usb/const.py @@ -22,14 +22,14 @@ UNDO_UPDATE_LISTENER: Final[str] = "undo_update_listener" -PLUGWISE_USB_PLATFORMS: Final[list[str]] = [ +PLUGWISE_USB_PLATFORMS: Final[list[Platform]] = [ Platform.BINARY_SENSOR, + Platform.BUTTON, + Platform.EVENT, Platform.NUMBER, Platform.SELECT, Platform.SENSOR, Platform.SWITCH, - Platform.BUTTON, - Platform.EVENT, ] CONF_USB_PATH: Final[str] = "usb_path" SERVICE_DISABLE_PRODUCTION: Final[str] = "disable_production" diff --git a/custom_components/plugwise_usb/entity.py b/custom_components/plugwise_usb/entity.py index f9530153..aa47e050 100644 --- a/custom_components/plugwise_usb/entity.py +++ b/custom_components/plugwise_usb/entity.py @@ -45,7 +45,9 @@ def __init__( @property def available(self) -> bool: """Return if entity is available.""" - return self.node_duc.node.available and super().available + available = self.node_duc.node.available and super().available + _LOGGER.debug("Entity %s | available = %s", self.entity_description.key, available) + return available @property def device_info(self) -> DeviceInfo: diff --git a/custom_components/plugwise_usb/event.py b/custom_components/plugwise_usb/event.py index 821f6b3a..7c50dc3f 100644 --- a/custom_components/plugwise_usb/event.py +++ b/custom_components/plugwise_usb/event.py @@ -83,14 +83,15 @@ async def async_add_event(node_event: NodeEvent, mac: str) -> None: return entities: list[PlugwiseUSBEntity] = [] if (node_duc := config_entry.runtime_data[NODES].get(mac)) is not None: - _LOGGER.debug("Add event entities for node %s", node_duc.node.name) - entities.extend( - [ - PlugwiseUSBEventEntity(node_duc, entity_description) - for entity_description in EVENT_TYPES - if entity_description.node_feature in node_duc.node.features - ] - ) + for entity_description in EVENT_TYPES: + if entity_description.node_feature not in node_duc.node.features: + continue + entities.append(PlugwiseUSBEventEntity(node_duc, entity_description)) + _LOGGER.debug( + "Add %s event for node %s", + entity_description.translation_key, + node_duc.node.name, + ) if entities: async_add_entities(entities) @@ -109,9 +110,11 @@ async def async_add_event(node_event: NodeEvent, mac: str) -> None: for mac, node in api_stick.nodes.items(): if node.is_loaded: await async_add_event(NodeEvent.LOADED, mac) - + else: + _LOGGER.debug("Adding event(s) for node %s failed, not loaded", mac) async def async_unload_entry( + _hass: HomeAssistant, config_entry: PlugwiseUSBConfigEntry, ) -> None: """Unload a config entry.""" diff --git a/custom_components/plugwise_usb/manifest.json b/custom_components/plugwise_usb/manifest.json index e7e94c54..66ef11bb 100644 --- a/custom_components/plugwise_usb/manifest.json +++ b/custom_components/plugwise_usb/manifest.json @@ -8,6 +8,6 @@ "integration_type": "hub", "iot_class": "local_polling", "loggers": ["plugwise_usb"], - "requirements": ["plugwise-usb==0.44.12"], - "version": "0.55.9" + "requirements": ["plugwise-usb==0.44.13"], + "version": "0.55.10" } diff --git a/custom_components/plugwise_usb/number.py b/custom_components/plugwise_usb/number.py index f4f56cef..a060d5c9 100644 --- a/custom_components/plugwise_usb/number.py +++ b/custom_components/plugwise_usb/number.py @@ -113,14 +113,15 @@ async def async_add_number(node_event: NodeEvent, mac: str) -> None: return entities: list[PlugwiseUSBEntity] = [] if (node_duc := config_entry.runtime_data[NODES].get(mac)) is not None: - _LOGGER.debug("Add number entities for node %s", node_duc.node.name) - entities.extend( - [ - PlugwiseUSBNumberEntity(node_duc, entity_description) - for entity_description in NUMBER_TYPES - if entity_description.node_feature in node_duc.node.features - ] - ) + for entity_description in NUMBER_TYPES: + if entity_description.node_feature not in node_duc.node.features: + continue + entities.append(PlugwiseUSBNumberEntity(node_duc, entity_description)) + _LOGGER.debug( + "Add %s number for node %s", + entity_description.translation_key, + node_duc.node.name, + ) if entities: async_add_entities(entities) @@ -139,9 +140,11 @@ async def async_add_number(node_event: NodeEvent, mac: str) -> None: for mac, node in api_stick.nodes.items(): if node.is_loaded: await async_add_number(NodeEvent.LOADED, mac) - + else: + _LOGGER.debug("Adding number(s) for node %s failed, not loaded", mac) async def async_unload_entry( + _hass: HomeAssistant, config_entry: PlugwiseUSBConfigEntry, ) -> None: """Unload a config entry.""" diff --git a/custom_components/plugwise_usb/select.py b/custom_components/plugwise_usb/select.py index f951ebf7..1f8eb72a 100644 --- a/custom_components/plugwise_usb/select.py +++ b/custom_components/plugwise_usb/select.py @@ -57,14 +57,15 @@ async def async_add_select(node_event: NodeEvent, mac: str) -> None: return entities: list[PlugwiseUSBEntity] = [] if (node_duc := config_entry.runtime_data[NODES].get(mac)) is not None: - _LOGGER.debug("Add select entities for node %s", node_duc.node.name) - entities.extend( - [ - PlugwiseUSBSelectEntity(node_duc, entity_description) - for entity_description in SELECT_TYPES - if entity_description.node_feature in node_duc.node.features - ] - ) + for entity_description in SELECT_TYPES: + if entity_description.node_feature not in node_duc.node.features: + continue + entities.append(PlugwiseUSBSelectEntity(node_duc, entity_description)) + _LOGGER.debug( + "Add %s select for node %s", + entity_description.translation_key, + node_duc.node.name, + ) if entities: async_add_entities(entities) @@ -83,7 +84,8 @@ async def async_add_select(node_event: NodeEvent, mac: str) -> None: for mac, node in api_stick.nodes.items(): if node.is_loaded: await async_add_select(NodeEvent.LOADED, mac) - + else: + _LOGGER.debug("Adding select(s) for node %s failed, not loaded", mac) async def async_unload_entry( _hass: HomeAssistant, diff --git a/custom_components/plugwise_usb/sensor.py b/custom_components/plugwise_usb/sensor.py index 3bbccabd..5d071fc5 100644 --- a/custom_components/plugwise_usb/sensor.py +++ b/custom_components/plugwise_usb/sensor.py @@ -172,22 +172,19 @@ async def async_setup_entry( async def async_add_sensor(node_event: NodeEvent, mac: str) -> None: """Initialize DUC for sensor.""" - _LOGGER.debug("async_add_sensor | %s | node_event=%s", mac, node_event) 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 sensor entities for node %s", node_duc.node.name) - entities.extend( - [ - PlugwiseUSBSensorEntity(node_duc, entity_description) - for entity_description in SENSOR_TYPES - if entity_description.node_feature in node_duc.node.features - ] - ) - else: - _LOGGER.debug("async_add_sensor | %s | GET MAC FAILED", mac) - + for entity_description in SENSOR_TYPES: + if entity_description.node_feature not in node_duc.node.features: + continue + entities.append(PlugwiseUSBSensorEntity(node_duc, entity_description)) + _LOGGER.debug( + "Add %s sensor for node %s", + entity_description.translation_key, + node_duc.node.name, + ) if entities: async_add_entities(entities) @@ -206,7 +203,8 @@ async def async_add_sensor(node_event: NodeEvent, mac: str) -> None: for mac, node in api_stick.nodes.items(): if node.is_loaded: await async_add_sensor(NodeEvent.LOADED, mac) - + else: + _LOGGER.debug("Adding sensor(s) for node %s failed, not loaded", mac) async def async_unload_entry( _hass: HomeAssistant, diff --git a/custom_components/plugwise_usb/switch.py b/custom_components/plugwise_usb/switch.py index b1a46684..f7a22b55 100644 --- a/custom_components/plugwise_usb/switch.py +++ b/custom_components/plugwise_usb/switch.py @@ -86,14 +86,15 @@ async def async_add_switch(node_event: NodeEvent, mac: str) -> None: return entities: list[PlugwiseUSBEntity] = [] if (node_duc := config_entry.runtime_data[NODES].get(mac)) is not None: - _LOGGER.debug("Add switch entities for node %s", node_duc.node.name) - entities.extend( - [ - PlugwiseUSBSwitchEntity(node_duc, entity_description) - for entity_description in SWITCH_TYPES - if entity_description.node_feature in node_duc.node.features - ] - ) + for entity_description in SWITCH_TYPES: + if entity_description.node_feature not in node_duc.node.features: + continue + entities.append(PlugwiseUSBSwitchEntity(node_duc, entity_description)) + _LOGGER.debug( + "Add %s switch for node %s", + entity_description.translation_key, + node_duc.node.name, + ) if entities: async_add_entities(entities) @@ -112,7 +113,8 @@ async def async_add_switch(node_event: NodeEvent, mac: str) -> None: for mac, node in api_stick.nodes.items(): if node.is_loaded: await async_add_switch(NodeEvent.LOADED, mac) - + else: + _LOGGER.debug("Adding switch(es) for node %s failed, not loaded", mac) async def async_unload_entry( _hass: HomeAssistant, diff --git a/pyproject.toml b/pyproject.toml index 3ff021fd..10e6e62e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "plugwise_usb-beta" -version = "0.55.9" +version = "0.55.10" description = "Plugwise USB custom_component (BETA)" readme = "README.md" requires-python = ">=3.13"