Add outdoor temperature ant time display.

This commit is contained in:
Moirtz Wagner 2025-11-07 23:10:15 +01:00
parent 6d878cc41b
commit bb1eee6cda
11 changed files with 60 additions and 6 deletions

View File

@ -14,8 +14,8 @@ board = seeed_xiao_esp32c3
monitor_speed = 115200 monitor_speed = 115200
framework = arduino framework = arduino
board_build.partitions = min_spiffs.csv board_build.partitions = min_spiffs.csv
;upload_protocol = espota upload_protocol = espota
;upload_port = TMP-EG-Bad.fritz.box upload_port = TMP-EG-WoZi.fritz.box
lib_deps = lib_deps =
moononournation/GFX Library for Arduino@^1.5.3 moononournation/GFX Library for Arduino@^1.5.3
lvgl/lvgl@^9.2.2 lvgl/lvgl@^9.2.2
@ -26,4 +26,4 @@ build_flags =
-D LV_LVGL_H_INCLUDE_SIMPLE -D LV_LVGL_H_INCLUDE_SIMPLE
-I src -I src
;to install on all targets: ;to install on all targets:
;(pio run -t nobuild -t upload --upload-port TMP-EG-WoZi.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-EG-Florian.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-EG-Bad.fritz.box) ;(pio run -t nobuild -t upload --upload-port TMP-EG-WoZi.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-EG-Florian.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-EG-Bad.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-OG-Bad.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-OG-Buero.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-OG-KiZi.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-OGSchlafen.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-OGWoZi.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-UG-Bad.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-UG-Buero.fritz.box) -and (pio run -t nobuild -t upload --upload-port TMP-UG-Kueche.fritz.box)

View File

