diff --git a/appdaemon/apps.yaml b/appdaemon/apps.yaml index 5f6b33ae..cd7d5544 100644 --- a/appdaemon/apps.yaml +++ b/appdaemon/apps.yaml @@ -3,28 +3,58 @@ nspanel: module: nspanel-lovelace-ui2 class: NsPanelLovelaceUIManager config: - panelRecvTopic: "tele/tasmota_nspdebugtest/RESULT" - panelSendTopic: "cmnd/tasmota_nspdebugtest/CustomSend" + panelRecvTopic: "tele/tasmota_your_mqtt_topic/RESULT" + panelSendTopic: "cmnd/tasmota_your_mqtt_topic/CustomSend" + updateMode: "auto-notify" + timeoutScreensaver: 20 + #brightnessScreensaver: 10 + brightnessScreensaver: + - time: "7:00:00" + value: 10 + - time: "23:00:00" + value: 0 + locale: "de_DE" # only used if babel python package is installed + dateFormatBabel: "full" # only used if babel python package is installed + # formatting options on https://babel.pocoo.org/en/latest/dates.html?highlight=name%20of%20day#date-fields + timeFormat: "%H:%M" + dateFormat: "%A, %d. %B %Y" # ignored if babel python package is installed + buttonText: KLICKEN + sceneText: ACTIVIEREN + weatherEntity: weather.example pages: - - type: screensaver - weather: weather.k3ll3r + - type: cardEntities + heading: Example Page 1 items: - - type: cardEntities - heading: Test Entities 1 - items: - - switch.test_item - - type: cardEntities - heading: Test Entities 1 - items: - - switch.test_item - - switch.deckenbeleuchtung_hinten - - switch.test_item - - switch.test_item - - switch.deckenbeleuchtung_hinten - - switch.test_item - - type: cardGrid - heading: Test Grid 1 - items: - - switch.test_item - - switch.test_item - - switch.test_item + - cover.example_cover + - switch.example_switch + - input_boolean.example_input_boolean + - 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 + 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 + heading: Exampe Media + item: media_player.spotify_user \ No newline at end of file diff --git a/apps/nspanel-lovelace-ui/luibackend/config.py b/apps/nspanel-lovelace-ui/luibackend/config.py index d2aa16b2..f2a8258d 100644 --- a/apps/nspanel-lovelace-ui/luibackend/config.py +++ b/apps/nspanel-lovelace-ui/luibackend/config.py @@ -1,8 +1,5 @@ import logging -from luibackend.exceptions import LuiBackendConfigIncomplete -from luibackend.exceptions import LuiBackendConfigError - LOGGER = logging.getLogger(__name__) diff --git a/apps/nspanel-lovelace-ui/luibackend/controller.py b/apps/nspanel-lovelace-ui/luibackend/controller.py index 97a550ec..146e6a65 100644 --- a/apps/nspanel-lovelace-ui/luibackend/controller.py +++ b/apps/nspanel-lovelace-ui/luibackend/controller.py @@ -29,6 +29,28 @@ class LuiController(object): # register callbacks self.register_callbacks() + self.current_screensaver_brightness = 20 + # calc screensaver brightness + # set brightness of screensaver + if type(self._config.get("brightnessScreensaver")) == int: + self.current_screensaver_brightness = self._config.get("brightnessScreensaver") + elif type(self._config.get("brightnessScreensaver")) == list: + sorted_timesets = sorted(self._config.get("brightnessScreensaver"), key=lambda d: self._ha_api.parse_time(d['time'])) + found_current_dim_value = False + for index, timeset in enumerate(sorted_timesets): + self._ha_api.run_daily(self.update_screensaver_brightness, timeset["time"], value=timeset["value"]) + LOGGER.info("Current time %s", self._ha_api.get_now().time()) + if self._ha_api.parse_time(timeset["time"]) > self._ha_api.get_now().time() and not found_current_dim_value: + # first time after current time, set dim value + self.current_screensaver_brightness = sorted_timesets[index-1]["value"] + LOGGER.info("Setting dim value to %s", sorted_timesets[index-1]) + found_current_dim_value = True + # still no dim value + if not found_current_dim_value: + self.current_screensaver_brightness = sorted_timesets[-1]["value"] + # send screensaver brightness in case config has changed + self.update_screensaver_brightness(kwargs={"value": self.current_screensaver_brightness}) + def startup(self): LOGGER.info(f"Startup Event") # send time and date on startup @@ -39,6 +61,10 @@ class LuiController(object): self._pages_gen.page_type("screensaver") self.weather_update("") + def update_screensaver_brightness(self, kwargs): + self.current_screensaver_brightness = kwargs['value'] + self._send_mqtt_msg(f"dimmode,{self.current_screensaver_brightness}") + def weather_update(self, kwargs): we_name = self._config.get("weather") unit = "°C" @@ -48,7 +74,8 @@ class LuiController(object): items = self._config.get_root_page().get_all_items_recursive() LOGGER.info(f"Registering callbacks for the following items: {items}") for item in items: - self._ha_api.listen_state(self.state_change_callback, entity_id=item, attribute="all") + if self._ha_api.entity_exists(item): + self._ha_api.listen_state(self.state_change_callback, entity_id=item, attribute="all") def state_change_callback(self, entity, attribute, old, new, kwargs): LOGGER.info(f"Got callback for: {entity}") @@ -71,18 +98,21 @@ class LuiController(object): def button_press(self, entity_id, button_type, value): LOGGER.debug(f"Button Press Event; entity_id: {entity_id}; button_type: {button_type}; value: {value} ") # internal buttons - if(entity_id == "screensaver" and button_type == "enter"): + if entity_id == "screensaver" and button_type == "enter": self._pages_gen.render_page(self._current_page) - if(button_type == "bExit"): + if button_type == "bExit": self._pages_gen.render_page(self._current_page) - if(button_type == "bNext"): + if button_type == "bNext": self._current_page = self._current_page.next() self._pages_gen.render_page(self._current_page) - if(button_type == "bPrev"): + if button_type == "bPrev": self._current_page = self._current_page.prev() self._pages_gen.render_page(self._current_page) + elif entity_id == "updateDisplayNoYes" and value == "no": + self._pages_gen.render_page(self._current_page) + # buttons with actions on HA if button_type == "OnOff": if value == "1": diff --git a/apps/nspanel-lovelace-ui/luibackend/localization.py b/apps/nspanel-lovelace-ui/luibackend/localization.py new file mode 100644 index 00000000..b59d0d1e --- /dev/null +++ b/apps/nspanel-lovelace-ui/luibackend/localization.py @@ -0,0 +1,12 @@ +translations = { + 'de_DE': { + 'ACTIVATE': "AKTIVIEREN", + 'PRESS': "DRÜCKEN", + } +} + +def get_translation(locale, input): + if locale in translations: + return translations.get(locale).get(input, input) + else: + return input \ No newline at end of file diff --git a/apps/nspanel-lovelace-ui/luibackend/mqttListener.py b/apps/nspanel-lovelace-ui/luibackend/mqttListener.py index 24bf8d87..1d3d1c5a 100644 --- a/apps/nspanel-lovelace-ui/luibackend/mqttListener.py +++ b/apps/nspanel-lovelace-ui/luibackend/mqttListener.py @@ -43,6 +43,10 @@ class LuiMqttListener(object): entity_id = msg[2] btype = msg[3] value = msg[4] if len(msg) > 4 else None + + if entity_id == "updateDisplayNoYes" and value == "yes": + self._updater.update_panel_driver() + self._controller.button_press(entity_id, btype, value) if msg[1] == "pageOpenDetail": self._controller.detail_open(msg[2], msg[3]) diff --git a/apps/nspanel-lovelace-ui/luibackend/pages.py b/apps/nspanel-lovelace-ui/luibackend/pages.py index 0184f365..3fce0ec7 100644 --- a/apps/nspanel-lovelace-ui/luibackend/pages.py +++ b/apps/nspanel-lovelace-ui/luibackend/pages.py @@ -4,6 +4,7 @@ import datetime from icon_mapping import get_icon_id from icons import get_icon_id_ha from helper import scale, pos_to_color, rgb_dec565, rgb_brightness +from localization import get_translation # check Babel import importlib @@ -18,6 +19,7 @@ class LuiPagesGen(object): def __init__(self, ha_api, config, send_mqtt_msg): self._ha_api = ha_api self._config = config + self._locale = config.get("locale") self._send_mqtt_msg = send_mqtt_msg def getEntityColor(self, entity): @@ -44,8 +46,7 @@ class LuiPagesGen(object): global babel_spec if babel_spec is not None: dateformat = self._config.get("dateFormatBabel") - locale = self._config.get("locale") - date = babel.dates.format_date(datetime.datetime.now(), dateformat, locale=locale) + date = babel.dates.format_date(datetime.datetime.now(), dateformat, locale=self._locale) else: dateformat = self._config.get("dateFormat") date = datetime.datetime.now().strftime(dateformat) @@ -81,8 +82,8 @@ class LuiPagesGen(object): global babel_spec if babel_spec is not None: - up1 = babel.dates.format_date(up1, "E", locale=self.config["locale"]) - up2 = babel.dates.format_date(up2, "E", locale=self.config["locale"]) + up1 = babel.dates.format_date(up1, "E", locale=self._locale) + up2 = babel.dates.format_date(up2, "E", locale=self._locale) else: up1 = up1.strftime("%a") up2 = up2.strftime("%a") @@ -103,7 +104,8 @@ class LuiPagesGen(object): return f",{item_type},,,,," if item_type == "navigate": icon_id = get_icon_id_ha("button", overwrite=icon) - return f",button,{item},0,17299,{item},PRESS" + text = get_translation(self._locale,"PRESS") + return f",button,{item},0,17299,{item},{text}" if not self._ha_api.entity_exists(item): return f",text,{item},{get_icon_id('alert-circle-outline')},17299,Not found check, apps.yaml" # HA Entities @@ -134,7 +136,8 @@ class LuiPagesGen(object): return f",button,{item},{icon_id},17299,{name},PRESS" if item_type == "scene": icon_id = get_icon_id_ha("scene", overwrite=icon) - return f",button,{item},{icon_id},17299,{name},ACTIVATE" + text = get_translation(self._locale,"PRESS") + return f",button,{item},{icon_id},17299,{name},{text}" def generate_entities_page(self, heading, items): diff --git a/apps/nspanel-lovelace-ui/luibackend/updater.py b/apps/nspanel-lovelace-ui/luibackend/updater.py index 93d16652..aa976850 100644 --- a/apps/nspanel-lovelace-ui/luibackend/updater.py +++ b/apps/nspanel-lovelace-ui/luibackend/updater.py @@ -3,14 +3,15 @@ import logging LOGGER = logging.getLogger(__name__) class Updater: - def __init__(self, controller, mode, desired_display_firmware_version, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url): + def __init__(self, send_mqtt_msg, topic_send, mode, desired_display_firmware_version, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url): self.desired_display_firmware_version = desired_display_firmware_version self.desired_display_firmware_url = desired_display_firmware_url self.desired_tasmota_driver_version = desired_tasmota_driver_version self.desired_tasmota_driver_url = desired_tasmota_driver_url self.mode = mode - self.controller = controller + self._send_mqtt_msg = send_mqtt_msg + self.topic_send = topic_send self.current_tasmota_driver_version = None self.current_display_firmware_version = None @@ -29,6 +30,10 @@ class Updater: return True return False + def send_message_page(self, id, heading, msg, b1, b2): + self._send_mqtt_msg(f"pageType,popupNotify") + self._send_mqtt_msg(f"entityUpdateDetail,|{id}|{heading}|65535|{b1}|65535|{b2}|65535|{msg}|65535|0") + def check_updates(self): # return's true if a notification was send to the panel # run pre req check @@ -44,7 +49,7 @@ class Updater: # send notification about the update if self.mode == "auto-notify": update_msg = "There's an update avalible for the tasmota berry driver, do you want to start the update now? If you encounter issues after the update or this message appears frequently, please checkthe manual and repeat the installation steps for the tasmota berry driver. " - self.controller._pages_gen.send_message_page("updateBerryNoYes", "Driver Update available!", update_msg, "Dismiss", "Yes") + self.send_message_page("updateBerryNoYes", "Driver Update available!", update_msg, "Dismiss", "Yes") return True return False # check if display firmware needs an update @@ -57,7 +62,7 @@ class Updater: # send notification about the update if self.mode == "auto-notify": update_msg = "There's a firmware update avalible for the nextion sceen inside of nspanel, do you want to start the update now? If the update fails check the installation manual and flash again over the tasmota console. Be pationed the update will take a while." - self.controller._pages_gen.send_message_page("updateDisplayNoYes", "Display Update available!", update_msg, "Dismiss", "Yes") + self.send_message_page("updateDisplayNoYes", "Display Update available!", update_msg, "Dismiss", "Yes") return True return False else: @@ -65,8 +70,8 @@ class Updater: return False def update_berry_driver(self): - topic = self.controller._config["panelSendTopic"].replace("CustomSend", "UpdateDriverVersion") - self.controller._send_mqtt_msg(topic, self.desired_tasmota_driver_url) + topic = self.topic_send.replace("CustomSend", "UpdateDriverVersion") + self._send_mqtt_msg(self.desired_tasmota_driver_url, topic=topic) def update_panel_driver(self): - topic = self.controller._config["panelSendTopic"].replace("CustomSend", "FlashNextion") - self.controller._send_mqtt_msg(topic, self.desired_display_firmware_url) + topic = self.topic_send.replace("CustomSend", "FlashNextion") + self._send_mqtt_msg(self.desired_display_firmware_url, topic=topic) diff --git a/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py b/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py index a82bb5c8..d15d294a 100644 --- a/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py +++ b/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py @@ -56,9 +56,11 @@ class NsPanelLovelaceUIManager(hass.Hass): cfg = self._cfg = LuiBackendConfig(self.args["config"]) topic_send = cfg.get("panelSendTopic") - def send_mqtt_msg(msg): + def send_mqtt_msg(msg, topic=None): + if topic is None: + topic = topic_send LOGGER.info(f"Sending MQTT Message: {msg}") - mqtt_api.mqtt_publish(topic_send, msg) + mqtt_api.mqtt_publish(topic, msg) # Request Tasmota Driver Version mqtt_api.mqtt_publish(topic_send.replace("CustomSend", "GetDriverVersion"), "x") @@ -71,7 +73,8 @@ class NsPanelLovelaceUIManager(hass.Hass): desired_tasmota_driver_url = "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be" mode = cfg.get("updateMode") - updater = Updater(controller, mode, desired_display_firmware_version, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url) + topic_send = cfg.get("panelSendTopic") + updater = Updater(send_mqtt_msg, topic_send, mode, desired_display_firmware_version, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url) topic_recv = cfg.get("panelRecvTopic") mqtt_listener = LuiMqttListener(mqtt_api, topic_recv, controller, updater)