diff --git a/WifiControlSensor/MQTT.h b/WifiControlSensor/MQTT.h index acf5b83..97b1d56 100644 --- a/WifiControlSensor/MQTT.h +++ b/WifiControlSensor/MQTT.h @@ -1,15 +1,33 @@ #pragma once + +//FEED have the following formats /feeds/USER/DEVICE_NAME/.... +#define TEMPERATURE_FEED_FORMAT "/feeds/%s/%s/temperature" +#define PRESSURE_FEED_FORMAT "/feeds/%s/%s/pressure" +#define TEMPERATURE_DHT_FEED_FORMAT "/feeds/%s/%s/dht/temperature" +#define HUMIDITY_DHT_FEED_FORMAT "/feeds/%s/%s/dht/humidity" +#define DRY_FEED_FORMAT "/feeds/%s/%s/dry" +#define GPIO_FEED_FORMAT "/feeds/%s/%s/gpio/%d" +#define GPIO_SET_FEED_FORMAT "/feeds/%s/%s/gpio/%d/set" +#define PWM_FEED_FORMAT "/feeds/%s/%s/gpio/%d" +#define PWM_SET_FEED_FORMAT "/feeds/%s/%s/gpio/%d/set" +#define IP_FEED_FORMAT "/feeds/%s/%s/configuration/ip/addr" #ifndef CONFIG_DISABLE_MQTT #include "Adafruit_MQTT.h" + typedef struct {uint8_t updated; int value;} gpioInfo; + +struct mqttInfo { + float value; + char *topic; + uint8_t retain; + uint8_t qos; +}; +int MqttBatchPublish(std::vector tab, ...); Adafruit_MQTT_Publish *MqttCreatePublisher(uint8_t qos, uint8_t retain, const char *fmt, ...); int MqttConnect(); int MqttIsConnected(); int MqttSetup(char *server, char *user, char *passwd, int port, char * hostname); template int MqttPublish(Adafruit_MQTT_Publish *publisher, T value); -int MqttPublishBMP180(double temp, double pressure); -int MqttPublishDHT(float temp, float humidity); -int MqttPublishDry(int dry); int MqttPublishIp(const String &ip); void MqttCheckSubscription(); void MqttCheckIRQ(); @@ -18,13 +36,11 @@ void MqttChangePWMValue(int gpio, int value); void MqttNofityIRQ(uint8_t gpio, int value); void MqttNofity(int gpio, int value); #else +int MqttBatchPublish(std::vector tab, ...){return 0;} int MqttConnect(){return 0;} int MqttIsConnected(){return 0;} int MqttSetup(char *server, char *user, char *passwd, int port, char * hostname){return 0;} template int MqttPublish(Adafruit_MQTT_Publish *publisher, T value){return 0;} -int MqttPublishBMP180(double temp, double pressure){return 0;} -int MqttPublishDHT(float temp, float humidity){return 0;} -int MqttPublishDry(int dry){return 0;} int MqttPublishIP(const String &ip){return 0;} void MqttCheckSubscription(){} void MqttCheckIRQ(){} diff --git a/WifiControlSensor/MQTT.ino b/WifiControlSensor/MQTT.ino index c9aaed0..ae050ac 100644 --- a/WifiControlSensor/MQTT.ino +++ b/WifiControlSensor/MQTT.ino @@ -6,11 +6,6 @@ #define MAX_PIN 15 #define MAX_GPIO_OBSERVED (MAXSUBSCRIPTIONS*2) Adafruit_MQTT_Client *mqtt; -Adafruit_MQTT_Publish *mqtt_temp; -Adafruit_MQTT_Publish *mqtt_pressure; -Adafruit_MQTT_Publish *mqtt_dht_temp; -Adafruit_MQTT_Publish *mqtt_dht_humidity; -Adafruit_MQTT_Publish *mqtt_dry; Adafruit_MQTT_Publish *mqtt_ip; Adafruit_MQTT_Publish *mqttGpio[MAXSUBSCRIPTIONS] = {}; Adafruit_MQTT_Publish *mqttPwm[MAXSUBSCRIPTIONS] = {}; @@ -19,18 +14,6 @@ gpioInfo mqttIRQ[MAX_PIN + 1] = {}; #define FEED_MAX_SIZE 96 -//FEED have the following formats /feeds/USER/DEVICE_NAME/.... -#define TEMPERATURE_FEED_FORMAT "/feeds/%s/%s/temperature" -#define PRESSURE_FEED_FORMAT "/feeds/%s/%s/pressure" -#define TEMPERATURE_DHT_FEED_FORMAT "/feeds/%s/%s/dht/temperature" -#define HUMIDITY_DHT_FEED_FORMAT "/feeds/%s/%s/dht/humidity" -#define DRY_FEED_FORMAT "/feeds/%s/%s/dry" -#define GPIO_FEED_FORMAT "/feeds/%s/%s/gpio/%d" -#define GPIO_SET_FEED_FORMAT "/feeds/%s/%s/gpio/%d/set" -#define PWM_FEED_FORMAT "/feeds/%s/%s/gpio/%d" -#define PWM_SET_FEED_FORMAT "/feeds/%s/%s/gpio/%d/set" -#define IP_FEED_FORMAT "/feeds/%s/%s/configuration/ip/addr" - char *mqttId; bool isMqttConfigured = false; @@ -42,29 +25,24 @@ int MqttSetup(char *server, char *user, char *passwd, int port, char *hostname) useMqtts = (port == 8883); isMqttConfigured = server[0] != '\0'; - if(!isMqttConfigured) + if (!isMqttConfigured) return 0; #ifndef CONFIG_DISABLE_SSL - if(useMqtts) + if (useMqtts) mqtt = new Adafruit_MQTT_Client(new WiFiClientSecure(), server, port, user, passwd); else #endif mqtt = new Adafruit_MQTT_Client(new WiFiClient(), server, port, user, passwd); - mqtt_dht_temp = MqttCreatePublisher(0, 0, TEMPERATURE_DHT_FEED_FORMAT, user, mqttId); - mqtt_dht_humidity = MqttCreatePublisher(0, 0, HUMIDITY_DHT_FEED_FORMAT, user, mqttId); - mqtt_temp = MqttCreatePublisher(0, 0, TEMPERATURE_FEED_FORMAT, user, mqttId); - mqtt_pressure = MqttCreatePublisher(0, 0, PRESSURE_FEED_FORMAT, user, mqttId); - mqtt_dry = MqttCreatePublisher(0, 0, DRY_FEED_FORMAT, user, mqttId); mqtt_ip = MqttCreatePublisher(0, 1, IP_FEED_FORMAT, user, mqttId); - if (NB_ELEMENTS(gpioControlled) + NB_ELEMENTS(pwmControlled) > MAXSUBSCRIPTIONS){ - SKETCH_DEBUG_PRINTF("Too much gpio/pwm to control\n Nb gpio %d Nb pwm %d Max is %d", + if (NB_ELEMENTS(gpioControlled) + NB_ELEMENTS(pwmControlled) > MAXSUBSCRIPTIONS) { + SKETCH_DEBUG_PRINTF("Too much gpio/pwm to control\n Nb gpio %d Nb pwm %d Max is %d", NB_ELEMENTS(gpioControlled), NB_ELEMENTS(pwmControlled), MAXSUBSCRIPTIONS); return -1; } - if (NB_ELEMENTS(gpioObserved) > MAX_GPIO_OBSERVED){ + if (NB_ELEMENTS(gpioObserved) > MAX_GPIO_OBSERVED) { SKETCH_DEBUG_PRINTF("Too much gpio observed\n Nb gpio %d Nb is %d", NB_ELEMENTS(gpioObserved), MAX_GPIO_OBSERVED); return -1; @@ -88,7 +66,7 @@ int MqttSetup(char *server, char *user, char *passwd, int port, char *hostname) return 0; } -Adafruit_MQTT_Publish *MqttCreatePublisher( uint8_t qos, uint8_t retain, const char *fmt, ...){ +Adafruit_MQTT_Publish *MqttCreatePublisher( uint8_t qos, uint8_t retain, const char *fmt, ...) { char buf[FEED_MAX_SIZE]; va_list args; va_start (args, fmt); @@ -97,7 +75,27 @@ Adafruit_MQTT_Publish *MqttCreatePublisher( uint8_t qos, uint8_t retain, const c return new Adafruit_MQTT_Publish(mqtt, strdup(buf), qos, retain); } -Adafruit_MQTT_Subscribe *MqttCreateSubscribe(const char *fmt, ...){ + +int MqttBatchPublish(std::vector tab, ...) { + if (!MqttConnect()) { + SKETCH_DEBUG_PRINTLN("cannot connect to mqtt"); + return -1; + } + for (auto info : tab) { + char buf[FEED_MAX_SIZE]; + va_list args; + va_start (args, tab); + vsnprintf(buf, sizeof(buf), (const char *)info.topic, args); + va_end(args); + SKETCH_DEBUG_PRINTF("publishing %f for %s\n", info.value, buf); + Adafruit_MQTT_Publish client(mqtt, buf, info.qos, info.retain); + if (!client.publish(info.value)) + SKETCH_DEBUG_PRINTLN("Fail :("); + } + return 0; +} + +Adafruit_MQTT_Subscribe *MqttCreateSubscribe(const char *fmt, ...) { char buf[FEED_MAX_SIZE]; va_list args; va_start (args, fmt); @@ -137,7 +135,7 @@ int MqttConnect() { return 0; } -template int MqttPublish(Adafruit_MQTT_Publish *publisher, T value){ +template int MqttPublish(Adafruit_MQTT_Publish *publisher, T value) { if (MqttConnect() == 0) { publisher->publish(value); return 0; @@ -145,22 +143,10 @@ template int MqttPublish(Adafruit_MQTT_Publish *publisher, T value){ return -1; } -int MqttPublishBMP180(double temp, double pressure) { - return MqttPublish(mqtt_temp, temp) + MqttPublish(mqtt_pressure, pressure); -} - -int MqttPublishDry(int dry) { - return MqttPublish(mqtt_dry, (dry*100)/1024); -} - int MqttPublishIP(const String &ip) { return MqttPublish(mqtt_ip, ip.c_str()); } -int MqttPublishDHT(float temp, float humidity) { - return MqttPublish(mqtt_dht_temp, temp) + MqttPublish(mqtt_dht_humidity, humidity); -} - int getGpioFromSubscription(Adafruit_MQTT_Subscribe *subscription, const char *pattern) { char *temp = strstr(subscription->topic, pattern); if (!temp) @@ -175,12 +161,12 @@ int getGpioFromSubscription(Adafruit_MQTT_Subscribe *subscription, const char *p return -1; } -void MqttNofityIRQ(uint8_t gpio, int value){ +void MqttNofityIRQ(uint8_t gpio, int value) { mqttIRQ[gpio].updated = 1; mqttIRQ[gpio].value = value; } -void MqttNofity(int gpio, int value){ +void MqttNofity(int gpio, int value) { if (MqttIsConnected()) { int watchIdx = findIndex(gpio, gpioControlled); if (watchIdx >= 0 ) { @@ -206,7 +192,7 @@ void MqttChangePWMValue(int gpio, int value) { void MqttCheckIRQ() { for (uint i = 0 ; i < NB_ELEMENTS(mqttIRQ); i++) { - if(mqttIRQ[i].updated == 1){ + if (mqttIRQ[i].updated == 1) { mqttIRQ[i].updated = 0; MqttNofity(i, mqttIRQ[i].value); } diff --git a/WifiControlSensor/WifiControlSensor.ino b/WifiControlSensor/WifiControlSensor.ino index a298376..ae99b9c 100644 --- a/WifiControlSensor/WifiControlSensor.ino +++ b/WifiControlSensor/WifiControlSensor.ino @@ -28,7 +28,7 @@ - +#include #include #include #include @@ -87,8 +87,8 @@ void WebSetupServer(int bootmode); #ifdef CONFIG_SETUP_BUTTON -void onLongButtonPressed(uint8_t pin){ - if(pin == CONFIG_SETUP_BUTTON){ +void onLongButtonPressed(uint8_t pin) { + if (pin == CONFIG_SETUP_BUTTON) { reconfig = 1; SKETCH_DEBUG_PRINTLN("Putting device in setup mode"); mode = BOOTMODE_SETUP; @@ -110,7 +110,7 @@ void WifiSetup(productConfig conf) { //Disable previous AP mode WiFi.softAPdisconnect(true); SKETCH_DEBUG_PRINTLN("Connecting to Wifi..."); - if(conf.ip_mode == 1){ + if (conf.ip_mode == 1) { SKETCH_DEBUG_PRINTLN("Use static ip configuration"); WiFi.config(IPAddress(conf.ip), IPAddress(conf.gw), IPAddress(conf.mask), IPAddress(conf.dns), IPAddress(conf.dns2)); } @@ -118,12 +118,12 @@ void WifiSetup(productConfig conf) { uint8_t bssid[6]; if (conf.bssid[0] != '\0') { String bssidStr = conf.bssid; - bssid[0] = strtoul(bssidStr.substring(0,2).c_str(), NULL, 16); - bssid[1] = strtoul(bssidStr.substring(3,5).c_str(), NULL, 16); - bssid[2] = strtoul(bssidStr.substring(6,8).c_str(), NULL, 16); - bssid[3] = strtoul(bssidStr.substring(9,11).c_str(), NULL, 16); - bssid[4] = strtoul(bssidStr.substring(12,14).c_str(), NULL, 16); - bssid[5] = strtoul(bssidStr.substring(15,17).c_str(), NULL, 16); + bssid[0] = strtoul(bssidStr.substring(0, 2).c_str(), NULL, 16); + bssid[1] = strtoul(bssidStr.substring(3, 5).c_str(), NULL, 16); + bssid[2] = strtoul(bssidStr.substring(6, 8).c_str(), NULL, 16); + bssid[3] = strtoul(bssidStr.substring(9, 11).c_str(), NULL, 16); + bssid[4] = strtoul(bssidStr.substring(12, 14).c_str(), NULL, 16); + bssid[5] = strtoul(bssidStr.substring(15, 17).c_str(), NULL, 16); SKETCH_DEBUG_PRINTF("Using BSSID: %x:%x:%x:%x:%x:%x\n", bssid[5], bssid[4], bssid[3], bssid[2], bssid[1], bssid[0]); bssidConf = bssid; } @@ -131,11 +131,11 @@ void WifiSetup(productConfig conf) { while (WiFi.status() != WL_CONNECTED) { delay(500); SKETCH_DEBUG_PRINT("."); - if (reconfig == 1){ + if (reconfig == 1) { reconfig = 0; return; } - if(connectionTry == 10){ + if (connectionTry == 10) { SKETCH_DEBUG_PRINTLN("Cannot connect to wifi. Try withour BSSID and channel"); WiFi.begin(conf.ssid, conf.password); } @@ -245,8 +245,8 @@ void setup() { SKETCH_DEBUG_PRINTLN("No configuration saved"); } - SKETCH_DEBUG_PRINTF("Force Setup Mode ? : %s\n",txStatus ? "No" : "Yes"); - if(txStatus == 0){ + SKETCH_DEBUG_PRINTF("Force Setup Mode ? : %s\n", txStatus ? "No" : "Yes"); + if (txStatus == 0) { mode = BOOTMODE_SETUP; } @@ -259,13 +259,13 @@ void setup() { if (mode == BOOTMODE_OTA) { OTASetup(); } else { - if (!BMP180Setup(CONFIG_BMP180_SDA, CONFIG_BMP180_SCL)){ + if (!BMP180Setup(CONFIG_BMP180_SDA, CONFIG_BMP180_SCL)) { SKETCH_DEBUG_PRINTLN("BMP180 init success"); } - if (!DHTSetup(CONFIG_DHT_PIN)){ + if (!DHTSetup(CONFIG_DHT_PIN)) { SKETCH_DEBUG_PRINTLN("DHT init success"); } - if (!DrySetup(CONFIG_DRY_POWER_PIN)){ + if (!DrySetup(CONFIG_DRY_POWER_PIN)) { SKETCH_DEBUG_PRINTLN("DRY init success"); } WebSetupServer(mode); @@ -281,7 +281,7 @@ void loop() { ArduinoOTA.handle(); } else { server.handleClient(); - if (mode == BOOTMODE_NORMAL){ + if (mode == BOOTMODE_NORMAL) { MqttCheckSubscription(); MqttCheckIRQ(); } @@ -289,29 +289,23 @@ void loop() { nbCycle++; if (nbCycle > CONFIG_SAMPLING_PERIODE_MS / CONFIG_WEB_DELAY_MS) { + std::vector batchInfo; if (!BMP180GetTempAndPressure(temp, pressure)) { - SKETCH_DEBUG_PRINT("Current T°C "); - SKETCH_DEBUG_PRINT(temp); - SKETCH_DEBUG_PRINT(" Pressure mB "); - SKETCH_DEBUG_PRINTLN(pressure); - if (mode == BOOTMODE_NORMAL) - MqttPublishBMP180(temp, pressure); + SKETCH_DEBUG_PRINTF("Current %f°C Pressure %fmB\n", temp, pressure); + batchInfo.push_back({(float)temp, TEMPERATURE_FEED_FORMAT, 0, 0}); + batchInfo.push_back({(float)pressure, PRESSURE_FEED_FORMAT, 0, 0}); } if (!DHTGetTempAndHumidity(dhtTemp, dhtHumidity)) { - SKETCH_DEBUG_PRINT("Current T°C "); - SKETCH_DEBUG_PRINT(dhtTemp); - SKETCH_DEBUG_PRINT(" Humidity "); - SKETCH_DEBUG_PRINTLN(dhtHumidity); - if (mode == BOOTMODE_NORMAL) - MqttPublishDHT(dhtTemp, dhtHumidity); + SKETCH_DEBUG_PRINTF("Current %f°C %f%% Humidity\n", dhtTemp, dhtHumidity); + batchInfo.push_back({dhtTemp, TEMPERATURE_DHT_FEED_FORMAT, 0, 0}); + batchInfo.push_back({dhtHumidity, HUMIDITY_DHT_FEED_FORMAT, 0, 0}); } - if (!DryGetMeasure(dryness)){ - SKETCH_DEBUG_PRINT("Current dryness "); - SKETCH_DEBUG_PRINT((dryness*100)/1024); - SKETCH_DEBUG_PRINTLN("%"); - if (mode == BOOTMODE_NORMAL) - MqttPublishDry(dryness); + if (!DryGetMeasure(dryness)) { + SKETCH_DEBUG_PRINTF("Current dryness %d %%\n", (dryness * 100) / 1024); + batchInfo.push_back({dryness, DRY_FEED_FORMAT, 0, 0}); } + if (mode == BOOTMODE_NORMAL) + MqttBatchPublish(batchInfo, conf.mqttUser, conf.host); nbCycle = 0; } }