Compare commits
10 Commits
3c170a1f69
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| a08bb8f2a5 | |||
| 91e98d7c89 | |||
| 664d91d6f4 | |||
| 5529ece98f | |||
| 23abbb837a | |||
| 251c73b517 | |||
| c57572262f | |||
| e66633186b | |||
| 8de24db46d | |||
| eb1a102120 |
BIN
CYD_Bad.tgz
Normal file
BIN
CYD_Bad.tgz
Normal file
Binary file not shown.
18
doc/mqtt.md
18
doc/mqtt.md
@@ -1,6 +1,8 @@
|
|||||||
# MQTT - Kommandos
|
# MQTT - Kommandos
|
||||||
|
|
||||||
Da das **ESPAsyncMQTT** (meines Erachtens) nicht mehrere verschiedene Topics subscriben kann, wird auf **nuccy** mit Hilfe von **Node-Red** aus den jeweiligen unterschiedlichen Smart-Home-Daten ein eigenes Topic erzeugt. Dieses heißt immer **CYD/** und hat verschiedene Untertopics (die über die Wildcard **#** subscribed werden können).
|
Da das **ESPAsyncMQTT** (meines Erachtens) nicht sehr zuverlässig arbeitet bzw. mit dem LVGL anscheinedn nicht wirklich klar kommt (macht immer wieder Resets), wird das alte PubSub-Client verwendet.
|
||||||
|
|
||||||
|
Es werden auf **nuccy** mit Hilfe von **Node-Red** aus den jeweiligen unterschiedlichen Smart-Home-Daten ein eigenes Topic erzeugt. Dieses heißt immer **CYD/** und hat verschiedene Untertopics (die über die Wildcard **#** subscribed werden können).
|
||||||
|
|
||||||
|
|
||||||
Das generelle Topic, auf das subscribed und das published wird ist **CYD/**.
|
Das generelle Topic, auf das subscribed und das published wird ist **CYD/**.
|
||||||
@@ -24,10 +26,15 @@ Auch hier sind es Float-Zahlen
|
|||||||
* **parameter/**
|
* **parameter/**
|
||||||
Hiermit können divere Parameter des Gerätes gesetzt werden. Unterschieden werden sie in der Payload. Im Moment sind folgende Parameter möglich:
|
Hiermit können divere Parameter des Gerätes gesetzt werden. Unterschieden werden sie in der Payload. Im Moment sind folgende Parameter möglich:
|
||||||
|
|
||||||
* **{"bmerate": rrr}**
|
* **{"bmerate":rrr}**
|
||||||
Einstellen der Einleserate des BME280-Sensors (in Sekunden).
|
Einstellen der Einleserate des BME280-Sensors (in Sekunden).
|
||||||
* **{"updaterate": rrr}**
|
* **{"updaterate":rrr}**
|
||||||
Einstellen der Updaterate der Grafik (in Sekunden).
|
Einstellen der Updaterate der Grafik (in Sekunden).
|
||||||
|
* **{"tempoffset":ttt}**
|
||||||
|
Einstellen des Offset für die Temperatur (in den Gehäuse ist es zu warm)
|
||||||
|
* **{"humoffset":hhh}** Einstellen des Feuchte-Offsets (der BME misst etwas zu wenig)
|
||||||
|
|
||||||
|
Alle Wert sind Float-Werte!
|
||||||
|
|
||||||
|
|
||||||
### get-Topic
|
### get-Topic
|
||||||
@@ -35,12 +42,13 @@ Folgende daten werden aus dem Gerät heraus gesendet:
|
|||||||
|
|
||||||
* **CYD/get/bme280**
|
* **CYD/get/bme280**
|
||||||
mit der Payload:
|
mit der Payload:
|
||||||
**{"temperature": tttt, "humidity": hhhh"}**
|
**{"temperature":tttt,"tempmess":ttt,"humidity":hhhh,"hummess":hhh}**
|
||||||
Wieder mit Float-Zahlen. Dies sind die Werte, die mit dem lokalen BME280 gemessen werden.
|
Wieder mit Float-Zahlen. Die xxxmess-Werte sind die Werte, die mit dem lokalen BME280 gemessen werden, die anderen beiden sind die auf aktelle Tempteratur und Feuchte umgerechneten Werte (die auf der Anzeige angezeigt werden)
|
||||||
|
|
||||||
|
|
||||||
## Versionen
|
## Versionen
|
||||||
|
|
||||||
|Version | Datum | Bemerkung |
|
|Version | Datum | Bemerkung |
|
||||||
|--------|-------|---------|
|
|--------|-------|---------|
|
||||||
|
| 1.1| 2024-08-21 | PubSub client, weitere Parameter
|
||||||
|1.0 | 2024-07-22 | erste Version |
|
|1.0 | 2024-07-22 | erste Version |
|
||||||
|
|||||||
@@ -12,12 +12,12 @@
|
|||||||
platform = espressif32
|
platform = espressif32
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
lib_compat_mode = strict
|
||||||
lib_deps =
|
lib_deps =
|
||||||
https://github.com/me-no-dev/AsyncTCP/archive/refs/heads/master.zip
|
|
||||||
https://github.com/marvinroger/async-mqtt-client/archive/refs/heads/develop.zip
|
|
||||||
bblanchon/ArduinoJson@^7.1.0
|
bblanchon/ArduinoJson@^7.1.0
|
||||||
adafruit/Adafruit BME280 Library@^2.2.4
|
adafruit/Adafruit BME280 Library@^2.2.4
|
||||||
lvgl/lvgl@^9.1.0
|
bodmer/TFT_eSPI@^2.5.43
|
||||||
bodmer/TFT_eSPI@^2.5.43
|
knolleary/PubSubClient@^2.8
|
||||||
|
ayushsharma82/ElegantOTA@^3.1.5
|
||||||
|
lvgl/lvgl@9.1.0
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|||||||
105
src/grafik.cpp
105
src/grafik.cpp
@@ -1,10 +1,18 @@
|
|||||||
// Grafik Routinen
|
// Grafik Routinen
|
||||||
#define GRAFIK
|
#define GRAFIK
|
||||||
|
|
||||||
#include "handlebme280.h"
|
// #include "handlebme280.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "grafik.h"
|
#include "grafik.h"
|
||||||
|
|
||||||
|
// Definition der diversen Farben
|
||||||
|
#define TEXTCOLOTR_TFAUSSEN 0x57d3F7
|
||||||
|
#define BACKGROUND_COLOR 0xD3F0FF
|
||||||
|
#define TEXTCOLOR 0x0000FF
|
||||||
|
#define TEXTCOLOR_FEUCHTE 0xFF0000
|
||||||
|
#define TEXTCOLOR_XACHSE 0x0000FF
|
||||||
|
#define TEXTCOLOR_INFO 0x404040
|
||||||
|
|
||||||
#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))
|
#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))
|
||||||
uint32_t draw_buf[DRAW_BUF_SIZE / 4];
|
uint32_t draw_buf[DRAW_BUF_SIZE / 4];
|
||||||
|
|
||||||
@@ -31,7 +39,7 @@ void buildarc(ARC arc)
|
|||||||
lv_obj_set_size(arc.arc, arc.size, arc.size);
|
lv_obj_set_size(arc.arc, arc.size, arc.size);
|
||||||
lv_arc_set_rotation(arc.arc, 180);
|
lv_arc_set_rotation(arc.arc, 180);
|
||||||
lv_arc_set_bg_angles(arc.arc, 0, 180);
|
lv_arc_set_bg_angles(arc.arc, 0, 180);
|
||||||
lv_arc_set_value(arc.arc, arc.value);
|
lv_arc_set_value(arc.arc, arc.value+arc.value_offset);
|
||||||
lv_obj_align(arc.arc, LV_ALIGN_LEFT_MID, arc.x, arc.y);
|
lv_obj_align(arc.arc, LV_ALIGN_LEFT_MID, arc.x, arc.y);
|
||||||
lv_obj_remove_style(arc.arc, NULL, LV_PART_KNOB);
|
lv_obj_remove_style(arc.arc, NULL, LV_PART_KNOB);
|
||||||
|
|
||||||
@@ -55,10 +63,10 @@ void buildarc(ARC arc)
|
|||||||
|
|
||||||
lv_obj_t *value_label = lv_label_create(arc.arc);
|
lv_obj_t *value_label = lv_label_create(arc.arc);
|
||||||
char value[10];
|
char value[10];
|
||||||
sprintf(value, arc.valformat, arc.value);
|
sprintf(value, arc.valformat, arc.value + arc.value_offset);
|
||||||
// Serial.println(value);
|
// Serial.println(value);
|
||||||
lv_label_set_text(value_label, value);
|
lv_label_set_text(value_label, value);
|
||||||
lv_obj_align(value_label, LV_ALIGN_LEFT_MID, 38 + arc.value_offset, 0);
|
lv_obj_align(value_label, LV_ALIGN_LEFT_MID, 38 + arc.value_xoffset, 0);
|
||||||
static lv_style_t style_value_label;
|
static lv_style_t style_value_label;
|
||||||
lv_style_init(&style_value_label);
|
lv_style_init(&style_value_label);
|
||||||
lv_style_set_text_font(&style_value_label, &lv_font_montserrat_18);
|
lv_style_set_text_font(&style_value_label, &lv_font_montserrat_18);
|
||||||
@@ -105,7 +113,7 @@ void showAussenData(float val, bool what)
|
|||||||
static lv_style_t style_tta_label;
|
static lv_style_t style_tta_label;
|
||||||
lv_style_init(&style_tta_label);
|
lv_style_init(&style_tta_label);
|
||||||
lv_style_set_text_font(&style_tta_label, &lv_font_montserrat_10);
|
lv_style_set_text_font(&style_tta_label, &lv_font_montserrat_10);
|
||||||
lv_style_set_text_color(&style_tta_label, LV_COLOR_MAKE(0x60, 0x60, 0xFF));
|
lv_style_set_text_color(&style_tta_label, lv_color_hex(TEXTCOLOTR_TFAUSSEN));
|
||||||
lv_obj_add_style(tta_label, &style_tta_label, 0);
|
lv_obj_add_style(tta_label, &style_tta_label, 0);
|
||||||
lv_obj_add_style(tfa_label, &style_tta_label, 0);
|
lv_obj_add_style(tfa_label, &style_tta_label, 0);
|
||||||
}
|
}
|
||||||
@@ -141,27 +149,6 @@ void lv_create_main_gui(void)
|
|||||||
lv_obj_align(refresh_label, LV_ALIGN_CENTER, 0, -45);
|
lv_obj_align(refresh_label, LV_ALIGN_CENTER, 0, -45);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Text als Überschrift an die Axen
|
|
||||||
lv_obj_t *feuchte_label = lv_label_create(lv_screen_active());
|
|
||||||
lv_label_set_text(feuchte_label, "Feuchte");
|
|
||||||
lv_obj_align(feuchte_label, LV_ALIGN_RIGHT_MID, -3, 15);
|
|
||||||
|
|
||||||
// Set font type and font size. More information: https://docs.lvgl.io/master/overview/font.html
|
|
||||||
static lv_style_t style_feuchte_label;
|
|
||||||
lv_style_init(&style_feuchte_label);
|
|
||||||
lv_style_set_text_font(&style_feuchte_label, &lv_font_montserrat_10);
|
|
||||||
lv_obj_add_style(feuchte_label, &style_feuchte_label, 0);
|
|
||||||
|
|
||||||
lv_obj_t *temp_label = lv_label_create(lv_screen_active());
|
|
||||||
lv_label_set_text(temp_label, "Temperatur");
|
|
||||||
lv_obj_align(temp_label, LV_ALIGN_LEFT_MID, 3, 15);
|
|
||||||
|
|
||||||
// Set font type and font size. More information: https://docs.lvgl.io/master/overview/font.html
|
|
||||||
static lv_style_t style_temp_label;
|
|
||||||
lv_style_init(&style_temp_label);
|
|
||||||
lv_style_set_text_font(&style_temp_label, &lv_font_montserrat_10);
|
|
||||||
lv_obj_add_style(temp_label, &style_temp_label, 0);
|
|
||||||
|
|
||||||
/*Create an Arc*/
|
/*Create an Arc*/
|
||||||
lv_obj_t *aTemp = lv_arc_create(lv_screen_active());
|
lv_obj_t *aTemp = lv_arc_create(lv_screen_active());
|
||||||
arcTemp.arc = aTemp;
|
arcTemp.arc = aTemp;
|
||||||
@@ -220,7 +207,7 @@ void drawChart()
|
|||||||
// Create a container to display the chart and scale
|
// Create a container to display the chart and scale
|
||||||
lv_obj_t *container_row = lv_obj_create(lv_screen_active());
|
lv_obj_t *container_row = lv_obj_create(lv_screen_active());
|
||||||
lv_obj_set_size(container_row, CONTAINER_WIDTH, CONTAINER_HEIGHT);
|
lv_obj_set_size(container_row, CONTAINER_WIDTH, CONTAINER_HEIGHT);
|
||||||
lv_obj_align(container_row, LV_ALIGN_BOTTOM_MID, 0, 0);
|
lv_obj_align(container_row, LV_ALIGN_BOTTOM_MID, 0, -4);
|
||||||
// Set the container in a flexbox row layout aligned center
|
// Set the container in a flexbox row layout aligned center
|
||||||
lv_obj_set_flex_flow(container_row, LV_FLEX_FLOW_ROW);
|
lv_obj_set_flex_flow(container_row, LV_FLEX_FLOW_ROW);
|
||||||
lv_obj_set_flex_align(container_row, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
lv_obj_set_flex_align(container_row, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
@@ -229,7 +216,7 @@ void drawChart()
|
|||||||
lv_style_set_pad_row(&style_container_row, 0);
|
lv_style_set_pad_row(&style_container_row, 0);
|
||||||
// lv_style_set_bg_color(&style_container_row, lv_palette_lighten(LV_PALETTE_LIGHT_BLUE, 4));
|
// lv_style_set_bg_color(&style_container_row, lv_palette_lighten(LV_PALETTE_LIGHT_BLUE, 4));
|
||||||
lv_obj_add_style(container_row, &style_container_row, 0);
|
lv_obj_add_style(container_row, &style_container_row, 0);
|
||||||
lv_obj_set_style_border_side(container_row, LV_BORDER_SIDE_BOTTOM, LV_PART_MAIN);
|
lv_obj_set_style_border_side(container_row, LV_BORDER_SIDE_NONE, LV_PART_MAIN);
|
||||||
lv_obj_set_style_bg_color(container_row, lv_color_hex(BACKGROUND_COLOR), LV_PART_MAIN);
|
lv_obj_set_style_bg_color(container_row, lv_color_hex(BACKGROUND_COLOR), LV_PART_MAIN);
|
||||||
|
|
||||||
// linke Axe
|
// linke Axe
|
||||||
@@ -254,7 +241,7 @@ void drawChart()
|
|||||||
static lv_style_t style_scaleT;
|
static lv_style_t style_scaleT;
|
||||||
lv_style_init(&style_scaleT);
|
lv_style_init(&style_scaleT);
|
||||||
lv_style_set_text_font(&style_scaleT, &lv_font_montserrat_10);
|
lv_style_set_text_font(&style_scaleT, &lv_font_montserrat_10);
|
||||||
lv_style_set_text_color(&style_scaleT, lv_color_hex(0x0000FF));
|
lv_style_set_text_color(&style_scaleT, lv_color_hex(TEXTCOLOR));
|
||||||
// lv_style_set_bg_color(&style_scaleT, lv_color_hex(0xFF00FF));
|
// lv_style_set_bg_color(&style_scaleT, lv_color_hex(0xFF00FF));
|
||||||
lv_obj_add_style(scaleT, &style_scaleT, 0);
|
lv_obj_add_style(scaleT, &style_scaleT, 0);
|
||||||
|
|
||||||
@@ -305,7 +292,7 @@ void drawChart()
|
|||||||
static lv_style_t style_scale;
|
static lv_style_t style_scale;
|
||||||
lv_style_init(&style_scale);
|
lv_style_init(&style_scale);
|
||||||
lv_style_set_text_font(&style_scale, &lv_font_montserrat_10);
|
lv_style_set_text_font(&style_scale, &lv_font_montserrat_10);
|
||||||
lv_style_set_text_color(&style_scale, lv_color_hex(0xFF0000));
|
lv_style_set_text_color(&style_scale, lv_color_hex(TEXTCOLOR_FEUCHTE));
|
||||||
lv_obj_add_style(scale, &style_scale, 0);
|
lv_obj_add_style(scale, &style_scale, 0);
|
||||||
|
|
||||||
// X-Achse
|
// X-Achse
|
||||||
@@ -332,32 +319,39 @@ void drawChart()
|
|||||||
static lv_style_t style_xscale;
|
static lv_style_t style_xscale;
|
||||||
lv_style_init(&style_xscale);
|
lv_style_init(&style_xscale);
|
||||||
lv_style_set_text_font(&style_xscale, &lv_font_montserrat_10);
|
lv_style_set_text_font(&style_xscale, &lv_font_montserrat_10);
|
||||||
lv_style_set_text_color(&style_xscale, lv_color_hex(0x0000FF));
|
lv_style_set_text_color(&style_xscale, lv_color_hex(TEXTCOLOR_XACHSE));
|
||||||
lv_obj_add_style(xscale, &style_xscale, 0);
|
lv_obj_add_style(xscale, &style_xscale, 0);
|
||||||
|
|
||||||
|
// Text als Überschrift an die Axen
|
||||||
|
lv_obj_t *feuchte_label = lv_label_create(lv_screen_active());
|
||||||
|
lv_label_set_text(feuchte_label, "Feuchte");
|
||||||
|
lv_obj_align(feuchte_label, LV_ALIGN_RIGHT_MID, -3, 8);
|
||||||
|
|
||||||
|
lv_obj_t *temp_label = lv_label_create(lv_screen_active());
|
||||||
|
lv_label_set_text(temp_label, "Temperatur");
|
||||||
|
lv_obj_align(temp_label, LV_ALIGN_LEFT_MID, 3, 8);
|
||||||
|
|
||||||
|
// Set font type and font size. More information: https://docs.lvgl.io/master/overview/font.html
|
||||||
|
static lv_style_t style_tf_label;
|
||||||
|
lv_style_init(&style_tf_label);
|
||||||
|
lv_style_set_text_font(&style_tf_label, &lv_font_montserrat_10);
|
||||||
|
lv_obj_add_style(feuchte_label, &style_tf_label, 0);
|
||||||
|
lv_obj_add_style(temp_label, &style_tf_label, 0);
|
||||||
|
|
||||||
/* ganz unten etwas Info anzeigen */
|
/* ganz unten etwas Info anzeigen */
|
||||||
// Style dafür
|
// Style dafür
|
||||||
static lv_style_t style_info_label;
|
static lv_style_t style_info_label;
|
||||||
lv_style_init(&style_info_label);
|
lv_style_init(&style_info_label);
|
||||||
lv_style_set_text_font(&style_info_label, &lv_font_montserrat_8);
|
lv_style_set_text_font(&style_info_label, &lv_font_montserrat_8);
|
||||||
lv_style_set_text_color(&style_info_label, LV_COLOR_MAKE(0x40, 0x40, 0x40));
|
lv_style_set_text_color(&style_info_label, lv_color_hex(TEXTCOLOR_INFO));
|
||||||
|
|
||||||
// Versionsnummer und Datum
|
// Versionsnummer, IP-Adresse und Datum
|
||||||
lv_obj_t *version_label = lv_label_create(lv_screen_active());
|
lv_obj_t *version_label = lv_label_create(lv_screen_active());
|
||||||
char ver[20];
|
char ver[40];
|
||||||
sprintf(ver, "V %s %s", VERSION, VDATE);
|
sprintf(ver, "V %s %s %s", VERSION, VDATE, VTIME);
|
||||||
lv_label_set_text(version_label, ver);
|
lv_label_set_text(version_label, ver);
|
||||||
lv_obj_align(version_label, LV_ALIGN_BOTTOM_MID, 0, 0);
|
lv_obj_align(version_label, LV_ALIGN_BOTTOM_RIGHT, -4, 0);
|
||||||
lv_obj_add_style(version_label, &style_info_label, LV_PART_MAIN);
|
lv_obj_add_style(version_label, &style_info_label, LV_PART_MAIN);
|
||||||
|
|
||||||
// links davon die Abtastrate
|
|
||||||
// bmr_label = lv_label_create(lv_screen_active());
|
|
||||||
// char rate[20];
|
|
||||||
// sprintf(rate, "Rate: %ds", updateTime / 1000);
|
|
||||||
// lv_label_set_text(bmr_label, rate);
|
|
||||||
// lv_obj_align(bmr_label, LV_ALIGN_BOTTOM_LEFT, 40, 0);
|
|
||||||
// lv_obj_add_style(bmr_label, &style_info_label, LV_PART_MAIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void showRate(int r) {
|
void showRate(int r) {
|
||||||
@@ -366,7 +360,6 @@ void showRate(int r) {
|
|||||||
lv_label_set_text(bmr_label, rate);
|
lv_label_set_text(bmr_label, rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void updatechartData(float value, float humvalue)
|
void updatechartData(float value, float humvalue)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -385,7 +378,7 @@ void setAussenDataValues(float val, bool what, struct tm t)
|
|||||||
{
|
{
|
||||||
if (what)
|
if (what)
|
||||||
{
|
{
|
||||||
lv_label_set_text_fmt(ta_label,"Ta:\n%.1f °C", val);
|
lv_label_set_text_fmt(ta_label,"Taussen:\n%.1f °C", val);
|
||||||
lv_obj_align(ta_label, LV_ALIGN_TOP_LEFT, 10, 10);
|
lv_obj_align(ta_label, LV_ALIGN_TOP_LEFT, 10, 10);
|
||||||
lv_label_set_text_fmt(tta_label,"%02d:%02d\n", t.tm_hour, t.tm_min);
|
lv_label_set_text_fmt(tta_label,"%02d:%02d\n", t.tm_hour, t.tm_min);
|
||||||
lv_obj_align(tta_label, LV_ALIGN_TOP_LEFT, 10, 45);
|
lv_obj_align(tta_label, LV_ALIGN_TOP_LEFT, 10, 45);
|
||||||
@@ -420,4 +413,24 @@ void show2lines() {
|
|||||||
lv_obj_add_style(line2, &style_line, 0);
|
lv_obj_add_style(line2, &style_line, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showResetTime(struct tm tinfo) {
|
||||||
|
static lv_style_t style_info_label;
|
||||||
|
lv_style_init(&style_info_label);
|
||||||
|
lv_style_set_text_font(&style_info_label, &lv_font_montserrat_8);
|
||||||
|
lv_style_set_text_color(&style_info_label, lv_color_hex(TEXTCOLOR_INFO));
|
||||||
|
|
||||||
|
char date[20];
|
||||||
|
strftime(date, 20, "%d-%m-%Y %H:%M", &tinfo);
|
||||||
|
|
||||||
|
lv_obj_t *resdate_label = lv_label_create(lv_screen_active());
|
||||||
|
lv_label_set_text(resdate_label, date);
|
||||||
|
lv_obj_align(resdate_label, LV_ALIGN_BOTTOM_LEFT, 4, 0);
|
||||||
|
lv_obj_add_style(resdate_label, &style_info_label, LV_PART_MAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDateTime(char *time, char *date)
|
||||||
|
{
|
||||||
|
lv_label_set_text(time_label, time);
|
||||||
|
lv_label_set_text(date_label, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
11
src/grafik.h
11
src/grafik.h
@@ -26,7 +26,8 @@ typedef struct {
|
|||||||
int highvalue;
|
int highvalue;
|
||||||
int green;
|
int green;
|
||||||
int yellow;
|
int yellow;
|
||||||
int value_offset;
|
int value_xoffset;
|
||||||
|
float value_offset;
|
||||||
|
|
||||||
} ARC;
|
} ARC;
|
||||||
|
|
||||||
@@ -34,10 +35,9 @@ typedef struct {
|
|||||||
#define SCREEN_WIDTH 320
|
#define SCREEN_WIDTH 320
|
||||||
#define SCREEN_HEIGHT 240
|
#define SCREEN_HEIGHT 240
|
||||||
|
|
||||||
#define BACKGROUND_COLOR 0xD3F0FF
|
|
||||||
#ifdef MAIN
|
#ifdef MAIN
|
||||||
ARC arcTemp = {NULL, "temp", 40, -6, 110, 30.0, "%.1f°C", "°C", 15, 35, 20, 25, -11};
|
ARC arcTemp = {NULL, "temp", 40, -10, 110, 30.0, "%.1f°C", "°C", 15, 35, 20, 25, -11, 0.0};
|
||||||
ARC arcHum = {NULL, "humi", 170, -6, 110, 60.0, "%.0f%%", "%", 40, 100, 65, 70, 2};
|
ARC arcHum = {NULL, "humi", 170, -10, 110, 60.0, "%.0f%%", "%", 40, 100, 65, 70, 2, 0.0};
|
||||||
lv_obj_t * date_label;
|
lv_obj_t * date_label;
|
||||||
lv_obj_t * time_label;
|
lv_obj_t * time_label;
|
||||||
lv_obj_t * ta_label;
|
lv_obj_t * ta_label;
|
||||||
@@ -66,6 +66,9 @@ void updatechartData(float value, float value_hum);
|
|||||||
void setAussenDataValues(float val, bool what, struct tm t);
|
void setAussenDataValues(float val, bool what, struct tm t);
|
||||||
void showRate(int r);
|
void showRate(int r);
|
||||||
void show2lines();
|
void show2lines();
|
||||||
|
void showResetTime(struct tm tinfo);
|
||||||
|
void setDateTime(char *time, char *date);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
46
src/interpolation.cpp
Normal file
46
src/interpolation.cpp
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// Berechnung der Feuchte über die Sättigungsfeuchte und die Temperatur
|
||||||
|
//
|
||||||
|
// Die gemessene Temperatur ist (empirisch ernittelt) um 3.2°C zu hoch, deshalb ist die gemessene
|
||||||
|
// Feuchte immer deutlich zu niedrig. Mit Hilfe der Sättigungs-Tabelle wird nun die absolute Feuchte bei der
|
||||||
|
// wahren Temperatur (Tmess - 3.2°C) ermittelt und dann die relative Feuchte berechnet.
|
||||||
|
|
||||||
|
#define INTERPOL
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "interpolation.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Berechnung des Dampgehaltes bei der gemessenen Temperatur über Interpolation in der dampftabelle
|
||||||
|
//
|
||||||
|
// dampfgehalt = d[t] + ((d[t+1] - d[t]) / 1) * (temp - t)
|
||||||
|
// mit t = int(temp)-indexOffset
|
||||||
|
// d[t] = dampftabelle[t]
|
||||||
|
// temp: gemessene Temperatur
|
||||||
|
// return: Dampfgehalt in g/m3
|
||||||
|
float getDampfgehalt(float temp)
|
||||||
|
{
|
||||||
|
int index = (int)temp - indexOffset;
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
if (index > sizeof(dampftabelle) / sizeof(dampftabelle[0]))
|
||||||
|
{
|
||||||
|
index = sizeof(dampftabelle) / sizeof(dampftabelle[0]) - 1;
|
||||||
|
}
|
||||||
|
float d1 = dampftabelle[index];
|
||||||
|
float d2 = dampftabelle[index + 1];
|
||||||
|
return d1 + ((d2 - d1) / 1) * (temp - (index + indexOffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Berechnung der relativen Feuchte
|
||||||
|
//
|
||||||
|
// temp: gemessene Temperatur
|
||||||
|
// hum: gemessene relative Feuchte
|
||||||
|
// return: relative Feuchte
|
||||||
|
int getRelativeFeuchte(float temp, float hum)
|
||||||
|
{
|
||||||
|
float dampfmess = getDampfgehalt(temp);
|
||||||
|
float dampfecht = getDampfgehalt(temp - tempOffset);
|
||||||
|
return round((dampfmess * hum / dampfecht) + humOffset);
|
||||||
|
}
|
||||||
28
src/interpolation.h
Normal file
28
src/interpolation.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef IUNTERPOL_H
|
||||||
|
#define INTERPOL_H
|
||||||
|
|
||||||
|
// Tabelle mit dem Wasserdampgehalt (g/m3) über der Temperatur (°C)
|
||||||
|
// Die Temperatur ist der Index in die Tabelle
|
||||||
|
// Der erste Wert ist der von 15°C (index 0)
|
||||||
|
|
||||||
|
const float dampftabelle[] = {
|
||||||
|
// 15, 16, 17, 18, 19
|
||||||
|
12.85, 13.65, 14.50, 15.40, 16.30,
|
||||||
|
// 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
|
||||||
|
17.30, 18.35, 19.40, 20.55, 21.80, 23.05, 24.35, 25.75, 27.20, 28.7,
|
||||||
|
// 30, 31, 32, 33, 34, 35 36
|
||||||
|
30.35, 32.05, 33, 85, 35.70, 37.65, 39.6, 41.7};
|
||||||
|
const int indexOffset = 15;
|
||||||
|
|
||||||
|
#ifdef INTERPOL
|
||||||
|
float tempOffset = 3.2;
|
||||||
|
float humOffset = 5.0;
|
||||||
|
#else
|
||||||
|
extern float tempOffset;
|
||||||
|
extern float humOffset;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float getDampfgehalt(float temp);
|
||||||
|
int getRelativeFeuchte(float temp, float hum);
|
||||||
|
|
||||||
|
#endif
|
||||||
82
src/main.cpp
82
src/main.cpp
@@ -22,10 +22,11 @@
|
|||||||
#include <TFT_eSPI.h>
|
#include <TFT_eSPI.h>
|
||||||
|
|
||||||
|
|
||||||
#include "Weifi.h"
|
#include "weifi.h"
|
||||||
#include "mqtt.h"
|
#include "mqtt.h"
|
||||||
#include "handlebme280.h"
|
// #include "handlebme280.h"
|
||||||
#include "grafik.h"
|
#include "grafik.h"
|
||||||
|
// #include "interpolation.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
@@ -35,11 +36,10 @@
|
|||||||
long bmeReadtimer = 0;
|
long bmeReadtimer = 0;
|
||||||
long updatetimer = 0;
|
long updatetimer = 0;
|
||||||
|
|
||||||
BME280Data bmedata;
|
|
||||||
|
|
||||||
int currentSecond = -1;
|
int currentSecond = -1;
|
||||||
|
|
||||||
void showDateTime(struct tm tinfo);
|
void updateDateTime(struct tm tinfo);
|
||||||
|
|
||||||
void setBMEreadtime(int time) {
|
void setBMEreadtime(int time) {
|
||||||
bmeReadTime = time * 1000;
|
bmeReadTime = time * 1000;
|
||||||
@@ -56,13 +56,15 @@ void setup() {
|
|||||||
delay (1000);
|
delay (1000);
|
||||||
Serial.println(LVGL_Arduino);
|
Serial.println(LVGL_Arduino);
|
||||||
|
|
||||||
initBME280();
|
// initBME280();
|
||||||
|
|
||||||
// Start LVGL
|
// Start LVGL
|
||||||
setup_grafik();
|
setup_grafik();
|
||||||
Serial.println("LVGL started");
|
Serial.println("LVGL started");
|
||||||
|
|
||||||
bmedata = readBME280();
|
// bmedata = readBME280();
|
||||||
|
// bmedata.hum = getRelativeFeuchte(bmedata.temp, bmedata.hum);
|
||||||
|
// bmedata.temp = bmedata.temp - tempOffset;
|
||||||
arcTemp.value = bmedata.temp;
|
arcTemp.value = bmedata.temp;
|
||||||
arcHum.value = bmedata.hum;
|
arcHum.value = bmedata.hum;
|
||||||
delay(1000);
|
delay(1000);
|
||||||
@@ -75,16 +77,16 @@ void setup() {
|
|||||||
connectToWifi();
|
connectToWifi();
|
||||||
|
|
||||||
// Start MQTT
|
// Start MQTT
|
||||||
setupMQTT();
|
setup_mqtt();
|
||||||
connectToMqtt();
|
|
||||||
Serial.println("MQTT started");
|
// Get the time
|
||||||
|
|
||||||
timeinfo = gettheTime(NTPREADTIME);
|
timeinfo = gettheTime(NTPREADTIME);
|
||||||
showDateTime(timeinfo);
|
updateDateTime(timeinfo);
|
||||||
|
|
||||||
bmeReadtimer = millis();
|
bmeReadtimer = millis();
|
||||||
|
|
||||||
drawChart();
|
drawChart();
|
||||||
|
showResetTime(timeinfo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Register print function for debugging
|
// Register print function for debugging
|
||||||
@@ -97,36 +99,70 @@ void setup() {
|
|||||||
*/
|
*/
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
|
/* Test Routinen
|
||||||
|
const float tsttemp[] = {27.7, 26.9, 26.7, 26.7, 26.0};
|
||||||
|
const float tsthum[] = {62.0, 53.0, 50.0, 48.0, 39.0};
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
Serial.printf("%d temp: %.1f hum: %.1f relF: %d\n", i, tsttemp[i], tsthum[i], getRelativeFeuchte(tsttemp[i], tsthum[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
timeinfo = gettheTime(NTPREADTIME);
|
timeinfo = gettheTime(NTPREADTIME);
|
||||||
if (timeinfo.tm_sec == 0) { // minute over
|
if (timeinfo.tm_sec == 0) { // minute over
|
||||||
showDateTime(timeinfo);
|
updateDateTime(timeinfo);
|
||||||
}
|
}
|
||||||
if (millis() - bmeReadtimer > bmeReadTime) {
|
if (millis() - bmeReadtimer > bmeReadTime) {
|
||||||
bmeReadtimer = millis();
|
bmeReadtimer = millis();
|
||||||
bmedata = readBME280();
|
// bmedata = readBME280();
|
||||||
publishMQTTmessage(bmedata.temp, bmedata.hum);
|
// float tmess = bmedata.temp;
|
||||||
|
// float hmess = bmedata.hum;
|
||||||
|
// bmedata.hum = getRelativeFeuchte(bmedata.temp, bmedata.hum);
|
||||||
|
// bmedata.temp = bmedata.temp - tempOffset;
|
||||||
|
// doPublish(bmedata.temp, bmedata.hum, tmess, hmess);
|
||||||
}
|
}
|
||||||
if (millis() - updatetimer > updateTime) {
|
if (millis() - updatetimer > updateTime) {
|
||||||
updatetimer = millis();
|
updatetimer = millis();
|
||||||
updatechartData(bmedata.temp, bmedata.hum);
|
updatechartData(bmedata.temp+arcTemp.value_offset, bmedata.hum+arcHum.value_offset);
|
||||||
setValuetoArc(arcTemp, bmedata.temp);
|
setValuetoArc(arcTemp, bmedata.temp+arcTemp.value_offset);
|
||||||
setValuetoArc(arcHum, bmedata.hum);
|
setValuetoArc(arcHum, bmedata.hum+arcHum.value_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkMQTT();
|
||||||
|
// if (!client.connected())
|
||||||
|
// {
|
||||||
|
// reconnect();
|
||||||
|
// }
|
||||||
|
// client.loop();
|
||||||
|
|
||||||
|
|
||||||
|
server.handleClient();
|
||||||
|
ElegantOTA.loop();
|
||||||
|
|
||||||
lv_task_handler(); // let the GUI do its work
|
lv_task_handler(); // let the GUI do its work
|
||||||
lv_tick_inc(5); // tell LVGL how much time has passed
|
lv_tick_inc(5); // tell LVGL how much time has passed
|
||||||
delay(5); // let this time pass
|
delay(5); // let this time pass
|
||||||
}
|
}
|
||||||
|
|
||||||
void showDateTime(struct tm tinfo) {
|
void updateDateTime(struct tm tinfo) {
|
||||||
char time[6];
|
char time[6];
|
||||||
char date[50];
|
static char date[50];
|
||||||
strftime(time, 6, "%H:%M", &tinfo);
|
strftime(time, 6, "%H:%M", &tinfo);
|
||||||
strftime(date, 50, "%A, %d %B %Y", &tinfo);
|
int wd = tinfo.tm_wday;
|
||||||
lv_label_set_text(time_label, time);
|
int mo = tinfo.tm_mon;
|
||||||
lv_label_set_text(date_label, date);
|
int day = tinfo.tm_mday;
|
||||||
}
|
int year = tinfo.tm_year + 1900;
|
||||||
|
sprintf(date, "%s, %d. %s %d", wday[wd], day, month[mo], year);
|
||||||
|
setDateTime(time, date);
|
||||||
|
// Check if day has just changed
|
||||||
|
if (timeinfo.tm_hour = 0 && timeinfo.tm_min == 0 && timeinfo.tm_sec == 0) {
|
||||||
|
esp_restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
19
src/main.h
19
src/main.h
@@ -1,33 +1,46 @@
|
|||||||
#ifndef MAIN_H
|
#ifndef MAIN_H
|
||||||
#define MAIN_H
|
#define MAIN_H
|
||||||
|
|
||||||
|
#include <version.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/timers.h"
|
#include "freertos/timers.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VERSION "1.3.3"
|
|
||||||
#define VDATE "2024-07-23"
|
|
||||||
|
|
||||||
//#define MAXREADINGS 224
|
//#define MAXREADINGS 224
|
||||||
#define MAXREADINGS 200
|
#define MAXREADINGS 200
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float temp;
|
||||||
|
float hum;
|
||||||
|
float pres;
|
||||||
|
} BME280Data;
|
||||||
|
|
||||||
#ifdef MAIN
|
#ifdef MAIN
|
||||||
|
const char* wday[] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
|
||||||
|
const char* month[] = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"};
|
||||||
TimerHandle_t mqttReconnectTimer;
|
TimerHandle_t mqttReconnectTimer;
|
||||||
TimerHandle_t wifiReconnectTimer;
|
TimerHandle_t wifiReconnectTimer;
|
||||||
int bmeReadTime = 10000;
|
int bmeReadTime = 10000;
|
||||||
int updateTime = 30000;
|
int updateTime = 30000;
|
||||||
struct tm timeinfo;
|
struct tm timeinfo;
|
||||||
|
int oldDay = 0;
|
||||||
|
BME280Data bmedata;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
extern const char* wday[7];
|
||||||
|
extern const char* month[12];
|
||||||
extern TimerHandle_t mqttReconnectTimer;
|
extern TimerHandle_t mqttReconnectTimer;
|
||||||
extern TimerHandle_t wifiReconnectTimer;
|
extern TimerHandle_t wifiReconnectTimer;
|
||||||
extern int bmeReadTime;
|
extern int bmeReadTime;
|
||||||
extern int updateTime;
|
extern int updateTime;
|
||||||
extern struct tm timeinfo;
|
extern struct tm timeinfo;
|
||||||
|
extern BME280Data bmedata;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void setBMEreadtime(int time);
|
void setBMEreadtime(int time);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
180
src/mqtt.cpp
180
src/mqtt.cpp
@@ -1,93 +1,43 @@
|
|||||||
#define MQTT
|
#define MQTT
|
||||||
|
|
||||||
#include "grafik.h"
|
#include "grafik.h"
|
||||||
|
// #include "handlebme280.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "weifi.h"
|
#include "weifi.h"
|
||||||
|
// #include "interpolation.h"
|
||||||
#include "mqtt.h"
|
#include "mqtt.h"
|
||||||
|
|
||||||
void setupMQTT() {
|
|
||||||
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
|
|
||||||
// wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
|
|
||||||
// WiFi.onEvent(WiFiEvent);
|
|
||||||
mqttClient.onConnect(onMqttConnect);
|
|
||||||
mqttClient.onDisconnect(onMqttDisconnect);
|
|
||||||
mqttClient.onSubscribe(onMqttSubscribe);
|
|
||||||
mqttClient.onUnsubscribe(onMqttUnsubscribe);
|
|
||||||
mqttClient.onMessage(onMqttMessage);
|
|
||||||
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
|
|
||||||
mqttClient.setCredentials(BROKER_USER, BROKER_PASS);
|
|
||||||
// connectToWifi();
|
|
||||||
}
|
|
||||||
|
|
||||||
void connectToMqtt() {
|
|
||||||
Serial.println("Connecting to MQTT...");
|
|
||||||
mqttClient.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
void onMqttConnect(bool sessionPresent) {
|
|
||||||
Serial.println("Connected to MQTT.");
|
|
||||||
/*Serial.print("Session present: ");
|
|
||||||
Serial.println(sessionPresent);*/
|
|
||||||
|
|
||||||
// Subscribe to topic "message" when it connects to the broker
|
|
||||||
char topic[50];
|
|
||||||
strcpy(topic, MQTT_TOPIC);
|
|
||||||
strcat(topic,"#");
|
|
||||||
Serial.println(topic);
|
|
||||||
uint16_t packetIdSub = mqttClient.subscribe(topic, 2);
|
|
||||||
//Serial.print("Subscribing at QoS 2, packetId: ");
|
|
||||||
//Serial.println(packetIdSub);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
|
|
||||||
Serial.println("Disconnected from MQTT.");
|
|
||||||
Serial.printf("Wifi-Connected: %d\n", WiFi.isConnected());
|
|
||||||
if (WiFi.isConnected()) {
|
|
||||||
xTimerStart(mqttReconnectTimer, 0);
|
|
||||||
} else {
|
|
||||||
connectToWifi();
|
|
||||||
xTimerStart(mqttReconnectTimer, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
|
|
||||||
/*Serial.println("Subscribe acknowledged.");
|
|
||||||
Serial.print(" packetId: ");
|
|
||||||
Serial.println(packetId);
|
|
||||||
Serial.print(" qos: ");
|
|
||||||
Serial.println(qos);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void onMqttUnsubscribe(uint16_t packetId) {
|
|
||||||
/*Serial.println("Unsubscribe acknowledged.");
|
|
||||||
Serial.print(" packetId: ");
|
|
||||||
Serial.println(packetId);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
|
|
||||||
void parseMQTTmessages(char *topic, String msg) {
|
//-----------------------------------------
|
||||||
// Parse the JSON message
|
// MQTT message arrives
|
||||||
DeserializationError error = deserializeJson(doc, msg);
|
void onmessage(char *tp, byte *msg, unsigned int length)
|
||||||
|
{
|
||||||
|
String topic = String(tp);
|
||||||
|
msg[length] = '\0';
|
||||||
|
String message = String((char *)(msg));
|
||||||
|
Serial.printf("Message arrived: %s %s\n", topic.c_str(), message.c_str());
|
||||||
|
DeserializationError error = deserializeJson(doc, message);
|
||||||
if (error) {
|
if (error) {
|
||||||
Serial.print(F("deserializeJson() failed: "));
|
Serial.print(F("deserializeJson() failed: "));
|
||||||
Serial.println(error.c_str());
|
Serial.println(error.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Extract values
|
|
||||||
bool istemp = true;
|
bool istemp = true;
|
||||||
float val = 0.0;
|
float val = 0.0;
|
||||||
if (strcmp(topic, "CYD/set/hm/aussen") == 0) {
|
|
||||||
if(doc.containsKey("temperature")) {
|
if (topic.startsWith("hm/status/Aussen_Temp:1/")) {
|
||||||
|
struct tm timeinfo = gettheTime(1);
|
||||||
|
if (topic.endsWith("TEMPERATURE")) {
|
||||||
istemp = true;
|
istemp = true;
|
||||||
val = doc["temperature"];
|
|
||||||
}
|
}
|
||||||
if(doc.containsKey("humidity")) {
|
if (topic.endsWith("HUMIDITY")) {
|
||||||
istemp = false;
|
istemp = false;
|
||||||
val = doc["humidity"];
|
|
||||||
}
|
}
|
||||||
|
val = doc["val"];
|
||||||
setAussenDataValues(val, istemp, timeinfo);
|
setAussenDataValues(val, istemp, timeinfo);
|
||||||
} else if (strcmp(topic, "CYD/set/parameter") == 0) {
|
} else if (topic == MQTT_TOPIC "set/parameter") {
|
||||||
if(doc.containsKey("bmerate")) {
|
if(doc.containsKey("bmerate")) {
|
||||||
setBMEreadtime(doc["bmerate"]);
|
setBMEreadtime(doc["bmerate"]);
|
||||||
// showRate(doc["bmerate"]);
|
// showRate(doc["bmerate"]);
|
||||||
@@ -96,28 +46,82 @@ void parseMQTTmessages(char *topic, String msg) {
|
|||||||
setBMEreadtime(doc["updaterate"]);
|
setBMEreadtime(doc["updaterate"]);
|
||||||
// showRate(doc["updaterate"]);
|
// showRate(doc["updaterate"]);
|
||||||
}
|
}
|
||||||
|
// if(doc.containsKey("tempoffset")) {
|
||||||
|
// tempOffset = (float)doc["tempoffset"];
|
||||||
|
// }
|
||||||
|
// if(doc.containsKey("humoffset")) {
|
||||||
|
// humOffset = (float)doc["humoffset"];
|
||||||
|
// }
|
||||||
|
// Serial.printf("tempoffset: %.1f, humoffset: %.1f\n",tempOffset, humOffset);
|
||||||
|
} else if (topic == MQTT_TOPIC "set/messwerte") {
|
||||||
|
// aktuelle Messwerte kommen rein
|
||||||
|
if (doc.containsKey("temperature")) {
|
||||||
|
bmedata.temp = doc["temperature"];
|
||||||
|
}
|
||||||
|
if (doc.containsKey("humidity")) {
|
||||||
|
bmedata.hum = doc["humidity"];
|
||||||
|
}
|
||||||
|
} else if (topic == MQTT_TOPIC "get") {
|
||||||
|
if(doc.containsKey("send")) {
|
||||||
|
if(doc["send"] == "ip") {
|
||||||
|
char ip[30];
|
||||||
|
sprintf(ip, "{\"ip\":\"%s\"}", WiFi.localIP().toString().c_str());
|
||||||
|
client.publish(MQTT_TOPIC "get/ip", ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
|
|
||||||
// Do whatever you want when you receive a message
|
|
||||||
// Save the message in a variable
|
|
||||||
String received_message;
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
received_message += (char)payload[i];
|
|
||||||
}
|
|
||||||
Serial.printf("%s:%s\n", topic, received_message.c_str());
|
|
||||||
// Display the text message on the display receive from the MQTT topic "message"
|
|
||||||
parseMQTTmessages(topic, received_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MQTT_PUB_TEMP "CYD/get/bme280"
|
// Connect or reconnect to MQTT and subscribe
|
||||||
|
void reconnect(void)
|
||||||
|
{
|
||||||
|
while (!client.connected())
|
||||||
|
{
|
||||||
|
Serial.print("Reconnecting...");
|
||||||
|
bool erg = client.connect(CLIENT_ID, MQTT_USER, MQTT_PASSWD);
|
||||||
|
Serial.println(erg);
|
||||||
|
|
||||||
|
if (!client.connect(CLIENT_ID, MQTT_USER, MQTT_PASSWD))
|
||||||
|
{
|
||||||
|
Serial.print("failed, rc=");
|
||||||
|
Serial.print(client.state());
|
||||||
|
Serial.println(" retrying in 5 seconds");
|
||||||
|
delay(5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.println("Connected");
|
||||||
|
client.subscribe(MQTT_TOPIC "set/parameter");
|
||||||
|
client.subscribe(MQTT_TOPIC "set/messwerte");
|
||||||
|
client.subscribe(MQTT_TOPIC "get");
|
||||||
|
client.subscribe("hm/status/Aussen_Temp:1/#");
|
||||||
|
}
|
||||||
|
|
||||||
|
void doPublish(float temp, float hum, float tm, float hm) {
|
||||||
|
char payload[80];
|
||||||
|
sprintf(payload, "{\"temperature\":%.1f,\"tempmess\":%.1f,\"humidity\":%.1f,\"hummess\":%.1f}", temp, tm, hum, hm);
|
||||||
|
client.publish(MQTT_PUB_TEMP, payload);
|
||||||
|
Serial.printf("Published: %s %s\n", MQTT_PUB_TEMP, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// check MQTT in the loop
|
||||||
|
void checkMQTT(void) {
|
||||||
|
if (!client.connected())
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.println("try to reconnect");
|
||||||
|
reconnect();
|
||||||
|
}
|
||||||
|
client.loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Setup MQTT client
|
||||||
|
void setup_mqtt(void) {
|
||||||
|
Serial.printf("Setup MQTT to broker %s ...\n", MQTT_BROKER);
|
||||||
|
client.setClient(espClient);
|
||||||
|
client.setServer(MQTT_BROKER, MQTT_PORT);
|
||||||
|
client.setCallback(onmessage);
|
||||||
|
}
|
||||||
|
|
||||||
void publishMQTTmessage(float temp, float hum) {
|
|
||||||
// Publish an MQTT message on topic esp32/ds18b20/temperature
|
|
||||||
char payload[50];
|
|
||||||
sprintf(payload, "{\"temperature\":%.1f,\"humidity\":%.1f}", temp, hum);
|
|
||||||
uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, payload);
|
|
||||||
// Serial.printf("Publishing on topic %s at QoS 1, packetId: ", MQTT_PUB_TEMP);
|
|
||||||
// Serial.println(packetIdPub1);
|
|
||||||
}
|
|
||||||
35
src/mqtt.h
35
src/mqtt.h
@@ -1,33 +1,22 @@
|
|||||||
#ifndef MQTT_H
|
#pragma once
|
||||||
#define MQTT_H
|
|
||||||
|
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <AsyncMqttClient.h>
|
#include <PubSubClient.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
#define MQTT_HOST IPAddress(192,168,178,92) // MQTT BROKER IP ADDRESS
|
#define CLIENT_ID "Bad"
|
||||||
//#define MQTT_HOST "example.com" // MQTT BROKER URL
|
#define MQTT_TOPIC "CYD/Bad/"
|
||||||
#define MQTT_PORT 1883
|
#define MQTT_PUB_TEMP "CYD/Bad/state/bme280"
|
||||||
#define BROKER_USER "rxf"
|
|
||||||
#define BROKER_PASS "Tux4S!ech"
|
|
||||||
|
|
||||||
#define MQTT_TOPIC "CYD/set/"
|
|
||||||
|
|
||||||
#ifdef MQTT
|
#ifdef MQTT
|
||||||
AsyncMqttClient mqttClient;
|
WiFiClient espClient;
|
||||||
|
PubSubClient client(espClient);
|
||||||
#else
|
#else
|
||||||
extern AsyncMqttClient mqttClient;
|
extern PubSubClient client;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void setupMQTT();
|
|
||||||
void connectToMqtt();
|
|
||||||
void onMqttConnect(bool sessionPresent);
|
|
||||||
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason);
|
|
||||||
void onMqttSubscribe(uint16_t packetId, uint8_t qos);
|
|
||||||
void onMqttUnsubscribe(uint16_t packetId);
|
|
||||||
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total);
|
|
||||||
void publishMQTTmessage(float temp, float hum);
|
|
||||||
|
|
||||||
|
void reconnect(void);
|
||||||
#endif
|
void doPublish(float temp, float hum, float tm, float hm);
|
||||||
|
void checkMQTT(void);
|
||||||
|
void setup_mqtt(void);
|
||||||
54
src/version.h
Normal file
54
src/version.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// Versionsgeschichte
|
||||||
|
|
||||||
|
#define VERSION "2.0.1"
|
||||||
|
#define VDATE "2025-10-26"
|
||||||
|
#define VTIME "08:00 UTC"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Version Date Author
|
||||||
|
2.0.1 2025-10-26 rxf
|
||||||
|
- DST jetzt hoffentlich richtig mit dem TZ-String
|
||||||
|
|
||||||
|
2.0.0 2025-06-09 rxf
|
||||||
|
- Messwerte werden nun vom ZigBee-Sensor per MQTT empfangen,
|
||||||
|
d.h. der BME280 wird nicht mehr verwendet
|
||||||
|
|
||||||
|
1.6.4 2025-04-12 rxf
|
||||||
|
- Neuer Versuchmit DST
|
||||||
|
- täglich um 0h00 Restart
|
||||||
|
|
||||||
|
1.6.3 2024-10-27 rxf
|
||||||
|
- Daylight-Saving-Time (DST) berücksichtigt (DST-Offset = 0!!)
|
||||||
|
|
||||||
|
1.6.2 2024-08-23 rxf
|
||||||
|
- IP-Adresse per MQTT abfragen
|
||||||
|
- Farben per #define festlegen
|
||||||
|
|
||||||
|
1.6.1 2024-08-23 rxf
|
||||||
|
- Publish mit Topic CYD/Bad/status/bme280
|
||||||
|
- MQTT confidentials nach config.h verschoben
|
||||||
|
- Versionsnummer nach rechts
|
||||||
|
|
||||||
|
1.6.0 2024-08-23 rxf
|
||||||
|
- MQTT CLINT_ID auf 'Bad'
|
||||||
|
- MQTT_TOPIC auf 'CYD/Bad/'
|
||||||
|
- Subcriben von hm/... direkt (nicht mehr über CYD-Topic)
|
||||||
|
- Datum-Texte auf deutsch
|
||||||
|
|
||||||
|
1.5.2 2024-08-21 rxf
|
||||||
|
- Payloadbuffer für MQTT auf 80 Byte vergrößert
|
||||||
|
- Version-Time zu version.h hinzugefügt und zur Anzeige
|
||||||
|
- tempoffset und humoffset per MQTT einstellbar
|
||||||
|
|
||||||
|
1.5.1 2024-08-21 rxf
|
||||||
|
- Temperaturanzeige ebenfalls angepasst (-3.2°C)
|
||||||
|
- via MQTT gemessen und berechte Werte ausgeben
|
||||||
|
|
||||||
|
1.5.0 2024-08-21 rxf
|
||||||
|
- Mit Hilfe von Interpolation werde die echten Feuchtewerte ausgerechnet und angezeigt
|
||||||
|
- Die Werte sind jetzt (soweit) korrekt
|
||||||
|
|
||||||
|
1.4.0 2024-08-19 rxf
|
||||||
|
- Funktioniert soweit allerdings sind die Werte nicht korrekt, da sich der Sensor erwärmt
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "mqtt.h"
|
#include "mqtt.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
|
|
||||||
struct tm gettheTime(int repeat) {
|
struct tm gettheTime(int repeat) {
|
||||||
if(!getLocalTime(&timeinfo)){
|
if(!getLocalTime(&timeinfo)){
|
||||||
Serial.println("Failed to obtain time");
|
Serial.println("Failed to obtain time");
|
||||||
@@ -54,11 +55,23 @@ void connectToWifi() {
|
|||||||
Serial.print("Connected to the WiFi with IP: ");
|
Serial.print("Connected to the WiFi with IP: ");
|
||||||
Serial.println(WiFi.localIP());
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
|
configTime(0, 0 , ntpServer);
|
||||||
|
setenv("TZ","CET-1CEST,M3.5.0,M10.5.0/3",1);
|
||||||
|
tzset();
|
||||||
printLocalTime();
|
printLocalTime();
|
||||||
|
|
||||||
|
server.on("/", []() {
|
||||||
|
server.send(200, "text/plain", "Hi! This is ElegantOTA Demo.");
|
||||||
|
});
|
||||||
|
|
||||||
|
ElegantOTA.begin(&server); // Start ElegantOTA
|
||||||
|
server.begin();
|
||||||
|
Serial.println("HTTP server started");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void WiFiEvent(WiFiEvent_t event) {
|
void WiFiEvent(WiFiEvent_t event) {
|
||||||
Serial.printf("[WiFi-event] event: %d\n", event);
|
Serial.printf("[WiFi-event] event: %d\n", event);
|
||||||
|
|||||||
12
src/weifi.h
12
src/weifi.h
@@ -2,6 +2,11 @@
|
|||||||
#define WEIFI_H
|
#define WEIFI_H
|
||||||
|
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
#include <WebServer.h>
|
||||||
|
|
||||||
|
#include <ElegantOTA.h>
|
||||||
|
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -12,7 +17,12 @@
|
|||||||
#ifdef WEIFI
|
#ifdef WEIFI
|
||||||
const char *ntpServer = "pool.ntp.org";
|
const char *ntpServer = "pool.ntp.org";
|
||||||
const long gmtOffset_sec = 3600;
|
const long gmtOffset_sec = 3600;
|
||||||
const int daylightOffset_sec = 3600;
|
const int daylightOffset_sec = 0;
|
||||||
|
|
||||||
|
WebServer server(80);
|
||||||
|
|
||||||
|
#else
|
||||||
|
extern WebServer server;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user