mirror of
https://github.com/joBr99/nspanel-lovelace-ui.git
synced 2025-12-20 22:47:01 +01:00
implement status icons
This commit is contained in:
@@ -14,11 +14,22 @@ class HAEntity(panel_cards.Entity):
|
|||||||
super().__init__(locale, config, panel)
|
super().__init__(locale, config, panel)
|
||||||
|
|
||||||
def render(self, cardType=""):
|
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
|
# get data from HA
|
||||||
data = libs.home_assistant.get_entity_data(self.entity_id)
|
data = libs.home_assistant.get_entity_data(self.entity_id)
|
||||||
if data:
|
if data:
|
||||||
self.state = data.get("state")
|
self.state = data.get("state")
|
||||||
self.attributes = data.get("attributes", [])
|
self.attributes = data.get("attributes", [])
|
||||||
|
else:
|
||||||
|
return "~text~iid.404~X~6666~not found~"
|
||||||
|
|
||||||
# HA Entities
|
# HA Entities
|
||||||
entity_type_panel = "text"
|
entity_type_panel = "text"
|
||||||
@@ -203,11 +214,11 @@ class HACard(panel_cards.Card):
|
|||||||
# Generate Entity for each Entity in Config
|
# Generate Entity for each Entity in Config
|
||||||
self.entities = []
|
self.entities = []
|
||||||
if "entity" in config:
|
if "entity" in config:
|
||||||
iid, entity = entity_factory(locale, config, panel)
|
entity = HAEntity(locale, config, panel)
|
||||||
self.entities.append(entity)
|
self.entities.append(entity)
|
||||||
if "entities" in config:
|
if "entities" in config:
|
||||||
for e in config.get("entities"):
|
for e in config.get("entities"):
|
||||||
iid, entity = entity_factory(locale, e, panel)
|
entity = HAEntity(locale, e, panel)
|
||||||
self.entities.append(entity)
|
self.entities.append(entity)
|
||||||
|
|
||||||
def get_iid_entities(self):
|
def get_iid_entities(self):
|
||||||
@@ -246,7 +257,7 @@ class EntitiesCard(HACard):
|
|||||||
result = f"{self.title}~{self.gen_nav()}"
|
result = f"{self.title}~{self.gen_nav()}"
|
||||||
for e in self.entities:
|
for e in self.entities:
|
||||||
result += e.render(cardType=self.type)
|
result += e.render(cardType=self.type)
|
||||||
return result
|
libs.panel_cmd.entityUpd(self.panel.sendTopic, result)
|
||||||
|
|
||||||
class QRCard(HACard):
|
class QRCard(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
@@ -258,7 +269,7 @@ class QRCard(HACard):
|
|||||||
result = f"{self.title}~{self.gen_nav()}~{self.qrcode}"
|
result = f"{self.title}~{self.gen_nav()}~{self.qrcode}"
|
||||||
for e in self.entities:
|
for e in self.entities:
|
||||||
result += e.render()
|
result += e.render()
|
||||||
return result
|
libs.panel_cmd.entityUpd(self.panel.sendTopic, result)
|
||||||
|
|
||||||
class PowerCard(HACard):
|
class PowerCard(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
@@ -276,7 +287,7 @@ class PowerCard(HACard):
|
|||||||
# if isinstance(speed, str):
|
# if isinstance(speed, str):
|
||||||
# speed = apis.ha_api.render_template(speed)
|
# speed = apis.ha_api.render_template(speed)
|
||||||
result += f"~{speed}"
|
result += f"~{speed}"
|
||||||
return result
|
libs.panel_cmd.entityUpd(self.panel.sendTopic, result)
|
||||||
|
|
||||||
class MediaCard(HACard):
|
class MediaCard(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
@@ -313,7 +324,7 @@ class MediaCard(HACard):
|
|||||||
for e in self.entities[1:]:
|
for e in self.entities[1:]:
|
||||||
button_str += e.render()
|
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}"
|
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):
|
class ClimateCard(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
@@ -408,7 +419,7 @@ class ClimateCard(HACard):
|
|||||||
detailPage = "0"
|
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}"
|
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):
|
class AlarmCard(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
@@ -478,18 +489,54 @@ class AlarmCard(HACard):
|
|||||||
if len(supported_modes) < 4:
|
if len(supported_modes) < 4:
|
||||||
arm_buttons += "~"*((4-len(supported_modes))*2)
|
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}"
|
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):
|
class Screensaver(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
super().__init__(locale, config, panel)
|
super().__init__(locale, config, panel)
|
||||||
|
|
||||||
if not self.type:
|
if not self.type:
|
||||||
self.type = "screensaver"
|
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):
|
def render(self):
|
||||||
result = ""
|
result = ""
|
||||||
for e in self.entities:
|
for e in self.entities:
|
||||||
result += e.render(cardType=self.type)
|
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):
|
def card_factory(locale, settings, panel):
|
||||||
@@ -511,15 +558,6 @@ def card_factory(locale, settings, panel):
|
|||||||
return "NotImplemented", None
|
return "NotImplemented", None
|
||||||
return card.iid, card
|
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):
|
def detail_open(locale, detail_type, ha_entity_id, entity_id):
|
||||||
data = libs.home_assistant.get_entity_data(ha_entity_id)
|
data = libs.home_assistant.get_entity_data(ha_entity_id)
|
||||||
if data:
|
if data:
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ def on_message(ws, message):
|
|||||||
_get_all_states()
|
_get_all_states()
|
||||||
if ON_CONNECT_HANDLER is not None:
|
if ON_CONNECT_HANDLER is not None:
|
||||||
ON_CONNECT_HANDLER()
|
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":
|
elif json_msg["type"] == "event" and json_msg["event"]["event_type"] == "state_changed":
|
||||||
entity_id = json_msg["event"]["data"]["entity_id"]
|
entity_id = json_msg["event"]["data"]["entity_id"]
|
||||||
home_assistant_entity_state_cache[entity_id] = json_msg["event"]["data"]["new_state"]
|
home_assistant_entity_state_cache[entity_id] = json_msg["event"]["data"]["new_state"]
|
||||||
@@ -68,7 +71,6 @@ def on_message(ws, message):
|
|||||||
else:
|
else:
|
||||||
if json_msg["id"] in response_buffer:
|
if json_msg["id"] in response_buffer:
|
||||||
response_buffer[json_msg["id"]] = json_msg["result"]
|
response_buffer[json_msg["id"]] = json_msg["result"]
|
||||||
|
|
||||||
return None # Ignore success result messages
|
return None # Ignore success result messages
|
||||||
else:
|
else:
|
||||||
logging.debug(message)
|
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.")
|
logging.exception("Failed to call Home Assisatant script.")
|
||||||
return False
|
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):
|
def get_entity_data(entity_id: str):
|
||||||
if entity_id in home_assistant_entity_state_cache:
|
if entity_id in home_assistant_entity_state_cache:
|
||||||
return home_assistant_entity_state_cache[entity_id]
|
return home_assistant_entity_state_cache[entity_id]
|
||||||
|
|||||||
@@ -40,4 +40,7 @@ def dimmode(topic, dimValue, dimValueNormal, backgroundColor, fontColor, featExp
|
|||||||
custom_send(topic, f"dimmode~{dimValue}~{dimValueNormal}~{backgroundColor}~{fontColor}~{featExperimentalSliders}")
|
custom_send(topic, f"dimmode~{dimValue}~{dimValueNormal}~{backgroundColor}~{fontColor}~{featExperimentalSliders}")
|
||||||
|
|
||||||
def entityUpdateDetail(topic, data):
|
def entityUpdateDetail(topic, data):
|
||||||
custom_send(topic, f"entityUpdateDetail~{data}")
|
custom_send(topic, f"entityUpdateDetail~{data}")
|
||||||
|
|
||||||
|
def statusUpdate(topic, data):
|
||||||
|
custom_send(topic, f"statusUpdate~{data}")
|
||||||
@@ -125,10 +125,7 @@ class LovelaceUIPanel:
|
|||||||
if switchPages:
|
if switchPages:
|
||||||
libs.panel_cmd.page_type(self.sendTopic, self.current_card.type)
|
libs.panel_cmd.page_type(self.sendTopic, self.current_card.type)
|
||||||
|
|
||||||
if self.current_card.type in ["screensaver", "screensaver2"]:
|
self.current_card.render()
|
||||||
libs.panel_cmd.weatherUpdate(self.sendTopic, self.current_card.render())
|
|
||||||
else:
|
|
||||||
libs.panel_cmd.entityUpd(self.sendTopic, self.current_card.render())
|
|
||||||
# send sleepTimeout
|
# send sleepTimeout
|
||||||
sleepTimeout = self.settings.get("sleepTimeout", 20)
|
sleepTimeout = self.settings.get("sleepTimeout", 20)
|
||||||
if self.current_card.config.get("sleepTimeout"):
|
if self.current_card.config.get("sleepTimeout"):
|
||||||
|
|||||||
@@ -30,6 +30,13 @@ class Entity:
|
|||||||
self.icon_overwrite = config.get("icon", None)
|
self.icon_overwrite = config.get("icon", None)
|
||||||
self.name_overwrite = config.get("name", None)
|
self.name_overwrite = config.get("name", None)
|
||||||
self.color_overwrite = config.get("color", 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=""):
|
def render(self, cardType=""):
|
||||||
icon_char = self.icon_overwrite or ""
|
icon_char = self.icon_overwrite or ""
|
||||||
|
|||||||
Reference in New Issue
Block a user