An error occurred while loading the file. Please try again.
mqtt.cpp 8.58 KiB
#include "mqtt.h"
namespace config {
  // Values should be defined in config.h
  uint16_t sending_interval = MQTT_SENDING_INTERVAL; // [s]
  //INFO: Listen to every CO2 sensor which is connected to the server:
  //  mosquitto_sub -h MQTT_SERVER -t 'CO2sensors/#' -p 443 --capath /etc/ssl/certs/ -u "MQTT_USER" -P "MQTT_PASSWORD" -v
  const char *mqtt_server = MQTT_SERVER;
  const uint16_t mqtt_port = MQTT_PORT;
  const char *mqtt_user = MQTT_USER;
  const char *mqtt_password = MQTT_PASSWORD;
  const char *fingerprint PROGMEM = MQTT_SERVER_FINGERPRINT;
  const bool allow_mqtt_commands = ALLOW_MQTT_COMMANDS;
  const unsigned long wait_after_fail = 900; // [s] Wait 15 minutes after an MQTT connection fail, before trying again.
#if defined(ESP32)
#  include <WiFiClientSecure.h>
#endif
WiFiClientSecure espClient;
PubSubClient mqttClient(espClient);
namespace mqtt {
  unsigned long last_sent_at = 0;
  unsigned long last_failed_at = 0;
  String publish_topic;
  const char *json_sensor_format;
  String last_successful_publish = "";
  void initialize(String &topic) {
    json_sensor_format = PSTR("{\"time\":\"%s\", \"co2\":%d, \"temp\":%.1f, \"rh\":%.1f}");
    publish_topic = topic;
#if defined(ESP8266)
    espClient.setFingerprint(config::fingerprint); // not supported by ESP32
#endif
    // mqttClient.setSocketTimeout(config::mqtt_timeout); //NOTE: somehow doesn't seem to have any effect on connect()
    mqttClient.setServer(config::mqtt_server, config::mqtt_port);
  void publish(const String &timestamp, int16_t co2, float temperature, float humidity) {
    if (WiFi.status() == WL_CONNECTED && mqttClient.connected()) {
      LedEffects::onBoardLEDOn();
      Serial.print(F("Publishing MQTT message ... "));
      char payload[75]; // Should be enough for json...
      snprintf(payload, sizeof(payload), json_sensor_format, timestamp.c_str(), co2, temperature, humidity);
      // Topic is the same as clientID. e.g. 'CO2sensors/ESP3d03da'
      if (mqttClient.publish(publish_topic.c_str(), payload)) {
        Serial.println(F("OK"));
        last_successful_publish = ntp::getLocalTime();
      } else {
        Serial.println(F("Failed."));
      LedEffects::onBoardLEDOff();
  void setTimer(String messageString) {
    messageString.replace("timer ", "");
    int timestep = messageString.toInt();
    if (timestep >= 2 && timestep <= 1800) {
      Serial.print(F("Setting Measurement Interval to : "));
      Serial.print(timestep);
      Serial.println("s.");
      sensor::scd30.setMeasurementInterval(messageString.toInt());
      config::measurement_timestep = messageString.toInt();
      LedEffects::showKITTWheel(color::green, 1);