try to add tahoma functionality--> RAM overflow -->removed Tahome for now
This commit is contained in:
+252
-167
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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()){
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user