Mqtt: use batch publish to generalize code

And fix indentation
This commit is contained in:
Mathieu Maret 2019-05-14 23:44:46 +02:00
parent eab447abc6
commit caf88dcd98
3 changed files with 83 additions and 87 deletions

View File

@ -1,15 +1,33 @@
#pragma once #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 #ifndef CONFIG_DISABLE_MQTT
#include "Adafruit_MQTT.h" #include "Adafruit_MQTT.h"
typedef struct {uint8_t updated; int value;} gpioInfo; typedef struct {uint8_t updated; int value;} gpioInfo;
struct mqttInfo {
float value;
char *topic;
uint8_t retain;
uint8_t qos;
};
int MqttBatchPublish(std::vector<struct mqttInfo> tab, ...);
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, ...);
int MqttConnect(); int MqttConnect();
int MqttIsConnected(); int MqttIsConnected();
int MqttSetup(char *server, char *user, char *passwd, int port, char * hostname); int MqttSetup(char *server, char *user, char *passwd, int port, char * hostname);
template<typename T> int MqttPublish(Adafruit_MQTT_Publish *publisher, T value); template<typename T> 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); int MqttPublishIp(const String &ip);
void MqttCheckSubscription(); void MqttCheckSubscription();
void MqttCheckIRQ(); void MqttCheckIRQ();
@ -18,13 +36,11 @@ void MqttChangePWMValue(int gpio, int value);
void MqttNofityIRQ(uint8_t gpio, int value); void MqttNofityIRQ(uint8_t gpio, int value);
void MqttNofity(int gpio, int value); void MqttNofity(int gpio, int value);
#else #else
int MqttBatchPublish(std::vector<struct mqttInfo> tab, ...){return 0;}
int MqttConnect(){return 0;} int MqttConnect(){return 0;}
int MqttIsConnected(){return 0;} int MqttIsConnected(){return 0;}
int MqttSetup(char *server, char *user, char *passwd, int port, char * hostname){return 0;} int MqttSetup(char *server, char *user, char *passwd, int port, char * hostname){return 0;}
template<typename T> int MqttPublish(Adafruit_MQTT_Publish *publisher, T value){return 0;} template<typename T> 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;} int MqttPublishIP(const String &ip){return 0;}
void MqttCheckSubscription(){} void MqttCheckSubscription(){}
void MqttCheckIRQ(){} void MqttCheckIRQ(){}

View File

