#include #include #include extern "C" { #include "freertos/FreeRTOS.h" #include "freertos/timers.h" } #define MQTT_VALVE_COMMAND MQTT_TOPIC_BASE_SUB "/" MQTT_DEVICE_ID "/valve" #define MQTT_SOIL_PROPERTIES MQTT_TOPIC_BASE_SUB "/" MQTT_DEVICE_ID "/soil" TimerHandle_t mqttReconnectTimer; TimerHandle_t wifiReconnectTimer; // TimerHandle_t mqttProcessingTimer; TaskHandle_t mqttTask; WebServer Server; AutoConnect Portal(Server); WiFiClient client; AutoConnectConfig Config; // Config.autoReconnect = true; // WiFi.config(Config); MQTTClient mqttClient; void connectWiFi() { Serial.println("Start WiFi..."); if (Portal.begin()) { digitalWrite(PIN_LED_G, HIGH); } } void mqttLoop(void *parameter) { bool x; do { x = mqttClient.loop(); delay(50); } while (mqttClient.connected()); if (!mqttClient.connected()) { Serial.println("Disconnected from MQTT."); if (WiFi.isConnected()) { xTimerStart(mqttReconnectTimer, 0); } } vTaskDelete(NULL); } void connectMQTT() { Serial.println("Connecting to MQTT..."); mqttClient.begin(MQTT_HOST, MQTT_PORT, client); mqttClient.connect(MQTT_DEVICE_ID); if (mqttClient.connected()) { Serial.println("Connected!"); } else { Serial.println("NOT Connected!"); } mqttClient.subscribe(MQTT_PATH_SUB, 2); Serial.print("subscribed to: "); Serial.println(MQTT_PATH_SUB); xTaskCreate( mqttLoop, /* Task function. */ "mqttLoop", /* String with name of task. */ 8192, /* Stack size in bytes. */ NULL, /* Parameter passed as input of the task */ 1, /* Priority of the task. */ &mqttTask); /* Task handle. */ //xTimerStart(mqttProcessingTimer, 0); } void WiFiEvent(WiFiEvent_t event) { Serial.printf("[WiFi-event] event: %d\n", event); switch (event) { case SYSTEM_EVENT_STA_GOT_IP: Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); connectMQTT(); break; case SYSTEM_EVENT_STA_DISCONNECTED: digitalWrite(PIN_LED_G, LOW); xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi // xTimerStop(mqttProcessingTimer, 0); xTimerStart(wifiReconnectTimer, 0); break; } } void onMqttMessage(MQTTClient *client, char topic[], char payload[], int payload_length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < payload_length; i++) { Serial.print((char)payload[i]); } Serial.println(); if (strcmp(topic, MQTT_VALVE_COMMAND) == 0) { Serial.println("toggling valve..."); Serial.println(topic); toggleValve(); } if (strcmp(topic, MQTT_SOIL_PROPERTIES) == 0) { Serial.println("receiving soil thresholds..."); Serial.println(topic); Serial.println(payload); // const int capacity = JSON_OBJECT_SIZE(3) + 2 * JSON_OBJECT_SIZE(1); StaticJsonDocument<1024> doc; DeserializationError err = deserializeJson(doc, payload); if (err == DeserializationError::Ok) { int fc = doc["fc"]; int pwp = doc["pwp"]; int sat = doc["sat"]; setSoilProperties(fc, pwp, sat); } else { Serial.println(err.c_str()); } } } void setupConnections() { Serial.println(); Serial.println(); mqttReconnectTimer = xTimerCreate( "mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void *)0, reinterpret_cast(connectMQTT)); wifiReconnectTimer = xTimerCreate( "wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void *)0, reinterpret_cast(connectWiFi)); // mqttProcessingTimer = xTimerCreate( // "messageTimer", pdMS_TO_TICKS(50), pdTRUE, (void *)0, reinterpret_cast(mqttLoop)); WiFi.onEvent(WiFiEvent); mqttClient.onMessageAdvanced(onMqttMessage); connectWiFi(); } void publishMessage(const char *topic, const char *msg) { mqttClient.publish(topic, msg, true, 1); }