diff --git a/Co2Huzzah/Co2Huzzah.ino b/Co2Huzzah/Co2Huzzah.ino
index a00f5a5d087a7f0a8eec3576ab7ba3c7e3c63f5d..67ce917cce33220f43118eec2a7285a47abcc800 100644
--- a/Co2Huzzah/Co2Huzzah.ino
+++ b/Co2Huzzah/Co2Huzzah.ino
@@ -14,6 +14,9 @@
 #include "certs.h"
 #include <ESP8266WebServer.h>
 
+/* MQTT Lib */
+#include <PubSubClient.h>
+
 /*  ==================== Variables ==================== */
 /* If defined, then mode is 1 measure every 15 min. written in a file.
    Setup is not done. */
@@ -21,9 +24,9 @@
 
 /* ---------- Default values ---------- */
 #define SERIAL_BAUDRATE 115200
-#define MEASUREMENT_INTERVAL 60 /* seconds */
+#define MEASUREMENT_INTERVAL 60  /* seconds */
 #define NTP_UPDATE_INTERVAL 1800 /* 30 min = 1800s. */
-#define ALTITUDE 352 /* Clermont les Carmes */
+#define ALTITUDE 352             /* Clermont les Carmes */
 #define DEFAULT_SSID "irstea_invite"
 #define DEFAULT_HOST "CO2opain"
 #define DEFAULT_AP_PASSWD "CO2chon2"
@@ -31,14 +34,14 @@
 /* ------------------------------------------------- */
 /*     Keep some usual Strings static and shared     */
 /* ------------------------------------------------- */
