diff --git a/operame.ino b/operame.ino index 5593276..7edb46c 100644 --- a/operame.ino +++ b/operame.ino @@ -1,9 +1,11 @@ #include +#include #include #include #include #include #include +#include #include #include #include @@ -12,6 +14,8 @@ #include #include //#include +#include "Stream.h" + #define LANGUAGE "nl" @@ -24,14 +28,17 @@ OperameLanguage::Texts T; enum Driver { AQC, MHZ }; -Driver driver; -MQTTClient mqtt; -HardwareSerial hwserial1(1); -TFT_eSPI display; -TFT_eSprite sprite(&display); -MHZ19 mhz; + +Driver driver; +MQTTClient mqtt; +HardwareSerial hwserial1(1); +TFT_eSPI display; +TFT_eSprite sprite(&display); +MHZ19 mhz; +WiFiClientSecure wificlient; DHT dht(DHTPIN, DHTTYPE); + const int pin_portalbutton = 35; const int pin_demobutton = 0; const int pin_backlight = 4; @@ -53,6 +60,15 @@ bool wifi_enabled; bool mqtt_enabled; int max_failures; +// REST configuration via WiFiSettings +unsigned long rest_interval; +int rest_port; +String rest_domain; +String rest_uri; +String rest_resource_id; +String rest_cert; +bool rest_enabled; + void retain(const String& topic, const String& message) { Serial.printf("%s %s\n", topic.c_str(), message.c_str()); mqtt.publish(topic, message, true, 0); @@ -440,6 +456,17 @@ void setup() { mqtt_template = WiFiSettings.string("operame_mqtt_template", "{} PPM", T.config_mqtt_template); WiFiSettings.info(T.config_template_info); + WiFiSettings.heading("REST"); + rest_enabled = WiFiSettings.checkbox("operame_rest", false, T.config_rest) && wifi_enabled; + rest_domain = WiFiSettings.string("rest_domain", 150, "", T.config_rest_domain); + rest_uri = WiFiSettings.string("rest_uri", 600, "", T.config_rest_uri); + rest_port = WiFiSettings.integer("rest_port", 0, 65535, 443, T.config_rest_port); + rest_interval = 1000UL * WiFiSettings.integer("operame_rest_interval", 10, 3600, 60 * 5, T.config_rest_interval); + rest_resource_id = WiFiSettings.string("rest_resource_id", 64, "", T.config_rest_resource_id); + bool rest_cert_enabled = WiFiSettings.checkbox("operame_rest_cert", false, T.config_rest_cert_enabled); + rest_cert = WiFiSettings.string("rest_cert", 2000, "", T.config_rest_cert); + rest_cert.replace("\\n", "\n"); + WiFiSettings.onConnect = [] { display_big(T.connecting, TFT_BLUE); check_portalbutton(); @@ -477,12 +504,25 @@ void setup() { if (wifi_enabled) WiFiSettings.connect(false, 15); - static WiFiClient wificlient; if (mqtt_enabled) mqtt.begin(server.c_str(), port, wificlient); + if (rest_cert_enabled) wificlient.setCACert(rest_cert.c_str()); + if (ota_enabled) setup_ota(); } +void post_rest_message(DynamicJsonDocument message, Stream& stream) { + stream.println("POST " + rest_uri + " HTTP/1.1"); + stream.println("Host: " + rest_domain); + stream.println("Content-Type: application/json"); + stream.println("Connection: keep-alive"); + stream.print("Content-Length: "); + stream.println(measureJson(message)); + stream.println(); + serializeJson(message, stream); + stream.println(); +} + #define every(t) for (static unsigned long _lasttime; (unsigned long)((unsigned long)millis() - _lasttime) >= (t); _lasttime = millis()) void loop() { @@ -534,6 +574,26 @@ void loop() { } } + if (rest_enabled) { + while(wificlient.available()){ + String line = wificlient.readStringUntil('\r'); + Serial.print(line); + } + + every(rest_interval) { + if (co2 <= 0) break; + + const size_t capacity = JSON_OBJECT_SIZE(2); + DynamicJsonDocument message(capacity); + message["co2"] = co2; + message["id"] = rest_resource_id.c_str(); + + if (wificlient.connected() || wificlient.connect(&rest_domain[0], rest_port)) { + post_rest_message(message, wificlient); + } + } + } + if (ota_enabled) ArduinoOTA.handle(); check_buttons(); } diff --git a/operame_strings.h b/operame_strings.h index 1370aea..7a39d99 100644 --- a/operame_strings.h +++ b/operame_strings.h @@ -26,6 +26,14 @@ struct Texts { *config_mqtt_interval, *config_mqtt_template, *config_template_info, + *config_rest, + *config_rest_domain, + *config_rest_uri, + *config_rest_port, + *config_rest_interval, + *config_rest_resource_id, + *config_rest_cert_enabled, + *config_rest_cert, *connecting, *wait ; @@ -72,6 +80,14 @@ bool select(Texts& T, String language) { T.config_mqtt_topic = "Topic"; // probably should not be translated T.config_mqtt_interval = "Publication interval [s]"; T.config_mqtt_template = "Message template"; + T.config_rest = "Publish measurements via the HTTPS protocol"; + T.config_rest_domain = "Domain"; + T.config_rest_uri = "URI"; + T.config_rest_port = "TCP Port"; + T.config_rest_interval = "Publication interval [s]"; + T.config_rest_resource_id = "ID of this device"; + T.config_rest_cert_enabled = "Use CA root certificate"; + T.config_rest_cert = "CA root certificat"; T.config_template_info = "The {} in the template is replaced by the measurement value."; T.connecting = "Connecting to WiFi..."; T.portal_instructions = { @@ -138,6 +154,14 @@ bool select(Texts& T, String language) { T.config_mqtt_topic = "Topic"; // zo heet dat in MQTT T.config_mqtt_interval = "Publicatie-interval [s]"; T.config_mqtt_template = "Berichtsjabloon"; + T.config_rest = "Metingen via het HTTPS-protocol versturen"; + T.config_rest_domain = "Domein"; + T.config_rest_uri = "URI"; + T.config_rest_port = "TCP-Poort"; + T.config_rest_interval = "Publicatie-interval [s]"; + T.config_rest_resource_id = "ID van dit apparaat"; + T.config_rest_cert_enabled = "Gebruik een CA root certificaat"; + T.config_rest_cert = "CA root certificaat"; T.config_template_info = "De {} in het sjabloon wordt vervangen door de gemeten waarde."; T.connecting = "Verbinden met WiFi..."; T.portal_instructions = { diff --git a/platformio.ini b/platformio.ini index b69dbd0..bdc3c07 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,38 +20,46 @@ board_build.partitions = default.csv framework = arduino targets = upload monitor_speed = 115200 -lib_deps = - ESP-WiFiSettings@^3.7.2 - MH-Z19 - TFT_eSPI - MQTT -build_flags = - -DLANGUAGE_EN - -DLANGUAGE_NL - -DUSER_SETUP_LOADED=1 - -DST7789_DRIVER=1 - -DCGRAM_OFFSET=1 - -DTFT_WIDTH=135 - -DTFT_HEIGHT=240 - -DTFT_MOSI=19 - -DTFT_SCLK=18 - -DTFT_CS=5 - -DTFT_DC=16 - -DTFT_RST=-23 - -DTFT_BL=4 - -DTFT_BACKLIGHT_ON=HIGH - -DLOAD_GLCD=1 - -DLOAD_FONT2=1 - -DLOAD_FONT4=1 - -DLOAD_FONT6=1 - -DLOAD_FONT7=1 - -DLOAD_FONT8=1 - -DLOAD_GFXFF=1 - -DSPI_FREQUENCY=40000000 + +lib_deps = + ESP-WiFiSettings@^3.7.2 + MH-Z19 + TFT_eSPI + MQTT + ArduinoJson + adafruit/DHT sensor library@^1.4.2 + +build_flags = +# ESP-WiFiSettings languages: + -DLANGUAGE_EN + -DLANGUAGE_NL +# ESP32 debugging: +# -DCORE_DEBUG_LEVEL=5 +# TFT_eSPI configuration: + -DUSER_SETUP_LOADED=1 + -DST7789_DRIVER=1 + -DCGRAM_OFFSET=1 + -DTFT_WIDTH=135 + -DTFT_HEIGHT=240 + -DTFT_MOSI=19 + -DTFT_SCLK=18 + -DTFT_CS=5 + -DTFT_DC=16 + -DTFT_RST=-23 + -DTFT_BL=4 + -DTFT_BACKLIGHT_ON=HIGH + -DLOAD_GLCD=1 + -DLOAD_FONT2=1 + -DLOAD_FONT4=1 + -DLOAD_FONT6=1 + -DLOAD_FONT7=1 + -DLOAD_FONT8=1 + -DLOAD_GFXFF=1 + -DSPI_FREQUENCY=40000000 + [env:serial] upload_protocol = esptool -lib_deps = adafruit/DHT sensor library@^1.4.2 [env:ota] upload_protocol = espota @@ -59,4 +67,3 @@ upload_port = operame-HEX_HERE.local upload_flags = --port=3232 --auth=PASSWORD_HERE -lib_deps = adafruit/DHT sensor library@^1.4.2