From d6e5753dd2a879ddcf9324dafd92d1bab1fa3ed4 Mon Sep 17 00:00:00 2001 From: Attila Farago Date: Sat, 4 Nov 2023 22:17:22 +0100 Subject: [PATCH] [Feature Request] Consider using HomeAssistant API instead of MQTT (#1007) * ha api improvements - device specific app filtering * refactored request_berry_driver_version messaging * improved ha api usage * improve ha event naming --- apps/nspanel-lovelace-ui/luibackend/mqtt.py | 58 +++++++++++++++---- .../nspanel-lovelace-ui/luibackend/updater.py | 19 +++--- .../nspanel-lovelace-ui.py | 20 ++++--- 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/apps/nspanel-lovelace-ui/luibackend/mqtt.py b/apps/nspanel-lovelace-ui/luibackend/mqtt.py index c1c9eed6..11946128 100644 --- a/apps/nspanel-lovelace-ui/luibackend/mqtt.py +++ b/apps/nspanel-lovelace-ui/luibackend/mqtt.py @@ -3,19 +3,37 @@ import apis class LuiMqttListener(object): - def __init__(self, topic, controller, updater): + def __init__(self, use_api, topic, api_panel_name, api_device_id, controller, updater): self._controller = controller self._updater = updater + self._api_device_id = api_device_id # Setup, mqtt subscription and callback - apis.mqtt_api.mqtt_subscribe(topic=topic) - apis.mqtt_api.listen_event(self.mqtt_event_callback, "MQTT_MESSAGE", topic=topic, namespace='mqtt') + if use_api: + apis.ha_api.listen_event(self.api_event_callback, "esphome.nspanel.data") + else: + apis.mqtt_api.mqtt_subscribe(topic=topic) + apis.mqtt_api.listen_event(self.mqtt_event_callback, "MQTT_MESSAGE", topic=topic, namespace='mqtt') + def api_event_callback(self, event_name, data, kwargs): + if not "device_id" in data: + return + if not data["device_id"] == self._api_device_id: + return + + apis.ha_api.log(f'API callback for: {data}') + + self.customrecv_event_callback(event_name, data, kwargs) def mqtt_event_callback(self, event_name, data, kwargs): - apis.mqtt_api.log(f'MQTT callback for: {data}') + apis.ha_api.log(f'MQTT callback for: {data}') + # Parse Json Message from Tasmota and strip out message from nextion display data = json.loads(data["payload"]) + + self.customrecv_event_callback(event_name, data, kwargs) + + def customrecv_event_callback(self, event_name, data, kwargs): if("nlui_driver_version" in data): msg = data["nlui_driver_version"] self._updater.set_tasmota_driver_version(int(msg)) @@ -23,7 +41,7 @@ class LuiMqttListener(object): if("CustomRecv" not in data): return msg = data["CustomRecv"] - apis.mqtt_api.log(f"Received Message from Screen: {msg}") + apis.ha_api.log(f"Received Message from Screen: {msg}") # Split message into parts seperated by "," msg = msg.split(",") # run action based on received command @@ -59,17 +77,35 @@ class LuiMqttListener(object): self._controller.detail_open(msg[2], msg[3]) class LuiMqttSender(object): - def __init__(self, api, topic_send): + def __init__(self, api, use_api, topic_send, api_panel_name): self._ha_api = api + self._use_api = use_api self._topic_send = topic_send + self._api_panel_name = api_panel_name self._prev_msg = "" def send_mqtt_msg(self, msg, topic=None, force=False): if not force and self._prev_msg == msg: - self._ha_api.log(f"Dropping identical consecutive message: {msg}") + apis.ha_api.log(f"Dropping identical consecutive message: {msg}") return self._prev_msg = msg - if topic is None: - topic = self._topic_send - self._ha_api.log(f"Sending MQTT Message: {msg}") - apis.mqtt_api.mqtt_publish(topic, msg) + + apis.ha_api.log(f"Sending Message: {msg}") + if self._use_api: + apis.ha_api.call_service(service="esphome/" + self._api_panel_name + "_nspanelui_api_call", command=2, data=msg) + else: + if topic is None: + topic = self._topic_send + apis.mqtt_api.mqtt_publish(topic, msg) + + def request_berry_driver_version(self): + if self._use_api: + apis.ha_api.call_service(service="esphome/" + self._api_panel_name + "_nspanelui_api_call", command=1, data="x") + else: + apis.mqtt_api.mqtt_publish(self._topic_send.replace("CustomSend", "GetDriverVersion"), "x") + + def flash_nextion(self, url): + if self._use_api: + apis.ha_api.call_service(service="esphome/" + self._api_panel_name + "_nspanelui_api_call", command=255, data=url) + else: + apis.mqtt_api.mqtt_publish(self._topic_send.replace("CustomSend", "FlashNextion"), url) diff --git a/apps/nspanel-lovelace-ui/luibackend/updater.py b/apps/nspanel-lovelace-ui/luibackend/updater.py index 81f15e28..86890a9a 100644 --- a/apps/nspanel-lovelace-ui/luibackend/updater.py +++ b/apps/nspanel-lovelace-ui/luibackend/updater.py @@ -1,6 +1,5 @@ class Updater: - def __init__(self, log, send_mqtt_msg, topic_send, mode, desired_display_firmware_version, desired_display_firmware_model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url): - + def __init__(self, log, mqttsend, topic_send, mode, desired_display_firmware_version, desired_display_firmware_model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url): self._log = log self.desired_display_firmware_version = desired_display_firmware_version @@ -10,7 +9,7 @@ class Updater: self.desired_tasmota_driver_url = desired_tasmota_driver_url self.mode = mode - self._send_mqtt_msg = send_mqtt_msg + self.mqttsend = mqttsend self.topic_send = topic_send self.current_tasmota_driver_version = None self.current_display_firmware_version = None @@ -18,6 +17,7 @@ class Updater: def set_tasmota_driver_version(self, driver_version): self.current_tasmota_driver_version = driver_version + def set_current_display_firmware_version(self, panel_version, panel_model=None): self.current_display_firmware_version = panel_version self.current_display_model = panel_model @@ -33,8 +33,8 @@ class Updater: 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") + self.mqttsend.send_mqtt_msg(f"pageType~popupNotify") + self.mqttsend.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 @@ -80,12 +80,11 @@ class Updater: def request_berry_driver_version(self): self.current_tasmota_driver_version = None - topic = self.topic_send.replace("CustomSend", "GetDriverVersion") - self._send_mqtt_msg("X", topic=topic) + self.mqttsend.request_berry_driver_version() def update_berry_driver(self): topic = self.topic_send.replace("CustomSend", "Backlog") - self._send_mqtt_msg(f"UpdateDriverVersion {self.desired_tasmota_driver_url}; Restart 1", topic=topic) + self.mqttsend.send_mqtt_msg(f"UpdateDriverVersion {self.desired_tasmota_driver_url}; Restart 1", topic=topic) + def update_panel_driver(self): - topic = self.topic_send.replace("CustomSend", "FlashNextion") - self._send_mqtt_msg(self.desired_display_firmware_url, topic=topic) + self.mqttsend.flash_nextion(self.desired_display_firmware_url) diff --git a/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py b/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py index 25bbf412..5436315d 100644 --- a/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py +++ b/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py @@ -15,14 +15,15 @@ class NsPanelLovelaceUIManager(hass.Hass): apis.mqtt_api = self.get_plugin_api("MQTT") cfg = self._cfg = LuiBackendConfig(self, self.args["config"]) - + + use_api = cfg.get("use_api") == True + topic_send = cfg.get("panelSendTopic") topic_recv = cfg.get("panelRecvTopic") + api_panel_name = cfg.get("panelName") + api_device_id = cfg.get("panelDeviceId") - mqttsend = LuiMqttSender(self, topic_send) - - # Request Tasmota Driver Version - apis.mqtt_api.mqtt_publish(topic_send.replace("CustomSend", "GetDriverVersion"), "x") + mqttsend = LuiMqttSender(self, use_api, topic_send, api_panel_name) controller = LuiController(cfg, mqttsend.send_mqtt_msg) @@ -39,11 +40,12 @@ class NsPanelLovelaceUIManager(hass.Hass): desired_display_firmware_url = cfg._config.get("displayURL-EU", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft") desired_tasmota_driver_url = cfg._config.get("berryURL", "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be") - - mode = cfg.get("updateMode") - updater = Updater(self.log, mqttsend.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(self.log, mqttsend, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url) + + # Request Tasmota Driver Version + updater.request_berry_driver_version() - LuiMqttListener(topic_recv, controller, updater) + LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, controller, updater) self.log(f'Started ({version})')