diff --git a/operame.ino b/operame.ino index d755952..bb7997f 100644 --- a/operame.ino +++ b/operame.ino @@ -1,25 +1,29 @@ #include +#include #include #include #include #include #include +#include #include #include #include #include #include +#include "Stream.h" #define LANGUAGE "nl" 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; const int pin_portalbutton = 35; const int pin_demobutton = 0; @@ -42,6 +46,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); @@ -392,6 +405,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(); @@ -429,12 +453,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() { @@ -467,6 +504,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 ba61e1f..2dc9d2a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,6 +25,7 @@ lib_deps = MH-Z19 TFT_eSPI MQTT + ArduinoJson build_flags = # ESP-WiFiSettings languages: