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 26fc1a76..e19e2545 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 @@ -533,6 +533,30 @@ class AlarmCard(HACard): result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}~{add_btn}" libs.panel_cmd.entityUpd(self.panel.sendTopic, result) + +class UnlockCard(HACard): + def __init__(self, locale, config, panel): + super().__init__(locale, config, panel) + + def render(self): + + color = rgb_dec565([255,0,0]) + icon = get_icon_char("lock") + supported_modes = ["cardUnlock-unlock"] + + entity_id = self.config.get("entity") + + # add padding to arm buttons + arm_buttons = "" + for b in supported_modes: + arm_buttons += f'~{get_translation(self.locale, "frontend.ui.card.lock.unlock")}~{b}' + if len(supported_modes) < 4: + arm_buttons += "~"*((4-len(supported_modes))*2) + numpad = "enable" + + result = f"{self.title}~{self.gen_nav()}~{entity_id}{arm_buttons}~{icon}~{color}~{numpad}~disable~" + libs.panel_cmd.entityUpd(self.panel.sendTopic, result) + class Screensaver(HACard): def __init__(self, locale, config, panel): super().__init__(locale, config, panel) @@ -594,6 +618,8 @@ def card_factory(locale, settings, panel): card = ClimateCard(locale, settings, panel) case 'cardAlarm': card = AlarmCard(locale, settings, panel) + case 'cardUnlock': + card = UnlockCard(locale, settings, panel) case _: logging.error("card type %s not implemented", settings["type"]) return "NotImplemented", None 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 2ec7cb33..7c6b404a 100644 --- a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel.py +++ b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel.py @@ -1,259 +1,265 @@ -from dateutil import tz -import datetime -import threading -import logging -import libs.panel_cmd -from scheduler import Scheduler -import scheduler.trigger as trigger -import time -import babel.dates -from ha_cards import Screensaver, EntitiesCard, card_factory, detail_open -import ha_control - -class LovelaceUIPanel: - - def __init__(self, name_panel, settings_panel): - self.name = name_panel - self.settings = settings_panel - self.sendTopic = self.settings["panelSendTopic"] - self.recvTopic = self.settings["panelRecvTopic"] - self.model = self.settings.get("model", "eu") - - - self.current_card = None - self.privious_cards = [] - self.cards = {} - self.hidden_cards = {} - self.screensaver = None - self.navigate_keys = {} - self.entity_iids = {} - - # generate cards for input settings - for c in self.settings.get("cards"): - iid, card = card_factory(self.settings["locale"], c, self) - # Check if we acually got a card - if card: - self.cards[iid] = card - # collect nav keys of cards - if card.navigate_key: - self.navigate_keys[card.navigate_key] = iid - # collect iids of entities - for e in card.get_iid_entities(): - self.entity_iids[e[0]] = e[1] - - # setup prev and next iids - top_level_cards = list(self.cards.values()) - card_iids = [card.iid for card in top_level_cards] - prev_iids = card_iids[-1:] + card_iids[:-1] - next_iids = card_iids[1:] + card_iids[: 1] - if len(card_iids) > 1: - for prev_iids, card, next_iids in zip(prev_iids, top_level_cards, next_iids): - (card.iid_prev, card.iid_next) = (prev_iids, next_iids) - - # generate cards for input settings - for c in self.settings.get("hiddenCards", []): - iid, card = card_factory(self.settings["locale"], c, self) - card.hidden = True - self.hidden_cards[iid] = card - # collect nav keys of cards - if card.navigate_key: - self.navigate_keys[card.navigate_key] = iid - # collect iids of entities - for e in card.get_iid_entities(): - self.entity_iids[e[0]] = e[1] - - self.schedule = Scheduler() - self.schedule.minutely(datetime.time(second=0), self.update_time) - self.schedule.hourly(datetime.time( - minute=0, second=0), self.update_time) - schedule_thread = threading.Thread(target=self.schedule_thread_target) - schedule_thread.daemon = True - schedule_thread.start() - - # check if ha state cache is already populated - ha_control.wait_for_ha_cache() - - #request templates on cards - for c in self.cards.values(): - if hasattr(c, "qrcode"): - if c.qrcode.startswith("ha:"): - libs.home_assistant.cache_template(c.qrcode) - for e in c.entities: - e.prerender() - for c in self.hidden_cards.values(): - if hasattr(c, "qrcode"): - if c.qrcode.startswith("ha:"): - libs.home_assistant.cache_template(c.qrcode) - for e in c.entities: - e.prerender() - self.screensaver = Screensaver(self.settings["locale"], self.settings["screensaver"], self) - if self.screensaver.statusIcon1: - self.screensaver.statusIcon1.prerender() - if self.screensaver.statusIcon2: - self.screensaver.statusIcon2.prerender() - for e in self.screensaver.entities: - e.prerender() - - libs.panel_cmd.page_type(self.sendTopic, "pageStartup") - - - def schedule_thread_target(self): - while True: - self.schedule.exec_jobs() - time.sleep(1) - - def update_time(self): - use_timezone = tz.gettz(self.settings["timeZone"]) - time_string = datetime.datetime.now( - use_timezone).strftime(self.settings["timeFormat"]) - libs.panel_cmd.send_time(self.sendTopic, time_string) - - def update_date(self): - dateformat = self.settings["dateFormat"] - date_string = babel.dates.format_date( - datetime.datetime.now(), dateformat, locale=self.settings["locale"]) - libs.panel_cmd.send_date(self.sendTopic, date_string) - - def searchCard(self, iid): - if iid in self.navigate_keys: - iid = self.navigate_keys[iid] - if iid in self.cards: - return self.cards[iid] - if iid in self.hidden_cards: - return self.hidden_cards[iid] - - def ha_event_callback(self, entity_id): - #logging.debug(f"{self.name} {entity_id} updated/state changed") - if self.current_card and entity_id in self.current_card.get_entities(): - self.render_current_page(requested=True) - - # 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, sendTopic=self.sendTopic)) - - involved_entities = ha_control.calculate_dim_values( - self.settings.get("sleepTracking"), - self.settings.get("sleepTrackingZones", ["not_home", "off"]), - self.settings.get("sleepBrightness"), - self.settings.get("screenBrightness"), - self.settings.get("sleepOverride"), - return_involved_entities=True - ) - if entity_id in involved_entities: - self.dimmode() - - - def render_current_page(self, switchPages=False, requested=False): - if switchPages: - libs.panel_cmd.page_type(self.sendTopic, self.current_card.type) - if requested: - self.current_card.render() - # send sleepTimeout - #sleepTimeout = self.settings.get("sleepTimeout", 20) - #if self.current_card.config.get("sleepTimeout"): - # sleepTimeout = self.current_card.config.get("sleepTimeout") - #libs.panel_cmd.timeout(self.sendTopic, sleepTimeout) - #self.dimmode() - - def dimmode(self): - # send dimmode - dimValue, dimValueNormal = ha_control.calculate_dim_values( - self.settings.get("sleepTracking"), - self.settings.get("sleepTrackingZones", ["not_home", "off"]), - self.settings.get("sleepBrightness"), - self.settings.get("screenBrightness"), - self.settings.get("sleepOverride"), - ) - - backgroundColor = self.settings.get("defaultBackgroundColor", "ha-dark") - if backgroundColor == "ha-dark": - backgroundColor = 6371 - elif backgroundColor == "black": - backgroundColor = 0 - fontColor = "" - featExperimentalSliders = self.settings.get("featExperimentalSliders", 0) - libs.panel_cmd.dimmode(self.sendTopic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders) - - - def customrecv_event_callback(self, msg): - logging.debug("Recv Message from NsPanel (%s): %s", self.name, msg) - msg = msg.split(",") - # run action based on received command - if msg[0] == "event": - if msg[1] == "startup": - # TODO: Handle Update Messages - self.update_date() - self.update_time() - - self.current_card = self.screensaver - self.render_current_page(switchPages=True) - - # send sleepTimeout - sleepTimeout = self.settings.get("sleepTimeout", 20) - if self.current_card.config.get("sleepTimeout"): - sleepTimeout = self.current_card.config.get("sleepTimeout") - libs.panel_cmd.timeout(self.sendTopic, sleepTimeout) - self.dimmode() - - if msg[1] == "sleepReached": - self.privious_cards.append(self.current_card) - self.current_card = self.screensaver - self.render_current_page(switchPages=True) - if msg[1] == "renderCurrentPage": - self.render_current_page(requested=True) - if msg[1] == "buttonPress2": - entity_id = msg[2] - btype = msg[3] - value = msg[4] if len(msg) > 4 else None - if btype == "bExit": - if entity_id=="screensaver" and self.settings.get("screensaver").get("doubleTapToUnlock") and value == "1": - return - - # in case privious_cards is empty add a default card - if len(self.privious_cards) == 0: - self.privious_cards.append( - list(self.cards.values())[0]) # TODO: Impelement default card config - self.current_card = self.privious_cards.pop() - self.render_current_page(switchPages=True) - return - - # 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] - - match btype: - case 'button': - match entity_id.split(".")[0]: - # handle internal stuff - case 'navigate': - card_iid = entity_id.split(".")[1] - if card_iid == "UP": - self.current_card = self.privious_cards.pop() - # TODO Handle privious_cards empty with default card - self.render_current_page(switchPages=True) - else: - self.privious_cards.append(self.current_card) - self.current_card = self.searchCard(card_iid) - self.render_current_page(switchPages=True) - # send ha stuff to ha - case _: - ha_control.handle_buttons(entity_id, btype, value) - case _: - ha_control.handle_buttons(entity_id, btype, value) - - if msg[1] == "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], sendTopic=self.sendTopic)) +from dateutil import tz +import datetime +import threading +import logging +import libs.panel_cmd +from scheduler import Scheduler +import scheduler.trigger as trigger +import time +import babel.dates +from ha_cards import Screensaver, EntitiesCard, card_factory, detail_open +import ha_control + +class LovelaceUIPanel: + + def __init__(self, name_panel, settings_panel): + self.name = name_panel + self.settings = settings_panel + self.sendTopic = self.settings["panelSendTopic"] + self.recvTopic = self.settings["panelRecvTopic"] + self.model = self.settings.get("model", "eu") + + + self.current_card = None + self.privious_cards = [] + self.cards = {} + self.hidden_cards = {} + self.screensaver = None + self.navigate_keys = {} + self.entity_iids = {} + + # generate cards for input settings + for c in self.settings.get("cards"): + iid, card = card_factory(self.settings["locale"], c, self) + # Check if we acually got a card + if card: + self.cards[iid] = card + # collect nav keys of cards + if card.navigate_key: + self.navigate_keys[card.navigate_key] = iid + # collect iids of entities + for e in card.get_iid_entities(): + self.entity_iids[e[0]] = e[1] + + # setup prev and next iids + top_level_cards = list(self.cards.values()) + card_iids = [card.iid for card in top_level_cards] + prev_iids = card_iids[-1:] + card_iids[:-1] + next_iids = card_iids[1:] + card_iids[: 1] + if len(card_iids) > 1: + for prev_iids, card, next_iids in zip(prev_iids, top_level_cards, next_iids): + (card.iid_prev, card.iid_next) = (prev_iids, next_iids) + + # generate cards for input settings + for c in self.settings.get("hiddenCards", []): + iid, card = card_factory(self.settings["locale"], c, self) + card.hidden = True + self.hidden_cards[iid] = card + # collect nav keys of cards + if card.navigate_key: + self.navigate_keys[card.navigate_key] = iid + # collect iids of entities + for e in card.get_iid_entities(): + self.entity_iids[e[0]] = e[1] + + self.schedule = Scheduler() + self.schedule.minutely(datetime.time(second=0), self.update_time) + self.schedule.hourly(datetime.time( + minute=0, second=0), self.update_time) + schedule_thread = threading.Thread(target=self.schedule_thread_target) + schedule_thread.daemon = True + schedule_thread.start() + + # check if ha state cache is already populated + ha_control.wait_for_ha_cache() + + #request templates on cards + for c in self.cards.values(): + if hasattr(c, "qrcode"): + if c.qrcode.startswith("ha:"): + libs.home_assistant.cache_template(c.qrcode) + for e in c.entities: + e.prerender() + for c in self.hidden_cards.values(): + if hasattr(c, "qrcode"): + if c.qrcode.startswith("ha:"): + libs.home_assistant.cache_template(c.qrcode) + for e in c.entities: + e.prerender() + self.screensaver = Screensaver(self.settings["locale"], self.settings["screensaver"], self) + if self.screensaver.statusIcon1: + self.screensaver.statusIcon1.prerender() + if self.screensaver.statusIcon2: + self.screensaver.statusIcon2.prerender() + for e in self.screensaver.entities: + e.prerender() + + libs.panel_cmd.page_type(self.sendTopic, "pageStartup") + + + def schedule_thread_target(self): + while True: + self.schedule.exec_jobs() + time.sleep(1) + + def update_time(self): + use_timezone = tz.gettz(self.settings["timeZone"]) + time_string = datetime.datetime.now( + use_timezone).strftime(self.settings["timeFormat"]) + libs.panel_cmd.send_time(self.sendTopic, time_string) + + def update_date(self): + dateformat = self.settings["dateFormat"] + date_string = babel.dates.format_date( + datetime.datetime.now(), dateformat, locale=self.settings["locale"]) + libs.panel_cmd.send_date(self.sendTopic, date_string) + + def searchCard(self, iid): + if iid in self.navigate_keys: + iid = self.navigate_keys[iid] + if iid in self.cards: + return self.cards[iid] + if iid in self.hidden_cards: + return self.hidden_cards[iid] + + def ha_event_callback(self, entity_id): + #logging.debug(f"{self.name} {entity_id} updated/state changed") + if self.current_card and entity_id in self.current_card.get_entities(): + self.render_current_page(requested=True) + + # 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, sendTopic=self.sendTopic)) + + involved_entities = ha_control.calculate_dim_values( + self.settings.get("sleepTracking"), + self.settings.get("sleepTrackingZones", ["not_home", "off"]), + self.settings.get("sleepBrightness"), + self.settings.get("screenBrightness"), + self.settings.get("sleepOverride"), + return_involved_entities=True + ) + if entity_id in involved_entities: + self.dimmode() + + + def render_current_page(self, switchPages=False, requested=False): + if switchPages: + libs.panel_cmd.page_type(self.sendTopic, self.current_card.type) + if requested: + self.current_card.render() + # send sleepTimeout + #sleepTimeout = self.settings.get("sleepTimeout", 20) + #if self.current_card.config.get("sleepTimeout"): + # sleepTimeout = self.current_card.config.get("sleepTimeout") + #libs.panel_cmd.timeout(self.sendTopic, sleepTimeout) + #self.dimmode() + + def dimmode(self): + # send dimmode + dimValue, dimValueNormal = ha_control.calculate_dim_values( + self.settings.get("sleepTracking"), + self.settings.get("sleepTrackingZones", ["not_home", "off"]), + self.settings.get("sleepBrightness"), + self.settings.get("screenBrightness"), + self.settings.get("sleepOverride"), + ) + + backgroundColor = self.settings.get("defaultBackgroundColor", "ha-dark") + if backgroundColor == "ha-dark": + backgroundColor = 6371 + elif backgroundColor == "black": + backgroundColor = 0 + fontColor = "" + featExperimentalSliders = self.settings.get("featExperimentalSliders", 0) + libs.panel_cmd.dimmode(self.sendTopic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders) + + + def customrecv_event_callback(self, msg): + logging.debug("Recv Message from NsPanel (%s): %s", self.name, msg) + msg = msg.split(",") + # run action based on received command + if msg[0] == "event": + if msg[1] == "startup": + # TODO: Handle Update Messages + self.update_date() + self.update_time() + + self.current_card = self.screensaver + self.render_current_page(switchPages=True) + + # send sleepTimeout + sleepTimeout = self.settings.get("sleepTimeout", 20) + if self.current_card.config.get("sleepTimeout"): + sleepTimeout = self.current_card.config.get("sleepTimeout") + libs.panel_cmd.timeout(self.sendTopic, sleepTimeout) + self.dimmode() + + if msg[1] == "sleepReached": + self.privious_cards.append(self.current_card) + self.current_card = self.screensaver + self.render_current_page(switchPages=True) + if msg[1] == "renderCurrentPage": + self.render_current_page(requested=True) + if msg[1] == "buttonPress2": + entity_id = msg[2] + btype = msg[3] + value = msg[4] if len(msg) > 4 else None + if btype == "bExit": + if entity_id=="screensaver" and self.settings.get("screensaver").get("doubleTapToUnlock") and value == "1": + return + + # in case privious_cards is empty add a default card + if len(self.privious_cards) == 0: + self.privious_cards.append( + list(self.cards.values())[0]) # TODO: Impelement default card config + self.current_card = self.privious_cards.pop() + self.render_current_page(switchPages=True) + return + + # 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] + + match btype: + case 'button': + match entity_id.split(".")[0]: + # handle internal stuff + case 'navigate': + card_iid = entity_id.split(".")[1] + if card_iid == "UP": + self.current_card = self.privious_cards.pop() + # TODO Handle privious_cards empty with default card + self.render_current_page(switchPages=True) + else: + self.privious_cards.append(self.current_card) + self.current_card = self.searchCard(card_iid) + self.render_current_page(switchPages=True) + # send ha stuff to ha + case _: + ha_control.handle_buttons(entity_id, btype, value) + case 'cardUnlock-unlock': + card_iid = entity_id.split(".")[1] + if int(self.current_card.config.get("pin")) == int(value): + self.privious_cards.append(self.current_card) + self.current_card = self.searchCard(card_iid) + self.render_current_page(switchPages=True) + case _: + ha_control.handle_buttons(entity_id, btype, value) + + if msg[1] == "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], sendTopic=self.sendTopic)) diff --git a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel_cards.py b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel_cards.py index 54c4ed0b..a42d73fb 100644 --- a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel_cards.py +++ b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel_cards.py @@ -1,70 +1,69 @@ -from libs.helper import iid, rgb_dec565 -from libs.icon_mapping import get_icon_char -from libs.localization import get_translation - - -class Card: - def __init__(self, locale, config, panel=None): - self.iid = iid() - self.iid_prev = None - self.iid_next = None - self.navigate_key = config.get("key", None) - self.locale = locale - self.title = config.get("title", "") - self.type = config.get("type", "") - self.config = config - self.panel = panel - self.hidden = False - - def render(self): - raise NotImplementedError - - -class Entity: - def __init__(self, locale, config, panel): - self.iid = iid() - self.locale = locale - self.entity_id = config["entity"] - self.etype = self.entity_id.split(".")[0] - self.config = config - self.panel = panel - self.icon_overwrite = config.get("icon", None) - self.name_overwrite = config.get("name", None) - self.color_overwrite = config.get("color", None) - self.value_overwrite = config.get("value", None) - font_mapping = { - "small": "1", - "medium": "2", - "medium-icon": "3", - "large": "4", - } - self.font = font_mapping.get(config.get("font", ""), "") - - def render(self, cardType=""): - icon_char = self.icon_overwrite or "mdi:gesture-tap-button" - color = rgb_dec565([68, 115, 158]) - if self.color_overwrite: - color = rgb_dec565(self.color_overwrite) - name = self.name_overwrite or "" - value = "" - match self.etype: - case 'delete': - return f"~delete~~~~~" - case 'navigate': - card_iid = self.entity_id.split(".")[1] - if card_iid == "UP": - return f"~button~{self.entity_id}~{get_icon_char(icon_char)}~{color}~{name}~{value}" - else: - page_search_res = self.panel.searchCard(card_iid) - if page_search_res is not None: - if name == "": - name = page_search_res.title - value = get_translation( - self.locale, "frontend.ui.card.button.press") - return f"~button~{self.entity_id}~{get_icon_char(icon_char)}~{color}~{name}~{value}" - else: - return f"~text~{self.entity_id}~{get_icon_char('mdi:alert-circle-outline')}~17299~page not found~" - case 'iText': - # TODO: Render as HA Template - value = self.entity_id.split(".")[1] - return f"~text~{self.entity_id}~{get_icon_char(icon_char)}~{color}~{name}~{value}" +from libs.helper import iid, rgb_dec565 +from libs.icon_mapping import get_icon_char +from libs.localization import get_translation + + +class Card: + def __init__(self, locale, config, panel=None): + self.iid = iid() + self.iid_prev = None + self.iid_next = None + self.navigate_key = config.get("key", None) + self.locale = locale + self.title = config.get("title", "") + self.type = config.get("type", "") + self.config = config + self.panel = panel + self.hidden = False + + def render(self): + raise NotImplementedError + +class Entity: + def __init__(self, locale, config, panel): + self.iid = iid() + self.locale = locale + self.entity_id = config["entity"] + self.etype = self.entity_id.split(".")[0] + self.config = config + self.panel = panel + self.icon_overwrite = config.get("icon", None) + self.name_overwrite = config.get("name", None) + self.color_overwrite = config.get("color", None) + self.value_overwrite = config.get("value", None) + font_mapping = { + "small": "1", + "medium": "2", + "medium-icon": "3", + "large": "4", + } + self.font = font_mapping.get(config.get("font", ""), "") + + def render(self, cardType=""): + icon_char = self.icon_overwrite or "mdi:gesture-tap-button" + color = rgb_dec565([68, 115, 158]) + if self.color_overwrite: + color = rgb_dec565(self.color_overwrite) + name = self.name_overwrite or "" + value = "" + match self.etype: + case 'delete': + return f"~delete~~~~~" + case 'navigate': + card_iid = self.entity_id.split(".")[1] + if card_iid == "UP": + return f"~button~{self.entity_id}~{get_icon_char(icon_char)}~{color}~{name}~{value}" + else: + page_search_res = self.panel.searchCard(card_iid) + if page_search_res is not None: + if name == "": + name = page_search_res.title + value = get_translation( + self.locale, "frontend.ui.card.button.press") + return f"~button~{self.entity_id}~{get_icon_char(icon_char)}~{color}~{name}~{value}" + else: + return f"~text~{self.entity_id}~{get_icon_char('mdi:alert-circle-outline')}~17299~page not found~" + case 'iText': + # TODO: Render as HA Template + value = self.entity_id.split(".")[1] + return f"~text~{self.entity_id}~{get_icon_char(icon_char)}~{color}~{name}~{value}"