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 65743efa..974a96f9 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 @@ -14,11 +14,22 @@ class HAEntity(panel_cards.Entity): super().__init__(locale, config, panel) def render(self, cardType=""): + + if self.icon_overwrite and self.icon_overwrite.startswith("ha:"): + out = libs.home_assistant.render_template(self.icon_overwrite[3:]) + self.icon_overwrite = out + + if self.etype in ["delete", "navigate", "iText"]: + out = super().render() + return out + # get data from HA data = libs.home_assistant.get_entity_data(self.entity_id) if data: self.state = data.get("state") self.attributes = data.get("attributes", []) + else: + return "~text~iid.404~X~6666~not found~" # HA Entities entity_type_panel = "text" @@ -203,11 +214,11 @@ class HACard(panel_cards.Card): # Generate Entity for each Entity in Config self.entities = [] if "entity" in config: - iid, entity = entity_factory(locale, config, panel) + entity = HAEntity(locale, config, panel) self.entities.append(entity) if "entities" in config: for e in config.get("entities"): - iid, entity = entity_factory(locale, e, panel) + entity = HAEntity(locale, e, panel) self.entities.append(entity) def get_iid_entities(self): @@ -246,7 +257,7 @@ class EntitiesCard(HACard): result = f"{self.title}~{self.gen_nav()}" for e in self.entities: result += e.render(cardType=self.type) - return result + libs.panel_cmd.entityUpd(self.panel.sendTopic, result) class QRCard(HACard): def __init__(self, locale, config, panel): @@ -258,7 +269,7 @@ class QRCard(HACard): result = f"{self.title}~{self.gen_nav()}~{self.qrcode}" for e in self.entities: result += e.render() - return result + libs.panel_cmd.entityUpd(self.panel.sendTopic, result) class PowerCard(HACard): def __init__(self, locale, config, panel): @@ -276,7 +287,7 @@ class PowerCard(HACard): # if isinstance(speed, str): # speed = apis.ha_api.render_template(speed) result += f"~{speed}" - return result + libs.panel_cmd.entityUpd(self.panel.sendTopic, result) class MediaCard(HACard): def __init__(self, locale, config, panel): @@ -313,7 +324,7 @@ class MediaCard(HACard): for e in self.entities[1:]: button_str += e.render() result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}~{title}~~{author}~~{volume}~{iconplaypause}~{onoffbutton}~{shuffleBtn}{media_icon}{button_str}" - return result + libs.panel_cmd.entityUpd(self.panel.sendTopic, result) class ClimateCard(HACard): def __init__(self, locale, config, panel): @@ -408,7 +419,7 @@ class ClimateCard(HACard): detailPage = "0" result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}~{current_temp} {temperature_unit}~{dest_temp}~{state_value}~{min_temp}~{max_temp}~{step_temp}{icon_res}~{currently_translation}~{state_translation}~{action_translation}~{temperature_unit_icon}~{dest_temp2}~{detailPage}" - return result + libs.panel_cmd.entityUpd(self.panel.sendTopic, result) class AlarmCard(HACard): def __init__(self, locale, config, panel): @@ -478,18 +489,54 @@ class AlarmCard(HACard): if len(supported_modes) < 4: arm_buttons += "~"*((4-len(supported_modes))*2) result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}~{add_btn}" - return result + libs.panel_cmd.entityUpd(self.panel.sendTopic, result) class Screensaver(HACard): def __init__(self, locale, config, panel): super().__init__(locale, config, panel) + if not self.type: self.type = "screensaver" + + self.statusIcon1 = None + if "statusIcon1" in config: + self.statusIcon1 = HAEntity(locale, config.get("statusIcon1"), panel) + self.statusIcon2 = None + if "statusIcon2" in config: + self.statusIcon2 = HAEntity(locale, config.get("statusIcon2"), panel) + + def get_entities(self): + ent = [e.entity_id for e in self.entities] + if self.statusIcon1: + ent.append(self.statusIcon1.entity_id) + if self.statusIcon2: + ent.append(self.statusIcon2.entity_id) + return ent + def render(self): result = "" for e in self.entities: result += e.render(cardType=self.type) - return result[1:] + libs.panel_cmd.weatherUpdate(self.panel.sendTopic, result[1:]) + + statusUpdateResult = "" + icon1font = "" + icon2font = "" + if self.statusIcon1: + si1 = self.statusIcon1.render().split('~') + statusUpdateResult += f"{si1[3]}~{si1[4]}" + icon1font = self.statusIcon1.font + else: + statusUpdateResult += "~" + if self.statusIcon2: + si2 = self.statusIcon2.render().split('~') + statusUpdateResult += f"~{si2[3]}~{si2[4]}" + icon2font = self.statusIcon2.font + else: + statusUpdateResult += "~~" + + libs.panel_cmd.statusUpdate(self.panel.sendTopic, f"{statusUpdateResult}~{icon1font}~{icon2font}") + def card_factory(locale, settings, panel): @@ -511,15 +558,6 @@ def card_factory(locale, settings, panel): return "NotImplemented", None return card.iid, card - -def entity_factory(locale, settings, panel): - etype = settings["entity"].split(".")[0] - if etype in ["delete", "navigate", "iText"]: - entity = panel_cards.Entity(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: diff --git a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/libs/home_assistant.py b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/libs/home_assistant.py index 0a241f51..223b825b 100644 --- a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/libs/home_assistant.py +++ b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/libs/home_assistant.py @@ -54,6 +54,9 @@ def on_message(ws, message): _get_all_states() if ON_CONNECT_HANDLER is not None: ON_CONNECT_HANDLER() + # for templates + elif json_msg["type"] == "event" and json_msg["id"] in response_buffer: + response_buffer[json_msg["id"]] = json_msg["event"] elif json_msg["type"] == "event" and json_msg["event"]["event_type"] == "state_changed": entity_id = json_msg["event"]["data"]["entity_id"] home_assistant_entity_state_cache[entity_id] = json_msg["event"]["data"]["new_state"] @@ -68,7 +71,6 @@ def on_message(ws, message): else: if json_msg["id"] in response_buffer: response_buffer[json_msg["id"]] = json_msg["result"] - return None # Ignore success result messages else: logging.debug(message) @@ -203,6 +205,33 @@ def execute_script(entity_name: str, domain: str, service: str, service_data: di logging.exception("Failed to call Home Assisatant script.") return False +def render_template(template): + global next_id, response_buffer + try: + call_id = next_id + # request answer for this call + response_buffer[call_id] = True + msg = { + "id": next_id, + "type": "render_template", + "template": 'template' + } + print(json.dumps(msg)) + send_message(json.dumps(msg)) + # busy waiting for response with a timeout of 0.2 seconds - maybe there's a better way of doing this + mustend = time.time() + 0.2 + while time.time() < mustend: + if response_buffer[call_id] == True or response_buffer[call_id] is None: + #print(f'loooooooooop {time.time()}') + time.sleep(0.0001) + else: + return response_buffer[call_id]["result"] + raise TimeoutError("Did not recive respose in time to HA template render call") + except Exception as e: + logging.exception("Failed to render template.") + return False + return "" + def get_entity_data(entity_id: str): if entity_id in home_assistant_entity_state_cache: return home_assistant_entity_state_cache[entity_id] 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 2d09e127..631273c0 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 @@ -40,4 +40,7 @@ def dimmode(topic, dimValue, dimValueNormal, backgroundColor, fontColor, featExp 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 + custom_send(topic, f"entityUpdateDetail~{data}") + +def statusUpdate(topic, data): + custom_send(topic, f"statusUpdate~{data}") \ No newline at end of file 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 c6bfc793..64221f30 100644 --- a/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel.py +++ b/nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/panel.py @@ -125,10 +125,7 @@ class LovelaceUIPanel: if switchPages: libs.panel_cmd.page_type(self.sendTopic, self.current_card.type) - if self.current_card.type in ["screensaver", "screensaver2"]: - libs.panel_cmd.weatherUpdate(self.sendTopic, self.current_card.render()) - else: - libs.panel_cmd.entityUpd(self.sendTopic, self.current_card.render()) + self.current_card.render() # send sleepTimeout sleepTimeout = self.settings.get("sleepTimeout", 20) if self.current_card.config.get("sleepTimeout"): 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 2126551c..e1a09762 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 @@ -30,6 +30,13 @@ class Entity: self.icon_overwrite = config.get("icon", None) self.name_overwrite = config.get("name", None) self.color_overwrite = config.get("color", 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 ""