@ -6,11 +6,6 @@
#define MAX_PIN 15 #define MAX_PIN 15
#define MAX_GPIO_OBSERVED (MAXSUBSCRIPTIONS*2) #define MAX_GPIO_OBSERVED (MAXSUBSCRIPTIONS*2)
Adafruit_MQTT_Client *mqtt; 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 *mqtt_ip;
Adafruit_MQTT_Publish *mqttGpio[MAXSUBSCRIPTIONS] = {}; Adafruit_MQTT_Publish *mqttGpio[MAXSUBSCRIPTIONS] = {};
Adafruit_MQTT_Publish *mqttPwm[MAXSUBSCRIPTIONS] = {}; Adafruit_MQTT_Publish *mqttPwm[MAXSUBSCRIPTIONS] = {};
@ -19,18 +14,6 @@ gpioInfo mqttIRQ[MAX_PIN + 1] = {};
#define FEED_MAX_SIZE 96 #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; char *mqttId;
bool isMqttConfigured = false; bool isMqttConfigured = false;
@ -42,29 +25,24 @@ int MqttSetup(char *server, char *user, char *passwd, int port, char *hostname)
useMqtts = (port == 8883); useMqtts = (port == 8883);
isMqttConfigured = server[0] != '\0'; isMqttConfigured = server[0] != '\0';
if(!isMqttConfigured) if (!isMqttConfigured)
return 0; return 0;
#ifndef CONFIG_DISABLE_SSL #ifndef CONFIG_DISABLE_SSL
if(useMqtts) if (useMqtts)
mqtt = new Adafruit_MQTT_Client(new WiFiClientSecure(), server, port, user, passwd); mqtt = new Adafruit_MQTT_Client(new WiFiClientSecure(), server, port, user, passwd);
else else
#endif #endif
mqtt = new Adafruit_MQTT_Client(new WiFiClient(), server, port, user, passwd); 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); mqtt_ip = MqttCreatePublisher(0, 1, IP_FEED_FORMAT, user, mqttId);
if (NB_ELEMENTS(gpioControlled) + NB_ELEMENTS(pwmControlled) > MAXSUBSCRIPTIONS){ 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", 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); NB_ELEMENTS(gpioControlled), NB_ELEMENTS(pwmControlled), MAXSUBSCRIPTIONS);
return -1; 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", SKETCH_DEBUG_PRINTF("Too much gpio observed\n Nb gpio %d Nb is %d",
NB_ELEMENTS(gpioObserved), MAX_GPIO_OBSERVED); NB_ELEMENTS(gpioObserved), MAX_GPIO_OBSERVED);
return -1; return -1;
@ -88,7 +66,7 @@ int MqttSetup(char *server, char *user, char *passwd, int port, char *hostname)
return 0; 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]; char buf[FEED_MAX_SIZE];
va_list args; va_list args;
va_start (args, fmt); 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); return new Adafruit_MQTT_Publish(mqtt, strdup(buf), qos, retain);
} }
Adafruit_MQTT_Subscribe *MqttCreateSubscribe(const char *fmt, ...){
int MqttBatchPublish(std::vector<struct mqttInfo> 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]; char buf[FEED_MAX_SIZE];
va_list args; va_list args;
va_start (args, fmt); va_start (args, fmt);
@ -137,7 +135,7 @@ int MqttConnect() {
return 0; return 0;
} }
template<typename T> int MqttPublish(Adafruit_MQTT_Publish *publisher, T value){ template<typename T> int MqttPublish(Adafruit_MQTT_Publish *publisher, T value) {
if (MqttConnect() == 0) { if (MqttConnect() == 0) {
publisher->publish(value); publisher->publish(value);
return 0; return 0;
@ -145,22 +143,10 @@ template<typename T> int MqttPublish(Adafruit_MQTT_Publish *publisher, T value){
return -1; 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) { int MqttPublishIP(const String &ip) {
return MqttPublish(mqtt_ip, ip.c_str()); 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) { int getGpioFromSubscription(Adafruit_MQTT_Subscribe *subscription, const char *pattern) {
char *temp = strstr(subscription->topic, pattern); char *temp = strstr(subscription->topic, pattern);
if (!temp) if (!temp)
@ -175,12 +161,12 @@ int getGpioFromSubscription(Adafruit_MQTT_Subscribe *subscription, const char *p
return -1; return -1;
} }
void MqttNofityIRQ(uint8_t gpio, int value){ void MqttNofityIRQ(uint8_t gpio, int value) {
mqttIRQ[gpio].updated = 1; mqttIRQ[gpio].updated = 1;
mqttIRQ[gpio].value = value; mqttIRQ[gpio].value = value;
} }
void MqttNofity(int gpio, int value){ void MqttNofity(int gpio, int value) {
if (MqttIsConnected()) { if (MqttIsConnected()) {
int watchIdx = findIndex(gpio, gpioControlled); int watchIdx = findIndex(gpio, gpioControlled);
if (watchIdx >= 0 ) { if (watchIdx >= 0 ) {
@ -206,7 +192,7 @@ void MqttChangePWMValue(int gpio, int value) {
void MqttCheckIRQ() { void MqttCheckIRQ() {
for (uint i = 0 ; i < NB_ELEMENTS(mqttIRQ); i++) { for (uint i = 0 ; i < NB_ELEMENTS(mqttIRQ); i++) {
if(mqttIRQ[i].updated == 1){ if (mqttIRQ[i].updated == 1) {
mqttIRQ[i].updated = 0; mqttIRQ[i].updated = 0;
MqttNofity(i, mqttIRQ[i].value); MqttNofity(i, mqttIRQ[i].value);
} }

View File

@ -28,7 +28,7 @@
#include <vector>
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <WiFiClient.h> #include <WiFiClient.h>
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
@ -87,8 +87,8 @@ void WebSetupServer(int bootmode);
#ifdef CONFIG_SETUP_BUTTON #ifdef CONFIG_SETUP_BUTTON
void onLongButtonPressed(uint8_t pin){ void onLongButtonPressed(uint8_t pin) {
if(pin == CONFIG_SETUP_BUTTON){ if (pin == CONFIG_SETUP_BUTTON) {
reconfig = 1; reconfig = 1;
SKETCH_DEBUG_PRINTLN("Putting device in setup mode"); SKETCH_DEBUG_PRINTLN("Putting device in setup mode");
mode = BOOTMODE_SETUP; mode = BOOTMODE_SETUP;
@ -110,7 +110,7 @@ void WifiSetup(productConfig conf) {
//Disable previous AP mode //Disable previous AP mode
WiFi.softAPdisconnect(true); WiFi.softAPdisconnect(true);
SKETCH_DEBUG_PRINTLN("Connecting to Wifi..."); SKETCH_DEBUG_PRINTLN("Connecting to Wifi...");
if(conf.ip_mode == 1){ if (conf.ip_mode == 1) {
SKETCH_DEBUG_PRINTLN("Use static ip configuration"); SKETCH_DEBUG_PRINTLN("Use static ip configuration");
WiFi.config(IPAddress(conf.ip), IPAddress(conf.gw), IPAddress(conf.mask), IPAddress(conf.dns), IPAddress(conf.dns2)); 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]; uint8_t bssid[6];
if (conf.bssid[0] != '\0') { if (conf.bssid[0] != '\0') {
String bssidStr = conf.bssid; String bssidStr = conf.bssid;
bssid[0] = strtoul(bssidStr.substring(0,2).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[1] = strtoul(bssidStr.substring(3, 5).c_str(), NULL, 16);
bssid[2] = strtoul(bssidStr.substring(6,8).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[3] = strtoul(bssidStr.substring(9, 11).c_str(), NULL, 16);
bssid[4] = strtoul(bssidStr.substring(12,14).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[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]); 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; bssidConf = bssid;
} }
@ -131,11 +131,11 @@ void WifiSetup(productConfig conf) {
while (WiFi.status() != WL_CONNECTED) { while (WiFi.status() != WL_CONNECTED) {
delay(500); delay(500);
SKETCH_DEBUG_PRINT("."); SKETCH_DEBUG_PRINT(".");
if (reconfig == 1){ if (reconfig == 1) {
reconfig = 0; reconfig = 0;
return; return;
} }
if(connectionTry == 10){ if (connectionTry == 10) {
SKETCH_DEBUG_PRINTLN("Cannot connect to wifi. Try withour BSSID and channel"); SKETCH_DEBUG_PRINTLN("Cannot connect to wifi. Try withour BSSID and channel");
WiFi.begin(conf.ssid, conf.password); WiFi.begin(conf.ssid, conf.password);
} }
@ -245,8 +245,8 @@ void setup() {
SKETCH_DEBUG_PRINTLN("No configuration saved"); SKETCH_DEBUG_PRINTLN("No configuration saved");
} }
SKETCH_DEBUG_PRINTF("Force Setup Mode ? : %s\n",txStatus ? "No" : "Yes"); SKETCH_DEBUG_PRINTF("Force Setup Mode ? : %s\n", txStatus ? "No" : "Yes");
if(txStatus == 0){ if (txStatus == 0) {
mode = BOOTMODE_SETUP; mode = BOOTMODE_SETUP;
} }
@ -259,13 +259,13 @@ void setup() {
if (mode == BOOTMODE_OTA) { if (mode == BOOTMODE_OTA) {
OTASetup(); OTASetup();
} else { } else {
if (!BMP180Setup(CONFIG_BMP180_SDA, CONFIG_BMP180_SCL)){ if (!BMP180Setup(CONFIG_BMP180_SDA, CONFIG_BMP180_SCL)) {
SKETCH_DEBUG_PRINTLN("BMP180 init success"); SKETCH_DEBUG_PRINTLN("BMP180 init success");
} }
if (!DHTSetup(CONFIG_DHT_PIN)){ if (!DHTSetup(CONFIG_DHT_PIN)) {
SKETCH_DEBUG_PRINTLN("DHT init success"); SKETCH_DEBUG_PRINTLN("DHT init success");
} }
if (!DrySetup(CONFIG_DRY_POWER_PIN)){ if (!DrySetup(CONFIG_DRY_POWER_PIN)) {
SKETCH_DEBUG_PRINTLN("DRY init success"); SKETCH_DEBUG_PRINTLN("DRY init success");
} }
WebSetupServer(mode); WebSetupServer(mode);
@ -281,7 +281,7 @@ void loop() {
ArduinoOTA.handle(); ArduinoOTA.handle();
} else { } else {
server.handleClient(); server.handleClient();
if (mode == BOOTMODE_NORMAL){ if (mode == BOOTMODE_NORMAL) {
MqttCheckSubscription(); MqttCheckSubscription();
MqttCheckIRQ(); MqttCheckIRQ();
} }
@ -289,29 +289,23 @@ void loop() {
nbCycle++; nbCycle++;
if (nbCycle > CONFIG_SAMPLING_PERIODE_MS / CONFIG_WEB_DELAY_MS) { if (nbCycle > CONFIG_SAMPLING_PERIODE_MS / CONFIG_WEB_DELAY_MS) {
std::vector<struct mqttInfo> batchInfo;
if (!BMP180GetTempAndPressure(temp, pressure)) { if (!BMP180GetTempAndPressure(temp, pressure)) {
SKETCH_DEBUG_PRINT("Current T°C "); SKETCH_DEBUG_PRINTF("Current %f°C Pressure %fmB\n", temp, pressure);
SKETCH_DEBUG_PRINT(temp); batchInfo.push_back({(float)temp, TEMPERATURE_FEED_FORMAT, 0, 0});
SKETCH_DEBUG_PRINT(" Pressure mB "); batchInfo.push_back({(float)pressure, PRESSURE_FEED_FORMAT, 0, 0});
SKETCH_DEBUG_PRINTLN(pressure);
if (mode == BOOTMODE_NORMAL)
MqttPublishBMP180(temp, pressure);
} }
if (!DHTGetTempAndHumidity(dhtTemp, dhtHumidity)) { if (!DHTGetTempAndHumidity(dhtTemp, dhtHumidity)) {
SKETCH_DEBUG_PRINT("Current T°C "); SKETCH_DEBUG_PRINTF("Current %f°C %f%% Humidity\n", dhtTemp, dhtHumidity);
SKETCH_DEBUG_PRINT(dhtTemp); batchInfo.push_back({dhtTemp, TEMPERATURE_DHT_FEED_FORMAT, 0, 0});
SKETCH_DEBUG_PRINT(" Humidity "); batchInfo.push_back({dhtHumidity, HUMIDITY_DHT_FEED_FORMAT, 0, 0});
SKETCH_DEBUG_PRINTLN(dhtHumidity);
if (mode == BOOTMODE_NORMAL)
MqttPublishDHT(dhtTemp, dhtHumidity);
} }
if (!DryGetMeasure(dryness)){ if (!DryGetMeasure(dryness)) {
SKETCH_DEBUG_PRINT("Current dryness "); SKETCH_DEBUG_PRINTF("Current dryness %d %%\n", (dryness * 100) / 1024);
SKETCH_DEBUG_PRINT((dryness*100)/1024); batchInfo.push_back({dryness, DRY_FEED_FORMAT, 0, 0});
SKETCH_DEBUG_PRINTLN("%");
if (mode == BOOTMODE_NORMAL)
MqttPublishDry(dryness);
} }
if (mode == BOOTMODE_NORMAL)
MqttBatchPublish(batchInfo, conf.mqttUser, conf.host);
nbCycle = 0; nbCycle = 0;
} }
} }