mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-24 11:46:34 +00:00
Add dispatch and calibrate
This commit is contained in:
parent
9eca4d694d
commit
2aa5e59fea
152
src/hasp.cpp
152
src/hasp.cpp
@ -36,11 +36,11 @@
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
uint8_t haspStartPage = 0;
|
||||
uint8_t haspThemeId = 0;
|
||||
uint16_t haspThemeHue = 200;
|
||||
String haspPagesPath;
|
||||
String haspZiFontPath;
|
||||
uint8_t haspStartPage = 0;
|
||||
uint8_t haspThemeId = 0;
|
||||
uint16_t haspThemeHue = 200;
|
||||
char haspPagesPath[32] = "/pages.jsonl\0";
|
||||
char haspZiFontPath[32];
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -256,6 +256,11 @@ void haspSendNewValue(lv_obj_t * obj, const char * txt)
|
||||
}
|
||||
}
|
||||
|
||||
void haspSendNewValue(lv_obj_t * obj, int16_t val)
|
||||
{
|
||||
haspSendNewValue(obj, (int32_t)val);
|
||||
}
|
||||
|
||||
int32_t get_cpicker_value(lv_obj_t * obj)
|
||||
{
|
||||
lv_color16_t c16;
|
||||
@ -263,11 +268,6 @@ int32_t get_cpicker_value(lv_obj_t * obj)
|
||||
return (int32_t)c16.full;
|
||||
}
|
||||
|
||||
void haspSendNewValue(lv_obj_t * obj, int16_t val)
|
||||
{
|
||||
haspSendNewValue(obj, (int32_t)val);
|
||||
}
|
||||
|
||||
void haspSendNewValue(lv_obj_t * obj, lv_color_t color)
|
||||
{
|
||||
haspSendNewValue(obj, get_cpicker_value(obj));
|
||||
@ -457,9 +457,6 @@ bool haspGetObjAttribute(lv_obj_t * obj, String strAttr, std::string & strPayloa
|
||||
return false;
|
||||
}
|
||||
|
||||
void haspSetAttr(String strTopic, String strPayload)
|
||||
{}
|
||||
|
||||
void haspSetObjAttribute(lv_obj_t * obj, String strAttr, String strPayload)
|
||||
{
|
||||
if(!obj) return;
|
||||
@ -551,37 +548,22 @@ void haspSetObjAttribute(lv_obj_t * obj, String strAttr, String strPayload)
|
||||
}
|
||||
}
|
||||
|
||||
void haspProcessAttribute(String strTopic, String strPayload)
|
||||
void haspProcessAttribute(uint8_t pageid, uint8_t objid, String strAttr, String strPayload)
|
||||
{
|
||||
if(strTopic.startsWith("p[")) {
|
||||
String strPageId = strTopic.substring(2, strTopic.indexOf("]"));
|
||||
String strTemp = strTopic.substring(strTopic.indexOf("]") + 1, strTopic.length());
|
||||
if(strTemp.startsWith(".b[")) {
|
||||
String strObjId = strTemp.substring(3, strTemp.indexOf("]"));
|
||||
String strAttr = strTemp.substring(strTemp.indexOf("]") + 1, strTemp.length());
|
||||
debugPrintln(strPageId + " && " + strObjId + " && " + strAttr);
|
||||
|
||||
int pageid = strPageId.toInt();
|
||||
int objid = strObjId.toInt();
|
||||
|
||||
if(pageid >= 0 && pageid <= 255 && objid > 0 && objid <= 255) {
|
||||
lv_obj_t * obj = FindObjFromId((uint8_t)pageid, (uint8_t)objid);
|
||||
if(obj) {
|
||||
if(strPayload != "")
|
||||
haspSetObjAttribute(obj, strAttr, strPayload);
|
||||
else {
|
||||
/* publish the change */
|
||||
std::string strValue = "";
|
||||
if(haspGetObjAttribute(obj, strAttr, strValue)) {
|
||||
mqttSendNewValue(pageid, objid, String(strValue.c_str()));
|
||||
} else {
|
||||
warningPrintln(String(F("HASP: %sUnknown property: ")) + strAttr);
|
||||
}
|
||||
} // payload
|
||||
} // obj
|
||||
} // valid page
|
||||
}
|
||||
}
|
||||
lv_obj_t * obj = FindObjFromId((uint8_t)pageid, (uint8_t)objid);
|
||||
if(obj) {
|
||||
if(strPayload != "")
|
||||
haspSetObjAttribute(obj, strAttr, strPayload);
|
||||
else {
|
||||
/* publish the change */
|
||||
std::string strValue = "";
|
||||
if(haspGetObjAttribute(obj, strAttr, strValue)) {
|
||||
mqttSendNewValue(pageid, objid, String(strValue.c_str()));
|
||||
} else {
|
||||
warningPrintln(String(F("HASP: %sUnknown property: ")) + strAttr);
|
||||
}
|
||||
} // payload
|
||||
} // obj
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -687,7 +669,6 @@ void haspDisplayAP(const char * ssid, const char * pass)
|
||||
void haspSetup(JsonObject settings)
|
||||
{
|
||||
char buffer[64];
|
||||
haspPagesPath = F("/pages.jsonl");
|
||||
|
||||
haspSetConfig(settings);
|
||||
|
||||
@ -706,66 +687,66 @@ void haspSetup(JsonObject settings)
|
||||
// static lv_font_t *
|
||||
// my_font = (lv_font_t *)lv_mem_alloc(sizeof(lv_font_t));
|
||||
|
||||
my_font = (lv_font_t *)lv_mem_alloc(sizeof(lv_font_t));
|
||||
my_font[0] = (lv_font_t *)lv_mem_alloc(sizeof(lv_font_t));
|
||||
lv_zifont_init();
|
||||
|
||||
if(lv_zifont_font_init(my_font, haspZiFontPath.c_str(), 24) != 0) {
|
||||
errorPrintln(String(F("HASP: %sFailed to set the custom font to ")) + haspZiFontPath);
|
||||
my_font = NULL; // Use default font
|
||||
if(lv_zifont_font_init(my_font[0], haspZiFontPath, 24) != 0) {
|
||||
errorPrintln(String(F("HASP: %sFailed to set the custom font to ")) + String(haspZiFontPath));
|
||||
my_font[0] = NULL; // Use default font
|
||||
}
|
||||
|
||||
lv_theme_t * th;
|
||||
switch(haspThemeId) {
|
||||
#if LV_USE_THEME_ALIEN == 1
|
||||
case 1:
|
||||
th = lv_theme_alien_init(haspThemeHue, my_font);
|
||||
th = lv_theme_alien_init(haspThemeHue, my_font[0]);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_THEME_NIGHT == 1
|
||||
case 2:
|
||||
th = lv_theme_night_init(haspThemeHue, my_font); // heavy
|
||||
th = lv_theme_night_init(haspThemeHue, my_font[0]); // heavy
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_THEME_MONO == 1
|
||||
case 3:
|
||||
th = lv_theme_mono_init(haspThemeHue, my_font); // lightweight
|
||||
th = lv_theme_mono_init(haspThemeHue, my_font[0]); // lightweight
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_THEME_MATERIAL == 1
|
||||
case 4:
|
||||
th = lv_theme_material_init(haspThemeHue, my_font);
|
||||
th = lv_theme_material_init(haspThemeHue, my_font[0]);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_THEME_ZEN == 1
|
||||
case 5:
|
||||
th = lv_theme_zen_init(haspThemeHue, my_font); // lightweight
|
||||
th = lv_theme_zen_init(haspThemeHue, my_font[0]); // lightweight
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_THEME_NEMO == 1
|
||||
case 6:
|
||||
th = lv_theme_nemo_init(haspThemeHue, my_font); // heavy
|
||||
th = lv_theme_nemo_init(haspThemeHue, my_font[0]); // heavy
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_THEME_TEMPL == 1
|
||||
case 7:
|
||||
th = lv_theme_templ_init(haspThemeHue, my_font); // lightweight, not for production...
|
||||
th = lv_theme_templ_init(haspThemeHue, my_font[0]); // lightweight, not for production...
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_THEME_HASP == 1
|
||||
case 8:
|
||||
th = lv_theme_hasp_init(haspThemeHue, my_font);
|
||||
th = lv_theme_hasp_init(haspThemeHue, my_font[0]);
|
||||
break;
|
||||
#endif
|
||||
case 0:
|
||||
#if LV_USE_THEME_DEFAULT == 1
|
||||
th = lv_theme_default_init(haspThemeHue, my_font);
|
||||
th = lv_theme_default_init(haspThemeHue, my_font[0]);
|
||||
#else
|
||||
th = lv_theme_hasp_init(512, my_font);
|
||||
th = lv_theme_hasp_init(512, my_font[0]);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
th = lv_theme_hasp_init(512, my_font);
|
||||
th = lv_theme_hasp_init(512, my_font[0]);
|
||||
debugPrintln(F("HASP: Unknown theme selected"));
|
||||
}
|
||||
|
||||
@ -799,6 +780,10 @@ void haspSetup(JsonObject settings)
|
||||
haspLoadPage(haspPagesPath);
|
||||
haspSetPage(haspStartPage);
|
||||
|
||||
// lv_obj_t * img_bin_t = lv_img_create(pages[current_page], NULL); /*Crate an image object*/
|
||||
// lv_img_set_src(img_bin_t, "F:/dogsmall(1).bin"); /*Set the created file as image (a red rose)*/
|
||||
// lv_obj_set_pos(img_bin_t, 64, 64); /*Set the positions*/
|
||||
|
||||
// // lv_page_set_style(page, LV_PAGE_STYLE_SB, &style_sb); /*Set the scrollbar style*/
|
||||
|
||||
// // lv_obj_t *img1 = lv_img_create(pages[2], NULL);
|
||||
@ -1027,6 +1012,11 @@ static void switch_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
if(event == LV_EVENT_VALUE_CHANGED) haspSendNewValue(obj, lv_sw_get_state(obj));
|
||||
}
|
||||
|
||||
static void checkbox_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) haspSendNewValue(obj, lv_cb_is_checked(obj));
|
||||
}
|
||||
|
||||
static void ddlist_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) {
|
||||
@ -1049,10 +1039,10 @@ static void roller_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void haspReset()
|
||||
void haspReset(bool write_config)
|
||||
{
|
||||
mqttStop(); // Stop the MQTT Client first
|
||||
configWriteConfig();
|
||||
if(write_config) configWriteConfig();
|
||||
debugStop();
|
||||
delay(250);
|
||||
wifiStop();
|
||||
@ -1159,7 +1149,7 @@ void haspNewObject(const JsonObject & config)
|
||||
case LV_HASP_CHECKBOX: {
|
||||
obj = lv_cb_create(parent_obj, NULL);
|
||||
if(config[F("txt")]) lv_cb_set_text(obj, config[F("txt")].as<String>().c_str());
|
||||
lv_obj_set_event_cb(obj, switch_event_handler);
|
||||
lv_obj_set_event_cb(obj, checkbox_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_LABEL: {
|
||||
@ -1360,11 +1350,6 @@ void haspLoadPage(String pages)
|
||||
|
||||
bool haspGetConfig(const JsonObject & settings)
|
||||
{
|
||||
if(!settings.isNull() && settings[FPSTR(F_CONFIG_STARTPAGE)] == haspStartPage &&
|
||||
settings[FPSTR(F_CONFIG_THEME)] == haspThemeId && settings[FPSTR(F_CONFIG_HUE)] == haspThemeHue &&
|
||||
settings[FPSTR(F_CONFIG_ZIFONT)] == haspZiFontPath && settings[FPSTR(F_CONFIG_PAGES)] == haspPagesPath)
|
||||
return false;
|
||||
|
||||
settings[FPSTR(F_CONFIG_STARTPAGE)] = haspStartPage;
|
||||
settings[FPSTR(F_CONFIG_THEME)] = haspThemeId;
|
||||
settings[FPSTR(F_CONFIG_HUE)] = haspThemeHue;
|
||||
@ -1381,55 +1366,30 @@ bool haspGetConfig(const JsonObject & settings)
|
||||
|
||||
bool haspSetConfig(const JsonObject & settings)
|
||||
{
|
||||
if(!settings.isNull() && settings[FPSTR(F_CONFIG_STARTPAGE)] == haspStartPage &&
|
||||
settings[FPSTR(F_CONFIG_THEME)] == haspThemeId && settings[FPSTR(F_CONFIG_HUE)] == haspThemeHue &&
|
||||
settings[FPSTR(F_CONFIG_ZIFONT)] == haspZiFontPath && settings[FPSTR(F_CONFIG_PAGES)] == haspPagesPath)
|
||||
return false;
|
||||
|
||||
bool changed = false;
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_PAGES)].isNull()) {
|
||||
if(haspPagesPath != settings[FPSTR(F_CONFIG_PAGES)].as<String>().c_str()) {
|
||||
debugPrintln(F("haspPagesPath changed"));
|
||||
}
|
||||
changed |= haspPagesPath != settings[FPSTR(F_CONFIG_PAGES)].as<String>().c_str();
|
||||
|
||||
haspPagesPath = settings[FPSTR(F_CONFIG_PAGES)].as<String>().c_str();
|
||||
changed |= strcmp(haspPagesPath, settings[FPSTR(F_CONFIG_PAGES)]) != 0;
|
||||
strncpy(haspPagesPath, settings[FPSTR(F_CONFIG_PAGES)], sizeof(haspPagesPath));
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_ZIFONT)].isNull()) {
|
||||
if(haspZiFontPath != settings[FPSTR(F_CONFIG_ZIFONT)].as<String>().c_str()) {
|
||||
debugPrintln(F("haspZiFontPath changed"));
|
||||
}
|
||||
changed |= haspZiFontPath != settings[FPSTR(F_CONFIG_ZIFONT)].as<String>().c_str();
|
||||
|
||||
haspZiFontPath = settings[FPSTR(F_CONFIG_ZIFONT)].as<String>().c_str();
|
||||
changed |= strcmp(haspZiFontPath, settings[FPSTR(F_CONFIG_ZIFONT)]) != 0;
|
||||
strncpy(haspZiFontPath, settings[FPSTR(F_CONFIG_ZIFONT)], sizeof(haspZiFontPath));
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_STARTPAGE)].isNull()) {
|
||||
if(haspStartPage != settings[FPSTR(F_CONFIG_STARTPAGE)].as<uint8_t>()) {
|
||||
debugPrintln(F("haspStartPage changed"));
|
||||
}
|
||||
changed |= haspStartPage != settings[FPSTR(F_CONFIG_STARTPAGE)].as<uint8_t>();
|
||||
|
||||
haspStartPage = settings[FPSTR(F_CONFIG_STARTPAGE)].as<uint8_t>();
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_THEME)].isNull()) {
|
||||
if(haspThemeId != settings[FPSTR(F_CONFIG_THEME)].as<uint8_t>()) {
|
||||
debugPrintln(F("haspThemeId changed"));
|
||||
}
|
||||
changed |= haspThemeId != settings[FPSTR(F_CONFIG_THEME)].as<uint8_t>();
|
||||
|
||||
haspThemeId = settings[FPSTR(F_CONFIG_THEME)].as<uint8_t>();
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_HUE)].isNull()) {
|
||||
if(haspThemeHue != settings[FPSTR(F_CONFIG_HUE)].as<uint16_t>()) {
|
||||
debugPrintln(F("haspStartPage changed"));
|
||||
}
|
||||
changed |= haspThemeHue != settings[FPSTR(F_CONFIG_HUE)].as<uint16_t>();
|
||||
|
||||
haspThemeHue = settings[FPSTR(F_CONFIG_HUE)].as<uint16_t>();
|
||||
}
|
||||
|
||||
|
@ -77,11 +77,10 @@ void haspSetNodename(String name);
|
||||
String haspGetNodename();
|
||||
float haspGetVersion();
|
||||
void haspBackground(uint16_t pageid, uint16_t imageid);
|
||||
void haspReset();
|
||||
void haspReset(bool write_config);
|
||||
|
||||
void haspSetLabelText(String value);
|
||||
void haspProcessAttribute(String strTopic, String strPayload);
|
||||
void haspSetAttr(String strTopic, String strPayload);
|
||||
void haspProcessAttribute(uint8_t pageid, uint8_t objid, String strAttr, String strPayload);
|
||||
void haspSendCmd(String nextionCmd);
|
||||
void haspParseJson(String & strPayload);
|
||||
|
||||
|
103
src/hasp_dispatch.cpp
Normal file
103
src/hasp_dispatch.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
#include "hasp_dispatch.h"
|
||||
#include "hasp_mqtt.h"
|
||||
#include "hasp_http.h"
|
||||
#include "hasp_mdns.h"
|
||||
#include "hasp_wifi.h"
|
||||
#include "hasp_log.h"
|
||||
#include "hasp_gui.h"
|
||||
#include "hasp.h"
|
||||
|
||||
void dispatchSetup()
|
||||
{}
|
||||
|
||||
void dispatchLoop()
|
||||
{}
|
||||
|
||||
// objectattribute=value
|
||||
void dispatchAttribute(String & strTopic, String & strPayload)
|
||||
{
|
||||
if(strTopic.startsWith("p[")) {
|
||||
String strPageId = strTopic.substring(2, strTopic.indexOf("]"));
|
||||
String strTemp = strTopic.substring(strTopic.indexOf("]") + 1, strTopic.length());
|
||||
if(strTemp.startsWith(".b[")) {
|
||||
String strObjId = strTemp.substring(3, strTemp.indexOf("]"));
|
||||
String strAttr = strTemp.substring(strTemp.indexOf("]") + 1, strTemp.length());
|
||||
// debugPrintln(strPageId + " && " + strObjId + " && " + strAttr);
|
||||
|
||||
int pageid = strPageId.toInt();
|
||||
int objid = strObjId.toInt();
|
||||
|
||||
if(pageid >= 0 && pageid <= 255 && objid > 0 && objid <= 255) {
|
||||
haspProcessAttribute((uint8_t)pageid, (uint8_t)objid, strAttr, strPayload);
|
||||
} // valid page
|
||||
}
|
||||
} else if(strTopic == "page") {
|
||||
} else if(strTopic == "dim") {
|
||||
}
|
||||
}
|
||||
|
||||
void dispatchPage(String & strPageid)
|
||||
{
|
||||
debugPrintln("PAGE:" + strPageid);
|
||||
|
||||
if(strPageid.length() == 0) {
|
||||
String strPayload = String(haspGetPage());
|
||||
mqttSendState("page", strPayload.c_str());
|
||||
} else {
|
||||
if(strPageid.toInt() <= 250) haspSetPage(strPageid.toInt());
|
||||
}
|
||||
}
|
||||
|
||||
void dispatchCommand(String cmnd)
|
||||
{
|
||||
debugPrintln("CMND: " + cmnd);
|
||||
|
||||
if(cmnd == "calibrate") {
|
||||
guiCalibrate();
|
||||
return;
|
||||
}
|
||||
|
||||
if(cmnd == "restart") {
|
||||
haspReset(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if(cmnd == "" || cmnd == "statusupdate") {
|
||||
haspReset(true);
|
||||
return;
|
||||
}
|
||||
|
||||
int pos = cmnd.indexOf("=");
|
||||
if(pos > 0) {
|
||||
String strTopic = cmnd.substring(0, pos);
|
||||
String strPayload = cmnd.substring(pos + 1, cmnd.length());
|
||||
debugPrintln("CMND: '" + strTopic + "'='" + strPayload + "'");
|
||||
dispatchAttribute(strTopic, strPayload);
|
||||
}
|
||||
}
|
||||
|
||||
void dispatchJson(String & strPayload)
|
||||
{ // Parse an incoming JSON array into individual commands
|
||||
if(strPayload.endsWith(",]")) {
|
||||
// Trailing null array elements are an artifact of older Home Assistant automations
|
||||
// and need to be removed before parsing by ArduinoJSON 6+
|
||||
strPayload.remove(strPayload.length() - 2, 2);
|
||||
strPayload.concat("]");
|
||||
}
|
||||
DynamicJsonDocument haspCommands(2048 + 1024);
|
||||
DeserializationError jsonError = deserializeJson(haspCommands, strPayload);
|
||||
if(jsonError) { // Couldn't parse incoming JSON command
|
||||
errorPrintln(String(F("JSON: %sFailed to parse incoming JSON command with error: ")) +
|
||||
String(jsonError.c_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < haspCommands.size(); i++) {
|
||||
dispatchCommand(haspCommands[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void dispatchIdle(const __FlashStringHelper * state)
|
||||
{
|
||||
mqttSendState(String(F("idle")).c_str(), String(state).c_str());
|
||||
}
|
15
src/hasp_dispatch.h
Normal file
15
src/hasp_dispatch.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef HASP_DISPATCH_H
|
||||
#define HASP_DISPATCH_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
void dispatchSetup(void);
|
||||
void dispatchLoop(void);
|
||||
|
||||
void dispatchAttribute(String & strTopic, String & strPayload);
|
||||
void dispatchCommand(String cmnd);
|
||||
void dispatchJson(String & strPayload);
|
||||
void dispatchPage(String & strPageid);
|
||||
void dispatchIdle(const __FlashStringHelper * state);
|
||||
|
||||
#endif
|
@ -1,7 +1,8 @@
|
||||
#include <Ticker.h>
|
||||
|
||||
#include "lvgl.h"
|
||||
#include "lv_conf.h"
|
||||
#include "lvgl.h"
|
||||
#include "lv_fs_if.h"
|
||||
|
||||
#include "TFT_eSPI.h"
|
||||
|
||||
@ -13,6 +14,7 @@
|
||||
#include "hasp_log.h"
|
||||
#include "hasp_debug.h"
|
||||
#include "hasp_config.h"
|
||||
#include "hasp_dispatch.h"
|
||||
#include "hasp_gui.h"
|
||||
|
||||
#define LVGL_TICK_PERIOD 30 // 30
|
||||
@ -20,14 +22,15 @@
|
||||
uint16_t guiSleepTime = 150; // 0.1 second resolution
|
||||
bool guiSleeping = false;
|
||||
uint8_t guiTickPeriod = 50;
|
||||
Ticker tick; /* timer for interrupt handler */
|
||||
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
|
||||
Ticker tick; /* timer for interrupt handler */
|
||||
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
|
||||
uint16_t calData[5] = {0, 0, 0, 0, 0};
|
||||
|
||||
bool IRAM_ATTR guiCheckSleep()
|
||||
{
|
||||
bool shouldSleep = lv_disp_get_inactive_time(NULL) > guiSleepTime * 100;
|
||||
if(shouldSleep && !guiSleeping) {
|
||||
debugPrintln(F("GUI: Going to sleep now..."));
|
||||
dispatchIdle(F("LONG"));
|
||||
guiSleeping = true;
|
||||
}
|
||||
return shouldSleep;
|
||||
@ -90,7 +93,7 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
|
||||
|
||||
bool shouldSleep = guiCheckSleep();
|
||||
if(!shouldSleep && guiSleeping) {
|
||||
debugPrintln(F("GUI: Waking up!"));
|
||||
dispatchIdle(F("OFF"));
|
||||
guiSleeping = false;
|
||||
}
|
||||
|
||||
@ -117,10 +120,35 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
|
||||
return false; /*Return `false` because we are not buffering and no more data to read*/
|
||||
}
|
||||
|
||||
void guiCalibrate()
|
||||
{
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setCursor(20, 0);
|
||||
// tft.setTextFont(2);
|
||||
tft.setTextSize(1);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
tft.println(PSTR("Touch corners as indicated"));
|
||||
|
||||
tft.setTextFont(1);
|
||||
tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);
|
||||
|
||||
for(uint8_t i = 0; i < 5; i++) {
|
||||
Serial.print(calData[i]);
|
||||
if(i < 4) Serial.print(", ");
|
||||
}
|
||||
|
||||
tft.setTouch(calData);
|
||||
lv_obj_invalidate(lv_disp_get_layer_sys(NULL));
|
||||
}
|
||||
|
||||
void guiSetup(TFT_eSPI & screen, JsonObject settings)
|
||||
{
|
||||
size_t buffer_size;
|
||||
tft = screen;
|
||||
|
||||
tft.setTouch(calData);
|
||||
|
||||
lv_init();
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
@ -209,6 +237,10 @@ void guiSetup(TFT_eSPI & screen, JsonObject settings)
|
||||
/*Initialize the graphics library's tick*/
|
||||
tick.attach_ms(guiTickPeriod, lv_tick_handler);
|
||||
|
||||
#if LV_USE_FS_IF != 0
|
||||
lv_fs_if_init();
|
||||
#endif
|
||||
|
||||
// guiLoop();
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,9 @@
|
||||
void guiSetup(TFT_eSPI & screen, JsonObject settings);
|
||||
void guiLoop(void);
|
||||
void guiStop(void);
|
||||
|
||||
void guiCalibrate();
|
||||
|
||||
bool guiGetConfig(const JsonObject & settings);
|
||||
|
||||
// lv_res_t guiChangeTheme(uint8_t themeid, uint16_t hue, String font, uint8_t fontsize);
|
||||
|
@ -251,10 +251,10 @@ void httpHandleReboot()
|
||||
delay(500);
|
||||
|
||||
debugPrintln(PSTR("HTTP: Reboot device"));
|
||||
haspSetAttr(F("p[0].b[1].txt"), F("\"Rebooting...\""));
|
||||
// haspProcessAttribute(F("p[0].b[1].txt"), F("\"Rebooting...\""));
|
||||
|
||||
delay(500);
|
||||
haspReset();
|
||||
haspReset(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1007,7 +1007,7 @@ void httpHandleResetConfig()
|
||||
if(resetConfirmed) {
|
||||
delay(250);
|
||||
// configClearSaved();
|
||||
haspReset();
|
||||
haspReset(false); // Do not save the current config
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef HASP_HTTP_H
|
||||
#define HASP_HTTP_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
void httpSetup(const JsonObject & settings);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "hasp_config.h"
|
||||
#include "hasp_mqtt.h"
|
||||
#include "hasp_wifi.h"
|
||||
#include "hasp_dispatch.h"
|
||||
#include "hasp.h"
|
||||
|
||||
#ifdef USE_CONFIG_OVERRIDE
|
||||
@ -71,8 +72,6 @@ std::string mqttPassword = "";
|
||||
std::string mqttGroupName = "plates";
|
||||
|
||||
/*
|
||||
const String mqttCommandSubscription = mqttCommandTopic + "/#";
|
||||
const String mqttGroupCommandSubscription = mqttGroupCommandTopic + "/#";
|
||||
const String mqttLightSubscription = "hasp/" + String(haspGetNodename()) + "/light/#";
|
||||
const String mqttLightBrightSubscription = "hasp/" + String(haspGetNodename()) + "/brightness/#";
|
||||
*/
|
||||
@ -82,87 +81,53 @@ PubSubClient mqttClient(wifiClient);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Send changed values OUT
|
||||
void mqttSendNewEvent(uint8_t pageid, uint8_t btnid, int32_t val)
|
||||
|
||||
void mqttSendState(const char * subtopic, const char * payload)
|
||||
{
|
||||
char topic[72];
|
||||
sprintf_P(topic, PSTR("hasp/%s/state/p[%u].b[%u].event"), haspGetNodename().c_str(), pageid, btnid);
|
||||
char value[32];
|
||||
itoa(val, value, 10);
|
||||
mqttClient.publish(topic, value);
|
||||
debugPrintln(String(F("MQTT OUT: ")) + String(topic) + " = " + String(value));
|
||||
// page = 0
|
||||
// p[0].b[0].attr = abc
|
||||
// dim = 100
|
||||
// idle = 0/1
|
||||
// light = 0/1
|
||||
// brightness = 100
|
||||
|
||||
char topic[128];
|
||||
sprintf_P(topic, PSTR("%sstate/%s"), mqttNodeTopic.c_str(), subtopic);
|
||||
mqttClient.publish(topic, payload);
|
||||
debugPrintln(String(F("MQTT OUT: ")) + String(topic) + " = " + String(payload));
|
||||
|
||||
// as json
|
||||
sprintf_P(topic, PSTR("hasp/%s/state/json"), haspGetNodename().c_str(), pageid, btnid);
|
||||
sprintf_P(value, PSTR("{\"event\":\"p[%u]].b[%u].event\", \"value\":%u}"), pageid, btnid, val);
|
||||
char value[256];
|
||||
sprintf_P(topic, PSTR("%sstate/json"), mqttNodeTopic.c_str());
|
||||
sprintf_P(value, PSTR("{\"%s\":\"%s\"}"), subtopic, payload);
|
||||
mqttClient.publish(topic, value);
|
||||
debugPrintln(String(F("MQTT OUT: ")) + String(topic) + " = " + String(value));
|
||||
}
|
||||
|
||||
void mqttSendNewValue(uint8_t pageid, uint8_t btnid, const char * attribute, String txt)
|
||||
{
|
||||
char subtopic[32];
|
||||
sprintf_P(subtopic, PSTR("p[%u].b[%u].%s"), pageid, btnid, attribute);
|
||||
mqttSendState(subtopic, txt.c_str());
|
||||
}
|
||||
|
||||
void mqttSendNewValue(uint8_t pageid, uint8_t btnid, int32_t val)
|
||||
{
|
||||
char topic[72];
|
||||
sprintf_P(topic, PSTR("hasp/%s/state/p[%u].b[%u].val"), haspGetNodename().c_str(), pageid, btnid);
|
||||
char value[32];
|
||||
char value[16];
|
||||
itoa(val, value, 10);
|
||||
mqttClient.publish(topic, value);
|
||||
debugPrintln(String(F("MQTT OUT: ")) + String(topic) + " = " + String(value));
|
||||
|
||||
// as json
|
||||
sprintf_P(topic, PSTR("hasp/%s/state/json"), haspGetNodename().c_str(), pageid, btnid);
|
||||
sprintf_P(value, PSTR("{\"event\":\"p[%u]].b[%u].val\", \"value\":%u}"), pageid, btnid, val);
|
||||
mqttClient.publish(topic, value);
|
||||
debugPrintln(String(F("MQTT OUT: ")) + String(topic) + " = " + String(value));
|
||||
mqttSendNewValue(pageid, btnid, "val", value);
|
||||
}
|
||||
|
||||
void mqttSendNewValue(uint8_t pageid, uint8_t btnid, String txt)
|
||||
{
|
||||
char topic[72];
|
||||
sprintf_P(topic, PSTR("hasp/%s/state/p[%u].b[%u].txt"), haspGetNodename().c_str(), pageid, btnid);
|
||||
mqttClient.publish(topic, txt.c_str());
|
||||
debugPrintln(String(F("MQTT OUT: ")) + String(topic) + " = " + txt);
|
||||
|
||||
// as json
|
||||
char value[64];
|
||||
sprintf_P(topic, PSTR("hasp/%s/state/json"), haspGetNodename().c_str(), pageid, btnid);
|
||||
sprintf_P(value, PSTR("{\"event\":\"p[%u]].b[%u].txt\", \"value\":\"%s\"}"), pageid, btnid, txt.c_str());
|
||||
mqttClient.publish(topic, value);
|
||||
debugPrintln(String(F("MQTT OUT: ")) + String(topic) + " = " + String(value));
|
||||
mqttSendNewValue(pageid, btnid, "txt", txt);
|
||||
}
|
||||
|
||||
void mqttHandlePage(String strPageid)
|
||||
void mqttSendNewEvent(uint8_t pageid, uint8_t btnid, int32_t val)
|
||||
{
|
||||
if(strPageid.length() == 0) {
|
||||
String strPayload = String(haspGetPage());
|
||||
String topic = mqttNodeTopic + F("state/page");
|
||||
char buffer[64];
|
||||
sprintf_P(buffer, PSTR("MQTT OUT: %s = %s"), topic.c_str(), strPayload.c_str());
|
||||
debugPrintln(buffer);
|
||||
mqttClient.publish(topic.c_str(), strPayload.c_str());
|
||||
} else {
|
||||
if(strPageid.toInt() <= 250) haspSetPage(strPageid.toInt());
|
||||
}
|
||||
}
|
||||
|
||||
void mqttHandleJson(String & strPayload)
|
||||
{ // Parse an incoming JSON array into individual Nextion commands
|
||||
if(strPayload.endsWith(
|
||||
",]")) { // Trailing null array elements are an artifact of older Home Assistant automations and need to
|
||||
// be removed before parsing by ArduinoJSON 6+
|
||||
strPayload.remove(strPayload.length() - 2, 2);
|
||||
strPayload.concat("]");
|
||||
}
|
||||
DynamicJsonDocument nextionCommands(mqttMaxPacketSize + 1024);
|
||||
DeserializationError jsonError = deserializeJson(nextionCommands, strPayload);
|
||||
if(jsonError) { // Couldn't parse incoming JSON command
|
||||
debugPrintln(String(F("MQTT: [ERROR] Failed to parse incoming JSON command with error: ")) +
|
||||
String(jsonError.c_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < nextionCommands.size(); i++) {
|
||||
debugPrintln(nextionCommands[i]);
|
||||
// nextionSendCmd(nextionCommands[i]);
|
||||
}
|
||||
char value[16];
|
||||
itoa(val, value, 10);
|
||||
mqttSendNewValue(pageid, btnid, "event", value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -204,11 +169,7 @@ void mqttCallback(char * topic, byte * payload, unsigned int length)
|
||||
// debugPrintln(String(F("MQTT Short Topic : '")) + strTopic + "'");
|
||||
|
||||
if(strTopic == F("command")) {
|
||||
if(strPayload == "") { // '[...]/device/command' -m '' = No command requested, respond with mqttStatusUpdate()
|
||||
// mqttStatusUpdate(); // return status JSON via MQTT
|
||||
} else { // '[...]/device/command' -m 'dim=50' == nextionSendCmd("dim=50")
|
||||
// nextionSendCmd(strPayload);
|
||||
}
|
||||
dispatchCommand(strPayload);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -217,7 +178,7 @@ void mqttCallback(char * topic, byte * payload, unsigned int length)
|
||||
// debugPrintln(String(F("MQTT Shorter Command Topic : '")) + strTopic + "'");
|
||||
|
||||
if(strTopic == F("page")) { // '[...]/device/command/page' -m '1' == nextionSendCmd("page 1")
|
||||
mqttHandlePage(strPayload);
|
||||
dispatchPage(strPayload);
|
||||
} else if(strTopic == F("dim")) { // '[...]/device/command/page' -m '1' == nextionSendCmd("page 1")
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcWrite(0, map(strPayload.toInt(), 0, 100, 0, 1023)); // ledChannel and value
|
||||
@ -227,7 +188,7 @@ void mqttCallback(char * topic, byte * payload, unsigned int length)
|
||||
|
||||
} else if(strTopic == F("json")) { // '[...]/device/command/json' -m '["dim=5", "page 1"]' =
|
||||
// nextionSendCmd("dim=50"), nextionSendCmd("page 1")
|
||||
mqttHandleJson(strPayload); // Send to nextionParseJson()
|
||||
dispatchJson(strPayload); // Send to nextionParseJson()
|
||||
} else if(strTopic == F("statusupdate")) { // '[...]/device/command/statusupdate' == mqttStatusUpdate()
|
||||
// mqttStatusUpdate(); // return status JSON via MQTT
|
||||
} else if(strTopic == F("espupdate")) { // '[...]/device/command/espupdate' -m
|
||||
@ -240,17 +201,18 @@ void mqttCallback(char * topic, byte * payload, unsigned int length)
|
||||
}
|
||||
} else if(strTopic == F("reboot")) { // '[...]/device/command/reboot' == reboot microcontroller)
|
||||
debugPrintln(F("MQTT: Rebooting device"));
|
||||
haspReset();
|
||||
haspReset(true);
|
||||
} else if(strTopic == F("lcdreboot")) { // '[...]/device/command/lcdreboot' == reboot LCD panel)
|
||||
debugPrintln(F("MQTT: Rebooting LCD"));
|
||||
haspReset();
|
||||
haspReset(true);
|
||||
} else if(strTopic == F("factoryreset")) { // '[...]/device/command/factoryreset' == clear all saved settings)
|
||||
// configClearSaved();
|
||||
} else if(strPayload == "") { // '[...]/device/command/p[1].b[4].txt' -m '' == nextionGetAttr("p[1].b[4].txt")
|
||||
haspProcessAttribute(strTopic, "");
|
||||
//} else if(strPayload == "") { // '[...]/device/command/p[1].b[4].txt' -m '' ==
|
||||
// nextionGetAttr("p[1].b[4].txt")
|
||||
// haspProcessAttribute(strTopic, "");
|
||||
} else { // '[...]/device/command/p[1].b[4].txt' -m '"Lights On"' ==
|
||||
// nextionSetAttr("p[1].b[4].txt", "\"Lights On\"")
|
||||
haspProcessAttribute(strTopic, strPayload);
|
||||
dispatchAttribute(strTopic, strPayload);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -434,7 +396,7 @@ bool mqttSetConfig(const JsonObject & settings)
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_GROUP)].isNull()) {
|
||||
if(mqttGroupName != settings[FPSTR(F_CONFIG_GROUP)].as<String>().c_str()) {
|
||||
debugPrintln(F("mqttGroupName changed"));
|
||||
debugPrintln(F("mqttGroupName set"));
|
||||
}
|
||||
changed |= mqttGroupName != settings[FPSTR(F_CONFIG_GROUP)].as<String>().c_str();
|
||||
|
||||
@ -443,7 +405,7 @@ bool mqttSetConfig(const JsonObject & settings)
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_HOST)].isNull()) {
|
||||
if(mqttServer != settings[FPSTR(F_CONFIG_HOST)].as<String>().c_str()) {
|
||||
debugPrintln(F("mqttServer changed"));
|
||||
debugPrintln(F("mqttServer set"));
|
||||
}
|
||||
changed |= mqttServer != settings[FPSTR(F_CONFIG_HOST)].as<String>().c_str();
|
||||
|
||||
@ -452,7 +414,7 @@ bool mqttSetConfig(const JsonObject & settings)
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_PORT)].isNull()) {
|
||||
if(mqttPort != settings[FPSTR(F_CONFIG_PORT)].as<uint16_t>()) {
|
||||
debugPrintln(F("mqttPort changed"));
|
||||
debugPrintln(F("mqttPort set"));
|
||||
}
|
||||
changed |= mqttPort != settings[FPSTR(F_CONFIG_PORT)].as<uint16_t>();
|
||||
|
||||
@ -461,7 +423,7 @@ bool mqttSetConfig(const JsonObject & settings)
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_USER)].isNull()) {
|
||||
if(mqttUser != settings[FPSTR(F_CONFIG_USER)].as<String>().c_str()) {
|
||||
debugPrintln(F("mqttUser changed"));
|
||||
debugPrintln(F("mqttUser set"));
|
||||
}
|
||||
changed |= mqttUser != settings[FPSTR(F_CONFIG_USER)].as<String>().c_str();
|
||||
|
||||
@ -470,7 +432,7 @@ bool mqttSetConfig(const JsonObject & settings)
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_PASS)].isNull()) {
|
||||
if(mqttPassword != settings[FPSTR(F_CONFIG_PASS)].as<String>().c_str()) {
|
||||
debugPrintln(F("mqttPassword changed"));
|
||||
debugPrintln(F("mqttPassword set"));
|
||||
}
|
||||
changed |= mqttPassword != settings[FPSTR(F_CONFIG_PASS)].as<String>().c_str();
|
||||
|
||||
|
@ -8,6 +8,7 @@ void mqttLoop(bool wifiIsConnected);
|
||||
void mqttStop();
|
||||
void mqttReconnect();
|
||||
|
||||
void mqttSendState(const char * subtopic, const char * payload);
|
||||
void mqttSendNewEvent(uint8_t pageid, uint8_t btnid, int32_t val);
|
||||
void mqttSendNewValue(uint8_t pageid, uint8_t btnid, int32_t val);
|
||||
void mqttSendNewValue(uint8_t pageid, uint8_t btnid, String txt);
|
||||
|
@ -38,25 +38,6 @@ void tftSetup(TFT_eSPI & tft, JsonObject settings)
|
||||
// uint16_t calData[5] = {0, 0, 0, 0, 0};
|
||||
uint8_t calDataOK = 0;
|
||||
|
||||
// Calibrate
|
||||
if(0) {
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setCursor(20, 0);
|
||||
// tft.setTextFont(2);
|
||||
tft.setTextSize(1);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
tft.println(PSTR("Touch corners as indicated"));
|
||||
|
||||
tft.setTextFont(1);
|
||||
tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);
|
||||
|
||||
for(uint8_t i = 0; i < 5; i++) {
|
||||
Serial.print(calData[i]);
|
||||
if(i < 4) Serial.print(", ");
|
||||
}
|
||||
}
|
||||
|
||||
tft.setTouch(calData);
|
||||
}
|
||||
|
||||
@ -90,9 +71,6 @@ void tftPinInfo(String pinfunction, int8_t pin)
|
||||
}
|
||||
}
|
||||
|
||||
void tftCalibrate()
|
||||
{}
|
||||
|
||||
void tftShowConfig(TFT_eSPI & tft)
|
||||
{
|
||||
setup_t tftSetup;
|
||||
|
@ -7,6 +7,7 @@
|
||||
void tftSetup(TFT_eSPI & screen, JsonObject settings);
|
||||
void tftLoop(void);
|
||||
void tftStop(void);
|
||||
|
||||
void tftShowConfig(TFT_eSPI & tft);
|
||||
|
||||
#endif
|
@ -216,16 +216,11 @@ bool wifiGetConfig(const JsonObject & settings)
|
||||
|
||||
bool wifiSetConfig(const JsonObject & settings)
|
||||
{
|
||||
/* if(!settings.isNull() && settings[FPSTR(F_CONFIG_STARTPAGE)] == haspStartPage &&
|
||||
settings[FPSTR(F_CONFIG_THEME)] == haspThemeId && settings[FPSTR(F_CONFIG_HUE)] == haspThemeHue &&
|
||||
settings[FPSTR(F_CONFIG_ZIFONT)] == haspZiFontPath && settings[FPSTR(F_CONFIG_PAGES)] == haspPagesPath)
|
||||
return false;
|
||||
*/
|
||||
bool changed = false;
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_SSID)].isNull()) {
|
||||
if(wifiSsid != settings[FPSTR(F_CONFIG_SSID)].as<String>().c_str()) {
|
||||
debugPrintln(F("wifiSsid changed"));
|
||||
debugPrintln(F("wifiSsid set"));
|
||||
}
|
||||
changed |= wifiSsid != settings[FPSTR(F_CONFIG_SSID)].as<String>().c_str();
|
||||
|
||||
@ -234,7 +229,7 @@ bool wifiSetConfig(const JsonObject & settings)
|
||||
|
||||
if(!settings[FPSTR(F_CONFIG_PASS)].isNull() && settings[FPSTR(F_CONFIG_PASS)].as<String>() != F("********")) {
|
||||
if(wifiPassword != settings[FPSTR(F_CONFIG_PASS)].as<String>().c_str()) {
|
||||
debugPrintln(F("wifiPassword changed"));
|
||||
debugPrintln(F("wifiPassword set"));
|
||||
}
|
||||
changed |= wifiPassword != settings[FPSTR(F_CONFIG_PASS)].as<String>().c_str();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user