@ -47,6 +47,7 @@ void MQTT::begin(){
wm.addParameter(&custom_ntpServer); wm.addParameter(&custom_ntpServer);
psclient.setClient(client); psclient.setClient(client);
psclient.setServer(Settings::prefs.mqtt_server,Settings::prefs.mqtt_port); psclient.setServer(Settings::prefs.mqtt_server,Settings::prefs.mqtt_port);
psclient.setCallback(receiveTopic);
WiFi.setHostname(custom_hostname.getValue()); //define hostname WiFi.setHostname(custom_hostname.getValue()); //define hostname
wm.setConfigPortalBlocking(false); wm.setConfigPortalBlocking(false);
if(wm.autoConnect("TempReglerAP")){ if(wm.autoConnect("TempReglerAP")){
@ -127,11 +128,16 @@ void MQTT::saveConfigToFlash(void){
Settings::getInstance().saveSettings(); // Save dataset to persistent storage Settings::getInstance().saveSettings(); // Save dataset to persistent storage
} }
void MQTT::receiveTopic(char* topic, byte* payload, unsigned int length) {
glblData.outTemp = String((char*)payload).toFloat();
}
void MQTT::reconnect(void) { void MQTT::reconnect(void) {
// Loop until we're reconnected // Loop until we're reconnected
Serial.print("Attempting MQTT connection..."); Serial.print("Attempting MQTT connection...");
// Attempt to connect // Attempt to connect
if (psclient.connect(Settings::prefs.hostname)) { if (psclient.connect(Settings::prefs.hostname)) {
psclient.subscribe("weatherStation/tempAmb");
Serial.println("connected"); Serial.println("connected");
} else { } else {

View File

@ -40,6 +40,7 @@ public:
char* getHostname(void); char* getHostname(void);
char* getMqttTopic(void); char* getMqttTopic(void);
char* getMyIP(void); char* getMyIP(void);
static void receiveTopic(char* topic, byte* payload, unsigned int length);
void begin(); void begin();
void loop(void); void loop(void);
void publish(const char* msg); void publish(const char* msg);

View File

@ -153,12 +153,16 @@ void loop()
chart_autoscale(); chart_autoscale();
lv_chart_refresh(objects.chart); lv_chart_refresh(objects.chart);
} }
if(millis() - minutesTick > 10000){ if(millis() - minutesTick > 60000){
minutesTick = millis(); minutesTick = millis();
if(mqtt.wifiConnected){ if(mqtt.wifiConnected){
update_wifi_strength(glblData.wifiStrength,glblData.wifiMode); update_wifi_strength(glblData.wifiStrength,glblData.wifiMode);
} }
} }
if(millis() - secondsTick > 1000){
secondsTick = millis();
update_clockdots();
}
mqtt.loop(); mqtt.loop();
ui_tick(); ui_tick();
if(!ui_isSleeping()){ if(!ui_isSleeping()){

View File

@ -465,7 +465,8 @@ lv_font_t Bootstrap_Icons_18 = {
#endif #endif
.dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */
#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 #if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9
.fallback = NULL,
.fallback = &lv_font_montserrat_20,
#endif #endif
.user_data = NULL, .user_data = NULL,
}; };

View File

@ -16,6 +16,18 @@ void update_sensorNstatus(float temp, float hum, float seaLevelPress, bool presA
glblData.presAlarm = presAlarm; glblData.presAlarm = presAlarm;
update_status(); update_status();
} }
void update_clockdots(void){
static bool dotState = false;
dotState = !dotState;
char* time = lv_label_get_text(objects.time_txt);
if(dotState){
time[3] = ':';
lv_label_set_text(objects.time_txt, time);
}else{
time[3] = ' ';
lv_label_set_text(objects.time_txt, time);
}
}
static void alarm_ani_cb(void * var, int32_t v) static void alarm_ani_cb(void * var, int32_t v)
{ {
@ -38,9 +50,15 @@ void ui_settemp(float tmp){
} }
void update_status(void){ void update_status(void){
tm timeinfo;
getLocalTime(&timeinfo);
char buffer[15];
strftime(buffer, sizeof(buffer), "%R", &timeinfo);
static unsigned long fullOnTime = millis(); static unsigned long fullOnTime = millis();
lv_label_set_text_fmt(objects.press_txt,"%4.2f hPa",glblData.seaLevelPress); 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); lv_label_set_text_fmt(objects.hum_txt,"%2.0f %%rH",glblData.hum);
lv_label_set_text_fmt(objects.outTemp_txt,ICON_THERMOMETER_SNOW "%2.1f °C",glblData.outTemp);
lv_label_set_text(objects.time_txt,buffer);
if(!arc_pressed && !animating){ if(!arc_pressed && !animating){
lv_label_set_text_fmt(objects.temp_txt,"%2.1f °C",glblData.temp); lv_label_set_text_fmt(objects.temp_txt,"%2.1f °C",glblData.temp);
}else{ }else{

View File

@ -20,6 +20,7 @@ void rebootESP(lv_event_t * e);
void action_show_cursors_cb(lv_event_t * e); void action_show_cursors_cb(lv_event_t * e);
void chartDrawingCB(lv_event_t * e); void chartDrawingCB(lv_event_t * e);
void update_sensorNstatus(float temp, float hum, float seaLevelPress, bool presAlarm); void update_sensorNstatus(float temp, float hum, float seaLevelPress, bool presAlarm);
void update_clockdots(void);
void update_status(void); void update_status(void);
void update_wifi_strength(wifistrength_t strength, wifimode_t mode); void update_wifi_strength(wifistrength_t strength, wifimode_t mode);
void chart_autoscale(void); void chart_autoscale(void);

View File

@ -76,6 +76,7 @@ void create_screen_main() {
lv_label_set_text(obj, ""); lv_label_set_text(obj, "");
lv_obj_set_style_text_font(obj, &lv_font_montserrat_20, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(obj, &lv_font_montserrat_20, LV_PART_MAIN | LV_STATE_DEFAULT);
} }
{ {
// pressTxt // pressTxt
lv_obj_t *obj = lv_label_create(parent_obj); lv_obj_t *obj = lv_label_create(parent_obj);
@ -86,6 +87,25 @@ void create_screen_main() {
lv_label_set_text(obj, ""); lv_label_set_text(obj, "");
lv_obj_set_style_text_font(obj, &lv_font_montserrat_20, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(obj, &lv_font_montserrat_20, LV_PART_MAIN | LV_STATE_DEFAULT);
} }
{
// timeTxt
lv_obj_t *obj = lv_label_create(parent_obj);
objects.time_txt = obj;
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_align(obj,LV_ALIGN_CENTER,0,-60);
lv_label_set_text(obj, "");
lv_obj_set_style_text_font(obj, &Bootstrap_Icons_18, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// outTemp
lv_obj_t *obj = lv_label_create(parent_obj);
objects.outTemp_txt = obj;
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_align(obj,LV_ALIGN_CENTER,0,55);
lv_label_set_text(obj, ICON_THERMOMETER_SNOW "--°C");
lv_obj_set_style_text_font(obj, &Bootstrap_Icons_18, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{ {
// Heating active // Heating active
lv_obj_t *obj = lv_label_create(parent_obj); lv_obj_t *obj = lv_label_create(parent_obj);

View File

@ -27,6 +27,8 @@ typedef struct _objects_t {
lv_obj_t *bufferIcn; lv_obj_t *bufferIcn;
lv_obj_t *wifiIcn; lv_obj_t *wifiIcn;
lv_obj_t *alarmLED; lv_obj_t *alarmLED;
lv_obj_t *outTemp_txt;
lv_obj_t *time_txt;
lv_chart_cursor_t *chart_cursor; lv_chart_cursor_t *chart_cursor;
lv_chart_series_t *chart_series; lv_chart_series_t *chart_series;
} objects_t; } objects_t;

View File

@ -4,7 +4,7 @@
bool history_initialized = false; 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, .bootTime = {0}}; dataset_t glblData = {.temp = NAN, .hum = NAN, .pres = NAN, .seaLevelPress = NAN, .settemp= NAN, .outTemp = NAN, .heating=false, .enBuff =false, .relPowerSave=true, .presAlarm=false, .myIP={0}, .wifiStrength = WIFISTRENGTH_OFF, .wifiMode= WIFIMODE_OFF, .override = OVR_NONE, .bootTime = {0}};
hist_t history = {{0},{0},{0}}; hist_t history = {{0},{0},{0}};
int32_t* history_getPressPt(void){ int32_t* history_getPressPt(void){

View File

@ -52,6 +52,7 @@ typedef struct dataset_s{
float pres; float pres;
float seaLevelPress; float seaLevelPress;
float settemp; float settemp;
float outTemp;
bool heating; bool heating;
bool enBuff; bool enBuff;
bool relPowerSave; bool relPowerSave;