Add PCBs and Housing

Improve firmware to include MQTT and status icons.
This commit is contained in:
2025-03-26 19:06:40 +01:00
parent f690d03c57
commit 2e818a5d8c
127 changed files with 365045 additions and 78 deletions
+46 -5
View File
@@ -16,6 +16,40 @@ 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 ON\"}";
break;
case OVR_ALWAYSON:
sending += "\"Override\": \"Always OFF\"}";
break;
case OVR_NONE:
sending += "\"Override\": \"NONE\"}";
break;
}
server.send(404, "text/plain", sending);
}
void MQTT::serveData(void){
String sending;
sending = "{\"Temp[degC]\": ";
@@ -36,6 +70,8 @@ void MQTT::serveData(void){
request->send(404, "text/plain", sending);*/
}
void MQTT::sendStatus(void){
char buffer[10];
snprintf(buffer, sizeof buffer, "%0.1f", glblData.temp);
@@ -56,10 +92,12 @@ void MQTT::begin(){
prefs.begin("settings");
prefs.getString("HOST",hostname,40);
prefs.getString("MQTT_SERVER",mqtt_server,40);
prefs.getInt("MQTT_PORT",mqtt_port);
mqtt_port = prefs.getInt("MQTT_PORT",mqtt_port);
prefs.getString("MQTT_TOPIC",mqtt_topic,40);
prefs.getFloat("MQTT_PORT",defTemp);
prefs.getBool("MQTT_PORT",enBuff);
defTemp = prefs.getFloat("DEF_TMP",defTemp);
enBuff = prefs.getBool("EN_OVR",enBuff);
glblData.enBuff = enBuff;
ui_settemp(defTemp);
prefs.end();
wm.setSaveConfigCallback(MQTT::saveConfigCallback);
custom_hostname.setValue(hostname,40);
@@ -129,6 +167,7 @@ void MQTT::begin(){
// 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();
reconnect();
@@ -148,14 +187,16 @@ void MQTT::saveConfigToFlash(void){
if(custom_enbuff.getValue() != "0"){
enBuff = true;
}
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("MQTT_PORT",defTemp);
prefs.putBool("MQTT_PORT",enBuff);
prefs.putFloat("DEF_TMP",defTemp);
prefs.putBool("EN_OVR",enBuff);
prefs.end();
}
void MQTT::reconnect(void) {
+3 -1
View File
@@ -41,8 +41,10 @@ public:
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);
static void serveData(void);
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";
+4 -3
View File
@@ -1,4 +1,4 @@
#define HOSTNAME "Temp_Wozi_EG"
#include <Arduino_GFX_Library.h>
#include <TouchDrvCSTXXX.hpp>
#include "lv_conf.h"
@@ -57,11 +57,11 @@ void measure(void){ //update temp every 30secs
temp = temp - 1.0; //adjust temp to compensate head dissipation of ESP
seaLevelPress = EnvironmentCalculations::EquivalentSeaLevelPressure(barometerAltitude, temp, pres, EnvironmentCalculations::AltitudeUnit_Meters, EnvironmentCalculations::TempUnit_Celsius);
newMeasurement = true;
//if(++counter > 10 || history_isInitialized == false){ //add a point to history every 5 mins
if(++counter > 10 || history_isInitialized() == false){ //add a point to history every 5 mins
history_append(seaLevelPress,temp,hum);
counter = 0;
newHistory = true;
//}
}
}
@@ -112,6 +112,7 @@ void loop()
lv_chart_refresh(objects.chart);
}
mqtt.loop();
ui_tick();
lv_task_handler(); // let the GUI do its work
lv_tick_inc(millis() - lastms); // tell LVGL how much time has passed
lastms = millis();
+75 -22
View File
@@ -17,6 +17,10 @@ void update_sensorNstatus(float temp, float hum, float seaLevelPress){
update_status();
}
void ui_settemp(float tmp){
lv_arc_set_value(objects.temp_arc, (int32_t) (tmp*2));
}
void update_status(void){
lv_label_set_text_fmt(objects.press_txt,"%4.0f hPa",glblData.seaLevelPress);
lv_label_set_text_fmt(objects.hum_txt,"%2.0f %%rH",glblData.hum);
@@ -26,13 +30,36 @@ void update_status(void){
glblData.settemp = lv_arc_get_value(objects.temp_arc)/2.0;
lv_label_set_text_fmt(objects.temp_txt,"%2.1f °C",glblData.settemp);
}
if(temp < ui_getSetTemp()-TMP_HYST){
glblData.heating = true;
digitalWrite(PIN_REL,HIGH);
lv_obj_remove_flag(objects.heaterIcn, LV_OBJ_FLAG_HIDDEN);
switch(glblData.override){
case OVR_NONE:
if(glblData.temp < glblData.settemp-TMP_HYST){
glblData.heating = true;
}
else if(glblData.temp > glblData.settemp+TMP_HYST){
glblData.heating = false;
}
break;
case OVR_ALWAYSON:
if(glblData.temp < glblData.settemp+3.0){ //allow for 3degC overheating
glblData.heating = true;
}
else{
glblData.heating = false;
}
break;
case OVR_ALWAYSOFF:
if(glblData.temp < 12){ //ensure minimum of 12°C
glblData.heating = true;
}
else{
glblData.heating = false;
}
break;
}
else if(temp > ui_getSetTemp()+TMP_HYST){
glblData.heating = false;
if(glblData.heating){
digitalWrite(PIN_REL,LOW);
lv_obj_add_flag(objects.heaterIcn, LV_OBJ_FLAG_HIDDEN);
}else{
digitalWrite(PIN_REL,LOW);
lv_obj_add_flag(objects.heaterIcn, LV_OBJ_FLAG_HIDDEN);
}
@@ -41,23 +68,23 @@ void update_status(void){
void update_wifi_strength(wifi_strength_t strength){
switch(strength){
case WIFI_STRENGTH_HIGH:
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xf0f0f0),LV_STATE_DEFAULT | LV_PART_MAIN);
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xf0f0f0),LV_STATE_DEFAULT);
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 | LV_PART_MAIN);
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xf0f0f0),LV_STATE_DEFAULT);
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 | LV_PART_MAIN);
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xf0f0f0),LV_STATE_DEFAULT);
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 | LV_PART_MAIN);
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xf0f0f0),LV_STATE_DEFAULT);
lv_label_set_text(objects.wifiIcn,ICON_WIFI_OFF);
break;
case WIFI_STRENGTH_ERROR:
lv_obj_set_style_text_color(objects.wifiIcn,lv_color_hex(0xFF0000),LV_STATE_DEFAULT | LV_PART_MAIN);
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;
}
@@ -257,27 +284,49 @@ void action_zoom_set_temp(lv_event_t * e){
//lv_label_set_text_fmt(objects.temp_txt,"%2.1f °C",lv_arc_get_value(objects.temp_arc)/2.0);
update_status();
}
static void anim_height_cb(void * var, int32_t v)
{
lv_obj_t* obj = (lv_obj_t*) var;
lv_obj_set_height(obj, v);
}
void action_switch_screens(lv_event_t * e){
lv_dir_t gestDir = lv_indev_get_gesture_dir(lv_indev_get_act());
lastChartPt.x = -1; //clear labels on chart change
int32_t chartheight = lv_obj_get_height(objects.chart);
switch (gestDir){
case LV_DIR_LEFT:
case LV_DIR_RIGHT:
break;
case LV_DIR_TOP:
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){
loadScreen(SCREEN_ID_MAIN);
}
else{
loadChart(ui_getCurrentChart()+1);
}
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_exec_cb(&a, anim_height_cb);
lv_anim_set_var(&a, objects.chart);
lv_anim_set_values(&a, chartheight, 0);
lv_anim_set_duration(&a, 200);
lv_anim_set_path_cb(&a, lv_anim_path_bounce);
lv_anim_start(&a);
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);
}
else{
loadChart(ui_getCurrentChart()+1);
}
//}
lv_indev_wait_release(lv_indev_active());
break;
case LV_DIR_BOTTOM:
@@ -285,6 +334,10 @@ void action_switch_screens(lv_event_t * e){
break;
}
}
void showChartScreen(lv_event_t * e){
loadChart(0);
loadScreen(SCREEN_ID_CHART);
}
void showDebugScreen(lv_event_t * e){
loadScreen(SCREEN_ID_DEBUG);
+14 -5
View File
@@ -9,6 +9,12 @@ extern "C" {
#define PIN_REL 21
typedef enum override_e{
OVR_NONE,
OVR_ALWAYSON,
OVR_ALWAYSOFF
} override_t;
typedef struct dataset_s{
float temp;
float hum;
@@ -18,6 +24,7 @@ typedef struct dataset_s{
bool heating;
bool buffRequest;
bool enBuff;
override_t override;
}dataset_t;
typedef enum wifi_strength_e{
@@ -28,12 +35,14 @@ typedef enum wifi_strength_e{
WIFI_STRENGTH_ERROR
} wifi_strength_t;
extern void action_zoom_set_temp(lv_event_t * e);
extern void action_switch_screens(lv_event_t * e);
extern void showDebugScreen(lv_event_t * e);
void ui_settemp(float tmp);
void action_zoom_set_temp(lv_event_t * e);
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);
extern void action_show_cursors_cb(lv_event_t * e);
extern void chartDrawingCB(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);
void update_status(void);
void update_wifi_strength(wifi_strength_t strength);
+26 -27
View File
@@ -23,8 +23,8 @@ void create_screen_main() {
{
// tempArc
lv_obj_t *obj = lv_arc_create(parent_obj);
lv_obj_add_flag(obj, LV_OBJ_FLAG_ADV_HITTEST);
lv_obj_set_ext_click_area(obj,10);
//lv_obj_add_flag(obj, LV_OBJ_FLAG_ADV_HITTEST);
//lv_obj_set_ext_click_area(obj,10);
objects.temp_arc = obj;
lv_obj_set_pos(obj, 15, 15);
lv_obj_set_size(obj, 210, 210);
@@ -41,7 +41,7 @@ void create_screen_main() {
lv_obj_remove_style_all(btn);
lv_obj_set_size(btn, 100, 60);
lv_obj_set_align(btn,LV_ALIGN_CENTER);
lv_obj_add_event_cb(btn, showDebugScreen, LV_EVENT_LONG_PRESSED,NULL);
lv_obj_add_event_cb(btn, showChartScreen, LV_EVENT_LONG_PRESSED,NULL);
//lv_obj_add_flag(btn,LV_OBJ_FLAG_CLICKABLE);
// tempTxt
lv_obj_t *obj = lv_label_create(parent_obj);
@@ -110,13 +110,9 @@ void create_screen_main() {
}*/
}
tick_screen_main();
}
void tick_screen_main() {
}
void create_screen_second() {
void create_screen_chart() {
lv_obj_t *obj = lv_obj_create(0);
objects.second = obj;
lv_obj_set_pos(obj, 0, 0);
@@ -126,6 +122,25 @@ void create_screen_second() {
{
lv_obj_t *parent_obj = obj;
{
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_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 * 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_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);
lv_obj_center(lbl_btn_dbg);
lv_label_set_text(lbl_btn_dbg,LV_SYMBOL_SETTINGS);
/*Create a container*/
lv_obj_t * main_cont = lv_obj_create(parent_obj);
lv_obj_remove_style_all(main_cont);
@@ -213,12 +228,9 @@ void create_screen_second() {
lv_obj_set_style_align(obj, LV_ALIGN_TOP_MID, LV_PART_MAIN | LV_STATE_DEFAULT);
}
}
tick_screen_second();
}
void tick_screen_second() {
}
void create_screen_debug() {
lv_obj_t *obj = lv_obj_create(0);
@@ -238,7 +250,7 @@ void create_screen_debug() {
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_BACKSPACE);
lv_label_set_text(lbl_btn_back,LV_SYMBOL_HOME);
/*Create a container*/
lv_obj_t * main_cont = lv_obj_create(parent_obj);
lv_obj_set_size(main_cont, 170, 170);
@@ -258,25 +270,12 @@ void create_screen_debug() {
}
typedef void (*tick_screen_func_t)();
tick_screen_func_t tick_screen_funcs[] = {
tick_screen_main,
tick_screen_second,
};
void tick_screen(int screen_index) {
tick_screen_funcs[screen_index]();
}
void tick_screen_by_id(enum ScreensEnum screenId) {
tick_screen_funcs[screenId - 1]();
}
void create_screens() {
lv_disp_t *dispp = lv_disp_get_default();
lv_theme_t *theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_GREEN), lv_palette_main(LV_PALETTE_RED), true, LV_FONT_DEFAULT);
lv_disp_set_theme(dispp, theme);
create_screen_main();
create_screen_second();
create_screen_chart();
create_screen_debug();
}
+2 -9
View File
@@ -34,7 +34,7 @@ extern objects_t objects;
typedef enum ScreensEnum {
SCREEN_ID_MAIN = 1,
SCREEN_ID_SECOND = 2,
SCREEN_ID_CHART = 2,
SCREEN_ID_DEBUG = 3
}ScreensEnum;
@@ -47,14 +47,7 @@ typedef enum ChartsEnum {
}ChartsEnum;
void create_screen_main();
void tick_screen_main();
void create_screen_second();
void tick_screen_second();
void tick_screen_by_id(enum ScreensEnum screenId);
void tick_screen(int screen_index);
void create_screen_chart();
void create_screens();
+1 -4
View File
@@ -41,9 +41,6 @@ void DisplayInit(void){
gfx->fillScreen(0x0000);
}
float ui_getSetTemp(void){
return lv_arc_get_value(objects.temp_arc)/2.0;
}
@@ -140,7 +137,7 @@ void displayWake(){
}
attachInterrupt(TouchInt, []() {
isPressed = true;
}, FALLING);
}, CHANGE);
}