mirror of
https://github.com/joBr99/nspanel-lovelace-ui.git
synced 2025-12-19 22:24:15 +01:00
started on new config format
This commit is contained in:
@@ -24,41 +24,19 @@ nspanel-1:
|
|||||||
sensor.solar_power_current: # use this for overriding name and icon
|
sensor.solar_power_current: # use this for overriding name and icon
|
||||||
name: Sonne
|
name: Sonne
|
||||||
icon: solar-power
|
icon: solar-power
|
||||||
pages:
|
cards:
|
||||||
- type: cardEntities
|
- type: entities
|
||||||
heading: Example Page 1
|
entities:
|
||||||
items:
|
- entity: light.example_item
|
||||||
- cover.example_cover
|
name: NameOverride
|
||||||
- switch.example_switch
|
- entity: light.example_item
|
||||||
- input_boolean.example_input_boolean
|
title: Example Entities
|
||||||
- sensor.example_sensor
|
- type: gird
|
||||||
- type: cardEntities
|
entities:
|
||||||
heading: Example Page 2
|
- entity: select.example_item
|
||||||
items:
|
- entity: select.example_item
|
||||||
- button.example_button
|
- entity: light.example_item
|
||||||
- input_button.example_input_button
|
title: Exmaple Gird
|
||||||
- light.light_example
|
- type: climate
|
||||||
- delete # (read this as 'empty')
|
entity: light.example_item
|
||||||
- type: cardEntities
|
title: Exmaple Climate
|
||||||
heading: Example Page 3
|
|
||||||
items:
|
|
||||||
- scene.example_scene
|
|
||||||
- delete
|
|
||||||
- delete
|
|
||||||
- delete
|
|
||||||
- type: cardGrid
|
|
||||||
heading: Example Page 4
|
|
||||||
items:
|
|
||||||
- light.light_example
|
|
||||||
- button.example_button
|
|
||||||
- cover.example_cover
|
|
||||||
- scene.example_scene
|
|
||||||
- switch.example_switch
|
|
||||||
- delete
|
|
||||||
- type: cardThermo
|
|
||||||
heading: Exmaple Thermostat
|
|
||||||
item: climate.example_climate
|
|
||||||
- type: cardMedia
|
|
||||||
item: media_player.spotify_user
|
|
||||||
- type: cardAlarm
|
|
||||||
item: alarm_control_panel.alarmo
|
|
||||||
@@ -2,98 +2,27 @@ import logging
|
|||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
class PageNode(object):
|
HA_API = None
|
||||||
def __init__(self, data, parent=None):
|
|
||||||
self.data = data
|
|
||||||
self.name = None
|
|
||||||
self.childs = []
|
|
||||||
self.parent = parent
|
|
||||||
self.pos = None
|
|
||||||
|
|
||||||
if "items" in data:
|
class Entity(object):
|
||||||
childs = data.pop("items")
|
def __init__(self, entity_input_config):
|
||||||
for page in childs:
|
self.entityId = entity_input_config.get("entity", "unknown")
|
||||||
self.add_child(PageNode(page, self))
|
self.nameOverride = entity_input_config.get("name")
|
||||||
|
self.iconOverride = entity_input_config.get("icon")
|
||||||
|
|
||||||
name = self.data.get("heading", "unkown") if type(self.data) is dict else self.data
|
class Card(object):
|
||||||
ptype = self.data.get("type", "unkown") if type(self.data) is dict else "leaf"
|
def __init__(self, card_input_config):
|
||||||
|
self.cardType = card_input_config.get("type", "unknown")
|
||||||
|
self.title = card_input_config.get("title", "unknown")
|
||||||
|
# for single entity card like climate or media
|
||||||
|
self.entity = None
|
||||||
|
if card_input_config.get("entity") is not None:
|
||||||
|
self.entity = Entity(card_input_config.get("entity"))
|
||||||
|
# for pages like grid or entities
|
||||||
|
self.entities = []
|
||||||
|
for e in card_input_config.get("entities", []):
|
||||||
|
self.entities.append(Entity(e))
|
||||||
|
|
||||||
self.name = f"{ptype}.{name}" if type(self.data) is dict else self.data
|
|
||||||
self.name = self.name.replace(".","_")
|
|
||||||
self.name = self.name.replace(",","_")
|
|
||||||
self.name = self.name.replace(" ","_")
|
|
||||||
|
|
||||||
def add_child(self, obj):
|
|
||||||
obj.pos = len(self.childs)
|
|
||||||
self.childs.append(obj)
|
|
||||||
|
|
||||||
def next(self):
|
|
||||||
if self.parent is not None:
|
|
||||||
pos = self.pos
|
|
||||||
length = len(self.parent.childs)
|
|
||||||
return self.parent.childs[(pos+1)%length]
|
|
||||||
else:
|
|
||||||
return self
|
|
||||||
def prev(self):
|
|
||||||
if self.parent is not None:
|
|
||||||
pos = self.pos
|
|
||||||
length = len(self.parent.childs)
|
|
||||||
return self.parent.childs[(pos-1)%length]
|
|
||||||
else:
|
|
||||||
return self
|
|
||||||
|
|
||||||
def search_page_by_name(self, name):
|
|
||||||
name = name.replace("navigate.", "")
|
|
||||||
pages = []
|
|
||||||
for i in self.childs:
|
|
||||||
# compare name of current page
|
|
||||||
if i.name == name:
|
|
||||||
pages.append(i)
|
|
||||||
# current pages has also childs
|
|
||||||
if len(i.childs) > 0:
|
|
||||||
pages.extend(i.search_page_by_name(name))
|
|
||||||
return pages
|
|
||||||
|
|
||||||
return items
|
|
||||||
|
|
||||||
def dump(self, indent=0):
|
|
||||||
"""dump tree to string"""
|
|
||||||
tab = ' '*(indent-1) + ' |- ' if indent > 0 else ''
|
|
||||||
name = self.name
|
|
||||||
parent = self.parent.name if self.parent is not None else "root"
|
|
||||||
dumpstring = f"{tab}{self.pos}:{name} -> {parent} \n"
|
|
||||||
for obj in self.childs:
|
|
||||||
dumpstring += obj.dump(indent + 1)
|
|
||||||
return dumpstring
|
|
||||||
|
|
||||||
def get_items(self):
|
|
||||||
items = []
|
|
||||||
for i in self.childs:
|
|
||||||
if len(i.childs) > 0:
|
|
||||||
items.append(f"navigate.{i.name}")
|
|
||||||
else:
|
|
||||||
items.append(i.data)
|
|
||||||
return items
|
|
||||||
|
|
||||||
def get_all_item_names(self, recursive=True):
|
|
||||||
items = []
|
|
||||||
# current page
|
|
||||||
if type(self.data) is dict:
|
|
||||||
items.append(self.data.get("item", next(iter(self.data))))
|
|
||||||
else:
|
|
||||||
items.append(self.data)
|
|
||||||
# childs of page
|
|
||||||
for i in self.childs:
|
|
||||||
if len(i.childs) > 0:
|
|
||||||
if recursive:
|
|
||||||
items.extend(i.get_all_item_names())
|
|
||||||
else:
|
|
||||||
if type(i.data) is dict:
|
|
||||||
items.append(i.data.get("item", next(iter(i.data))))
|
|
||||||
else:
|
|
||||||
items.append(i.data)
|
|
||||||
return items
|
|
||||||
|
|
||||||
class LuiBackendConfig(object):
|
class LuiBackendConfig(object):
|
||||||
|
|
||||||
_DEFAULT_CONFIG = {
|
_DEFAULT_CONFIG = {
|
||||||
@@ -115,27 +44,41 @@ class LuiBackendConfig(object):
|
|||||||
'weatherOverrideForecast3': None,
|
'weatherOverrideForecast3': None,
|
||||||
'weatherOverrideForecast4': None,
|
'weatherOverrideForecast4': None,
|
||||||
'doubleTapToUnlock': False,
|
'doubleTapToUnlock': False,
|
||||||
'pages': [{
|
'cards': [{
|
||||||
'type': 'cardEntities',
|
'type': 'entities',
|
||||||
'heading': 'Test Entities 1',
|
'entities': [{
|
||||||
'items': ['switch.test_item', 'switch.test_item', 'switch.test_item']
|
'entity': 'switch.test_item',
|
||||||
}, {
|
'name': 'Test Item'
|
||||||
'type': 'cardGrid',
|
}, {
|
||||||
'heading': 'Test Grid 1',
|
'entity': 'switch.test_item'
|
||||||
'items': ['switch.test_item', 'switch.test_item', 'switch.test_item']
|
}],
|
||||||
}
|
'title': 'Example Entities Page'
|
||||||
]
|
}, {
|
||||||
|
'type': 'grid',
|
||||||
|
'entities': [{
|
||||||
|
'entity': 'switch.test_item'
|
||||||
|
}, {
|
||||||
|
'entity': 'switch.test_item'
|
||||||
|
}, {
|
||||||
|
'entity': 'switch.test_item'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'title': 'Example Grid Page'
|
||||||
|
}, {
|
||||||
|
'type': 'climate',
|
||||||
|
'entity': 'climate.test_item'
|
||||||
|
'title': 'Example Climate Page'
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, args=None, check=True):
|
def __init__(self, ha_api, config_in):
|
||||||
|
global HA_API
|
||||||
|
HA_API = ha_api
|
||||||
self._config = {}
|
self._config = {}
|
||||||
self._page_config = None
|
self._config_cards = []
|
||||||
|
self._current_card = None
|
||||||
if args:
|
|
||||||
self.load(args)
|
|
||||||
|
|
||||||
if check:
|
self.load(config_in)
|
||||||
self.check()
|
|
||||||
|
|
||||||
def load(self, args):
|
def load(self, args):
|
||||||
for k, v in args.items():
|
for k, v in args.items():
|
||||||
@@ -143,13 +86,11 @@ class LuiBackendConfig(object):
|
|||||||
self._config[k] = v
|
self._config[k] = v
|
||||||
LOGGER.info(f"Loaded config: {self._config}")
|
LOGGER.info(f"Loaded config: {self._config}")
|
||||||
|
|
||||||
root_page = {"items": self.get("pages"), "type": "internal", "heading": "root"}
|
for card in self.get("cards"):
|
||||||
self._page_config = PageNode(root_page)
|
self._config_cards.append(Card(card))
|
||||||
|
# set current card to first card
|
||||||
|
self._current_card = self._config_cards[0]
|
||||||
|
|
||||||
LOGGER.info(f"Parsed Page config to the following Tree: \n {self._page_config.dump()}")
|
|
||||||
|
|
||||||
def check(self):
|
|
||||||
return
|
|
||||||
|
|
||||||
def get(self, name):
|
def get(self, name):
|
||||||
value = self._config.get(name)
|
value = self._config.get(name)
|
||||||
@@ -157,6 +98,3 @@ class LuiBackendConfig(object):
|
|||||||
value = self._DEFAULT_CONFIG.get(name)
|
value = self._DEFAULT_CONFIG.get(name)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def get_root_page(self):
|
|
||||||
return self._page_config
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ from luibackend.updater import Updater
|
|||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AppDaemonLoggingHandler(logging.Handler):
|
class AppDaemonLoggingHandler(logging.Handler):
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -50,43 +49,44 @@ class NsPanelLovelaceUIManager(hass.Hass):
|
|||||||
def initialize(self):
|
def initialize(self):
|
||||||
LOGGER.info('Starting')
|
LOGGER.info('Starting')
|
||||||
mqtt_api = self._mqtt_api = self.get_plugin_api("MQTT")
|
mqtt_api = self._mqtt_api = self.get_plugin_api("MQTT")
|
||||||
cfg = self._cfg = LuiBackendConfig(self.args["config"])
|
cfg = self._cfg = LuiBackendConfig(self, self.args["config"])
|
||||||
|
|
||||||
topic_send = cfg.get("panelSendTopic")
|
#topic_send = cfg.get("panelSendTopic")
|
||||||
def send_mqtt_msg(msg, topic=None):
|
#def send_mqtt_msg(msg, topic=None):
|
||||||
if topic is None:
|
# if topic is None:
|
||||||
topic = topic_send
|
# topic = topic_send
|
||||||
LOGGER.info(f"Sending MQTT Message: {msg}")
|
# LOGGER.info(f"Sending MQTT Message: {msg}")
|
||||||
mqtt_api.mqtt_publish(topic, msg)
|
# mqtt_api.mqtt_publish(topic, msg)
|
||||||
|
#
|
||||||
# Request Tasmota Driver Version
|
## Request Tasmota Driver Version
|
||||||
mqtt_api.mqtt_publish(topic_send.replace("CustomSend", "GetDriverVersion"), "x")
|
#mqtt_api.mqtt_publish(topic_send.replace("CustomSend", "GetDriverVersion"), "x")
|
||||||
|
#
|
||||||
controller = LuiController(self, cfg, send_mqtt_msg)
|
#controller = LuiController(self, cfg, send_mqtt_msg)
|
||||||
|
#
|
||||||
desired_display_firmware_version = 26
|
#desired_display_firmware_version = 26
|
||||||
version = "v2.4.0"
|
#version = "v2.4.0"
|
||||||
|
#
|
||||||
model = cfg.get("model")
|
#model = cfg.get("model")
|
||||||
if model == "us-l":
|
#if model == "us-l":
|
||||||
# us landscape version
|
# # us landscape version
|
||||||
desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft"
|
# desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft"
|
||||||
elif model == "us-p":
|
#elif model == "us-p":
|
||||||
# us portrait version
|
# # us portrait version
|
||||||
desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft"
|
# desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft"
|
||||||
else:
|
#else:
|
||||||
# eu version
|
# # eu version
|
||||||
desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft"
|
# desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft"
|
||||||
|
#
|
||||||
|
#
|
||||||
desired_tasmota_driver_version = 3
|
#desired_tasmota_driver_version = 3
|
||||||
desired_tasmota_driver_url = "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be"
|
#desired_tasmota_driver_url = "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be"
|
||||||
|
#
|
||||||
mode = cfg.get("updateMode")
|
#mode = cfg.get("updateMode")
|
||||||
topic_send = cfg.get("panelSendTopic")
|
#topic_send = cfg.get("panelSendTopic")
|
||||||
updater = Updater(send_mqtt_msg, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url)
|
#updater = Updater(send_mqtt_msg, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url)
|
||||||
|
#
|
||||||
topic_recv = cfg.get("panelRecvTopic")
|
#topic_recv = cfg.get("panelRecvTopic")
|
||||||
LuiMqttListener(mqtt_api, topic_recv, controller, updater)
|
#LuiMqttListener(mqtt_api, topic_recv, controller, updater)
|
||||||
|
#
|
||||||
LOGGER.info('Started')
|
#LOGGER.info('Started')
|
||||||
|
#
|
||||||
Reference in New Issue
Block a user