diff --git a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/ha_cards.py b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/ha_cards.py index 0b3b832c..bf0a4c1c 100644 --- a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/ha_cards.py +++ b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/ha_cards.py @@ -7,7 +7,7 @@ import logging import dateutil.parser as dp import babel from libs.icon_mapping import get_icon_char -from libs.helper import rgb_dec565 +from libs.helper import rgb_dec565, scale class HAEntity(panel_cards.Entity): def __init__(self, locale, config, panel): @@ -19,7 +19,6 @@ class HAEntity(panel_cards.Entity): if data: self.state = data.get("state") self.attributes = data.get("attributes", []) - #print(data) # HA Entities entity_type_panel = "text" @@ -449,3 +448,62 @@ def entity_factory(locale, settings, panel): else: entity = HAEntity(locale, settings, panel) return entity.iid, entity + +def detail_open(locale, detail_type, ha_entity_id, entity_id): + data = libs.home_assistant.get_entity_data(ha_entity_id) + if data: + state = data.get("state") + attributes = data.get("attributes", []) + else: + logging.error("popup entity %s not found", ha_entity_id) + return + + match detail_type: + case 'popupShutter' | 'cover': + print(f"not implemented {detail_type}") + case 'popupLight' | 'light': + switch_val = 1 if state == "on" else 0 + icon_color = 6666 + brightness = "disable" + color_temp = "disable" + color = "disable" + effect_supported = "disable" + + if "onoff" not in attributes.get("supported_color_modes"): + brightness = 0 + if state == "on": + if "brightness" in attributes and attributes.get("brightness"): + # scale 0-255 brightness from ha to 0-100 + brightness = int(scale(attributes.get("brightness"),(0,255),(0,100))) + else: + brightness = "disable" + if "color_temp" in attributes.get("supported_color_modes"): + if "color_temp" in attributes and attributes.get("color_temp"): + # scale ha color temp range to 0-100 + color_temp = int(scale(attributes.get("color_temp"), (attributes.get("min_mireds"), attributes.get("max_mireds")),(0,100))) + else: + color_temp = "unknown" + else: + color_temp = "disable" + list_color_modes = ["xy", "rgb", "rgbw", "hs"] + if any(item in list_color_modes for item in attributes.get("supported_color_modes")): + color = "enable" + else: + color = "disable" + if "effect_list" in attributes: + effect_supported = "enable" + color_translation = "Color" + brightness_translation = get_translation(locale, "frontend.ui.card.light.brightness") + color_temp_translation = get_translation(locale, "frontend.ui.card.light.color_temperature") + return f'{entity_id}~~{icon_color}~{switch_val}~{brightness}~{color_temp}~{color}~{color_translation}~{color_temp_translation}~{brightness_translation}~{effect_supported}' + case 'popupFan' | 'fan': + print(f"not implemented {detail_type}") + case 'popupThermo' | 'climate': + print(f"not implemented {detail_type}") + case 'popupInSel' | 'input_select' | 'select': + print(f"not implemented {detail_type}") + case 'popupTimer' | 'timer': + print(f"not implemented {detail_type}") + case _: + logging.error("popup type %s not implemented", detail_type) + return "NotImplemented", None diff --git a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/ha_control.py b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/ha_control.py index 984d38bb..e006dbcd 100644 --- a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/ha_control.py +++ b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/ha_control.py @@ -1,7 +1,7 @@ import libs.home_assistant import logging import time -from libs.helper import pos_to_color +from libs.helper import pos_to_color, scale def wait_for_ha_cache(): mustend = time.time() + 5 @@ -83,7 +83,14 @@ def handle_buttons(entity_id, btype, value): } service = action_service_mapping[btype] call_ha_service(entity_id, service) - + case 'timer-start': + if value: + service_data = { + "duration": value + } + call_ha_service(entity_id, "start", service_data=service_data) + else: + call_ha_service(entity_id, "start") case 'positionSlider': service_data = { "position": int(value) @@ -144,10 +151,42 @@ def handle_buttons(entity_id, btype, value): "rgb_color": color } call_ha_service(entity_id, "turn_on", service_data=service_data) + case 'disarm' | 'arm_home' | 'arm_away' | 'arm_night' | 'arm_vacation': + service_data = { + "code": value + } + call_ha_service(entity_id, f"alarm_{button_type}", service_data=service_data) + case 'mode-preset_modes' | 'mode-swing_modes' | 'mode-fan_modes': + mapping = { + 'mode-preset_modes': 'preset_modes', + 'mode-swing_modes': 'swing_modes', + 'mode-fan_modes': 'fan_mode' + } + if btype in mapping: + modes = libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get(mapping[btype], []) + if modes: + mode = modes[int(value)] + service_data = { + mapping[btype]: mode + } + call_ha_service(entity_id, f"set_{mapping[btype]}", service_data=service_data) + case 'mode-input_select' | 'mode-select': + if btype in mapping: + modes = libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get(options, []) + if options: + option = options[int(value)] + service_data = { + "option": option + } + call_ha_service(entity_id, "select_option", service_data=service_data) + case _: logging.error("Not implemented: %s", btype) + + + # # for climate page # if button_type == "tempUpd": # temp = int(value)/10 @@ -163,19 +202,6 @@ def handle_buttons(entity_id, btype, value): # apis.ha_api.get_entity(entity_id).call_service( # "set_hvac_mode", hvac_mode=value) # - # # for alarm page - # if button_type in ["disarm", "arm_home", "arm_away", "arm_night", "arm_vacation"]: - # apis.ha_api.get_entity(entity_id).call_service( - # f"alarm_{button_type}", code=value) - # if button_type == "opnSensorNotify": - # msg = "" - # entity = apis.ha_api.get_entity(entity_id) - # if "open_sensors" in entity.attributes and entity.attributes.open_sensors is not None: - # for e in entity.attributes.open_sensors: - # msg += f"- {apis.ha_api.get_entity(e).attributes.friendly_name}\r\n" - # self._pages_gen.send_message_page( - # "opnSensorNotifyRes", "", msg, "", "") - # # # for cardUnlock # if button_type == "cardUnlock-unlock": # curCard = self._config.get_card_by_uuid( @@ -190,25 +216,6 @@ def handle_buttons(entity_id, btype, value): # self._current_card = dstCard # self._pages_gen.render_card(self._current_card) # - # if button_type == "mode-preset_modes": - # entity = apis.ha_api.get_entity(entity_id) - # preset_mode = entity.attributes.preset_modes[int(value)] - # entity.call_service("set_preset_mode", preset_mode=preset_mode) - # - # if button_type == "mode-swing_modes": - # entity = apis.ha_api.get_entity(entity_id) - # swing_mode = entity.attributes.swing_modes[int(value)] - # entity.call_service("set_swing_mode", swing_mode=swing_mode) - # - # if button_type == "mode-fan_modes": - # entity = apis.ha_api.get_entity(entity_id) - # fan_mode = entity.attributes.fan_modes[int(value)] - # entity.call_service("set_fan_mode", fan_mode=fan_mode) - # - # if button_type in ["mode-input_select", "mode-select"]: - # entity = apis.ha_api.get_entity(entity_id) - # option = entity.attributes.options[int(value)] - # entity.call_service("select_option", option=option) # # if button_type == "mode-light": # if entity_id.startswith('uuid'): @@ -227,14 +234,15 @@ def handle_buttons(entity_id, btype, value): # entity = apis.ha_api.get_entity(entity_id) # option = entity.attributes.source_list[int(value)] # entity.call_service("select_source", source=option) - # - # # timer detail page - # if button_type == "timer-start": - # if value is not None: - # apis.ha_api.get_entity(entity_id).call_service( - # "start", duration=value) - # else: - # apis.ha_api.get_entity(entity_id).call_service("start") + + # if button_type == "opnSensorNotify": + # msg = "" + # entity = apis.ha_api.get_entity(entity_id) + # if "open_sensors" in entity.attributes and entity.attributes.open_sensors is not None: + # for e in entity.attributes.open_sensors: + # msg += f"- {apis.ha_api.get_entity(e).attributes.friendly_name}\r\n" + # self._pages_gen.send_message_page( + # "opnSensorNotifyRes", "", msg, "", "") def call_ha_service(entity_id, service, service_data = {}): etype = entity_id.split(".")[0] diff --git a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/libs/panel_cmd.py b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/libs/panel_cmd.py index fe7a1fa5..2d09e127 100644 --- a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/libs/panel_cmd.py +++ b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/libs/panel_cmd.py @@ -37,4 +37,7 @@ def timeout(topic, timeout): def dimmode(topic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders): if dimValue==dimValueNormal: dimValue=dimValue-1 - custom_send(topic, f"dimmode~{dimValue}~{dimValueNormal}~{backgroundColor}~{fontColor}~{featExperimentalSliders}") \ No newline at end of file + custom_send(topic, f"dimmode~{dimValue}~{dimValueNormal}~{backgroundColor}~{fontColor}~{featExperimentalSliders}") + +def entityUpdateDetail(topic, data): + custom_send(topic, f"entityUpdateDetail~{data}") \ No newline at end of file diff --git a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/main.py b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/main.py index 871d21ce..6d07d500 100644 --- a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/main.py +++ b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/main.py @@ -15,8 +15,7 @@ from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer import signal import sys - - +logging.getLogger("watchdog").propagate = False settings = {} panels = {} diff --git a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel.py b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel.py index 43f9ca1b..c6bfc793 100644 --- a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel.py +++ b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel.py @@ -7,7 +7,7 @@ from scheduler import Scheduler import scheduler.trigger as trigger import time import babel.dates -from ha_cards import Screensaver, EntitiesCard, card_factory +from ha_cards import Screensaver, EntitiesCard, card_factory, detail_open import ha_control class LovelaceUIPanel: @@ -99,6 +99,16 @@ class LovelaceUIPanel: if entity_id in self.current_card.get_entities(): self.render_current_page() + # send update for detail popup in case it's open + etype = entity_id.split('.')[0] + if etype in ['light', 'timer', 'cover', 'input_select', 'select', 'fan']: + # figure out iid of entity + entity_id_iid = "" + for e in self.current_card.get_iid_entities(): + if entity_id == e[1]: + entity_id_iid = f'iid.{e[0]}' + libs.panel_cmd.entityUpdateDetail(self.sendTopic, detail_open(self.settings["locale"], etype, entity_id, entity_id_iid)) + involved_entities = ha_control.calculate_dim_values( self.settings.get("sleepTracking"), self.settings.get("sleepTrackingZones", ["not_home", "off"]), @@ -135,7 +145,6 @@ class LovelaceUIPanel: self.settings.get("screenBrightness"), self.settings.get("sleepOverride"), ) - print(dimValue, dimValueNormal) backgroundColor = self.settings.get("defaultBackgroundColor", "ha-dark") if backgroundColor == "ha-dark": @@ -205,4 +214,10 @@ class LovelaceUIPanel: ha_control.handle_buttons(entity_id, btype, value) if msg[1] == "pageOpenDetail": - print("pageOpenDetail") + entity_id = msg[3] + # replace iid with real entity id + if entity_id.startswith("iid."): + iid = entity_id.split(".")[1] + if iid in self.entity_iids: + entity_id = self.entity_iids[iid] + libs.panel_cmd.entityUpdateDetail(self.sendTopic, detail_open(self.settings["locale"], msg[2], entity_id, msg[3]))