mirror of
https://github.com/joBr99/nspanel-lovelace-ui.git
synced 2025-12-19 22:24:15 +01:00
new config format
This commit is contained in:
94
README.md
94
README.md
@@ -260,7 +260,7 @@ nspanel-1:
|
|||||||
config:
|
config:
|
||||||
panelRecvTopic: "tele/tasmota_your_mqtt_topic/RESULT"
|
panelRecvTopic: "tele/tasmota_your_mqtt_topic/RESULT"
|
||||||
panelSendTopic: "cmnd/tasmota_your_mqtt_topic/CustomSend"
|
panelSendTopic: "cmnd/tasmota_your_mqtt_topic/CustomSend"
|
||||||
#model: us-p # uncomment this if you have the us version, see table below for more information
|
updateMode: "auto-notify"
|
||||||
timeoutScreensaver: 20
|
timeoutScreensaver: 20
|
||||||
#brightnessScreensaver: 10
|
#brightnessScreensaver: 10
|
||||||
brightnessScreensaver:
|
brightnessScreensaver:
|
||||||
@@ -268,49 +268,28 @@ nspanel-1:
|
|||||||
value: 10
|
value: 10
|
||||||
- time: "23:00:00"
|
- time: "23:00:00"
|
||||||
value: 0
|
value: 0
|
||||||
locale: "de_DE"
|
locale: "de_DE" # used for translations in translations.py and for localized date if babel python package is installed
|
||||||
dateFormatBabel: "full"
|
screensaver:
|
||||||
timeFormat: "%H:%M"
|
weather: weather.k3ll3r
|
||||||
dateFormat: "%A, %d. %B %Y" # ignored if babel python package is installed
|
cards:
|
||||||
weather: weather.example
|
|
||||||
pages:
|
|
||||||
- type: cardEntities
|
- type: cardEntities
|
||||||
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: cardEntities
|
|
||||||
heading: Example Page 2
|
|
||||||
items:
|
|
||||||
- button.example_button
|
|
||||||
- input_button.example_input_button
|
|
||||||
- light.light_example
|
|
||||||
- delete # (read this as 'empty')
|
|
||||||
- type: cardEntities
|
|
||||||
heading: Example Page 3
|
|
||||||
items:
|
|
||||||
- scene.example_scene
|
|
||||||
- delete
|
|
||||||
- delete
|
|
||||||
- delete
|
|
||||||
- type: cardGrid
|
- type: cardGrid
|
||||||
heading: Example Page 4
|
entities:
|
||||||
items:
|
- entity: select.example_item
|
||||||
- light.light_example
|
- entity: select.example_item
|
||||||
- button.example_button
|
- entity: light.example_item
|
||||||
- cover.example_cover
|
title: Exmaple Gird
|
||||||
- scene.example_scene
|
|
||||||
- switch.example_switch
|
|
||||||
- delete
|
|
||||||
- type: cardThermo
|
- type: cardThermo
|
||||||
heading: Exmaple Thermostat
|
entity: climate.example_item
|
||||||
item: climate.example_climate
|
|
||||||
- type: cardMedia
|
- type: cardMedia
|
||||||
item: media_player.spotify_user
|
entity: media_player.example_item
|
||||||
- type: cardAlarm
|
- type: cardAlarm
|
||||||
item: alarm_control_panel.alarmo
|
entity: alarm_control_panel.alarmo
|
||||||
```
|
```
|
||||||
|
|
||||||
key | optional | type | default | description
|
key | optional | type | default | description
|
||||||
@@ -327,13 +306,21 @@ key | optional | type | default | description
|
|||||||
`panelSendTopic` | False | string | `cmnd/tasmota_your_mqtt_topic/CustomSend` | The mqtt topic used to send messages.
|
`panelSendTopic` | False | string | `cmnd/tasmota_your_mqtt_topic/CustomSend` | The mqtt topic used to send messages.
|
||||||
`updateMode` | True | string | `auto-notify` | Update Mode; Possible values: "auto", "auto-notify", "manual"
|
`updateMode` | True | string | `auto-notify` | Update Mode; Possible values: "auto", "auto-notify", "manual"
|
||||||
`model` | True | string | `eu` | Model; Possible values: "eu", "us-l" and "us-p"
|
`model` | True | string | `eu` | Model; Possible values: "eu", "us-l" and "us-p"
|
||||||
`timeoutScreensaver` | True | integer | `20` | Timeout for the screen to enter screensaver, to disable screensaver use 0
|
`sleepTimeout` | True | integer | `20` | Timeout for the screen to enter screensaver, to disable screensaver use 0
|
||||||
`brightnessScreensaver` | True | integer/complex | `20` | Brightness for the screen to enter screensaver, see example below for complex/scheduled config.
|
`sleepBrightness` | True | integer/complex | `20` | Brightness for the screen to enter screensaver, see example below for complex/scheduled config.
|
||||||
`brightnessScreensaverTracking` | True | string | None | Forces screensaver brightness to 0 in case entity state is not_home, can be a group, person or device_tracker entity.
|
`sleepTracking` | True | string | None | Forces screensaver brightness to 0 in case entity state is not_home, can be a group, person or device_tracker entity.
|
||||||
`locale` | True | string | `en_US` | Used by babel to determinante Date format on screensaver, also used for localization.
|
`locale` | True | string | `en_US` | Used by babel to determinante Date format on screensaver, also used for localization.
|
||||||
`dateFormatBabel` | True | string | `full` | formatting options on https://babel.pocoo.org/en/latest/dates.html?highlight=name%20of%20day#date-fields
|
`dateFormatBabel` | True | string | `full` | formatting options on https://babel.pocoo.org/en/latest/dates.html?highlight=name%20of%20day#date-fields
|
||||||
`timeFormat` | True | string | `%H:%M` | Time Format on screensaver. Substring after `?` is displayed in a seperate smaller textbox. Useful for 12h time format with AM/PM `"%I:%M ?%p"`
|
`timeFormat` | True | string | `%H:%M` | Time Format on screensaver. Substring after `?` is displayed in a seperate smaller textbox. Useful for 12h time format with AM/PM `"%I:%M ?%p"`
|
||||||
`dateFormat` | True | string | `%A, %d. %B %Y` | date format used if babel is not installed
|
`dateFormat` | True | string | `%A, %d. %B %Y` | date format used if babel is not installed
|
||||||
|
`cards` | False | complex | | configuration for pages that are displayed on panel
|
||||||
|
`screensaver` | True | complex | | configuration for screensaver
|
||||||
|
`hiddenCards` | True | complex | | configuration for pages that can be accessed though navigate items
|
||||||
|
|
||||||
|
Possible configuration values for screensaver config:
|
||||||
|
|
||||||
|
key | optional | type | default | description
|
||||||
|
-- | -- | -- | -- | --
|
||||||
`weather` | True | string | `weather.example` | weather entity from homeassistant
|
`weather` | True | string | `weather.example` | weather entity from homeassistant
|
||||||
`weatherUnit` | True | string | `celsius` | unit for temperature, valid values are `celsius` or `fahrenheit`
|
`weatherUnit` | True | string | `celsius` | unit for temperature, valid values are `celsius` or `fahrenheit`
|
||||||
`weatherOverrideForecast1` | True | string | `None` | sensor entity from home assistant here to override the first weather forecast item on the screensaver
|
`weatherOverrideForecast1` | True | string | `None` | sensor entity from home assistant here to override the first weather forecast item on the screensaver
|
||||||
@@ -341,14 +328,13 @@ key | optional | type | default | description
|
|||||||
`weatherOverrideForecast3` | True | string | `None` | sensor entity from home assistant here to override the third weather forecast item on the screensaver
|
`weatherOverrideForecast3` | True | string | `None` | sensor entity from home assistant here to override the third weather forecast item on the screensaver
|
||||||
`weatherOverrideForecast4` | True | string | `None` | sensor entity from home assistant here to override the forth weather forecast item on the screensaver
|
`weatherOverrideForecast4` | True | string | `None` | sensor entity from home assistant here to override the forth weather forecast item on the screensaver
|
||||||
`doubleTapToUnlock` | True | boolean | `False` | requires to tap screensaver two times
|
`doubleTapToUnlock` | True | boolean | `False` | requires to tap screensaver two times
|
||||||
`pages` | False | complex | | configuration for pages on panel
|
|
||||||
|
|
||||||
#### Schedule screensaver brightness
|
#### Schedule sleep brightness
|
||||||
|
|
||||||
It is possible to schedule a brightness change for the screen at specific times.
|
It is possible to schedule a brightness change for the screen at specific times.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
brightnessScreensaver:
|
sleepBrightness:
|
||||||
- time: "7:00:00"
|
- time: "7:00:00"
|
||||||
value: 10
|
value: 10
|
||||||
- time: "23:00:00"
|
- time: "23:00:00"
|
||||||
@@ -361,17 +347,13 @@ To override Icons or Names of entities you can configure an icon and/or name in
|
|||||||
Only the icons listed in the [Icon Table](HMI#icons-ids) are useable.
|
Only the icons listed in the [Icon Table](HMI#icons-ids) are useable.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- type: cardGrid
|
'entities': [{
|
||||||
heading: Lights
|
'entity': 'switch.test_item',
|
||||||
items:
|
'name': 'Test Item'
|
||||||
- light.wled
|
'icon': 'lightbulb'
|
||||||
- light.schreibtischlampe
|
}, {
|
||||||
- switch.deckenbeleuchtung_hinten:
|
'entity': 'switch.test_item'
|
||||||
icon: lightbulb
|
}],
|
||||||
name: Lampe
|
|
||||||
- delete
|
|
||||||
- delete
|
|
||||||
- type: cardMedia
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## How to update
|
## How to update
|
||||||
|
|||||||
@@ -13,30 +13,25 @@ nspanel-1:
|
|||||||
value: 10
|
value: 10
|
||||||
- time: "23:00:00"
|
- time: "23:00:00"
|
||||||
value: 0
|
value: 0
|
||||||
locale: "de_DE" # only used if babel python package is installed
|
locale: "de_DE" # used for translations in translations.py and for localized date if babel python package is installed
|
||||||
dateFormatBabel: "full" # only used if babel python package is installed
|
screensaver:
|
||||||
# formatting options on https://babel.pocoo.org/en/latest/dates.html?highlight=name%20of%20day#date-fields
|
weather: weather.k3ll3r
|
||||||
timeFormat: "%H:%M"
|
|
||||||
dateFormat: "%A, %d. %B %Y" # ignored if babel python package is installed
|
|
||||||
weather: weather.example
|
|
||||||
weatherOverrideForecast3: sensor.nas_cpu_perc
|
|
||||||
weatherOverrideForecast4:
|
|
||||||
sensor.solar_power_current: # use this for overriding name and icon
|
|
||||||
name: Sonne
|
|
||||||
icon: solar-power
|
|
||||||
cards:
|
cards:
|
||||||
- type: entities
|
- type: cardEntities
|
||||||
entities:
|
entities:
|
||||||
- entity: light.example_item
|
- entity: light.example_item
|
||||||
name: NameOverride
|
name: NameOverride
|
||||||
- entity: light.example_item
|
- entity: light.example_item
|
||||||
title: Example Entities
|
title: Example Entities
|
||||||
- type: gird
|
- type: cardGrid
|
||||||
entities:
|
entities:
|
||||||
- entity: select.example_item
|
- entity: select.example_item
|
||||||
- entity: select.example_item
|
- entity: select.example_item
|
||||||
- entity: light.example_item
|
- entity: light.example_item
|
||||||
title: Exmaple Gird
|
title: Exmaple Gird
|
||||||
- type: climate
|
- type: cardThermo
|
||||||
entity: light.example_item
|
entity: climate.example_item
|
||||||
title: Exmaple Climate
|
- type: cardMedia
|
||||||
|
entity: media_player.example_item
|
||||||
|
- type: cardAlarm
|
||||||
|
entity: alarm_control_panel.alarmo
|
||||||
@@ -11,17 +11,31 @@ class Entity(object):
|
|||||||
self.iconOverride = entity_input_config.get("icon")
|
self.iconOverride = entity_input_config.get("icon")
|
||||||
|
|
||||||
class Card(object):
|
class Card(object):
|
||||||
def __init__(self, card_input_config):
|
def __init__(self, card_input_config, pos=None):
|
||||||
|
self.pos = pos
|
||||||
|
self.raw_config = card_input_config
|
||||||
self.cardType = card_input_config.get("type", "unknown")
|
self.cardType = card_input_config.get("type", "unknown")
|
||||||
self.title = card_input_config.get("title", "unknown")
|
self.title = card_input_config.get("title", "unknown")
|
||||||
|
self.key = card_input_config.get("key", "unknown")
|
||||||
# for single entity card like climate or media
|
# for single entity card like climate or media
|
||||||
self.entity = None
|
self.entity = None
|
||||||
if card_input_config.get("entity") is not None:
|
if card_input_config.get("entity") is not None:
|
||||||
self.entity = Entity(card_input_config.get("entity"))
|
self.entity = Entity(card_input_config)
|
||||||
# for pages like grid or entities
|
# for pages like grid or entities
|
||||||
self.entities = []
|
self.entities = []
|
||||||
for e in card_input_config.get("entities", []):
|
for e in card_input_config.get("entities", []):
|
||||||
self.entities.append(Entity(e))
|
self.entities.append(Entity(e))
|
||||||
|
self.id = f"{self.cardType}_{self.key}".replace(".","_").replace("~","_").replace(" ","_")
|
||||||
|
LOGGER.info(f"Created Card {self.cardType} with pos {pos} and id {self.id}")
|
||||||
|
|
||||||
|
def get_entity_list(self):
|
||||||
|
entityIds = []
|
||||||
|
if self.entity is not None:
|
||||||
|
entityIds.append(self.entity.entityId)
|
||||||
|
else:
|
||||||
|
for e in self.entities:
|
||||||
|
entityIds.append(e.entityId)
|
||||||
|
return entityIds
|
||||||
|
|
||||||
class LuiBackendConfig(object):
|
class LuiBackendConfig(object):
|
||||||
|
|
||||||
@@ -30,22 +44,15 @@ class LuiBackendConfig(object):
|
|||||||
'panelSendTopic': "cmnd/tasmota_your_mqtt_topic/CustomSend",
|
'panelSendTopic': "cmnd/tasmota_your_mqtt_topic/CustomSend",
|
||||||
'updateMode': "auto-notify",
|
'updateMode': "auto-notify",
|
||||||
'model': "eu",
|
'model': "eu",
|
||||||
'timeoutScreensaver': 20,
|
'sleepTimeout': 20,
|
||||||
'brightnessScreensaver': 20,
|
'sleepBrightness': 20,
|
||||||
'brightnessScreensaverTracking': None,
|
'sleepTracking': None,
|
||||||
'locale': "en_US",
|
'locale': "en_US",
|
||||||
'timeFormat': "%H:%M",
|
'timeFormat': "%H:%M",
|
||||||
'dateFormatBabel': "full",
|
'dateFormatBabel': "full",
|
||||||
'dateFormat': "%A, %d. %B %Y",
|
'dateFormat': "%A, %d. %B %Y",
|
||||||
'weather': 'weather.example',
|
|
||||||
'weatherUnit': 'celsius',
|
|
||||||
'weatherOverrideForecast1': None,
|
|
||||||
'weatherOverrideForecast2': None,
|
|
||||||
'weatherOverrideForecast3': None,
|
|
||||||
'weatherOverrideForecast4': None,
|
|
||||||
'doubleTapToUnlock': False,
|
|
||||||
'cards': [{
|
'cards': [{
|
||||||
'type': 'entities',
|
'type': 'cardEntities',
|
||||||
'entities': [{
|
'entities': [{
|
||||||
'entity': 'switch.test_item',
|
'entity': 'switch.test_item',
|
||||||
'name': 'Test Item'
|
'name': 'Test Item'
|
||||||
@@ -54,7 +61,7 @@ class LuiBackendConfig(object):
|
|||||||
}],
|
}],
|
||||||
'title': 'Example Entities Page'
|
'title': 'Example Entities Page'
|
||||||
}, {
|
}, {
|
||||||
'type': 'grid',
|
'type': 'cardGrid',
|
||||||
'entities': [{
|
'entities': [{
|
||||||
'entity': 'switch.test_item'
|
'entity': 'switch.test_item'
|
||||||
}, {
|
}, {
|
||||||
@@ -66,9 +73,19 @@ class LuiBackendConfig(object):
|
|||||||
'title': 'Example Grid Page'
|
'title': 'Example Grid Page'
|
||||||
}, {
|
}, {
|
||||||
'type': 'climate',
|
'type': 'climate',
|
||||||
'entity': 'climate.test_item'
|
'entity': 'climate.test_item',
|
||||||
'title': 'Example Climate Page'
|
}],
|
||||||
}]
|
'screensaver': {
|
||||||
|
'type': 'screensaver',
|
||||||
|
'weather': 'weather.example',
|
||||||
|
'weatherUnit': 'celsius',
|
||||||
|
'weatherOverrideForecast1': None,
|
||||||
|
'weatherOverrideForecast2': None,
|
||||||
|
'weatherOverrideForecast3': None,
|
||||||
|
'weatherOverrideForecast4': None,
|
||||||
|
'doubleTapToUnlock': False
|
||||||
|
},
|
||||||
|
'hiddenCards': []
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, ha_api, config_in):
|
def __init__(self, ha_api, config_in):
|
||||||
@@ -76,7 +93,7 @@ class LuiBackendConfig(object):
|
|||||||
HA_API = ha_api
|
HA_API = ha_api
|
||||||
self._config = {}
|
self._config = {}
|
||||||
self._config_cards = []
|
self._config_cards = []
|
||||||
self._current_card = None
|
self._config_screensaver = None
|
||||||
|
|
||||||
self.load(config_in)
|
self.load(config_in)
|
||||||
|
|
||||||
@@ -85,16 +102,51 @@ class LuiBackendConfig(object):
|
|||||||
if k in self._DEFAULT_CONFIG:
|
if k in self._DEFAULT_CONFIG:
|
||||||
self._config[k] = v
|
self._config[k] = v
|
||||||
LOGGER.info(f"Loaded config: {self._config}")
|
LOGGER.info(f"Loaded config: {self._config}")
|
||||||
|
|
||||||
|
# parse cards displayed on panel
|
||||||
|
pos = 0
|
||||||
for card in self.get("cards"):
|
for card in self.get("cards"):
|
||||||
self._config_cards.append(Card(card))
|
self._config_cards.append(Card(card, pos))
|
||||||
# set current card to first card
|
pos = pos + 1
|
||||||
self._current_card = self._config_cards[0]
|
# parse screensaver
|
||||||
|
screensaver = Card(self.get("screensaver"))
|
||||||
|
|
||||||
|
# parsed hidden pages that can be accessed through navigate
|
||||||
|
for card in self.get("hiddenCards"):
|
||||||
|
self._config_hidden_cards.append(Card(card))
|
||||||
|
|
||||||
def get(self, name):
|
def get(self, name):
|
||||||
value = self._config.get(name)
|
path = name.split(".")
|
||||||
if value is None:
|
value = self._config
|
||||||
value = self._DEFAULT_CONFIG.get(name)
|
for p in path:
|
||||||
|
if value is not None:
|
||||||
|
value = value.get(p, None)
|
||||||
|
if value is not None:
|
||||||
|
return value
|
||||||
|
# try to get a value from default config
|
||||||
|
value = self._DEFAULT_CONFIG
|
||||||
|
for p in path:
|
||||||
|
if value is not None:
|
||||||
|
value = value.get(p, None)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def get_all_entity_names(self):
|
||||||
|
entities = []
|
||||||
|
for card in self._config_cards:
|
||||||
|
entities.extend(card.get_entity_list())
|
||||||
|
return entities
|
||||||
|
|
||||||
|
def getCard(self, pos):
|
||||||
|
card = self._config_cards[pos%len(self._config_cards)]
|
||||||
|
return card
|
||||||
|
|
||||||
|
def searchCard(self, id):
|
||||||
|
id = id.replace("navigate.", "")
|
||||||
|
for card in self._config_cards:
|
||||||
|
if card.id == id:
|
||||||
|
return card
|
||||||
|
if self._config_screensaver.id == id:
|
||||||
|
return screensaver
|
||||||
|
for card in self._config_hidden_cards:
|
||||||
|
if card.id == id:
|
||||||
|
return card
|
||||||
@@ -13,8 +13,8 @@ class LuiController(object):
|
|||||||
self._config = config
|
self._config = config
|
||||||
self._send_mqtt_msg = send_mqtt_msg
|
self._send_mqtt_msg = send_mqtt_msg
|
||||||
|
|
||||||
# first child of root page (default, after startup)
|
# first card (default, after startup)
|
||||||
self._current_page = self._config._page_config.childs[0]
|
self._current_card = self._config.getCard(0)
|
||||||
|
|
||||||
self._pages_gen = LuiPagesGen(ha_api, config, send_mqtt_msg)
|
self._pages_gen = LuiPagesGen(ha_api, config, send_mqtt_msg)
|
||||||
|
|
||||||
@@ -42,7 +42,6 @@ class LuiController(object):
|
|||||||
|
|
||||||
# calculate current brightness
|
# calculate current brightness
|
||||||
self.current_screensaver_brightness = self.calc_current_screensaver_brightness()
|
self.current_screensaver_brightness = self.calc_current_screensaver_brightness()
|
||||||
|
|
||||||
# call update_screensaver_brightness on changes of entity configured in brightnessScreensaverTracking
|
# call update_screensaver_brightness on changes of entity configured in brightnessScreensaverTracking
|
||||||
bst = self._config.get("brightnessScreensaverTracking")
|
bst = self._config.get("brightnessScreensaverTracking")
|
||||||
if bst is not None and self._ha_api.entity_exists(bst):
|
if bst is not None and self._ha_api.entity_exists(bst):
|
||||||
@@ -103,7 +102,7 @@ class LuiController(object):
|
|||||||
return current_screensaver_brightness
|
return current_screensaver_brightness
|
||||||
|
|
||||||
def register_callbacks(self):
|
def register_callbacks(self):
|
||||||
items = self._config.get_root_page().get_all_item_names()
|
items = self._config.get_all_entity_names()
|
||||||
LOGGER.debug(f"Registering callbacks for the following items: {items}")
|
LOGGER.debug(f"Registering callbacks for the following items: {items}")
|
||||||
for item in items:
|
for item in items:
|
||||||
if self._ha_api.entity_exists(item):
|
if self._ha_api.entity_exists(item):
|
||||||
@@ -111,12 +110,12 @@ class LuiController(object):
|
|||||||
|
|
||||||
def state_change_callback(self, entity, attribute, old, new, kwargs):
|
def state_change_callback(self, entity, attribute, old, new, kwargs):
|
||||||
LOGGER.debug(f"Got callback for: {entity}")
|
LOGGER.debug(f"Got callback for: {entity}")
|
||||||
LOGGER.debug(f"Current page has the following items: {self._current_page.get_items()}")
|
LOGGER.debug(f"Current page has the following items: {self._current_card.get_entity_list()}")
|
||||||
if entity in self._current_page.get_all_item_names(recursive=False):
|
if entity in self._current_card.get_entity_list():
|
||||||
LOGGER.debug(f"Callback Entity is on current page: {entity}")
|
LOGGER.debug(f"Callback Entity is on current page: {entity}")
|
||||||
self._pages_gen.render_page(self._current_page, send_page_type=False)
|
self._pages_gen.render_card(self._current_card, send_page_type=False)
|
||||||
# send detail page update, just in case
|
# send detail page update, just in case
|
||||||
if self._current_page.data.get("type", "unknown") in ["cardGrid", "cardEntities"]:
|
if self._current_card.cardType in ["cardGrid", "cardEntities"]:
|
||||||
if entity.startswith("light"):
|
if entity.startswith("light"):
|
||||||
self._pages_gen.generate_light_detail_page(entity)
|
self._pages_gen.generate_light_detail_page(entity)
|
||||||
if entity.startswith("cover"):
|
if entity.startswith("cover"):
|
||||||
@@ -134,9 +133,9 @@ class LuiController(object):
|
|||||||
# internal buttons
|
# internal buttons
|
||||||
if entity_id == "screensaver" and button_type == "bExit":
|
if entity_id == "screensaver" and button_type == "bExit":
|
||||||
if self._config.get("doubleTapToUnlock") and int(value) >= 2:
|
if self._config.get("doubleTapToUnlock") and int(value) >= 2:
|
||||||
self._pages_gen.render_page(self._current_page)
|
self._pages_gen.render_card(self._current_card)
|
||||||
elif not self._config.get("doubleTapToUnlock"):
|
elif not self._config.get("doubleTapToUnlock"):
|
||||||
self._pages_gen.render_page(self._current_page)
|
self._pages_gen.render_card(self._current_card)
|
||||||
return
|
return
|
||||||
|
|
||||||
if button_type == "sleepReached":
|
if button_type == "sleepReached":
|
||||||
@@ -144,17 +143,19 @@ class LuiController(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if button_type == "bExit":
|
if button_type == "bExit":
|
||||||
self._pages_gen.render_page(self._current_page)
|
self._pages_gen.render_card(self._current_card)
|
||||||
|
|
||||||
if button_type == "bNext":
|
if button_type == "bNext":
|
||||||
self._current_page = self._current_page.next()
|
card = self._config.getCard(self._current_card.pos+1)
|
||||||
self._pages_gen.render_page(self._current_page)
|
self._current_card = card
|
||||||
|
self._pages_gen.render_card(card)
|
||||||
if button_type == "bPrev":
|
if button_type == "bPrev":
|
||||||
self._current_page = self._current_page.prev()
|
card = self._config.getCard(self._current_card.pos-1)
|
||||||
self._pages_gen.render_page(self._current_page)
|
self._current_card = card
|
||||||
|
self._pages_gen.render_card(card)
|
||||||
|
|
||||||
elif entity_id == "updateDisplayNoYes" and value == "no":
|
elif entity_id == "updateDisplayNoYes" and value == "no":
|
||||||
self._pages_gen.render_page(self._current_page)
|
self._pages_gen.render_card(self._current_card)
|
||||||
|
|
||||||
# buttons with actions on HA
|
# buttons with actions on HA
|
||||||
if button_type == "OnOff":
|
if button_type == "OnOff":
|
||||||
@@ -180,8 +181,8 @@ class LuiController(object):
|
|||||||
if button_type == "button":
|
if button_type == "button":
|
||||||
if entity_id.startswith('navigate'):
|
if entity_id.startswith('navigate'):
|
||||||
# internal for navigation to nested pages
|
# internal for navigation to nested pages
|
||||||
self._current_page = self._config.get_root_page().search_page_by_name(entity_id)[0]
|
self._current_card = self._config.searchCard(entity_id)
|
||||||
self._pages_gen.render_page(self._current_page)
|
self._pages_gen.render_card(self._current_card)
|
||||||
elif entity_id.startswith('scene'):
|
elif entity_id.startswith('scene'):
|
||||||
self._ha_api.get_entity(entity_id).call_service("turn_on")
|
self._ha_api.get_entity(entity_id).call_service("turn_on")
|
||||||
elif entity_id.startswith('script'):
|
elif entity_id.startswith('script'):
|
||||||
|
|||||||
@@ -55,19 +55,19 @@ class LuiPagesGen(object):
|
|||||||
def page_type(self, target_page):
|
def page_type(self, target_page):
|
||||||
self._send_mqtt_msg(f"pageType~{target_page}")
|
self._send_mqtt_msg(f"pageType~{target_page}")
|
||||||
|
|
||||||
def generate_screensaver_page(self):
|
def generate_screensaver_page(self, card):
|
||||||
self.page_type("screensaver")
|
self.page_type("screensaver")
|
||||||
self.update_screensaver_weather()
|
self.update_screensaver_weather()
|
||||||
|
|
||||||
def update_screensaver_weather(self):
|
def update_screensaver_weather(self):
|
||||||
global babel_spec
|
global babel_spec
|
||||||
we_name = self._config.get("weather")
|
we_name = self._config.get("screensaver.weather")
|
||||||
unit = self._config.get("weatherUnit")
|
unit = self._config.get("screensaver.weatherUnit")
|
||||||
|
|
||||||
if self._ha_api.entity_exists(we_name):
|
if self._ha_api.entity_exists(we_name):
|
||||||
we = self._ha_api.get_entity(we_name)
|
we = self._ha_api.get_entity(we_name)
|
||||||
else:
|
else:
|
||||||
LOGGER.error("Skipping Weather Update, entity not found")
|
LOGGER.error("Skipping Weather Update, entity {we_name} not found")
|
||||||
return
|
return
|
||||||
|
|
||||||
icon_cur = get_icon_id_ha("weather", state=we.state)
|
icon_cur = get_icon_id_ha("weather", state=we.state)
|
||||||
@@ -75,7 +75,7 @@ class LuiPagesGen(object):
|
|||||||
|
|
||||||
weather_res = ""
|
weather_res = ""
|
||||||
for i in range(1,5):
|
for i in range(1,5):
|
||||||
wOF = self._config.get(f"weatherOverrideForecast{i}")
|
wOF = self._config.get(f"screensaver.weatherOverrideForecast{i}")
|
||||||
if wOF is None:
|
if wOF is None:
|
||||||
up = we.attributes.forecast[i-1]['datetime']
|
up = we.attributes.forecast[i-1]['datetime']
|
||||||
up = datetime.datetime.fromisoformat(up)
|
up = datetime.datetime.fromisoformat(up)
|
||||||
@@ -87,13 +87,9 @@ class LuiPagesGen(object):
|
|||||||
down = convert_temperature(we.attributes.forecast[i-1]['temperature'], unit)
|
down = convert_temperature(we.attributes.forecast[i-1]['temperature'], unit)
|
||||||
else:
|
else:
|
||||||
LOGGER.info(f"Forecast {i} is overriden with {wOF}")
|
LOGGER.info(f"Forecast {i} is overriden with {wOF}")
|
||||||
icon = None
|
icon = wOF.iconOverride
|
||||||
name = None
|
name = wOF.nameOverride
|
||||||
if type(wOF) is dict:
|
entity = self._ha_api.get_entity(wOF.entityId)
|
||||||
icon = next(iter(wOF.items()))[1].get('icon')
|
|
||||||
name = next(iter(wOF.items()))[1].get('name')
|
|
||||||
wOF = next(iter(wOF.items()))[0]
|
|
||||||
entity = self._ha_api.get_entity(wOF)
|
|
||||||
up = name if name is not None else entity.attributes.friendly_name
|
up = name if name is not None else entity.attributes.friendly_name
|
||||||
icon = get_icon_id_ha("sensor", state=entity.state, device_class=entity.attributes.get("device_class", ""), overwrite=icon)
|
icon = get_icon_id_ha("sensor", state=entity.state, device_class=entity.attributes.get("device_class", ""), overwrite=icon)
|
||||||
unit_of_measurement = entity.attributes.get("unit_of_measurement", "")
|
unit_of_measurement = entity.attributes.get("unit_of_measurement", "")
|
||||||
@@ -102,73 +98,69 @@ class LuiPagesGen(object):
|
|||||||
|
|
||||||
self._send_mqtt_msg(f"weatherUpdate~{icon_cur}~{text_cur}{weather_res}")
|
self._send_mqtt_msg(f"weatherUpdate~{icon_cur}~{text_cur}{weather_res}")
|
||||||
|
|
||||||
def generate_entities_item(self, item):
|
def generate_entities_item(self, entity):
|
||||||
icon = None
|
entityId = entity.entityId
|
||||||
name = None
|
icon = entity.iconOverride
|
||||||
if type(item) is dict:
|
name = entity.nameOverride
|
||||||
icon = next(iter(item.items()))[1].get('icon')
|
# type of the item is the string before the "." in the entityId
|
||||||
name = next(iter(item.items()))[1].get('name')
|
entityType = entityId.split(".")[0]
|
||||||
item = next(iter(item.items()))[0]
|
|
||||||
# type of the item is the string before the "." in the item name
|
LOGGER.debug(f"Generating item for {entityId} with type {entityType}",)
|
||||||
item_type = item.split(".")[0]
|
# Internal types
|
||||||
LOGGER.debug(f"Generating item command for {item} with type {item_type}",)
|
if entityType == "delete":
|
||||||
# Internal Entities
|
return f"~{entityType}~~~~~"
|
||||||
if item_type == "delete":
|
if entityType == "navigate":
|
||||||
return f"~{item_type}~~~~~"
|
page_search_res = self._config.searchPage(entityId)
|
||||||
if item_type == "navigate":
|
if page_search_res is not None:
|
||||||
page_search = self._config.get_root_page().search_page_by_name(item)
|
name = page_search_res.title
|
||||||
if len(page_search) > 0:
|
|
||||||
page_data = page_search[0].data
|
|
||||||
if name is None:
|
|
||||||
name = page_data.get("heading")
|
|
||||||
text = get_translation(self._locale,"PRESS")
|
text = get_translation(self._locale,"PRESS")
|
||||||
icon_id = get_icon_id(icon) if icon is not None else get_icon_id(page_data.get("icon", "gesture-tap-button"))
|
icon_id = get_icon_id(icon) if icon is not None else get_icon_id(page_data.get("icon", "gesture-tap-button"))
|
||||||
return f"~button~{item}~{icon_id}~17299~{name}~{text}"
|
return f"~button~{entityId}~{icon_id}~17299~{name}~{text}"
|
||||||
else:
|
else:
|
||||||
return f"~text~{item}~{get_icon_id('alert-circle-outline')}~17299~page not found~"
|
return f"~text~{entityId}~{get_icon_id('alert-circle-outline')}~17299~page not found~"
|
||||||
if not self._ha_api.entity_exists(item):
|
if not self._ha_api.entity_exists(entityId):
|
||||||
return f"~text~{item}~{get_icon_id('alert-circle-outline')}~17299~Not found check~ apps.yaml"
|
return f"~text~{entityId}~{get_icon_id('alert-circle-outline')}~17299~Not found check~ apps.yaml"
|
||||||
|
|
||||||
# HA Entities
|
# HA Entities
|
||||||
entity = self._ha_api.get_entity(item)
|
entity = self._ha_api.get_entity(entityId)
|
||||||
name = name if name is not None else entity.attributes.friendly_name
|
name = name if name is not None else entity.attributes.friendly_name
|
||||||
if item_type == "cover":
|
if entityType == "cover":
|
||||||
icon_id = get_icon_id_ha("cover", state=entity.state, overwrite=icon)
|
icon_id = get_icon_id_ha("cover", state=entity.state, overwrite=icon)
|
||||||
return f"~shutter~{item}~{icon_id}~17299~{name}~"
|
return f"~shutter~{entityId}~{icon_id}~17299~{name}~"
|
||||||
if item_type in "light":
|
if entityType in "light":
|
||||||
switch_val = 1 if entity.state == "on" else 0
|
switch_val = 1 if entity.state == "on" else 0
|
||||||
icon_color = self.get_entity_color(entity)
|
icon_color = self.get_entity_color(entity)
|
||||||
icon_id = get_icon_id_ha("light", overwrite=icon)
|
icon_id = get_icon_id_ha("light", overwrite=icon)
|
||||||
return f"~{item_type}~{item}~{icon_id}~{icon_color}~{name}~{switch_val}"
|
return f"~{entityType}~{entityId}~{icon_id}~{icon_color}~{name}~{switch_val}"
|
||||||
if item_type in ["switch", "input_boolean"]:
|
if entityType in ["switch", "input_boolean"]:
|
||||||
switch_val = 1 if entity.state == "on" else 0
|
switch_val = 1 if entity.state == "on" else 0
|
||||||
icon_color = self.get_entity_color(entity)
|
icon_color = self.get_entity_color(entity)
|
||||||
icon_id = get_icon_id_ha(item_type, state=entity.state, overwrite=icon)
|
icon_id = get_icon_id_ha(entityType, state=entity.state, overwrite=icon)
|
||||||
return f"~switch~{item}~{icon_id}~{icon_color}~{name}~{switch_val}"
|
return f"~switch~{entityId}~{icon_id}~{icon_color}~{name}~{switch_val}"
|
||||||
if item_type in ["sensor", "binary_sensor"]:
|
if entityType in ["sensor", "binary_sensor"]:
|
||||||
device_class = entity.attributes.get("device_class", "")
|
device_class = entity.attributes.get("device_class", "")
|
||||||
icon_id = get_icon_id_ha("sensor", state=entity.state, device_class=device_class, overwrite=icon)
|
icon_id = get_icon_id_ha("sensor", state=entity.state, device_class=device_class, overwrite=icon)
|
||||||
unit_of_measurement = entity.attributes.get("unit_of_measurement", "")
|
unit_of_measurement = entity.attributes.get("unit_of_measurement", "")
|
||||||
value = entity.state + " " + unit_of_measurement
|
value = entity.state + " " + unit_of_measurement
|
||||||
icon_color = self.get_entity_color(entity)
|
icon_color = self.get_entity_color(entity)
|
||||||
return f"~text~{item}~{icon_id}~{icon_color}~{name}~{value}"
|
return f"~text~{entityId}~{icon_id}~{icon_color}~{name}~{value}"
|
||||||
if item_type in ["button", "input_button"]:
|
if entityType in ["button", "input_button"]:
|
||||||
icon_id = get_icon_id_ha("button", overwrite=icon)
|
icon_id = get_icon_id_ha("button", overwrite=icon)
|
||||||
text = get_translation(self._locale,"PRESS")
|
text = get_translation(self._locale,"PRESS")
|
||||||
return f"~button~{item}~{icon_id}~17299~{name}~{text}"
|
return f"~button~{entityId}~{icon_id}~17299~{name}~{text}"
|
||||||
if item_type == "scene":
|
if entityType == "scene":
|
||||||
icon_id = get_icon_id_ha("scene", overwrite=icon)
|
icon_id = get_icon_id_ha("scene", overwrite=icon)
|
||||||
text = get_translation(self._locale,"ACTIVATE")
|
text = get_translation(self._locale,"ACTIVATE")
|
||||||
return f"~button~{item}~{icon_id}~17299~{name}~{text}"
|
return f"~button~{entityId}~{icon_id}~17299~{name}~{text}"
|
||||||
if item_type == "script":
|
if entityType == "script":
|
||||||
icon_id = get_icon_id_ha("script", overwrite=icon)
|
icon_id = get_icon_id_ha("script", overwrite=icon)
|
||||||
text = get_translation(self._locale,"run")
|
text = get_translation(self._locale,"run")
|
||||||
return f"~button~{item}~{icon_id}~17299~{name}~{text}"
|
return f"~button~{entityId}~{icon_id}~17299~{name}~{text}"
|
||||||
if item_type == "number":
|
if entityType == "number":
|
||||||
icon_id = get_icon_id_ha("number", overwrite=icon)
|
icon_id = get_icon_id_ha("number", overwrite=icon)
|
||||||
min_v = entity.attributes.get("min", 0)
|
min_v = entity.attributes.get("min", 0)
|
||||||
max_v = entity.attributes.get("max", 100)
|
max_v = entity.attributes.get("max", 100)
|
||||||
return f"~number~{item}~{icon_id}~17299~{name}~{entity.state}|{min_v}|{max_v}"
|
return f"~number~{entityId}~{icon_id}~17299~{name}~{entity.state}|{min_v}|{max_v}"
|
||||||
|
|
||||||
def generate_entities_page(self, heading, items):
|
def generate_entities_page(self, heading, items):
|
||||||
navigation = ""
|
navigation = ""
|
||||||
@@ -180,7 +172,8 @@ class LuiPagesGen(object):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def generate_thermo_page(self, item):
|
def generate_thermo_page(self, entity):
|
||||||
|
item = entity.entityId
|
||||||
if not self._ha_api.entity_exists(item):
|
if not self._ha_api.entity_exists(item):
|
||||||
command = f"entityUpd~{item}~Not found~220~220~Not found~150~300~5"
|
command = f"entityUpd~{item}~Not found~220~220~Not found~150~300~5"
|
||||||
else:
|
else:
|
||||||
@@ -237,7 +230,8 @@ class LuiPagesGen(object):
|
|||||||
command = f"entityUpd~{heading}~~{item}~{current_temp}~{dest_temp}~{status}~{min_temp}~{max_temp}~{step_temp}{icon_res}"
|
command = f"entityUpd~{heading}~~{item}~{current_temp}~{dest_temp}~{status}~{min_temp}~{max_temp}~{step_temp}{icon_res}"
|
||||||
self._send_mqtt_msg(command)
|
self._send_mqtt_msg(command)
|
||||||
|
|
||||||
def generate_media_page(self, item):
|
def generate_media_page(self, entity):
|
||||||
|
item = entity.entityId
|
||||||
if not self._ha_api.entity_exists(item):
|
if not self._ha_api.entity_exists(item):
|
||||||
command = f"entityUpd~|{item}|Not found|{get_icon_id('alert-circle-outline')}|Please check your|apps.yaml in AppDaemon|50|{get_icon_id('alert-circle-outline')}"
|
command = f"entityUpd~|{item}|Not found|{get_icon_id('alert-circle-outline')}|Please check your|apps.yaml in AppDaemon|50|{get_icon_id('alert-circle-outline')}"
|
||||||
else:
|
else:
|
||||||
@@ -270,7 +264,8 @@ class LuiPagesGen(object):
|
|||||||
command = f"entityUpd~|{heading}||{item}|{icon}|{title}|{author}|{volume}|{iconplaypause}|{source}|{speakerlist[:200]}|{onoffbutton}"
|
command = f"entityUpd~|{heading}||{item}|{icon}|{title}|{author}|{volume}|{iconplaypause}|{source}|{speakerlist[:200]}|{onoffbutton}"
|
||||||
self._send_mqtt_msg(command)
|
self._send_mqtt_msg(command)
|
||||||
|
|
||||||
def generate_alarm_page(self, item):
|
def generate_alarm_page(self, entity):
|
||||||
|
item = entity.entityId
|
||||||
if not self._ha_api.entity_exists(item):
|
if not self._ha_api.entity_exists(item):
|
||||||
command = f"entityUpd~{item}~Not found~Not found~Check your~Check your~apps.~apps.~yaml~yaml~0~~0"
|
command = f"entityUpd~{item}~Not found~Not found~Check your~Check your~apps.~apps.~yaml~yaml~0~~0"
|
||||||
else:
|
else:
|
||||||
@@ -330,23 +325,23 @@ class LuiPagesGen(object):
|
|||||||
command = f"entityUpd~{item}~{navigation}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}"
|
command = f"entityUpd~{item}~{navigation}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}"
|
||||||
self._send_mqtt_msg(command)
|
self._send_mqtt_msg(command)
|
||||||
|
|
||||||
def render_page(self, page, send_page_type=True):
|
def render_card(self, card, send_page_type=True):
|
||||||
config = page.data
|
LOGGER.info(f"Started rendering of page {card.pos} with type {card.cardType}")
|
||||||
page_type = config["type"]
|
|
||||||
LOGGER.info(f"Started rendering of page {page.pos} with type {page_type}")
|
|
||||||
# Switch to page
|
# Switch to page
|
||||||
if send_page_type:
|
if send_page_type:
|
||||||
self.page_type(page_type)
|
self.page_type(card.cardType)
|
||||||
if page_type in ["cardEntities", "cardGrid"]:
|
if card.cardType in ["cardEntities", "cardGrid"]:
|
||||||
heading = config.get("heading", "unknown")
|
self.generate_entities_page(card.title, card.entities)
|
||||||
self.generate_entities_page(heading, page.get_items())
|
|
||||||
return
|
return
|
||||||
if page_type == "cardThermo":
|
if card.cardType == "cardThermo":
|
||||||
self.generate_thermo_page(page.data.get("item"))
|
self.generate_thermo_page(card.entity)
|
||||||
if page_type == "cardMedia":
|
if card.cardType == "cardMedia":
|
||||||
self.generate_media_page(page.data.get("item"))
|
self.generate_media_page(card.entity)
|
||||||
if page_type == "cardAlarm":
|
if card.cardType == "cardAlarm":
|
||||||
self.generate_alarm_page(page.data.get("item"))
|
self.generate_alarm_page(card.entity)
|
||||||
|
|
||||||
|
if card.cardType == "screensaver":
|
||||||
|
self.generate_screensaver_page(card)
|
||||||
|
|
||||||
|
|
||||||
def generate_light_detail_page(self, entity):
|
def generate_light_detail_page(self, entity):
|
||||||
@@ -380,7 +375,7 @@ class LuiPagesGen(object):
|
|||||||
def generate_shutter_detail_page(self, entity):
|
def generate_shutter_detail_page(self, entity):
|
||||||
entity = self._ha_api.get_entity(entity)
|
entity = self._ha_api.get_entity(entity)
|
||||||
pos = 100-int(entity.attributes.get("current_position", 50))
|
pos = 100-int(entity.attributes.get("current_position", 50))
|
||||||
self._send_mqtt_msg(f"entityUpdateDetail,{pos}")
|
self._send_mqtt_msg(f"entityUpdateDetail~{pos}")
|
||||||
|
|
||||||
def send_message_page(self, id, heading, msg, b1, b2):
|
def send_message_page(self, id, heading, msg, b1, b2):
|
||||||
self._send_mqtt_msg(f"pageType~popupNotify")
|
self._send_mqtt_msg(f"pageType~popupNotify")
|
||||||
|
|||||||
@@ -51,42 +51,40 @@ class NsPanelLovelaceUIManager(hass.Hass):
|
|||||||
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, 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