try to add tahoma functionality--> RAM overflow -->removed Tahome for now

This commit is contained in:
2025-05-13 19:21:20 +02:00
parent f74fde8d82
commit df516837cc
614 changed files with 77666 additions and 288 deletions
+252 -167
View File
@@ -1,9 +1,11 @@
#include "MQTT.h"
#define MDNS_SERVICENAME ""
WiFiUDP MQTT::udp;
const char* MQTT::months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
char MQTT::ntpServer[40] = "nas.local";
WebServer MQTT::server = WebServer(80);
AsyncWebServer* MQTT::server = new AsyncWebServer(80);
AsyncWebSocket* MQTT::ws = new AsyncWebSocket("/ws");
bool MQTT::saveConfigFlag=false;
WiFiManagerParameter custom_hostname("hostname", "Hostname", "", 40);
@@ -18,109 +20,24 @@ MQTT::MQTT(){
}
void MQTT::serveOverride(void){
String sending;
sending = "{";
if(server.args() == 1 && glblData.enBuff){
if(server.argName(0)=="SW" || server.argName(0)=="sw"){
if(server.arg(0) == "ON"){
glblData.override = OVR_ALWAYSON;
sending = "{\"Status\": \"Success\", ";
}else if(server.arg(0) == "OFF"){
glblData.override = OVR_ALWAYSOFF;
sending = "{\"Status\": \"Success\", ";
}else{
glblData.override = OVR_NONE;
sending = "{\"Status\": \"Success\", ";
}
}
}else if(!glblData.enBuff){
sending = "{\"Status\": \"Not Enabled\", ";
glblData.override = OVR_NONE;
}
switch(glblData.override){
case OVR_ALWAYSOFF:
sending += "\"Override\": \"Always OFF\"}";
break;
case OVR_ALWAYSON:
sending += "\"Override\": \"Always ON\"}";
break;
case OVR_NONE:
sending += "\"Override\": \"NONE\"}";
break;
}
server.send(404, "text/plain", sending);
}
void MQTT::serveData(void){
String sending;
sending = "{\"Temp[degC]\": ";
sending += glblData.temp;
sending += ", \"pressure[hPa]\": ";
sending += glblData.seaLevelPress;
sending += ", \"rHum[%]\": ";
sending += glblData.hum;
sending += ", \"Heating\": ";
sending += glblData.heating;
sending += ", \"Set Temp[degC]\": ";
sending += glblData.settemp;
sending += " }";
Serial.println("Sending website...");
server.send(200, FPSTR(HTTP_HEAD_JSON), sending);
Serial.println("Sent website...");
/*
request->send(404, "text/plain", sending);*/
}
void MQTT::sendStatus(void){
tm timeinfo;
char buffer[35];
publish_sub("hostname", hostname);
publish_sub("IP", myIP);
publish_sub("NTP-Server", ntpServer);
if(!getLocalTime(&timeinfo)){
strcpy(buffer, "00-00-0000T00:00:00+0000");
}else{
strftime(buffer, sizeof(buffer), "%FT%T%z", &timeinfo);
}
publish_sub("timestamp",buffer,true);
snprintf(buffer, sizeof buffer, "%0.1f", glblData.temp);
publish_sub("Temp[degC]",buffer,true);
snprintf(buffer, sizeof buffer, "%0.0f", glblData.seaLevelPress);
publish_sub("pressure[hPa]",buffer,true);
snprintf(buffer, sizeof buffer, "%0.0f", glblData.hum);
publish_sub("rHum[%]",buffer,true);
snprintf(buffer, sizeof buffer, "%s", digitalRead(PIN_REL)?"true":"false");
publish_sub("Heating",buffer,true);
snprintf(buffer, sizeof buffer, "%0.1f", glblData.settemp);
publish_sub("Set Temp[degC]",buffer,true);
}
void MQTT::begin(){
saveConfigFlag = false;
prefs.begin("settings");
prefs.getString("HOST",hostname,40);
prefs.getString("MQTT_SERVER",mqtt_server,40);
mqtt_port = prefs.getInt("MQTT_PORT",mqtt_port);
prefs.getString("MQTT_TOPIC",mqtt_topic,40);
defTemp = prefs.getFloat("DEF_TMP",defTemp);
enBuff = prefs.getBool("EN_OVR",enBuff);
prefs.getString("NTP_SERVER",ntpServer,40);
glblData.enBuff = enBuff;
ui_settemp(defTemp);
prefs.end();
Settings::getInstance().loadSettings(); // Load dataset from persistent storage
wm.setSaveConfigCallback(MQTT::saveConfigCallback);
custom_hostname.setValue(hostname,40);
custom_mqtt_server.setValue(mqtt_server,40);
custom_mqtt_port.setValue(String(mqtt_port).c_str(),6);
custom_mqtt_topic.setValue(mqtt_topic,40);
custom_deftemp.setValue(String(defTemp).c_str(),6);
custom_enbuff.setValue(String(enBuff).c_str(),6);
custom_ntpServer.setValue(String(ntpServer).c_str(),40);
custom_hostname.setValue(Settings::prefs.hostname,40);
custom_mqtt_server.setValue(Settings::prefs.mqtt_server,40);
custom_mqtt_port.setValue(String(Settings::prefs.mqtt_port).c_str(),6);
custom_mqtt_topic.setValue(Settings::prefs.mqtt_topic,40);
custom_deftemp.setValue(String(Settings::prefs.defTemp).c_str(),6);
custom_enbuff.setValue(String(Settings::prefs.enBuff).c_str(),6);
custom_ntpServer.setValue(String(Settings::prefs.ntpServer).c_str(),40);
wm.setCleanConnect(true);
wm.setConnectRetries(5);
wm.setWiFiAutoReconnect(true);
wm.setMinimumSignalQuality(20);
WiFi.persistent(true);
WiFi.setAutoConnect(true);
WiFi.setAutoReconnect(true);
wm.addParameter(&custom_hostname);
wm.addParameter(&custom_mqtt_server);
wm.addParameter(&custom_mqtt_port);
@@ -129,15 +46,13 @@ void MQTT::begin(){
wm.addParameter(&custom_enbuff);
wm.addParameter(&custom_ntpServer);
psclient.setClient(client);
psclient.setServer(mqtt_server,mqtt_port);
psclient.setServer(Settings::prefs.mqtt_server,Settings::prefs.mqtt_port);
WiFi.setHostname(custom_hostname.getValue()); //define hostname
wm.setConfigPortalBlocking(false);
if(wm.autoConnect("AutoConnectAP")){
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
strcpy(myIP,WiFi.localIP().toString().c_str());
strcpy(glblData.myIP,WiFi.localIP().toString().c_str());
wm.setHttpPort(8080);
wm.startWebPortal();
wifiConnected = true;
@@ -148,7 +63,10 @@ void MQTT::begin(){
Serial.println("non blocking config portal running on Port 80");
}
if(wifiConnected){
ArduinoOTA.setHostname(hostname);
setenv("TZ", TZ_INFO, 1); // Zeitzone muss nach dem reset neu eingestellt werden
tzset();
configTzTime(TZ_INFO, Settings::prefs.ntpServer); // ESP32 Systemzeit mit NTP Synchronisieren
ArduinoOTA.setHostname(Settings::prefs.hostname);
ArduinoOTA
.onStart([]() {
String type;
@@ -176,16 +94,16 @@ void MQTT::begin(){
});
ArduinoOTA.begin();
// This is not the safest way to reset the webserver, it can cause crashes on callbacks initilized before this and since its a shared pointer...
// @todo add a new callback maybe, after webserver started, callback cannot override handlers, but can grab them first
/* Setup httpd callbacks, web pages: root, wifi config pages, SO captive portal detectors and not found. */
// G macro workaround for Uri() bug https://github.com/esp8266/Arduino/issues/7102
server.on("/", MQTT::serveData);
server.on("/override", MQTT::serveOverride);
server.on("/data", MQTT::serveData);
server.begin();
server->on("/", MQTT::serveData);
server->on("/override", MQTT::serveOverride);
server->on("/data", MQTT::serveData);
server->begin();
if (MDNS.begin(Settings::prefs.hostname)) {
Serial.println("mDNS responder started");
// Add service to MDNS-SD
MDNS.addService(MDNS_SERVICENAME, "tcp", 80);
MDNS.addService("http", "tcp", 80);
}
reconnect();
}
}
@@ -195,37 +113,26 @@ void MQTT::saveConfigCallback(void){
}
void MQTT::saveConfigToFlash(void){
strcpy(mqtt_server,custom_mqtt_server.getValue());
mqtt_port = atoi(custom_mqtt_port.getValue());
strcpy(hostname,custom_hostname.getValue());
strcpy(mqtt_topic,custom_mqtt_topic.getValue());
strcpy(ntpServer,custom_ntpServer.getValue());
defTemp = atof(custom_deftemp.getValue());
strcpy(Settings::prefs.mqtt_server,custom_mqtt_server.getValue());
Settings::prefs.mqtt_port = atoi(custom_mqtt_port.getValue());
strcpy(Settings::prefs.hostname,custom_hostname.getValue());
strcpy(Settings::prefs.mqtt_topic,custom_mqtt_topic.getValue());
strcpy(Settings::prefs.ntpServer,custom_ntpServer.getValue());
Settings::prefs.defTemp = atof(custom_deftemp.getValue());
if(custom_enbuff.getValue() != "0"){
enBuff = true;
Settings::prefs.enBuff = true;
}else{
Settings::prefs.enBuff = false;
}
glblData.enBuff = enBuff;
prefs.begin("settings");
prefs.putString("HOST",hostname);
prefs.putString("MQTT_SERVER",mqtt_server);
prefs.putInt("MQTT_PORT",mqtt_port);
prefs.putString("MQTT_TOPIC",mqtt_topic);
prefs.putFloat("DEF_TMP",defTemp);
prefs.putBool("EN_OVR",enBuff);
prefs.putString("NTP_SERVER",ntpServer);
prefs.end();
Settings::getInstance().saveSettings(); // Save dataset to persistent storage
}
void MQTT::reconnect(void) {
// Loop until we're reconnected
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (psclient.connect(hostname)) {
if (psclient.connect(Settings::prefs.hostname)) {
Serial.println("connected");
// Subscribe
if(strlen(mqtt_topic)>1)
psclient.subscribe(mqtt_topic);
} else {
Serial.print("failed, rc=");
Serial.print(psclient.state());
@@ -233,32 +140,67 @@ void MQTT::reconnect(void) {
}
void MQTT::loop(void){
static uint32_t resetCnt = 0;
unsigned long now = millis();
if(now-lastStatusUpdate > 15000){ //update wifi status every 15secs.
lastStatusUpdate = now;
if(WiFi.isConnected()){
resetCnt = 0;
if(WiFi.getMode() == WIFI_MODE_STA){
glblData.wifiMode = WIFIMODE_STA;
}else{
glblData.wifiMode = WIFIMODE_AP;
}
int32_t rssi = WiFi.RSSI();
if(rssi > -55){
update_wifi_strength(WIFI_STRENGTH_HIGH);
glblData.wifiStrength = WIFISTRENGTH_HIGH;
}else if(rssi > -75){
update_wifi_strength(WIFI_STRENGTH_MED);
glblData.wifiStrength = WIFISTRENGTH_MED;
}else if(rssi > -90){
update_wifi_strength(WIFI_STRENGTH_LOW);
glblData.wifiStrength = WIFISTRENGTH_LOW;
}else{
update_wifi_strength(WIFI_STRENGTH_OFF);
glblData.wifiStrength = WIFISTRENGTH_OFF;
}
if(!psclient.connected()){
update_wifi_strength(WIFI_STRENGTH_ERROR);
glblData.wifiStrength = WIFISTRENGTH_ERROR;
if(now-lastReconnectTry > 60000){
lastReconnectTry = now;
reconnect();
}
}
}else if(WiFi.getMode() == WIFI_MODE_STA){
resetCnt = 0;
glblData.wifiStrength = WIFISTRENGTH_OFF;
WiFi.disconnect(true);
delay(200);
WiFi.enableSTA(true);
wm.connectWifi("", "", true);
}else{
update_wifi_strength(WIFI_STRENGTH_OFF);
if(wm.getWiFiIsSaved()){
resetCnt++;
if(resetCnt > 5*5){
Serial.println("Resetting WiFi AP...");
ESP.restart();
}
}
glblData.wifiMode = WIFIMODE_AP;
switch(glblData.wifiStrength){
case WIFISTRENGTH_HIGH:
glblData.wifiStrength = WIFISTRENGTH_LOW;
break;
case WIFISTRENGTH_MED:
glblData.wifiStrength = WIFISTRENGTH_HIGH;
break;
case WIFISTRENGTH_LOW:
glblData.wifiStrength = WIFISTRENGTH_MED;
break;
default:
glblData.wifiStrength = WIFISTRENGTH_LOW;
break;
}
}
}
server.handleClient();
psclient.loop();
ArduinoOTA.handle();
wm.process();
@@ -271,35 +213,178 @@ void MQTT::loop(void){
}
}
char* MQTT::getMqttServer(void){
return mqtt_server;
}
uint16_t MQTT::getMqttPort(void){
return mqtt_port;
}
char* MQTT::getHostname(void){
return hostname;
}
char* MQTT::getMqttTopic(void){
return mqtt_topic;
}
char* MQTT::getMyIP(void){
return myIP;
}
void MQTT::publish(const char* msg){
psclient.publish(mqtt_topic,msg);
psclient.publish(Settings::prefs.mqtt_topic,msg);
}
void MQTT::publish(const char* msg, unsigned int len){
psclient.publish(mqtt_topic,msg,len);
psclient.publish(Settings::prefs.mqtt_topic,msg,len);
}
void MQTT::publish(const char* msg, bool retained){
psclient.publish(mqtt_topic,msg,retained);
psclient.publish(Settings::prefs.mqtt_topic,msg,retained);
}
void MQTT::publish_sub(const char* subtopic, const char* msg, bool retained){
char newtopic[60];
strcpy(newtopic,mqtt_topic);
strcpy(newtopic,Settings::prefs.mqtt_topic);
strcat(newtopic,"/");
strcat(newtopic,subtopic);
psclient.publish(newtopic,msg, retained);
}
}
/*
void MQTT::handleWebSocketMessage(void *arg, uint8_t *data, size_t len){
data[len] = 0; //ensure termination!
Serial.printf("WebSocket Msg '%s'\n", data);
}
void MQTT::handleWebSocket(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
switch (type) {
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
client->text(makeStatusJSON());
client->text(makeTimerJSON());
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
break;
case WS_EVT_DATA:
handleWebSocketMessage(arg, data, len);
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
}
}
*/
void MQTT::serveOverride(AsyncWebServerRequest *request){
String sending;
sending = "{";
if(Settings::prefs.enBuff){
if(request->hasParam("sw")){
int ovr = request->getParam("valve")->value().toInt();
if(ovr == 1){
glblData.override = OVR_ALWAYSON;
sending = "{\"Status\": \"Success\", ";
}else if(ovr == 0){
glblData.override = OVR_ALWAYSOFF;
sending = "{\"Status\": \"Success\", ";
}else{
glblData.override = OVR_NONE;
sending = "{\"Status\": \"Success\", ";
}
}
}else{
sending = "{\"Status\": \"Not Enabled\", ";
glblData.override = OVR_NONE;
}
switch(glblData.override){
case OVR_ALWAYSOFF:
sending += "\"Override\": \"Always OFF\"}";
break;
case OVR_ALWAYSON:
sending += "\"Override\": \"Always ON\"}";
break;
case OVR_NONE:
sending += "\"Override\": \"NONE\"}";
break;
}
request->send(404, "text/plain", sending);
}
void MQTT::serveData(AsyncWebServerRequest *request){
String sending;
sending = "{\"Temp[degC]\": ";
sending += glblData.temp;
sending += ", \"pressure[hPa]\": ";
sending += glblData.seaLevelPress;
sending += ", \"rHum[%]\": ";
sending += glblData.hum;
sending += ", \"Heating\": ";
sending += glblData.heating;
sending += ", \"Set Temp[degC]\": ";
sending += glblData.settemp;
sending += " }";
Serial.println("Sending website...");
request->send(200, FPSTR(HTTP_HEAD_JSON), sending);
Serial.println("Sent website...");
}
void MQTT::sendStatus(void){
tm timeinfo;
char buffer[35];
publish_sub("hostname", Settings::prefs.hostname, true);
publish_sub("IP", glblData.myIP, true);
publish_sub("NTP-Server", Settings::prefs.ntpServer, true);
if(!getLocalTime(&timeinfo)){
strcpy(buffer, "00-00-0000T00:00:00+0000");
}else{
strftime(buffer, sizeof(buffer), "%FT%T%z", &timeinfo);
}
publish_sub("timestamp",buffer,true);
snprintf(buffer, sizeof buffer, "%0.1f", glblData.temp);
publish_sub("Temp[degC]",buffer,true);
snprintf(buffer, sizeof buffer, "%0.0f", glblData.seaLevelPress);
publish_sub("pressure[hPa]",buffer,true);
snprintf(buffer, sizeof buffer, "%0.0f", glblData.hum);
publish_sub("rHum[%]",buffer,true);
snprintf(buffer, sizeof buffer, "%s", glblData.heating?"true":"false");
publish_sub("Heating",buffer,true);
snprintf(buffer, sizeof buffer, "%0.1f", glblData.settemp);
publish_sub("Set Temp[degC]",buffer,true);
snprintf(buffer, sizeof buffer, "%d", WiFi.RSSI());
publish_sub("RSSI [dBm]",buffer,true);
}
void MQTT::remoteLog(const char* str, int32_t num){
udp.beginPacket(Settings::prefs.mqtt_server,13377);
struct tm timeinfo;
getLocalTime(&timeinfo);
udp.printf("<13>%s %02d %02d:%02d:%02d %s Log: %s %d",months[timeinfo.tm_mon],timeinfo.tm_mday,timeinfo.tm_hour,timeinfo.tm_min,timeinfo.tm_sec,Settings::prefs.hostname,str,num);
udp.endPacket();
}
void MQTT::remoteLog(const char* str){
udp.beginPacket(Settings::prefs.mqtt_server,13377);
struct tm timeinfo;
getLocalTime(&timeinfo);
udp.printf("<13>%s %02d %02d:%02d:%02d %s Log: %s",months[timeinfo.tm_mon],timeinfo.tm_mday,timeinfo.tm_hour,timeinfo.tm_min,timeinfo.tm_sec,Settings::prefs.hostname,str);
udp.endPacket();
}
void MQTT::remoteLog(const char* str,const char* str2){
udp.beginPacket(Settings::prefs.mqtt_server,13377);
struct tm timeinfo;
getLocalTime(&timeinfo);
udp.printf("<13>%s %02d %02d:%02d:%02d %s Log: %s %s",months[timeinfo.tm_mon],timeinfo.tm_mday,timeinfo.tm_hour,timeinfo.tm_min,timeinfo.tm_sec,Settings::prefs.hostname,str,str2);
udp.endPacket();
}
void MQTT::remoteLogf(const char* format, ...){
udp.beginPacket(Settings::prefs.mqtt_server,13377);
struct tm timeinfo;
getLocalTime(&timeinfo);
char loc_buf[256];
char * temp = loc_buf;
va_list arg;
va_start(arg, format);
int len = snprintf(temp, sizeof(loc_buf), "<13>%s %02d %02d:%02d:%02d %s Log: ", months[timeinfo.tm_mon],timeinfo.tm_mday,timeinfo.tm_hour,timeinfo.tm_min,timeinfo.tm_sec,Settings::prefs.hostname);
if(len < (int)sizeof(loc_buf)){
len += vsnprintf(temp+len, sizeof(loc_buf)-len, format, arg);
}
va_end(arg);
if(len >= (int)sizeof(loc_buf)){ // comparation of same sign type for the compiler
udp.write((uint8_t*)temp, len);
udp.print("...Memory issue at log buffer!");
udp.endPacket();
return;
}
udp.write((uint8_t*)temp, len);
udp.endPacket();
return;
}
+33 -17
View File
@@ -1,18 +1,22 @@
#ifndef __MQTT_H_
#define __MQTT_H_
#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <Preferences.h>
#include <WiFiManager.h>
#include <WiFiClient.h>
#include <ArduinoOTA.h>
#include <ui/vars.h>
#include <MQTT.h>
#include "ui/actions.h"
#include <WebServer.h>
#include <ESPAsyncWebServer.h>
#include <settings.h>
#include <ArduinoJson.h>
#include <SPIFFS.h>
#include <ESPmDNS.h>
#include <time.h>
#define NTP_SERVER "pool.ntp.org"
#define TZ_INFO "WEST-1DWEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" // Western European Time
const char HTTP_HEAD_JSON[] PROGMEM = "text/json";
@@ -20,6 +24,7 @@ const char HTTP_HEAD_JSON[] PROGMEM = "text/json";
class MQTT: public PubSubClient{
public:
bool wifiConnected = false;
static bool saveConfigFlag;
MQTT(void);
@@ -28,6 +33,7 @@ public:
WiFiClient client;
Preferences prefs;
WiFiManager wm;
static WiFiUDP udp;
void sendStatus(void);
char* getMqttServer(void);
uint16_t getMqttPort(void);
@@ -37,27 +43,37 @@ public:
void begin();
void loop(void);
void publish(const char* msg);
void publish(String msg);
void publish(const char* msg, unsigned int len);
void publish(const char* msg, bool retained);
void publish(const char* msg, unsigned int len, bool retained);
void publish_sub(const char* subtopic, const char* msg, bool retained=false);
void publish_sub(const char* subtopic, const char* msg, bool retained = false);
static void remoteLog(const char* str,const char* str2);
static void remoteLog(const char* str);
static void remoteLog(const char* str, int32_t num);
static void remoteLogf(const char* format, ...);
private:
static void serveData(void);
static void serveOverride(void);
char myIP[16] = "0.0.0.0";
static constexpr char wifiInitialApPassword[] = "manage";
char mqtt_server[40] = "nas.local";
int mqtt_port = 1883;
float defTemp = 0.0;
bool enBuff = false;
static char ntpServer[40];
char hostname[40] = "TMP_WoZi-EG";
char mqtt_topic[40] = "Raumtemp/EG/Wohnzimmer";
static const char* months[];
static void serveData(AsyncWebServerRequest *request);
//static void serveIndex(AsyncWebServerRequest *request);
//static void serveCss(AsyncWebServerRequest *request);
static void serveOverride(AsyncWebServerRequest *request);
//static void serveSetValve(AsyncWebServerRequest *request);
// static void handleWebSocket(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
// static void handleWebSocketMessage(void *arg, uint8_t *data, size_t len);
static String processor(const String& var);
static String makeStatusJSON(void);
static String makeTimerJSON(void);
void sendMQTTstatus(void);
void saveConfigToFlash(void);
static void saveConfigCallback(void);
unsigned long lastReconnectTry{0};
unsigned long lastStatusUpdate{0};
static WebServer server;
unsigned long lastWSupdate{0};
static AsyncWebServer* server;
static AsyncWebSocket* ws;
static constexpr char wifiInitialApPassword[] = "12345678";
};
#endif
+2 -2
View File
@@ -497,7 +497,7 @@
#define LV_FONT_MONTSERRAT_36 0
#define LV_FONT_MONTSERRAT_38 1
#define LV_FONT_MONTSERRAT_40 0
#define LV_FONT_MONTSERRAT_42 1
#define LV_FONT_MONTSERRAT_42 0
#define LV_FONT_MONTSERRAT_44 0
#define LV_FONT_MONTSERRAT_46 0
#define LV_FONT_MONTSERRAT_48 0
@@ -1073,7 +1073,7 @@
*==================*/
/*Enable the examples to be built with the library*/
#define LV_BUILD_EXAMPLES 1
#define LV_BUILD_EXAMPLES 0
/*===================
* DEMO USAGE
+18 -12
View File
@@ -16,6 +16,7 @@
#include <Ticker.h>
#include <PubSubClient.h>
#include "MQTT.h"
#include <tahoma.h>
#define MEASINT_S 1
@@ -25,6 +26,7 @@
MQTT mqtt;
Ticker measurementTick;
Tahoma tahoma("1215-2900-8489.local","67ebd23e3a61763386d9");
unsigned char ChipID = 0x00;
volatile bool TouchEventFlag = false;
@@ -69,7 +71,7 @@ void measure(void){ //update temp every 30secs
//bme.setSettings(settings);
temp = temp - 1.0; //adjust temp to compensate head dissipation of ESP
seaLevelPress = EnvironmentCalculations::EquivalentSeaLevelPressure(barometerAltitude, temp, pres, EnvironmentCalculations::AltitudeUnit_Meters, EnvironmentCalculations::TempUnit_Celsius);
if(history_isInitialized() && old_pres - pres > 0.1){
/*if(history_isInitialized() && old_pres - pres > 0.1){
if(++dropCNT > 1){ //pressure drop at leaast 2 secs
old_pres = pres;
presAlarm = true;
@@ -78,7 +80,7 @@ void measure(void){ //update temp every 30secs
old_pres = pres;
dropCNT = 0;
presAlarm = false;
}
}*/
if(screen_update_cnt == 30 || presAlarm){ //update every 30 secs
newMeasurement = true;
screen_update_cnt = 0;
@@ -93,20 +95,18 @@ void measure(void){ //update temp every 30secs
}
/* 定义LVGL的分辨率等参数 */
void setup(void)
{
DisplayInit();
pinMode(PIN_REL,OUTPUT);
Serial.begin(115200);
lv_init();
//WiFi.setSleep(WIFI_PS_MIN_MODEM);
WiFi.setSleep(WIFI_PS_MIN_MODEM);
lv_log_register_print_cb(log_print);
TouchInit();
bme.begin();
lv_display_t * disp = lv_display_create(SCREEN_WIDTH, SCREEN_HEIGHT);
lv_display_set_buffers(disp,draw_buf, NULL, sizeof(draw_buf),LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_0);
@@ -115,19 +115,19 @@ void setup(void)
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, my_touch_read);
ui_init();
setBacklight(BL_BRIGHTNESS);
ledcAttachPin(PIN_REL, PWM_REL);
ledcSetup(PWM_REL, 100000, 8);
ledcWrite(PWM_REL, 0);
setBacklight(BL_BRIGHTNESS,300);
measurementTick.attach(MEASINT_S,measure);
mqtt.begin();
lv_label_set_text_fmt(objects.debugTxt, "IP:\n %s\n\nHostname:\n %s\n\nMqtt-Server:\n %s\n\nMqtt-Port:\n %d\n\nMqtt-Topic:\n %d\n\n",mqtt.getMyIP(),mqtt.getHostname(),mqtt.getMqttServer(),mqtt.getMqttPort(), mqtt.getMqttTopic());
lv_label_set_text_fmt(objects.debugTxt, "IP:\n %s\n\nHostname:\n %s\n\nMqtt-Server:\n %s\n\nMqtt-Port:\n %d\n\nMqtt-Topic:\n %s\n\nHeatBuffer:\n %d",glblData.myIP,Settings::prefs.hostname,Settings::prefs.mqtt_server,Settings::prefs.mqtt_port, Settings::prefs.mqtt_topic,glblData.enBuff);
measure();
}
unsigned long lastms = millis();
unsigned long lastTick = 0;
unsigned long secondsTick = 0, minutesTick = 0;
uint8_t statusCnt=0;
uint16_t tickCounter = 0;
void loop()
{
if(newMeasurement){
@@ -140,6 +140,12 @@ void loop()
chart_autoscale();
lv_chart_refresh(objects.chart);
}
if(millis() - minutesTick > 10000){
minutesTick = millis();
if(mqtt.wifiConnected){
update_wifi_strength(glblData.wifiStrength,glblData.wifiMode);
}
}
mqtt.loop();
ui_tick();
if(!ui_isSleeping()){
+60
View File
@@ -0,0 +1,60 @@
#include "settings.h"
Settings::preferences_t Settings::Settings::prefs;
// Singleton instance
Settings& Settings::getInstance() {
static Settings instance;
return instance;
}
// Constructor
Settings::Settings() {
loadSettings(); // Load dataset from persistent storage
// Initialize default values for the dataset
}
// Destructor
Settings::~Settings() {
}
// Save the current dataset to persistent storage
void Settings::saveSettings() {
preferences.begin("settings", false); // Open preferences in read-write mode
preferences.putFloat("deftemp", prefs.defTemp);
preferences.putBool("enBuff", prefs.enBuff);
glblData.enBuff = prefs.enBuff;
preferences.putString("hostname", prefs.hostname);
preferences.putString("mqtt_server", prefs.mqtt_server);
preferences.putString("mqtt_topic", prefs.mqtt_topic);
preferences.putString("ntpServer", prefs.ntpServer);
preferences.putInt("mqtt_port", prefs.mqtt_port);
preferences.putBool("relPowerSave", glblData.relPowerSave);
preferences.end();
}
// Load the dataset from persistent storage
void Settings::loadSettings() {
preferences.begin("settings", true); // Open preferences in read mode
prefs.defTemp = preferences.getFloat("deftemp", 22.0f);
glblData.settemp = prefs.defTemp;
prefs.enBuff = preferences.getBool("enBuff", false);
glblData.enBuff = prefs.enBuff;
strncpy(prefs.hostname, preferences.getString("hostname", "TMP-EG-WoZi").c_str(), sizeof(prefs.hostname) - 1);
prefs.hostname[sizeof(prefs.hostname) - 1] = '\0'; // Ensure null-termination
strncpy(prefs.mqtt_server, preferences.getString("mqtt_server", "nas.local").c_str(), sizeof(prefs.mqtt_server) - 1);
prefs.mqtt_server[sizeof(prefs.mqtt_server) - 1] = '\0'; // Ensure null-termination
strncpy(prefs.mqtt_topic, preferences.getString("mqtt_topic", "Raumtemp/EG/Wohnzimmer").c_str(), sizeof(prefs.mqtt_topic) - 1);
prefs.mqtt_topic[sizeof(prefs.mqtt_topic) - 1] = '\0'; // Ensure null-termination
strncpy(prefs.ntpServer, preferences.getString("ntpServer", "nas.local").c_str(), sizeof(prefs.ntpServer) - 1);
prefs.ntpServer[sizeof(prefs.ntpServer) - 1] = '\0'; // Ensure null-termination
prefs.mqtt_port = preferences.getInt("mqtt_port", 1883);
glblData.relPowerSave = preferences.getBool("relPowerSave", true);
preferences.end();
}
Settings::preferences_t& Settings::getPrefs(void) {
return prefs;
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef SETTINGS_H
#define SETTINGS_H
#include <Preferences.h>
#include <ui/vars.h>
class Settings {
public:
typedef struct preferences_s {
float defTemp;
bool enBuff;
char hostname[40];
char mqtt_server[40];
char mqtt_topic[40];
char ntpServer[40];
int mqtt_port;
} preferences_t;
static Settings& getInstance(void);
void saveSettings(void);
void loadSettings(void);
preferences_t& getPrefs(void);
static preferences_t prefs;
private:
Settings();
~Settings();
Preferences preferences;
};
#endif // SETTINGS_H
+121
View File
@@ -0,0 +1,121 @@
#include "tahoma.h"
const char* rootCACertificate = "-----BEGIN CERTIFICATE-----\n"\
"MIIDUTCCAjmgAwIBAgIBBDANBgkqhkiG9w0BAQsFADBLMRAwDgYDVQQKEwdPdmVy\n"\
"a2l6MRAwDgYDVQQLEwdSb290IENBMRgwFgYDVQQDEw9PdmVya2l6IFJvb3QgQ0Ex\n"\
"CzAJBgNVBAYTAkZSMB4XDTE2MDQyNzEyNTgxN1oXDTM2MDQyMjEyNTgxN1owZTEL\n"\
"MAkGA1UEBhMCRlIxEDAOBgNVBAoTB092ZXJraXoxITAfBgNVBAsTGE92ZXJraXog\n"\
"RGV2aWNlIFNlcnZlciBDQTEhMB8GA1UEAxMYT3ZlcmtpeiBEZXZpY2UgU2VydmVy\n"\
"IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzr/hwPW3ykSV+Rv/\n"\
"u+i1It8gq6aX4yLAP5vdrhzHGFrsNAhbviVe2SajBejfbuWTs0AvA03yHDsRhvlO\n"\
"rKUXFg2ZekipgkI+yqii6bmk3Qsqp/DNCoogp+Rg0qFivT4DGxmKio1cPU4i2mXc\n"\
"yIkSTR4bDUbhrFT+6ahEoYjcwvPaRxGUUobIpqJXDexPMzBSvy6/dLBay0Q1RMQ8\n"\
"LSyLtc/Zl1HkNTgSen9tHoq4A0JMeheLW47/HKgMYeQkeIsjzCKduLhZea893EYY\n"\
"tPS/EUlNfK0YiYbI4UIdNvJ6N0iu85KDreytFT7XAVnZSAbmLXuqtQC0U7EM7jEq\n"\
"uepAuwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIB\n"\
"BjANBgkqhkiG9w0BAQsFAAOCAQEAkxcJ80vpnS4VyBQMLbvmncg06b65tlCndSJm\n"\
"MXMS6rwdAhUs84Gqu6H/vN3k1ix4iYty/n7MPfyYOznidMANayXurf0YMdIDagoE\n"\
"Gv2QVOl63Oe7xhKbcdAgejDAewyXbC8+cZj156itUSQZjmNdZ/59pt7lMkV6YDR2\n"\
"pOPnPjqG16TQ7ju2iYonhoHPd/iWs7iKcBs8/eaMYxcpqQDbX+O6hN5qPcTBfGRB\n"\
"TFqwgSu0abNIZ3IJuSUGxkoPcIxNWLTxnwCgUN+TQTrg6rWw8T7GtSzKBljVk09R\n"\
"9YmKHPhUN7wjNRzWiecfomTi3FTgYbrzbwCSTj3FAogCxuHAwA==\n"\
"-----END CERTIFICATE-----\n";
Tahoma::Tahoma(const String _hostname, const String _token) : connected(false) {
hostname = _hostname;
token = _token;
}
// Destructor
Tahoma::~Tahoma() {
}
String url_encode(const String &value) {
String escaped;
for (uint16_t i = 0; i < value.length(); i++) {
char c = value.charAt(i);
// Keep alphanumeric and other accepted characters intact
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
escaped += c;
continue;
}else{
// Any other characters are percent-encoded
if(c < 0x10){
escaped += "%0" + String(c, HEX);
}else{
escaped += '%' + String(c, HEX);
}
}
}
return escaped;
}
String Tahoma::getDeviceName(const String _url)
{
//String url = "/enduser-mobile-web/1/enduserAPI/apiVersion"; // Construct the URL to fetch the device name
HTTPClient http; // Create an HTTP client object
String url = "/enduser-mobile-web/1/enduserAPI/setup/devices/" + url_encode(_url) + "/states/core:NameState"; // Construct the URL to fetch the device name
String deviceName;
http.begin("1215-2900-8489.local",8443,url,rootCACertificate); // Initialize the HTTP connection
http.addHeader("Authorization", "Bearer " + token); // Add the authorization header with the token
int httpCode = http.GET(); // Send the GET request and get the response code
if (httpCode > 0) { // Check if the request was successful
JsonDocument doc; // Create a JSON document to parse the response
String response = http.getString(); // Get the response as a string
deserializeJson(doc,response); // Deserialize the JSON response
Serial.println(response); // Print the response to the serial monitor for debugging
if (doc["value"].isNull()) { // Check if the value is null
Serial.println("Device not found"); // Print error message if the device is not found
}else{
deviceName = doc["value"].as<String>(); // Get the device name from the JSON response
Serial.println("Device Name: " + deviceName); // Print the device name to the serial monitor
}
} else {
Serial.print("Error on HTTP request:"); // Print error message if the request failed
Serial.println(httpCode); // Print the error code
Serial.print("Error message: "); // Print error message
Serial.println(http.errorToString(httpCode)); // Print the error code
Serial.println(url); // Print the URL for debugging
}
http.end(); // Close the HTTP connection
return deviceName; // Return the device name
}
void Tahoma::getAllDevices(void){
HTTPClient http; // Create an HTTP client object
String url = "/enduser-mobile-web/1/enduserAPI/setup/devices/controllables/io%3AExteriorVenetianBlindIOComponent"; // Construct the URL to fetch all devices
http.begin("1215-2900-8489.local",8443,url,rootCACertificate); // Initialize the HTTP connection
http.addHeader("Authorization", "Bearer " + token); // Add the authorization header with the token
int httpCode = http.GET(); // Send the GET request and get the response code
if (httpCode > 0) { // Check if the request was successful
JsonDocument doc; // Create a JSON document to parse the response
String response = http.getString(); // Get the response as a string
deserializeJson(doc,response); // Deserialize the JSON response
if(doc.size() > 0){ // Check if the JSON document is not empty
for (int i = 0; i < doc.size(); i++) { // Loop through the JSON array
devicelist[i].url = doc[i].as<String>(); // Get the device URL from the JSON response
Serial.println("Device URL: " + devicelist[i].url); // Print the device URL to the serial monitor
}
}
} else {
Serial.print("Error on HTTP request:"); // Print error message if the request failed
Serial.println(httpCode); // Print the error code
Serial.print("Error message: "); // Print error message
Serial.println(http.errorToString(httpCode)); // Print the error code
}
http.end(); // Close the HTTP connection
}
void Tahoma::getAllDeviceNames(void){
for (int i = 0; i < MAX_NUM_DEVICES; i++) { // Loop through the JSON array
if(devicelist[i].url == ""){ // Check if the device URL is empty
break; // Break the loop if the device URL is empty
}
devicelist[i].name = getDeviceName(devicelist[i].url); // Get the device name using the device URL
}
}
+39
View File
@@ -0,0 +1,39 @@
#ifndef TAHOMA_H
#define TAHOMA_H
#include <Arduino.h>
#include <WiFi.h>
#include <iostream>
#include <base64.h>
#include <HTTPClient.h>
#include <ArduinoJson.h> // Include the ArduinoJson library for JSON parsing
#include <ESPAsyncWebserver.h>
#include <WiFiClientSecure.h>
#define MAX_NUM_DEVICES 32 // Maximum number of devices to fetch
class Tahoma {
public:
typedef struct {
String name; // Device name
String url; // Device URL
} device_t;
// Constructor with hostname and token
// Initializes the Tahoma object with the provided hostname and token
Tahoma(const String hostname, const String token);
// Destructor
~Tahoma();
void getAllDevices(void); // Fetches the device name from the Tahoma system
String getDeviceName(const String _url); // Fetches the device name from the Tahoma system
void getAllDeviceNames(void); // Fetches all device names from the Tahoma system
private:
device_t devicelist[MAX_NUM_DEVICES];
String hostname; // Hostname of the Tahoma system
String token; // Authentication token for the Tahoma system
bool connected; // Connection status
// Simulate fetching data from the Tahoma system
void fetchData();
};
#endif // TAHOMA_H
+36 -32
View File
@@ -1,11 +1,10 @@
#include <Arduino.h>
#include "actions.h"
#include "vars.h"
#include "ui.h"
bool arc_pressed = false;
bool animating = false;
dataset_t glblData = {.temp = NAN, .hum = NAN, .pres = NAN, .seaLevelPress = NAN, .settemp= NAN, .heating=false, .enBuff =false, .presAlarm=false, .override=OVR_NONE};
float curr_temp = 0.0;
int32_t scale_max = 0, scale_min = 0, lastSelChartValue = 0;
lv_point_t lastChartPt;
@@ -22,15 +21,14 @@ static void alarm_ani_cb(void * var, int32_t v)
{
if(v > -1 && v < 256){
lv_led_set_brightness(objects.alarmLED, v);
//setBacklight((v<<4) | 0x00FF);
ledcFade(GFX_BL,ledcRead(GFX_BL),(v<<4) | 0x00FF,100);
setBacklight((v<<4) | 0x00FF,100);
}
}
static void alarm_ani_end_cb(lv_anim_t *var)
{
lv_obj_add_flag(objects.alarmLED, LV_OBJ_FLAG_HIDDEN);
setBacklight(BL_BRIGHTNESS);
setBacklight(BL_BRIGHTNESS,250);
lv_led_set_brightness(objects.alarmLED, 0);
}
@@ -40,6 +38,7 @@ void ui_settemp(float tmp){
}
void update_status(void){
static unsigned long fullOnTime = millis();
lv_label_set_text_fmt(objects.press_txt,"%4.2f hPa",glblData.seaLevelPress);
lv_label_set_text_fmt(objects.hum_txt,"%2.0f %%rH",glblData.hum);
if(!arc_pressed && !animating){
@@ -83,10 +82,17 @@ void update_status(void){
break;
}
if(glblData.heating){
digitalWrite(PIN_REL,HIGH);
if(ledcRead(PWM_REL) == 0){
ledcWrite(PWM_REL, 0xff); //turn on relay
fullOnTime = millis();
lv_obj_set_style_text_color(objects.heaterIcn,lv_color_hex(0xFFAA0000),LV_STATE_DEFAULT);
}else if(millis() - fullOnTime > 1000 && glblData.relPowerSave == true){ //if relay is on for more than 1 sec, reduce to 50% if powersave mode is enabled
ledcWrite(PWM_REL, 0x7f); //lower relay to 50%
lv_obj_set_style_text_color(objects.heaterIcn,lv_color_hex(0xFF00AA00),LV_STATE_DEFAULT);
}
lv_obj_remove_flag(objects.heaterIcn, LV_OBJ_FLAG_HIDDEN);
}else{
digitalWrite(PIN_REL,LOW);
ledcWrite(PWM_REL, 0); //turn off relay
lv_obj_add_flag(objects.heaterIcn, LV_OBJ_FLAG_HIDDEN);
}
if(glblData.presAlarm == true){
@@ -105,27 +111,31 @@ void update_status(void){
lv_anim_start(&alarmAni);
ui_exitSleep();
}
}
void update_wifi_strength(wifi_strength_t strength){
void update_wifi_strength(wifistrength_t strength, wifimode_t mode){
if(mode != WIFIMODE_STA){
Serial.println("WiFi mode not STA, not updating icon");
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xFF0000EE),LV_STATE_DEFAULT);
}else{
Serial.println("WiFi mode STA, updating icon");
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xf0f0f0),LV_STATE_DEFAULT);
}
switch(strength){
case WIFI_STRENGTH_HIGH:
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xf0f0f0),LV_STATE_DEFAULT);
case WIFISTRENGTH_HIGH:
lv_label_set_text(objects.wifiIcn,ICON_WIFI_HIGH);
break;
case WIFI_STRENGTH_MED:
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xf0f0f0),LV_STATE_DEFAULT);
case WIFISTRENGTH_MED:
lv_label_set_text(objects.wifiIcn,ICON_WIFI_MED);
break;
case WIFI_STRENGTH_LOW:
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xf0f0f0),LV_STATE_DEFAULT);
case WIFISTRENGTH_LOW:
lv_label_set_text(objects.wifiIcn,ICON_WIFI_LOW);
break;
case WIFI_STRENGTH_OFF:
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xf0f0f0),LV_STATE_DEFAULT);
case WIFISTRENGTH_OFF:
lv_label_set_text(objects.wifiIcn,ICON_WIFI_OFF);
break;
case WIFI_STRENGTH_ERROR:
case WIFISTRENGTH_ERROR:
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xFF0000),LV_STATE_DEFAULT);
lv_label_set_text(objects.wifiIcn,ICON_WIFI_OFF);
break;
@@ -341,9 +351,8 @@ void action_switch_screens(lv_event_t * e){
switch (gestDir){
case LV_DIR_LEFT:
case LV_DIR_RIGHT:
break;
case LV_DIR_TOP:
case LV_DIR_BOTTOM:
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_exec_cb(&a, anim_height_cb);
@@ -355,24 +364,15 @@ void action_switch_screens(lv_event_t * e){
lv_anim_set_values(&a, 0, chartheight);
lv_anim_set_delay(&a, 200);
lv_anim_start(&a);
//if(!arc_pressed){
/*if(ui_getCurrentScreen() == SCREEN_ID_MAIN){
loadChart(CHART_ID_TEMP);
loadScreen(SCREEN_ID_SECOND);
}
else */if(ui_getCurrentChart() == CHART_ID_LEN-1){
loadChart(0);
//loadScreen(SCREEN_ID_MAIN);
if(ui_getCurrentChart() == CHART_ID_LEN-1){
loadChart(1);
}
else{
loadChart(ui_getCurrentChart()+1);
}
//}
lv_indev_wait_release(lv_indev_active());
break;
case LV_DIR_BOTTOM:
case LV_DIR_TOP:
break;
}
}
@@ -385,6 +385,10 @@ void showDebugScreen(lv_event_t * e){
loadScreen(SCREEN_ID_DEBUG);
}
void rebootESP(lv_event_t * e){
ESP.restart();
}
void showMainScreen(lv_event_t * e){
loadScreen(SCREEN_ID_MAIN);
}
+4 -29
View File
@@ -2,39 +2,13 @@
#define EEZ_LVGL_UI_EVENTS_H
#include <lvgl.h>
#include "vars.h"
#include "ui.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PIN_REL 20
typedef enum override_e{
OVR_NONE,
OVR_ALWAYSON,
OVR_ALWAYSOFF
} override_t;
typedef struct dataset_s{
float temp;
float hum;
float pres;
float seaLevelPress;
float settemp;
bool heating;
bool enBuff;
bool presAlarm;
override_t override;
}dataset_t;
typedef enum wifi_strength_e{
WIFI_STRENGTH_OFF,
WIFI_STRENGTH_LOW,
WIFI_STRENGTH_MED,
WIFI_STRENGTH_HIGH,
WIFI_STRENGTH_ERROR
} wifi_strength_t;
void ui_settemp(float tmp);
void action_zoom_set_temp(lv_event_t * e);
@@ -42,11 +16,12 @@ void action_switch_screens(lv_event_t * e);
void showDebugScreen(lv_event_t * e);
void showChartScreen(lv_event_t * e);
void showMainScreen(lv_event_t * e);
void rebootESP(lv_event_t * e);
void action_show_cursors_cb(lv_event_t * e);
void chartDrawingCB(lv_event_t * e);
void update_sensorNstatus(float temp, float hum, float seaLevelPress, bool presAlarm);
void update_status(void);
void update_wifi_strength(wifi_strength_t strength);
void update_wifi_strength(wifistrength_t strength, wifimode_t mode);
void chart_autoscale(void);
extern dataset_t glblData;
void draw_event_cb(lv_event_t* e);
+19 -9
View File
@@ -141,8 +141,8 @@ void create_screen_chart() {
{
lv_obj_t * btn_back = lv_button_create(parent_obj);
lv_obj_remove_style_all(btn_back);
lv_obj_set_size(btn_back, 30, 40);
lv_obj_set_align(btn_back,LV_ALIGN_LEFT_MID);
lv_obj_set_size(btn_back, 40, 40);
lv_obj_align(btn_back,LV_ALIGN_BOTTOM_MID,-30,-10);
lv_obj_add_event_cb(btn_back, showMainScreen, LV_EVENT_RELEASED,NULL);
lv_obj_t * lbl_btn_back = lv_label_create(btn_back);
lv_obj_set_size(lbl_btn_back, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
@@ -151,8 +151,8 @@ void create_screen_chart() {
lv_obj_t * btn_dbg = lv_button_create(parent_obj);
lv_obj_remove_style_all(btn_dbg);
lv_obj_set_size(btn_dbg, 30, 40);
lv_obj_set_align(btn_dbg,LV_ALIGN_RIGHT_MID);
lv_obj_set_size(btn_dbg, 40, 40);
lv_obj_align(btn_dbg,LV_ALIGN_BOTTOM_MID,30,-10);
lv_obj_add_event_cb(btn_dbg, showDebugScreen, LV_EVENT_RELEASED,NULL);
lv_obj_t * lbl_btn_dbg = lv_label_create(btn_dbg);
lv_obj_set_size(lbl_btn_dbg, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
@@ -261,13 +261,23 @@ void create_screen_debug() {
{
lv_obj_t * btn_back = lv_button_create(parent_obj);
lv_obj_remove_style_all(btn_back);
lv_obj_set_size(btn_back, 30, 40);
lv_obj_set_size(btn_back, 40, 40);
lv_obj_set_align(btn_back,LV_ALIGN_LEFT_MID);
lv_obj_add_event_cb(btn_back, showMainScreen, LV_EVENT_RELEASED,NULL);
lv_obj_t * lbl_btn_back = lv_label_create(btn_back);
lv_obj_set_size(lbl_btn_back, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_center(lbl_btn_back);
lv_label_set_text(lbl_btn_back,LV_SYMBOL_HOME);
lv_obj_t * lbl_btn = lv_label_create(btn_back);
lv_obj_set_size(lbl_btn, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_center(lbl_btn);
lv_label_set_text(lbl_btn,LV_SYMBOL_HOME);
lv_obj_t * btn_reboot = lv_button_create(parent_obj);
lv_obj_remove_style_all(btn_reboot);
lv_obj_set_size(btn_reboot, 40, 40);
lv_obj_set_align(btn_reboot,LV_ALIGN_RIGHT_MID);
lv_obj_add_event_cb(btn_reboot, rebootESP, LV_EVENT_RELEASED,NULL);
lbl_btn = lv_label_create(btn_reboot);
lv_obj_set_size(lbl_btn, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_center(lbl_btn);
lv_obj_set_style_text_font(lbl_btn, &Bootstrap_Icons_16, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_label_set_text(lbl_btn,ICON_POWER);
/*Create a container*/
lv_obj_t * main_cont = lv_obj_create(parent_obj);
lv_obj_set_size(main_cont, 170, 170);
+31 -10
View File
@@ -11,8 +11,8 @@
Arduino_DataBus *bus = new Arduino_ESP32SPI(3 /* DC */, 5 /* CS */, 2 /* SCK */, 4 /* MOSI */, -1 /* MISO */, FSPI /* spi_num */);
Arduino_GC9A01 *gfx = new Arduino_GC9A01(bus, 0 /* RST */, 2 /* rotation */, true /* IPS */);
uint16_t brightness = 0, brightness_new = 0;
TouchDrvCSTXXX touch;
Ticker fadeTicker;
bool isPressed = false,sleeping=false;
unsigned long lastTouch;
static int16_t currentScreen = -1;
@@ -31,9 +31,34 @@ void loadScreen(ScreensEnum screenId) {
lv_scr_load_anim(screen, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, false);
}
void fadeBrightness(uint16_t _newBrightness) {
uint16_t bright = ledcRead(GFX_BL);
if (_newBrightness > bright) {
bright += 10;
} else if (_newBrightness < bright) {
bright -= 10;
}
ledcWrite(GFX_BL, bright);
if (_newBrightness == bright) {
fadeTicker.detach();
}
}
void setBacklight(uint16_t brightness, uint16_t fadeTime){
if(brightness > BL_BRIGHTNESS)
brightness = BL_BRIGHTNESS;
ledcWrite(GFX_BL,brightness);
/* uint16_t fadeTickTime = fadeTime/(abs(brightness - (uint16_t)ledcRead(GFX_BL))/10);
if(fadeTickTime < 1)
fadeTickTime = 1;
fadeTicker.detach();
fadeTicker.attach_ms(fadeTickTime, fadeBrightness,brightness);*/
}
void DisplayInit(void){
ledcAttach(GFX_BL, 1000, 12);
ledcAttachPin(GFX_BL, GFX_BL);
ledcSetup(GFX_BL, 2000, 10);
ledcWrite(GFX_BL, 0);
gfx->begin(80000000);
gfx->fillScreen(0x0000);
@@ -116,7 +141,7 @@ void ui_tick() {
void displaySleep(){
gfx->displayOff();
ledcFade(GFX_BL, BL_BRIGHTNESS, 0x000, 300);
setBacklight(0,300);
}
void displayWake(){
@@ -125,7 +150,7 @@ void displayWake(){
delay(10);
lv_obj_invalidate(objects.temp_arc);
lv_task_handler(); // let the GUI do its work
ledcFade(GFX_BL, 0x000, BL_BRIGHTNESS, 300);
setBacklight(BL_BRIGHTNESS,200);
}
@@ -136,9 +161,10 @@ void displayWake(){
delay(30);
digitalWrite(TouchRST, HIGH);
delay(50);
touch.setPins(TouchRST, TouchInt);
Wire.begin(SDA,SCL); //初始化IIC,设置引脚 SCL:22 SDA:21
Wire.setClock(200000); //设置频率400KHZ
touch.setPins(TouchRST, TouchInt);
if(touch.begin(Wire, TouchI2CAddr, SDA, SCL)){
Serial.println("Touch screen initialization done");
}
@@ -197,8 +223,3 @@ void log_print(lv_log_level_t level, const char * buf) {
* Inform LVGL that flushing is complete so buffer can be modified again. */
lv_display_flush_ready(display);
}
void setBacklight(uint16_t _brightness){
ledcFade(GFX_BL,ledcRead(GFX_BL),_brightness,250);
}
+2 -2
View File
@@ -5,7 +5,7 @@
#define SLEEP_TIMEOUT 30000 //sleep display after 30 secs
#define GFX_BL 1
#define BL_BRIGHTNESS 0x3FF
#define BL_BRIGHTNESS 0x1FF
#define TouchInt 8
#define TouchRST 9
@@ -56,7 +56,7 @@ void displayWake();
void TouchInit();
void my_touch_read(lv_indev_t * indev, lv_indev_data_t * data);
void my_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map);
void setBacklight(uint16_t _brightness);
void setBacklight(uint16_t _brightness, uint16_t _fadeTime);
#ifdef __cplusplus
+1
View File
@@ -4,6 +4,7 @@
bool history_initialized = false;
dataset_t glblData = {.temp = NAN, .hum = NAN, .pres = NAN, .seaLevelPress = NAN, .settemp= NAN, .heating=false, .enBuff =false, .relPowerSave=true, .presAlarm=false, .myIP={0}, .wifiStrength = WIFISTRENGTH_OFF, .wifiMode= WIFIMODE_OFF, .override = OVR_NONE};
hist_t history = {{0},{0},{0}};
int32_t* history_getPressPt(void){
+47 -1
View File
@@ -10,8 +10,9 @@ extern "C" {
#define HISTLEN 48*12
#define TMP_HYST 0.5
#define PIN_REL 20
#define PWM_REL 2
extern float temp;
// enum declarations
typedef struct hist_s{
@@ -20,6 +21,51 @@ typedef struct hist_s{
int32_t press[HISTLEN];
} hist_t;
typedef enum override_e{
OVR_NONE,
OVR_ALWAYSON,
OVR_ALWAYSOFF
} override_t;
typedef enum wifistrength_e{
WIFISTRENGTH_OFF,
WIFISTRENGTH_LOW,
WIFISTRENGTH_MED,
WIFISTRENGTH_HIGH,
WIFISTRENGTH_ERROR
} wifistrength_t;
typedef enum wifimode_e{
WIFIMODE_OFF,
WIFIMODE_STA,
WIFIMODE_AP,
WIFIMODE_APSTA
} wifimode_t;
typedef struct dataset_s{
float temp;
float hum;
float pres;
float seaLevelPress;
float settemp;
bool heating;
bool enBuff;
bool relPowerSave;
bool presAlarm;
char myIP[16];
wifistrength_t wifiStrength;
wifimode_t wifiMode;
override_t override;
}dataset_t;
extern dataset_t glblData;
// Native global variables
int32_t* history_getPressPt(void);