From 71ed2a0b3c1c773cddaddbde9d8c35339c07115b Mon Sep 17 00:00:00 2001 From: Caspar Zaal Date: Mon, 8 Jan 2024 11:27:11 +0100 Subject: [PATCH 1/4] Create only modules that are present, and name dispay different as bar --- custom_components/button_plus/button.py | 31 ++++++++---------- custom_components/button_plus/config_flow.py | 4 ++- custom_components/button_plus/light.py | 30 +++++++---------- custom_components/button_plus/switch.py | 31 ++++++++---------- custom_components/button_plus/text.py | 34 ++++++++------------ 5 files changed, 53 insertions(+), 77 deletions(-) diff --git a/custom_components/button_plus/button.py b/custom_components/button_plus/button.py index 2afeee3..115e49b 100644 --- a/custom_components/button_plus/button.py +++ b/custom_components/button_plus/button.py @@ -25,7 +25,8 @@ async def async_setup_entry( hub: ButtonPlusHub = hass.data[DOMAIN][config_entry.entry_id] - buttons = hub.config.mqtt_buttons + active_connectors = [connector.connector_id for connector in filter(lambda c: c.connector_type in [1,2],hub.config.info.connectors)] + buttons = filter(lambda b: b.button_id//2 in active_connectors,hub.config.mqtt_buttons) for button in buttons: _LOGGER.debug(f"Creating button with parameters: {button.button_id} {button.label} {hub.hub_id}") @@ -47,6 +48,7 @@ def __init__(self, btn_id: int, hub: ButtonPlusHub): self._attr_name = f'button-{btn_id}' self._name = f'Button {btn_id}' self._device_class = ButtonDeviceClass.IDENTIFY + self._connector = hub.config.info.connectors[btn_id//2] @property def name(self) -> str: @@ -65,24 +67,17 @@ def device_info(self): "manufacturer": MANUFACTURER, } - match self._btn_id: - case 0 | 1: - return {"identifiers": {(DOMAIN, self._hub_id)}} - case 2 | 3: - device_info["name"] = f"BAR Module 1" - device_info["connections"] = {("bar_module", 1)} + match self._connector.connector_type: + case 1: + device_info["name"] = f"BAR Module {self._connector.connector_id}" + device_info["connections"] = {("bar_module", self._connector.connector_id)} device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_1')} - case 4 | 5: - device_info["name"] = f"BAR Module 2" - device_info["connections"] = {("bar_module", 2)} - device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_2')} - case 6 | 7: - device_info["name"] = f"BAR Module 3" - device_info["connections"] = {("bar_module", 3)} - device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_3')} + device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_{self._connector.connector_id}')} + case 2: + device_info["name"] = f"Display Module" + device_info["connections"] = {("display_module", 1)} + device_info["model"] = "Display Module" + device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_display_module')} return device_info diff --git a/custom_components/button_plus/config_flow.py b/custom_components/button_plus/config_flow.py index e8499cd..401b987 100644 --- a/custom_components/button_plus/config_flow.py +++ b/custom_components/button_plus/config_flow.py @@ -242,8 +242,10 @@ def add_broker_to_config(self, device_config: DeviceConfiguration) -> DeviceConf def add_topics_to_buttons(self, device_config) -> DeviceConfiguration: device_id = device_config.info.device_id + + active_connectors = [connector.connector_id for connector in filter(lambda c: c.connector_type in [1,2],device_config.info.connectors)] - for button in device_config.mqtt_buttons: + for button in filter(lambda b: b.button_id//2 in active_connectors,device_config.mqtt_buttons): # Create topics for button main label button.topics.append({ diff --git a/custom_components/button_plus/light.py b/custom_components/button_plus/light.py index def5acf..c5f3223 100644 --- a/custom_components/button_plus/light.py +++ b/custom_components/button_plus/light.py @@ -45,6 +45,7 @@ def __init__(self, btn_id: int, hub: ButtonPlusHub, light_type: str): self.entity_id = f"light.{light_type}_{self._hub_id}_{btn_id}" self._attr_name = f'light-{light_type}-{btn_id}' self._state = False + self._connector = hub.config.info.connectors[btn_id//2] @property def is_on(self) -> bool | None: @@ -76,26 +77,17 @@ def device_info(self): "manufacturer": MANUFACTURER, } - match self._btn_id: - case 0 | 1: - return {"identifiers": {(DOMAIN, self._hub_id)}} - - case 2 | 3: - device_info["name"] = f"BAR Module 1" - device_info["connections"] = {("bar_module", 1)} - device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_1')} - - case 4 | 5: - device_info["name"] = f"BAR Module 2" - device_info["connections"] = {("bar_module", 2)} - device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_2')} - case 6 | 7: - device_info["name"] = f"BAR Module 3" - device_info["connections"] = {("bar_module", 3)} + match self._connector.connector_type: + case 1: + device_info["name"] = f"BAR Module {self._connector.connector_id}" + device_info["connections"] = {("bar_module", self._connector.connector_id)} device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_3')} + device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_{self._connector.connector_id}')} + case 2: + device_info["name"] = f"Display Module" + device_info["connections"] = {("display_module", 1)} + device_info["model"] = "Display Module" + device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_display_module')} return device_info diff --git a/custom_components/button_plus/switch.py b/custom_components/button_plus/switch.py index 67eea2c..b7a5668 100644 --- a/custom_components/button_plus/switch.py +++ b/custom_components/button_plus/switch.py @@ -24,7 +24,8 @@ async def async_setup_entry( """Add switches for passed config_entry in HA.""" hub: ButtonPlusHub = hass.data[DOMAIN][config_entry.entry_id] - buttons = hub.config.mqtt_buttons + active_connectors = [connector.connector_id for connector in filter(lambda c: c.connector_type in [1,2],hub.config.info.connectors)] + buttons = filter(lambda b: b.button_id//2 in active_connectors,hub.config.mqtt_buttons) for button in buttons: # _LOGGER.debug(f"Creating switch with parameters: {button.button_id} {button.label} {hub.hub_id}") @@ -44,6 +45,7 @@ def __init__(self, btn_id: int, hub: ButtonPlusHub): self._attr_name = f'switch-{btn_id}' self._name = f'Button {btn_id}' self._device_class = SwitchDeviceClass.SWITCH + self._connector = hub.config.info.connectors[btn_id//2] @property def name(self) -> str: @@ -58,24 +60,17 @@ def device_info(self): "manufacturer": MANUFACTURER, } - match self._btn_id: - case 0 | 1: - return {"identifiers": {(DOMAIN, self._hub_id)}} - case 2 | 3: - device_info["name"] = f"BAR Module 1" - device_info["connections"] = {("bar_module", 1)} + match self._connector.connector_type: + case 1: + device_info["name"] = f"BAR Module {self._connector.connector_id}" + device_info["connections"] = {("bar_module", self._connector.connector_id)} device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_1')} - case 4 | 5: - device_info["name"] = f"BAR Module 2" - device_info["connections"] = {("bar_module", 2)} - device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_2')} - case 6 | 7: - device_info["name"] = f"BAR Module 3" - device_info["connections"] = {("bar_module", 3)} - device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_3')} + device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_{self._connector.connector_id}')} + case 2: + device_info["name"] = f"Display Module" + device_info["connections"] = {("display_module", 1)} + device_info["model"] = "Display Module" + device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_display_module')} return device_info diff --git a/custom_components/button_plus/text.py b/custom_components/button_plus/text.py index b8ca320..2a620a5 100644 --- a/custom_components/button_plus/text.py +++ b/custom_components/button_plus/text.py @@ -26,8 +26,8 @@ async def async_setup_entry( """Add text entity for each top and main label from config_entry in HA.""" hub: ButtonPlusHub = hass.data[DOMAIN][config_entry.entry_id] - - buttons = hub.config.mqtt_buttons + active_connectors = [connector.connector_id for connector in filter(lambda c: c.connector_type in [1,2],hub.config.info.connectors)] + buttons = filter(lambda b: b.button_id//2 in active_connectors,hub.config.mqtt_buttons) for button in buttons: _LOGGER.debug( @@ -55,6 +55,7 @@ def __init__(self, btn_id: int, hub: ButtonPlusHub, btn_label: str, text_type: s self.entity_id = f"text.{text_type}_{self._hub_id}_{btn_id}" self._attr_name = f'text-{text_type}-{btn_id}' self._attr_native_value = btn_label + self._connector = hub.config.info.connectors[btn_id//2] @property def should_poll(self) -> bool: @@ -74,26 +75,17 @@ def device_info(self): "manufacturer": MANUFACTURER, } - match self._btn_id: - case 0 | 1: - return {"identifiers": {(DOMAIN, self._hub_id)}} - - case 2 | 3: - device_info["name"] = f"BAR Module 1" - device_info["connections"] = {("bar_module", 1)} - device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_1')} - - case 4 | 5: - device_info["name"] = f"BAR Module 2" - device_info["connections"] = {("bar_module", 2)} - device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_2')} - case 6 | 7: - device_info["name"] = f"BAR Module 3" - device_info["connections"] = {("bar_module", 3)} + match self._connector.connector_type: + case 1: + device_info["name"] = f"BAR Module {self._connector.connector_id}" + device_info["connections"] = {("bar_module", self._connector.connector_id)} device_info["model"] = "BAR Module" - device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_3')} + device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_bar_module_{self._connector.connector_id}')} + case 2: + device_info["name"] = f"Display Module" + device_info["connections"] = {("display_module", 1)} + device_info["model"] = "Display Module" + device_info["identifiers"] = {(DOMAIN, f'{self._btn_id}_display_module')} return device_info From e4ec0581fcd92b7e57cf67fed395a2fdae579264 Mon Sep 17 00:00:00 2001 From: Koen Hendriks Date: Sun, 14 Jan 2024 14:02:37 +0100 Subject: [PATCH 2/4] Update issue template for bug --- .github/ISSUE_TEMPLATE/bug_report.md | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..1b09042 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,34 @@ +--- +name: Bug report +about: Create a report to help us improve and solve bugs +title: '' +labels: bug +assignees: koenhendriks + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots from Home assistant to help explain your problem. + +**Additional context and/or debug log.** +Add any other context about the problem here. You can enable debug logging for this component by adding the following to your home assistant `configuration.yaml`: + +```yaml +logger: + default: info + logs: + custom_components.button_plus: debug +``` From 3436193c421eb0a023c3295b8f8f95bb45ae9d8a Mon Sep 17 00:00:00 2001 From: Koen Hendriks Date: Sun, 14 Jan 2024 15:10:10 +0100 Subject: [PATCH 3/4] Reformatted proposed changes for clarity and PEP 8 --- custom_components/button_plus/button.py | 11 ++++++++--- custom_components/button_plus/config_flow.py | 10 +++++++--- custom_components/button_plus/light.py | 2 +- custom_components/button_plus/switch.py | 12 +++++++++--- custom_components/button_plus/text.py | 12 +++++++++--- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/custom_components/button_plus/button.py b/custom_components/button_plus/button.py index 115e49b..828806e 100644 --- a/custom_components/button_plus/button.py +++ b/custom_components/button_plus/button.py @@ -25,8 +25,13 @@ async def async_setup_entry( hub: ButtonPlusHub = hass.data[DOMAIN][config_entry.entry_id] - active_connectors = [connector.connector_id for connector in filter(lambda c: c.connector_type in [1,2],hub.config.info.connectors)] - buttons = filter(lambda b: b.button_id//2 in active_connectors,hub.config.mqtt_buttons) + active_connectors = active_connectors = [ + connector.connector_id + for connector in hub.config.info.connectors + if connector.connector_type in [1, 2] + ] + + buttons = filter(lambda b: b.button_id // 2 in active_connectors, hub.config.mqtt_buttons) for button in buttons: _LOGGER.debug(f"Creating button with parameters: {button.button_id} {button.label} {hub.hub_id}") @@ -48,7 +53,7 @@ def __init__(self, btn_id: int, hub: ButtonPlusHub): self._attr_name = f'button-{btn_id}' self._name = f'Button {btn_id}' self._device_class = ButtonDeviceClass.IDENTIFY - self._connector = hub.config.info.connectors[btn_id//2] + self._connector = hub.config.info.connectors[btn_id // 2] @property def name(self) -> str: diff --git a/custom_components/button_plus/config_flow.py b/custom_components/button_plus/config_flow.py index 401b987..3ad66a4 100644 --- a/custom_components/button_plus/config_flow.py +++ b/custom_components/button_plus/config_flow.py @@ -242,10 +242,14 @@ def add_broker_to_config(self, device_config: DeviceConfiguration) -> DeviceConf def add_topics_to_buttons(self, device_config) -> DeviceConfiguration: device_id = device_config.info.device_id - - active_connectors = [connector.connector_id for connector in filter(lambda c: c.connector_type in [1,2],device_config.info.connectors)] - for button in filter(lambda b: b.button_id//2 in active_connectors,device_config.mqtt_buttons): + active_connectors = [ + connector.connector_id + for connector in device_config.info.connectors + if connector.connector_type in [1, 2] + ] + + for button in filter(lambda b: b.button_id // 2 in active_connectors, device_config.mqtt_buttons): # Create topics for button main label button.topics.append({ diff --git a/custom_components/button_plus/light.py b/custom_components/button_plus/light.py index c5f3223..850975b 100644 --- a/custom_components/button_plus/light.py +++ b/custom_components/button_plus/light.py @@ -45,7 +45,7 @@ def __init__(self, btn_id: int, hub: ButtonPlusHub, light_type: str): self.entity_id = f"light.{light_type}_{self._hub_id}_{btn_id}" self._attr_name = f'light-{light_type}-{btn_id}' self._state = False - self._connector = hub.config.info.connectors[btn_id//2] + self._connector = hub.config.info.connectors[btn_id // 2] @property def is_on(self) -> bool | None: diff --git a/custom_components/button_plus/switch.py b/custom_components/button_plus/switch.py index b7a5668..eef75b3 100644 --- a/custom_components/button_plus/switch.py +++ b/custom_components/button_plus/switch.py @@ -24,8 +24,14 @@ async def async_setup_entry( """Add switches for passed config_entry in HA.""" hub: ButtonPlusHub = hass.data[DOMAIN][config_entry.entry_id] - active_connectors = [connector.connector_id for connector in filter(lambda c: c.connector_type in [1,2],hub.config.info.connectors)] - buttons = filter(lambda b: b.button_id//2 in active_connectors,hub.config.mqtt_buttons) + + active_connectors = [ + connector.connector_id + for connector in hub.config.info.connectors + if connector.connector_type in [1, 2] + ] + + buttons = filter(lambda b: b.button_id // 2 in active_connectors,hub.config.mqtt_buttons) for button in buttons: # _LOGGER.debug(f"Creating switch with parameters: {button.button_id} {button.label} {hub.hub_id}") @@ -45,7 +51,7 @@ def __init__(self, btn_id: int, hub: ButtonPlusHub): self._attr_name = f'switch-{btn_id}' self._name = f'Button {btn_id}' self._device_class = SwitchDeviceClass.SWITCH - self._connector = hub.config.info.connectors[btn_id//2] + self._connector = hub.config.info.connectors[btn_id // 2] @property def name(self) -> str: diff --git a/custom_components/button_plus/text.py b/custom_components/button_plus/text.py index 2a620a5..5f29272 100644 --- a/custom_components/button_plus/text.py +++ b/custom_components/button_plus/text.py @@ -26,8 +26,14 @@ async def async_setup_entry( """Add text entity for each top and main label from config_entry in HA.""" hub: ButtonPlusHub = hass.data[DOMAIN][config_entry.entry_id] - active_connectors = [connector.connector_id for connector in filter(lambda c: c.connector_type in [1,2],hub.config.info.connectors)] - buttons = filter(lambda b: b.button_id//2 in active_connectors,hub.config.mqtt_buttons) + + active_connectors = [ + connector.connector_id + for connector in hub.config.info.connectors + if connector.connector_type in [1, 2] + ] + + buttons = filter(lambda b: b.button_id // 2 in active_connectors, hub.config.mqtt_buttons) for button in buttons: _LOGGER.debug( @@ -55,7 +61,7 @@ def __init__(self, btn_id: int, hub: ButtonPlusHub, btn_label: str, text_type: s self.entity_id = f"text.{text_type}_{self._hub_id}_{btn_id}" self._attr_name = f'text-{text_type}-{btn_id}' self._attr_native_value = btn_label - self._connector = hub.config.info.connectors[btn_id//2] + self._connector = hub.config.info.connectors[btn_id // 2] @property def should_poll(self) -> bool: From d1ff5fc02575ddedd15bb13314a38d4fdc5ab035 Mon Sep 17 00:00:00 2001 From: Koen Hendriks Date: Sun, 14 Jan 2024 20:57:46 +0100 Subject: [PATCH 4/4] Add missing state write to home assistant. --- custom_components/button_plus/text.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/custom_components/button_plus/text.py b/custom_components/button_plus/text.py index 5f29272..bff67d1 100644 --- a/custom_components/button_plus/text.py +++ b/custom_components/button_plus/text.py @@ -4,6 +4,7 @@ import logging from homeassistant.components.text import TextEntity + from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.components.mqtt import client as mqtt @@ -102,6 +103,7 @@ async def async_set_value(self, value: str) -> None: _LOGGER.debug(f"ButtonPlus label update to {label_topic} with new value: {value}") await mqtt.async_publish(hass=self.hass, topic=label_topic, payload=value, qos=0, retain=True) self._attr_native_value = value + self.async_write_ha_state() class ButtonPlusLabel(ButtonPlusText):