-static String MSG[7]={
-  "[ERROR] ",
-  "[WARN] ",
-  "[INFO] ",
-  "application/octet-stream",
-  "application/json",
-  "text/html",
-  "HTTP1.1 required",
+static String MSG[7] = {
+    "[ERROR] ",
+    "[WARN] ",
+    "[INFO] ",
+    "application/octet-stream",
+    "application/json",
+    "text/html",
+    "HTTP1.1 required",
 };
 
 #define ERR 0
@@ -51,8 +54,6 @@ static String MSG[7]={
 
 /* ------------------------------------------------- */
 
-
-
 static char ssid[48];
 static char password[72];
 static char host[48];
@@ -63,11 +64,11 @@ static bool writeData = false;
 
 static String ntpServerName = "fr.pool.ntp.org";
 static String timezone = "Europe/Paris";
-const char* timeformat = "Y-m-d~TH:i:s;T";
+const char *timeformat = "Y-m-d~TH:i:s;T";
 
 /* ---------- filesystem ---------- */
-const char* fsName = "LittleFS";
-FS* fileSystem = &LittleFS;
+const char *fsName = "LittleFS";
+FS *fileSystem = &LittleFS;
 LittleFSConfig fileSystemConfig = LittleFSConfig();
 static bool fsOK;
 String unsupportedFiles = String();
@@ -109,57 +110,110 @@ static char cbuf[BUF_SIZE];
 
 static bool LED_STATUS = false;
 
+/* ---------- MQTT ------------------------*/
+const char *mqtt_broker = "10.63.65.95";
+const char *topic_co2 = "N4/ESP8266/SDC30/CO2";
+const char *topic_temp = "N4/ESP8266/SDC30/airTemperature";
+const char *topic_hum = "N4/ESP8266/SDC30/airHumidity";
+const int mqtt_port = 1883;
+const char *client_id = "CO2Pain";
+
+WiFiClient espClient;
+PubSubClient client(espClient);
 
 /*  ==================== Fonctions ==================== */
 
+/*----------- MQTT ---------- */
+
+void publishMQTT()
+{
+  for (int i = 0; i < 5; i++)
+  {
+    {
+      if (!client.connected())
+      {
+        client.connect(client_id);
+        delay(2000);
+      }
+      else
+      {
+        break;
+      }
+    }
+    char *co2_str[8];
+    dtostrf(co2, 5, 0, co2_str);
+    client.publish(topic_co2, co2_str);
+    char *temp_str[8];
+    dtostrf(temperature, 6, 2, temp_str);
+    client.publish(topic_temp, temp_str);
+    char *hum_str[8];
+    dtostrf(humidity, 6, 2, hum_str);
+    client.publish(topic_hum, hum_str);
+  }
+}
+
 /* ---------- HTTP ---------- */
 
 template <typename ServerType>
-void replyOK(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
+void replyOK(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
   (*server).send(200, FPSTR(TEXT_PLAIN), "");
 }
 
 template <typename ServerType>
-void replyOKWithMsg(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server, String msg) {
+void replyOKWithMsg(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server, String msg)
+{
   (*server).send(200, FPSTR(TEXT_PLAIN), msg);
 }
 
 template <typename ServerType>
-void replyNotFound(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server, String msg) {
+void replyNotFound(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server, String msg)
+{
   (*server).send(404, FPSTR(TEXT_PLAIN), msg);
 }
 
 template <typename ServerType>
-void replyBadRequest(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server, String msg) {
+void replyBadRequest(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server, String msg)
+{
   (*server).send(400, FPSTR(TEXT_PLAIN), msg + "\n");
 }
 
 template <typename ServerType>
-void replyServerError(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server, String msg) {
+void replyServerError(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server, String msg)
+{
   (*server).send(500, FPSTR(TEXT_PLAIN), msg + "\n");
 }
 
 /* Reads the given file from the filesystem and stream it back to the client */
 template <typename ServerType>
-bool handleFileRead(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server, String path) {
-  if (!fsOK) {
+bool handleFileRead(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server, String path)
+{
+  if (!fsOK)
+  {
     replyServerError(server, FPSTR(FS_INIT_ERROR));
     return true;
   }
-  if (path.startsWith("/wifiSetup.cfg") || path.startsWith("/apSetup.cfg")) {
+  if (path.startsWith("/wifiSetup.cfg") || path.startsWith("/apSetup.cfg"))
+  {
     replyNotFound(server, "File not found.");
     return true;
   }
 
-  if (path.endsWith("/")) path += "index.htm";
-  if (!fileSystem->exists(path)) path += "l";
-  if (!fileSystem->exists(path)) return false; // Re-try with .htm*l*
+  if (path.endsWith("/"))
+    path += "index.htm";
+  if (!fileSystem->exists(path))
+    path += "l";
+  if (!fileSystem->exists(path))
+    return false; // Re-try with .htm*l*
 
-  if ((*server).hasArg("download")) buf = MSG[MIME_STREAM];
-  else buf = mime::getContentType(path);
+  if ((*server).hasArg("download"))
+    buf = MSG[MIME_STREAM];
+  else
+    buf = mime::getContentType(path);
 
   File file = fileSystem->open(path, "r");
-  if ((*server).streamFile(file, buf) != file.size()) {
+  if ((*server).streamFile(file, buf) != file.size())
+  {
     // DBG_OUTPUT_PORT.println("Sent less data than expected!");
   }
   file.close();
@@ -168,25 +222,28 @@ bool handleFileRead(esp8266webserver::ESP8266WebServerTemplate<ServerType> *serv
 bool HTTPhandleFileRead(String path) { return handleFileRead(&HTTPserver, path); }
 bool HTTPShandleFileRead(String path) { return handleFileRead(&HTTPSserver, path); }
 
-
 /* The "Not Found" handler catches all URI not explicitly declared in code
    First try to find and return the requested file from the filesystem,
    and if it fails, return a 404 page with debug information */
 template <typename ServerType>
-void handleNotFound(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
-  if (!fsOK) return replyServerError(server, FPSTR(FS_INIT_ERROR));
+void handleNotFound(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
+  if (!fsOK)
+    return replyServerError(server, FPSTR(FS_INIT_ERROR));
 
   buf = ESP8266WebServer::urlDecode((*server).uri()); // required to read paths with blanks
-  if (handleFileRead(server, buf)) return;
+  if (handleFileRead(server, buf))
+    return;
 
   // Dump debug data
   buf = F("Error: File not found\n\nURI: ") + buf;
   buf += F("\nMethod: ");
-  buf += ((*server).method()==HTTP_GET)?"GET":"POST";
+  buf += ((*server).method() == HTTP_GET) ? "GET" : "POST";
   buf += F("\nArguments: ");
   buf += (*server).args();
   buf += '\n';
-  for (i = 0; i < (*server).args(); i++) {
+  for (i = 0; i < (*server).args(); i++)
+  {
     buf += F(" NAME:");
     buf += (*server).argName(i);
     buf += F("\n VALUE:");
@@ -202,67 +259,84 @@ void handleNotFound(esp8266webserver::ESP8266WebServerTemplate<ServerType> *serv
 void HTTPhandleNotFound() { return handleNotFound(&HTTPserver); }
 void HTTPShandleNotFound() { return handleNotFound(&HTTPSserver); }
 
-
 /* Returns the list of files in the directory specified by the "dir" query string parameter.
    Also demonstrates the use of chunked responses. */
 template <typename ServerType>
-void handleFileList(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
-  if (!fsOK) return replyServerError(server,FPSTR(FS_INIT_ERROR));
+void handleFileList(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
+  if (!fsOK)
+    return replyServerError(server, FPSTR(FS_INIT_ERROR));
 
-  if (!fileSystem->exists("/data")) {
+  if (!fileSystem->exists("/data"))
+  {
     (*server).send(200, MSG[MIME_JSON], "[]");
-    return; }
+    return;
+  }
 
   // use HTTP/1.1 Chunked response to avoid building a huge temporary string
-  if (!(*server).chunkedResponseModeStart(200, MSG[MIME_JSON])) {
+  if (!(*server).chunkedResponseModeStart(200, MSG[MIME_JSON]))
+  {
     (*server).send(505, MSG[MIME_HTML], MSG[SRV_MSG_HTTP]);
-    return; }
+    return;
+  }
 
   Dir dir = fileSystem->openDir("/data");
   buf = ""; // Will use the same string for every line
-  while (dir.next()) {
-    if (buf.length()) { // send string from previous iteration as an HTTP chunk
+  while (dir.next())
+  {
+    if (buf.length())
+    { // send string from previous iteration as an HTTP chunk
       (*server).sendContent(buf);
       buf = ',';
-    } else buf = '[';
+    }
+    else
+      buf = '[';
 
-    if (!dir.isDirectory()) {
+    if (!dir.isDirectory())
+    {
       buf += F("{\"size\":\"");
       buf += dir.fileSize();
     }
 
     buf += F("\",\"name\":\"");
     // Always return names without leading "/"
-    if (dir.fileName()[0] == '/') buf += &(dir.fileName()[1]);
-    else buf += dir.fileName();
+    if (dir.fileName()[0] == '/')
+      buf += &(dir.fileName()[1]);
+    else
+      buf += dir.fileName();
 
     buf += "\"}";
   }
 
-  buf += "]";   // send last string
+  buf += "]"; // send last string
   (*server).sendContent(buf);
   (*server).chunkedResponseFinalize();
 }
 void HTTPhandleFileList() { return handleFileList(&HTTPserver); }
 void HTTPShandleFileList() { return handleFileList(&HTTPSserver); }
 
-
 template <typename ServerType>
-void handleWifiScan(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
+void handleWifiScan(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
   int n = WiFi.scanNetworks();
-  if (!(*server).chunkedResponseModeStart(200, MSG[MIME_JSON])) {
+  if (!(*server).chunkedResponseModeStart(200, MSG[MIME_JSON]))
+  {
     (*server).send(505, MSG[MIME_HTML], MSG[SRV_MSG_HTTP]);
-    return; }
+    return;
+  }
 #ifdef DEMO_MODE
   (*server).sendContent(F("[\"* AP_1 (-71)\",\"  AP_2 (-59)\",\"* AP_3 (-75)\"]"));
 #else
-  buf='[';
-  for (i = 0; i < n; buf="") {
-    buf+="\"";
-    buf+=((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
-    buf+=" "+WiFi.SSID(i)+" ("+WiFi.RSSI(i)+")\"";
-    if (++i == n) buf+="]";
-    else buf+=",";
+  buf = '[';
+  for (i = 0; i < n; buf = "")
+  {
+    buf += "\"";
+    buf += ((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : "*");
+    buf += " " + WiFi.SSID(i) + " (" + WiFi.RSSI(i) + ")\"";
+    if (++i == n)
+      buf += "]";
+    else
+      buf += ",";
     (*server).sendContent(buf);
   }
 #endif
@@ -271,14 +345,15 @@ void handleWifiScan(esp8266webserver::ESP8266WebServerTemplate<ServerType> *serv
 void HTTPhandleWifiScan() { return handleWifiScan(&HTTPserver); }
 void HTTPShandleWifiScan() { return handleWifiScan(&HTTPSserver); }
 
-
-bool wifiConnect(char* ssId, char* pw) {
+bool wifiConnect(char *ssId, char *pw)
+{
   WiFi.begin(ssId, pw);
   delay(500);
   i = 0; /* 60 loops ~30s. */
   while ((WiFi.status() != WL_CONNECTED) && (i++ < 60))
     delay(500);
-  if (WiFi.status() == WL_CONNECTED) {
+  if (WiFi.status() == WL_CONNECTED)
+  {
     Serial.print(MSG[INFO]);
     Serial.print(F("Wifi connected to "));
     Serial.print(ssId);
@@ -295,7 +370,8 @@ bool wifiConnect(char* ssId, char* pw) {
 
 /* Initilizes Wifi. Uses global variables ssid, assword, host, ap_password.
  * Returns true if connected to an AP. */
-bool initWifi() {
+bool initWifi()
+{
   WiFi.mode(WIFI_AP_STA); /* Client AND AP */
   delay(100);
   WiFi.softAP(host, ap_password);
@@ -304,20 +380,26 @@ bool initWifi() {
 }
 
 template <typename ServerType>
-void handleWifiSet(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
+void handleWifiSet(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
   bool cnx, donotsave = true;
 #ifndef DEMO_MODE
   buf = (*server).arg("ssid");
-  if (buf.length() > 0) {
+  if (buf.length() > 0)
+  {
     buf.toCharArray(ssid, sizeof(ssid));
     buf = (*server).arg("pass");
     buf.toCharArray(password, sizeof(password));
     donotsave = (*server).hasArg("save");
-  } else return;
+  }
+  else
+    return;
 
   cnx = initWifi();
-  if (cnx) {
-    if ((fsOK) && (!donotsave)) {
+  if (cnx)
+  {
+    if ((fsOK) && (!donotsave))
+    {
       Serial.print(MSG[INFO]);
       Serial.println(F("Saving Wifi configuration."));
       File file = fileSystem->open("/wifiSetup.cfg", "w");
@@ -326,7 +408,9 @@ void handleWifiSet(esp8266webserver::ESP8266WebServerTemplate<ServerType> *serve
       delay(10);
       file.close();
     }
-  } else {
+  }
+  else
+  {
     Serial.print(MSG[WARN]);
     Serial.println(F("Resetting."));
     ESP.reset();
@@ -337,37 +421,48 @@ void handleWifiSet(esp8266webserver::ESP8266WebServerTemplate<ServerType> *serve
 void HTTPhandleWifiSet() { return handleWifiSet(&HTTPserver); }
 void HTTPShandleWifiSet() { return handleWifiSet(&HTTPSserver); }
 
-
 template <typename ServerType>
-void handleAP(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
+void handleAP(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
 #ifdef DEMO_MODE
-  buf="{\"ap\":\""; buf+=host; buf+="\",\"pw\":\"demo\"}";
+  buf = "{\"ap\":\"";
+  buf += host;
+  buf += "\",\"pw\":\"demo\"}";
 #else
-  buf="{\"ap\":\""; buf+=host; buf+="\",\"pw\":\""; buf+=ap_password; buf+="\"}";
+  buf = "{\"ap\":\"";
+  buf += host;
+  buf += "\",\"pw\":\"";
+  buf += ap_password;
+  buf += "\"}";
 #endif
   (*server).send(200, MSG[MIME_JSON], buf);
 }
 void HTTPhandleAP() { return handleAP(&HTTPserver); }
 void HTTPShandleAP() { return handleAP(&HTTPSserver); }
 
-
 template <typename ServerType>
-void handleAPSet(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
+void handleAPSet(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
   bool donotsave = true;
 #ifndef DEMO_MODE
   buf = (*server).arg("pass");
-  if (buf.length() < 8) {
+  if (buf.length() < 8)
+  {
     replyBadRequest(server, F("Password too short (8 char. min)"));
     return;
   }
-  if (buf.length() > 0) {
+  if (buf.length() > 0)
+  {
     buf.toCharArray(ap_password, sizeof(ap_password));
     buf = (*server).arg("ssid");
     buf.toCharArray(host, sizeof(host));
     donotsave = (*server).hasArg("save");
-  } else return;
+  }
+  else
+    return;
   initWifi();
-  if ((fsOK) && (!donotsave)) {
+  if ((fsOK) && (!donotsave))
+  {
     Serial.print(MSG[INFO]);
     Serial.println(F("Saving AP configuration."));
     File file = fileSystem->open("/apSetup.cfg", "w");
@@ -382,34 +477,37 @@ void handleAPSet(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
 void HTTPhandleAPSet() { return handleAPSet(&HTTPserver); }
 void HTTPShandleAPSet() { return handleAPSet(&HTTPSserver); }
 
-
 template <typename ServerType>
-void handleSensorSet(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
+void handleSensorSet(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
   bool donotsave = (*server).hasArg("save");
   bool w = (*server).hasArg("write");
 #ifndef DEMO_MODE
   buf = (*server).arg("ftxt");
   i = buf.toInt();
-  if ((i>0) && (i!=interval)) {
+  if ((i > 0) && (i != interval))
+  {
     interval = i;
     airSensor.setMeasurementInterval(interval);
   }
   buf = (*server).arg("alt");
   j = buf.toInt();
-  if ((j>=0) && (j!=altitude)) {
+  if ((j >= 0) && (j != altitude))
+  {
     altitude = j;
     airSensor.setAltitudeCompensation(altitude);
   }
   if ((w) && (!writeData))
-    datafile = "data/"+tz.dateTime("YmdHi")+".csv";
+    datafile = "data/" + tz.dateTime("YmdHi") + ".csv";
   writeData = w;
-  if ((fsOK) && (!donotsave)) {
+  if ((fsOK) && (!donotsave))
+  {
     Serial.print(MSG[INFO]);
     Serial.println(F("Saving Sensor configuration."));
     File file = fileSystem->open("/sensorSetup.cfg", "w");
     file.println(interval);
     file.println(altitude);
-    file.println((writeData)?"y":"n");
+    file.println((writeData) ? "y" : "n");
     delay(10);
     file.close();
   }
@@ -420,45 +518,58 @@ void HTTPhandleSensorSet() { return handleSensorSet(&HTTPserver); }
 void HTTPShandleSensorSet() { return handleSensorSet(&HTTPSserver); }
 
 template <typename ServerType>
-void handleStatus(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
+void handleStatus(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
   IPAddress ip = WiFi.softAPIP();
   FSInfo fs_info;
-  if (!(*server).chunkedResponseModeStart(200, MSG[MIME_JSON])) {
+  if (!(*server).chunkedResponseModeStart(200, MSG[MIME_JSON]))
+  {
     (*server).send(505, MSG[MIME_HTML], MSG[SRV_MSG_HTTP]);
-    return; }
+    return;
+  }
 
-  buf = F("{\"ap\":\""); buf += host; buf += F("\",\"aip\":\"");
-  for (i=0;i<4; buf+=((i==4)?"":".")) buf += ip[i++];
+  buf = F("{\"ap\":\"");
+  buf += host;
+  buf += F("\",\"aip\":\"");
+  for (i = 0; i < 4; buf += ((i == 4) ? "" : "."))
+    buf += ip[i++];
   buf += "\",";
   (*server).sendContent(buf);
 
   buf = F("\"ssid\":\"");
-  if (WiFi.status() == WL_CONNECTED) {
+  if (WiFi.status() == WL_CONNECTED)
+  {
     ip = WiFi.localIP();
-    buf += ssid; buf += "\",\"ip\":\"";
-    for (i=0;i<4; buf+=((i==4)?"":".")) buf+=ip[i++];
-  } else
+    buf += ssid;
+    buf += "\",\"ip\":\"";
+    for (i = 0; i < 4; buf += ((i == 4) ? "" : "."))
+      buf += ip[i++];
+  }
+  else
     buf += "\",\"ip\":\"";
   buf += "\",";
   (*server).sendContent(buf);
 
   buf = F("\"file\":\"");
-  if ((fsOK) && (writeData)) buf += datafile;
+  if ((fsOK) && (writeData))
+    buf += datafile;
   (*server).sendContent(buf);
   buf = F("\",\"freq\":");
-  buf += (sensorOK)?interval:-1;
+  buf += (sensorOK) ? interval : -1;
   buf += F(",\"alt\":");
-  buf += (sensorOK)?altitude:-1;
+  buf += (sensorOK) ? altitude : -1;
   buf += ",";
   (*server).sendContent(buf);
 
   buf = F("\"du\":");
-  if (fsOK) {
+  if (fsOK)
+  {
     fileSystem->info(fs_info);
     buf += fs_info.usedBytes;
     buf += F(",\"ds\":");
     buf += fs_info.totalBytes;
-  } else
+  }
+  else
     buf += F("-1,\"ds\":-1");
   buf += "}";
   (*server).sendContent(buf);
@@ -467,33 +578,37 @@ void handleStatus(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server
 void HTTPhandleStatus() { return handleStatus(&HTTPserver); }
 void HTTPShandleStatus() { return handleStatus(&HTTPSserver); }
 
-
 template <typename ServerType>
-void handleSetup(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
+void handleSetup(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
   buf = F("{\"freq\":");
-  buf += (sensorOK)?interval:-1;
+  buf += (sensorOK) ? interval : -1;
   buf += F(",\"alt\":");
-  buf += (sensorOK)?altitude:-1;
+  buf += (sensorOK) ? altitude : -1;
   buf += F(",\"write\":");
-  buf += (writeData)?"true":"false";
+  buf += (writeData) ? "true" : "false";
   buf += "}";
   (*server).send(200, MSG[MIME_JSON], buf);
 }
 void HTTPhandleSetup() { return handleSetup(&HTTPserver); }
 void HTTPShandleSetup() { return handleSetup(&HTTPSserver); }
 
-
-
 /* ---------- Date and time ---------- */
 template <typename ServerType>
-void handleDateTime(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
-  int h,m,d,mo,y;
+void handleDateTime(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
+  int h, m, d, mo, y;
 #ifndef DEMO_MODE
-  buf = (*server).arg("H"); h=buf.toInt();
-  buf = (*server).arg("M"); m=buf.toInt();
-  buf = (*server).arg("d"); d=buf.toInt();
-  buf = (*server).arg("mo"); mo=buf.toInt();
-  buf = (*server).arg("y"); y=buf.toInt();
+  buf = (*server).arg("H");
+  h = buf.toInt();
+  buf = (*server).arg("M");
+  m = buf.toInt();
+  buf = (*server).arg("d");
+  d = buf.toInt();
+  buf = (*server).arg("mo");
+  mo = buf.toInt();
+  buf = (*server).arg("y");
+  y = buf.toInt();
   setTime(h, m, 30, d, mo, y);
 #endif
   handleFileRead(server, "/");
@@ -501,35 +616,44 @@ void handleDateTime(esp8266webserver::ESP8266WebServerTemplate<ServerType> *serv
 void HTTPhandleDateTime() { return handleDateTime(&HTTPserver); }
 void HTTPShandleDateTime() { return handleDateTime(&HTTPSserver); }
 
-
 template <typename ServerType>
-void handleNTP(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
+void handleNTP(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
   bool donotsave = (*server).hasArg("save");
   bool chg = false;
 
 #ifndef DEMO_MODE
   buf = (*server).arg("ntp");
-  if (chg = (ntpServerName != buf)) {
+  if (chg = (ntpServerName != buf))
+  {
     ntpServerName = buf;
-    setServer(ntpServerName); }
+    setServer(ntpServerName);
+  }
 
   buf = (*server).arg("tz");
   if (timezone != buf)
-    if (!tz.setLocation(buf)) {
+    if (!tz.setLocation(buf))
+    {
       Serial.print(MSG[WARN]);
       Serial.print(F("Timezone setting failed -> "));
       Serial.println(buf);
-    } else {
+    }
+    else
+    {
       chg = true;
-      timezone = buf; }
+      timezone = buf;
+    }
 
   buf = (*server).arg("req");
   i = buf.toInt();
-  if (ntpUpdateInterval != i) {
+  if (ntpUpdateInterval != i)
+  {
     chg = true;
-    setInterval(ntpUpdateInterval); }
+    setInterval(ntpUpdateInterval);
+  }
 
-  if ((fsOK) && (chg) && (!donotsave)) {
+  if ((fsOK) && (chg) && (!donotsave))
+  {
     Serial.print(MSG[INFO]);
     Serial.println(F("Saving NTP configuration."));
     File file = fileSystem->open("/NTPSetup.cfg", "w");
@@ -537,28 +661,34 @@ void handleNTP(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
     file.println(timezone);
     file.println(ntpUpdateInterval);
     delay(10);
-    file.close(); }
+    file.close();
+  }
 #endif
   handleFileRead(server, "/");
 }
 void HTTPhandleNTP() { return handleNTP(&HTTPserver); }
 void HTTPShandleNTP() { return handleNTP(&HTTPSserver); }
 
-
 template <typename ServerType>
-void handleDateTimeZone(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
-  if (!(*server).chunkedResponseModeStart(200, MSG[MIME_JSON])) {
+void handleDateTimeZone(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
+  if (!(*server).chunkedResponseModeStart(200, MSG[MIME_JSON]))
+  {
     (*server).send(505, MSG[MIME_HTML], MSG[SRV_MSG_HTTP]);
-    return; }
+    return;
+  }
   (*server).sendContent(F("{\"tz\":\""));
   (*server).sendContent(timezone);
   (*server).sendContent(F("\",\"ntp\":\""));
   (*server).sendContent(ntpServerName);
   (*server).sendContent(F("\",\"freq\":\""));
-  buf=""; buf+=ntpUpdateInterval; if (buf=="") buf="1800";
+  buf = "";
+  buf += ntpUpdateInterval;
+  if (buf == "")
+    buf = "1800";
   (*server).sendContent(buf);
   (*server).sendContent(F("\",\"sync\":"));
-  buf = (timeStatus() == timeSet)?"true":"false";
+  buf = (timeStatus() == timeSet) ? "true" : "false";
   buf += "}";
   (*server).sendContent(buf);
   (*server).chunkedResponseFinalize();
@@ -566,46 +696,52 @@ void handleDateTimeZone(esp8266webserver::ESP8266WebServerTemplate<ServerType> *
 void HTTPhandleDateTimeZone() { return handleDateTimeZone(&HTTPserver); }
 void HTTPShandleDateTimeZone() { return handleDateTimeZone(&HTTPSserver); }
 
-
 /* ---------- CO2 sensor ---------- */
-void HTTPhandleSensor() { /* RQ : longueur du message : 68 octets. */
+void HTTPhandleSensor()
+{ /* RQ : longueur du message : 68 octets. */
   HTTPserver.send(200, MSG[MIME_JSON], sensorJson);
 }
-void HTTPShandleSensor() { HTTPSserver.send(200, MSG[MIME_JSON], sensorJson);}
+void HTTPShandleSensor() { HTTPSserver.send(200, MSG[MIME_JSON], sensorJson); }
 
 /* Fills co2, temperature and humidity values if new values
  * are available from sensor. Returns true if new values read.
  */
-bool getSensorData() {
+bool getSensorData()
+{
   if (!airSensor.dataAvailable())
     return false;
   co2 = airSensor.getCO2();
   temperature = airSensor.getTemperature();
   humidity = airSensor.getHumidity();
   /* sensorJson */
-  sensorJson = "{\"d\":\""+tz.dateTime("d/m/Y");
-  sensorJson += "\",\"t\":\""+tz.dateTime("H:i");
+  sensorJson = "{\"d\":\"" + tz.dateTime("d/m/Y");
+  sensorJson += "\",\"t\":\"" + tz.dateTime("H:i");
   sensorJson += "\",\"co2\":";
   sensorJson += co2;
-  sensorJson += ",\"temp\":"+String(temperature, 2);
-  sensorJson += ",\"hum\":"+String(humidity, 2)+"}";
+  sensorJson += ",\"temp\":" + String(temperature, 2);
+  sensorJson += ",\"hum\":" + String(humidity, 2) + "}";
   return true;
 }
 
-
 template <typename ServerType>
-void handleFileManage(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server) {
+void handleFileManage(esp8266webserver::ESP8266WebServerTemplate<ServerType> *server)
+{
   String ch;
 
-  if (!fsOK) return replyServerError(server, FPSTR(FS_INIT_ERROR));
+  if (!fsOK)
+    return replyServerError(server, FPSTR(FS_INIT_ERROR));
   if (!(*server).hasArg("file"))
     return replyBadRequest(server, F("No file selected"));
-  buf = "/data/"+(*server).arg("file");
-  if ((*server).arg("todo").startsWith("get")) {
+  buf = "/data/" + (*server).arg("file");
+  if ((*server).arg("todo").startsWith("get"))
+  {
     /* Already done by javascript code */
     return replyOK(server);
-  } else {
-    if ((*server).arg("todo").startsWith("del")) { /* to be sure */
+  }
+  else
+  {
+    if ((*server).arg("todo").startsWith("del"))
+    { /* to be sure */
       Serial.print(MSG[INFO]);
 #ifdef DEMO_MODE
       Serial.print(F("(demo:) Not deleting file "));
@@ -613,7 +749,8 @@ void handleFileManage(esp8266webserver::ESP8266WebServerTemplate<ServerType> *se
 #else
       Serial.print(F("Deleting file "));
       Serial.println(buf);
-      if (!LittleFS.remove(buf)) {
+      if (!LittleFS.remove(buf))
+      {
         Serial.print(MSG[ERR]);
         Serial.println("Delete failed");
       }
@@ -626,18 +763,20 @@ void handleFileManage(esp8266webserver::ESP8266WebServerTemplate<ServerType> *se
 void HTTPhandleFileManage() { return handleFileManage(&HTTPserver); }
 void HTTPShandleFileManage() { return handleFileManage(&HTTPSserver); }
 
-
-
 /* ---------- Tools ---------- */
-void readLineInFile(File &f, char* c, int len) {
+void readLineInFile(File &f, char *c, int len)
+{
   buf = f.readStringUntil('\n');
-  for (i = 0; ((int) buf.charAt(i)) > 31; i++);
-  if (i < buf.length()) buf.remove(i);
+  for (i = 0; ((int)buf.charAt(i)) > 31; i++)
+    ;
+  if (i < buf.length())
+    buf.remove(i);
   buf.toCharArray(c, len);
 }
 
 /*  ==================== Main ==================== */
-void setup() {
+void setup()
+{
   /* --- Initialize default values. --- */
   buf.reserve(BUF_SIZE);
   buf = DEFAULT_SSID;
@@ -665,44 +804,58 @@ void setup() {
   fileSystem->setConfig(fileSystemConfig);
   fsOK = fileSystem->begin();
 
-  if (!fsOK) {
+  if (!fsOK)
+  {
     Serial.print(MSG[WARN]);
     Serial.println(F("Filesystem init failed !"));
-  } else {
+  }
+  else
+  {
     Serial.print(MSG[INFO]);
     Serial.println(F("Reading configuration files."));
     File file = fileSystem->open("/wifiSetup.cfg", "r");
-    if (file) {
+    if (file)
+    {
       readLineInFile(file, ssid, sizeof(ssid));
       readLineInFile(file, password, sizeof(password));
       file.close();
-    } else {
+    }
+    else
+    {
       Serial.print(MSG[WARN]);
       Serial.println(F("No wifi setup file found."));
     }
 
 #ifndef DEMO_MODE
     file = fileSystem->open("/apSetup.cfg", "r");
-    if (file) {
+    if (file)
+    {
       readLineInFile(file, host, sizeof(host));
       readLineInFile(file, ap_password, sizeof(ap_password));
       file.close();
-    } else {
+    }
+    else
+    {
       Serial.print(MSG[WARN]);
       Serial.println(F("No AP setup file found."));
     }
 #endif
 
     file = fileSystem->open("/sensorSetup.cfg", "r");
-    if (file) {
+    if (file)
+    {
       readLineInFile(file, cbuf, sizeof(cbuf));
-      buf = cbuf; interval = buf.toInt();
+      buf = cbuf;
+      interval = buf.toInt();
       readLineInFile(file, cbuf, sizeof(cbuf));
-      buf = cbuf; altitude = buf.toInt();
+      buf = cbuf;
+      altitude = buf.toInt();
       readLineInFile(file, cbuf, sizeof(cbuf));
-      writeData = (cbuf[0]=='y');
+      writeData = (cbuf[0] == 'y');
       file.close();
-    } else {
+    }
+    else
+    {
       Serial.print(MSG[WARN]);
       Serial.println(F("No sensor setup file found."));
     }
@@ -713,15 +866,19 @@ void setup() {
 #endif
 
     file = fileSystem->open("/NTPSetup.cfg", "r");
-    if (file) {
+    if (file)
+    {
       readLineInFile(file, cbuf, sizeof(cbuf));
       ntpServerName = cbuf;
       readLineInFile(file, cbuf, sizeof(cbuf));
       timezone = cbuf;
       readLineInFile(file, cbuf, sizeof(cbuf));
-      buf = cbuf; ntpUpdateInterval = buf.toInt();
+      buf = cbuf;
+      ntpUpdateInterval = buf.toInt();
       file.close();
-    } else {
+    }
+    else
+    {
       Serial.print(MSG[WARN]);
       Serial.println(F("No NTP setup file found."));
     }
@@ -729,20 +886,26 @@ void setup() {
   digitalWrite(RED_LED, HIGH); /* HIGH value turns it off */
 
   /* WiFi.mode(WIFI_STA); */ /* Client only */
-  WiFi.mode(WIFI_AP_STA); /* Client AND AP */
+  WiFi.mode(WIFI_AP_STA);    /* Client AND AP */
   delay(100);
   WiFi.softAP(host, ap_password);
   delay(100);
   wifiConnect(ssid, password);
 
+  /* MQTT init */
+  client.setServer(mqtt_broker, mqtt_port);
+
   Serial.print(MSG[INFO]);
   Serial.print(F("AP IP address: "));
   Serial.println(WiFi.softAPIP());
 
-  if (MDNS.begin(host)) {
+  if (MDNS.begin(host))
+  {
     MDNS.addService("http", "tcp", 80);
     MDNS.addService("https", "tcp", 443);
-  } else {
+  }
+  else
+  {
     Serial.print(MSG[WARN]);
     Serial.println(F("Error setting up MDNS responder!"));
   }
@@ -788,9 +951,10 @@ void setup() {
   /* NTP */
   setDebug(NONE);
   setServer(ntpServerName);
-  waitForSync(60); /* Waits NTP sync for max. 60 seconds. */
+  waitForSync(60);  /* Waits NTP sync for max. 60 seconds. */
   setInterval(120); /* Try every 2 minutes until success */
-  if (!tz.setLocation(timezone)) {
+  if (!tz.setLocation(timezone))
+  {
     Serial.print(MSG[WARN]);
     Serial.print(F("Timezone setting failed -> "));
     Serial.println(timezone);
@@ -800,12 +964,14 @@ void setup() {
 
   delay(1000);
   i = 0;
-  while ((!(sensorOK = airSensor.begin())) && (i++ < 6)) {
+  while ((!(sensorOK = airSensor.begin())) && (i++ < 6))
+  {
     Serial.print(MSG[ERR]);
     Serial.println(F("Air sensor not detected. Please check wiring. Waiting 10s..."));
     delay(10000);
   }
-  if (sensorOK) {
+  if (sensorOK)
+  {
     airSensor.setMeasurementInterval(interval);
     airSensor.setAltitudeCompensation(altitude);
   }
@@ -813,76 +979,101 @@ void setup() {
 
   /* Set datafile name */
   tzOK = (timeStatus() == timeSet);
-  if (tzOK) {
+  if (tzOK)
+  {
     setInterval(ntpUpdateInterval);
-    datafile = "data/"+tz.dateTime("YmdHi")+".csv";
+    datafile = "data/" + tz.dateTime("YmdHi") + ".csv";
     Serial.print(MSG[INFO]);
     Serial.print(F("NTP date and time set : "));
     Serial.println(tz.dateTime(timeformat));
-  } else {
+  }
+  else
+  {
     Serial.print(MSG[WARN]);
     Serial.println(F("NTP date and time not set."));
-    if (fsOK) { /* If !(fsOK), we won't save any data. */
+    if (fsOK)
+    { /* If !(fsOK), we won't save any data. */
       Dir dir = fileSystem->openDir("/data");
       j = 0;
-      while (dir.next()) {
-        if (!dir.isDirectory()) {
+      while (dir.next())
+      {
+        if (!dir.isDirectory())
+        {
           // Always return names without leading "/"
-          if (dir.fileName()[0] == '/') buf = &(dir.fileName()[1]);
-          else buf = dir.fileName();
-          i = buf.substring(0,11).toInt();
-          if (i>j) j = i;
+          if (dir.fileName()[0] == '/')
+            buf = &(dir.fileName()[1]);
+          else
+            buf = dir.fileName();
+          i = buf.substring(0, 11).toInt();
+          if (i > j)
+            j = i;
         }
       }
-      if (j > 0) datafile = "data/"+String(j)+"-NS.csv";
-      else datafile = F("data/197001010000-NS.csv");
-    } else {
+      if (j > 0)
+        datafile = "data/" + String(j) + "-NS.csv";
+      else
+        datafile = F("data/197001010000-NS.csv");
+    }
+    else
+    {
       datafile = "";
     }
   }
-  if ((datafile.length() > 0) && (writeData)) {
+  if ((datafile.length() > 0) && (writeData))
+  {
     Serial.print(MSG[INFO]);
     Serial.print(F("Writing data into "));
     Serial.println(datafile);
   }
-}
 
+  /* --- MQTT --- */
+  publishMQTT();
+}
 
-void loop() {
+void loop()
+{
   File file;
 
   /* --- NTP sync --- */
   events();
   /* NTP time just set */
-  if ((!tzOK) && (timeStatus() == timeSet)) {
+  if ((!tzOK) && (timeStatus() == timeSet))
+  {
     setInterval(NTP_UPDATE_INTERVAL);
     Serial.print(MSG[INFO]);
     Serial.print(F("NTP date and time set : "));
     Serial.println(tz.dateTime(timeformat));
     tzOK = true;
-    if (fsOK) { /* Have to rename filename */
-      buf = "data/"+tz.dateTime("YmdHi")+".csv";
-      if ((writeData) && (datafile.length() > 0)) {
-        if (!fileSystem->rename(datafile, buf)) {
+    if (fsOK)
+    { /* Have to rename filename */
+      buf = "data/" + tz.dateTime("YmdHi") + ".csv";
+      if ((writeData) && (datafile.length() > 0))
+      {
+        if (!fileSystem->rename(datafile, buf))
+        {
           Serial.print(MSG[ERR]);
-          Serial.println("Couldn't rename "+datafile+" to "+buf);
-        } else {
+          Serial.println("Couldn't rename " + datafile + " to " + buf);
+        }
+        else
+        {
           Serial.print(MSG[INFO]);
-          Serial.println("Renamed "+datafile+" to "+buf+" and write data into it.");
+          Serial.println("Renamed " + datafile + " to " + buf + " and write data into it.");
           datafile = buf;
         }
-      } else /* Should never happend. */
-        datafile = "data/"+tz.dateTime("YmdHi")+".csv";
+      }
+      else /* Should never happend. */
+        datafile = "data/" + tz.dateTime("YmdHi") + ".csv";
     }
   }
 
   /* --- Get sensor data if available and write it to file. --- */
-  if (getSensorData()) {
+  if (getSensorData())
+  {
     /* Write to file */
     cbuf[0] = ';';
-    buf = tzOK?tz.dateTime(timeformat):"";
+    buf = tzOK ? tz.dateTime(timeformat) : "";
     buf += cbuf[0]; /* ';' */
-    buf += (int) co2;
+    buf += (int)co2;
     buf += cbuf[0];
     buf += temperature;
     buf += cbuf[0];
@@ -891,14 +1082,19 @@ void loop() {
     buf += millis();
     Serial.print(F("[MEASURE] "));
     Serial.println(buf);
-    if ((writeData) && (fsOK)) { /* Write to file */
+    if ((writeData) && (fsOK))
+    { /* Write to file */
       file = LittleFS.open(datafile, "a");
-      if (!file) {
+      if (!file)
+      {
         Serial.print(MSG[ERR]);
         Serial.print(F("Failed to open file for appending : "));
         Serial.println(datafile);
-      } else {
-        if (!file.println(buf)) {
+      }
+      else
+      {
+        if (!file.println(buf))
+        {
           Serial.print(MSG[ERR]);
           Serial.print(F("Failed to write data to file "));
           Serial.println(datafile);
@@ -908,6 +1104,9 @@ void loop() {
     }
   }
 
+  /* --- MQTT --- */
+  publishMQTT();
+
   HTTPserver.handleClient();
   HTTPSserver.handleClient();
   MDNS.update();
diff --git a/Co2Huzzah/README.md b/Co2Huzzah/README.md
index 0b9c49297a76da8805c110b1e5bd51f48b9b7752..d7f037b8679683879a1c7e737313bb3aaf966214 100644
--- a/Co2Huzzah/README.md
+++ b/Co2Huzzah/README.md
@@ -28,7 +28,6 @@ La librairie
 est nécessaire pour copier le contenu du dossier `data/` sur la mémoire flash
 du nœud.
 
-
 ## Utilisation
 
 Le nœud fonctionne en serveur HTTP, tant en point d'accès Wifi (IP: 192.168.4.1)
@@ -55,8 +54,7 @@ commencera par signaler une alerte de sécurité à laquelle il faudra
 passer outre. À noter que le mode HTTPS est extrêmement lent (il oblige le
 nœud à utiliser ses maigres ressources pour crypter toutes les communications).
 
-
-#### Génération de certificats
+### Génération de certificats
 
 Voir [https://github.com/esp8266/Arduino/blob/master/doc/esp8266wifi/bearssl-server-secure-class.rst]()
 
@@ -72,13 +70,17 @@ Il faut ensuite copier le contenu des deux fichiers générés dans `certs.h` :
 - `cert.pem` dans *serverCert[]*,
 - `key.pem` dans *serverKey[]*.
 
-##### Remarque
+#### Remarque
 
 Les certificats fournis dans l'exemple sont des certificats de 512 octets
 (changer la valeur après rsa: dans la ligne de commande pour générer les
 certificats). Ceci accélère quelque peu les échanges. En revanche c'est moins
 sécurisé.
 
+### MQTT
+
+Une fois connecté à un point d'accès, si celui-ci dispose d'un broker MQTT, le noeud tentera de publier les mesures du capteur. Le format du topic est `IdNoeud/ReferenceNoeud/ReferenceCapteur/TypeMesure`.
+
 ## À noter
 
 La page permettant la visualisation des courbes de mesures utilise