2016-04-08 01:03:57 +02:00
|
|
|
#include <stdarg.h>
|
2016-03-14 01:47:43 +01:00
|
|
|
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
|
|
|
|
WiFiClient client;
|
|
|
|
Adafruit_MQTT_Client *mqtt;
|
|
|
|
Adafruit_MQTT_Publish *mqtt_temp;
|
2016-03-16 00:54:13 +01:00
|
|
|
Adafruit_MQTT_Publish *mqtt_pressure;
|
2016-04-07 02:04:38 +02:00
|
|
|
Adafruit_MQTT_Publish *mqtt_dht_temp;
|
|
|
|
Adafruit_MQTT_Publish *mqtt_dht_humidity;
|
2016-03-14 01:47:43 +01:00
|
|
|
|
2016-03-22 20:01:05 +01:00
|
|
|
#define NB_ELEMENTS(x) (sizeof(x)/ sizeof(x[0]))
|
2016-03-25 01:08:48 +01:00
|
|
|
#define FEED_MAX_SIZE 64
|
2016-03-21 00:56:27 +01:00
|
|
|
|
2016-03-25 01:08:48 +01:00
|
|
|
#define TEMPERATURE_FEED_FORMAT "/feeds/%s/temperature"
|
|
|
|
#define PRESSURE_FEED_FORMAT "/feeds/%s/pressure"
|
2016-04-07 02:04:38 +02:00
|
|
|
#define TEMPERATURE_DHT_FEED_FORMAT "/feeds/%s/dht/temperature"
|
|
|
|
#define HUMIDITY_DHT_FEED_FORMAT "/feeds/%s/dht/humidity"
|
|
|
|
|
2016-03-25 01:08:48 +01:00
|
|
|
char temperatureFeed[FEED_MAX_SIZE] = {};
|
|
|
|
char pressureFeed[FEED_MAX_SIZE] = {};
|
2016-04-07 02:04:38 +02:00
|
|
|
char temperatureDhtFeed[FEED_MAX_SIZE] = {};
|
|
|
|
char humidityDhtFeed[FEED_MAX_SIZE] = {};
|
2016-03-14 01:47:43 +01:00
|
|
|
|
2016-03-22 20:01:05 +01:00
|
|
|
// Should have less that MAXSUBSCRIPTIONS elements
|
|
|
|
// MAXSUBSCRIPTIONS is defined is Adafruit_mqtt.h
|
2016-03-30 00:44:37 +02:00
|
|
|
const int gpioWatched[] = CONFIG_MQTT_CONTROLLED_GPIO;
|
2016-03-21 00:56:27 +01:00
|
|
|
|
2016-03-25 01:08:48 +01:00
|
|
|
#define GPIO_FEED_FORMAT "/feeds/%s/gpio/%d"
|
|
|
|
#define GPIO_SET_FEED_FORMAT "/feeds/%s/gpio/%d/set"
|
|
|
|
|
|
|
|
char *mqttId;
|
|
|
|
char GPIO_FEED[MAXSUBSCRIPTIONS][FEED_MAX_SIZE] = {};
|
|
|
|
char GPIO_SET_FEED[MAXSUBSCRIPTIONS][FEED_MAX_SIZE] = {};
|
2016-03-14 01:47:43 +01:00
|
|
|
|
2016-03-22 20:01:05 +01:00
|
|
|
Adafruit_MQTT_Publish * mqttGpio[MAXSUBSCRIPTIONS] = {};
|
2016-03-21 00:56:27 +01:00
|
|
|
|
2016-04-01 00:14:12 +02:00
|
|
|
bool isMqttConfigured = false;
|
|
|
|
|
2016-03-25 01:08:48 +01:00
|
|
|
int MqttSetup(char *server, char *user, char *passwd, int port, char * hostname) {
|
|
|
|
mqttId = hostname;
|
|
|
|
snprintf(temperatureFeed, FEED_MAX_SIZE, TEMPERATURE_FEED_FORMAT, mqttId);
|
|
|
|
snprintf(pressureFeed, FEED_MAX_SIZE, PRESSURE_FEED_FORMAT, mqttId);
|
2016-04-07 15:26:01 +02:00
|
|
|
snprintf(temperatureDhtFeed, FEED_MAX_SIZE, TEMPERATURE_DHT_FEED_FORMAT, mqttId);
|
|
|
|
snprintf(humidityDhtFeed, FEED_MAX_SIZE, HUMIDITY_DHT_FEED_FORMAT, mqttId);
|
2016-03-25 01:08:48 +01:00
|
|
|
|
2016-03-14 17:18:36 +01:00
|
|
|
mqtt = new Adafruit_MQTT_Client(&client, server, port, user, passwd);
|
2016-03-25 01:08:48 +01:00
|
|
|
mqtt_temp = new Adafruit_MQTT_Publish(mqtt, temperatureFeed);
|
|
|
|
mqtt_pressure = new Adafruit_MQTT_Publish(mqtt, pressureFeed);
|
2016-04-07 02:04:38 +02:00
|
|
|
mqtt_dht_temp = new Adafruit_MQTT_Publish(mqtt, temperatureDhtFeed);
|
|
|
|
mqtt_dht_humidity = new Adafruit_MQTT_Publish(mqtt, humidityDhtFeed);
|
2016-03-25 01:08:48 +01:00
|
|
|
|
2016-04-01 00:14:12 +02:00
|
|
|
isMqttConfigured = server[0] != '\0';
|
|
|
|
|
2016-04-07 16:14:19 +02:00
|
|
|
for (uint i = 0 ; i < NB_ELEMENTS(gpioWatched) && i < MAXSUBSCRIPTIONS; i++) {
|
2016-03-25 01:08:48 +01:00
|
|
|
snprintf(GPIO_FEED[i], FEED_MAX_SIZE, GPIO_FEED_FORMAT, mqttId, gpioWatched[i]);
|
|
|
|
snprintf(GPIO_SET_FEED[i], FEED_MAX_SIZE, GPIO_SET_FEED_FORMAT, mqttId, gpioWatched[i]);
|
|
|
|
|
2016-03-22 20:01:05 +01:00
|
|
|
Adafruit_MQTT_Subscribe *gpioSet = new Adafruit_MQTT_Subscribe(mqtt, GPIO_SET_FEED[i]);
|
|
|
|
mqtt->subscribe(gpioSet);
|
|
|
|
|
|
|
|
Adafruit_MQTT_Publish *gpio = new Adafruit_MQTT_Publish(mqtt, GPIO_FEED[i]);
|
|
|
|
mqttGpio[i] = gpio;
|
|
|
|
}
|
2016-03-14 01:47:43 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-08 01:03:57 +02:00
|
|
|
Adafruit_MQTT_Publish *MqttCreatePublisher(const char *fmt, ...){
|
|
|
|
char buf[128];
|
|
|
|
va_list args;
|
|
|
|
va_start (args, fmt);
|
|
|
|
vsnprintf(buf, sizeof(buf), (const char *)fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
String *url = new String(buf);
|
|
|
|
return new Adafruit_MQTT_Publish(mqtt, url->c_str());
|
|
|
|
}
|
|
|
|
|
2016-04-07 02:04:38 +02:00
|
|
|
bool MqttIsConfigured() {
|
2016-04-01 00:14:12 +02:00
|
|
|
return isMqttConfigured;
|
|
|
|
}
|
2016-04-10 01:59:37 +02:00
|
|
|
|
2016-03-24 14:54:55 +01:00
|
|
|
int MqttIsConnected() {
|
2016-04-10 01:59:37 +02:00
|
|
|
return (mqtt != NULL) ? mqtt->connected() : 0;
|
2016-03-14 18:05:14 +01:00
|
|
|
}
|
|
|
|
|
2016-03-11 01:31:03 +01:00
|
|
|
// Function to connect and reconnect as necessary to the MQTT server.
|
|
|
|
// Should be called in the loop function and it will take care if connecting.
|
2016-03-24 14:54:55 +01:00
|
|
|
int MqttConnect() {
|
2016-03-11 01:31:03 +01:00
|
|
|
int8_t ret;
|
|
|
|
|
2016-04-10 01:59:37 +02:00
|
|
|
if(!isMqttConfigured)
|
|
|
|
return -1;
|
|
|
|
|
2016-03-11 01:31:03 +01:00
|
|
|
// Stop if already connected.
|
2016-03-14 01:47:43 +01:00
|
|
|
if (mqtt->connected()) {
|
2016-03-11 01:31:03 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t retries = 3;
|
2016-03-14 01:47:43 +01:00
|
|
|
while ((ret = mqtt->connect()) != 0) { // connect will return 0 for connected
|
2016-03-26 15:07:15 +01:00
|
|
|
SKETCH_DEBUG_PRINTLN(mqtt->connectErrorString(ret));
|
|
|
|
SKETCH_DEBUG_PRINTLN("Retrying MQTT connection ...");
|
2016-03-14 01:47:43 +01:00
|
|
|
mqtt->disconnect();
|
2016-03-11 01:31:03 +01:00
|
|
|
delay(100); // wait
|
|
|
|
retries--;
|
|
|
|
if (retries == 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2016-03-22 20:01:05 +01:00
|
|
|
|
2016-03-24 14:54:55 +01:00
|
|
|
int MqttPublish(double temp, double pressure) {
|
|
|
|
if (MqttConnect() == 0) {
|
2016-03-26 15:07:15 +01:00
|
|
|
SKETCH_DEBUG_PRINTLN("publishing !");
|
2016-03-22 20:01:05 +01:00
|
|
|
mqtt_temp->publish(temp);
|
|
|
|
mqtt_pressure->publish(pressure);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-07 15:26:01 +02:00
|
|
|
int MqttDhtPublish(float temp, float humidity) {
|
2016-04-07 02:04:38 +02:00
|
|
|
if (MqttConnect() == 0) {
|
|
|
|
SKETCH_DEBUG_PRINTLN("publishing DHT!");
|
|
|
|
mqtt_dht_temp->publish(temp);
|
|
|
|
mqtt_dht_humidity->publish(humidity);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-03-22 20:01:05 +01:00
|
|
|
int getGpioFromSubscription(Adafruit_MQTT_Subscribe *subscription) {
|
2016-03-25 01:08:48 +01:00
|
|
|
char *temp = strstr(subscription->topic, "/gpio/");
|
|
|
|
if (!temp)
|
2016-03-22 20:01:05 +01:00
|
|
|
return -1;
|
2016-03-25 01:08:48 +01:00
|
|
|
String gpioStr(temp + strlen("/gpio/"));
|
2016-03-22 20:01:05 +01:00
|
|
|
int idx = gpioStr.indexOf("/");
|
2016-03-23 00:34:50 +01:00
|
|
|
int gpio = gpioStr.substring(0, idx).toInt();
|
|
|
|
|
|
|
|
if (gpio >= 0 && gpio < 32 )
|
2016-03-22 20:01:05 +01:00
|
|
|
return gpio;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-03-23 00:34:50 +01:00
|
|
|
int getGpioWatchedIndex(int gpio) {
|
2016-04-07 16:14:19 +02:00
|
|
|
for ( uint i = 0; i < NB_ELEMENTS(gpioWatched); i++) {
|
2016-03-23 00:34:50 +01:00
|
|
|
if (gpio == gpioWatched[i])
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-03-24 14:54:55 +01:00
|
|
|
void MqttChangeGpioValue(int gpio, int value) {
|
2016-03-23 00:34:50 +01:00
|
|
|
pinMode(gpio, OUTPUT);
|
|
|
|
digitalWrite(gpio, value);
|
|
|
|
int watchIdx = getGpioWatchedIndex(gpio);
|
|
|
|
if (watchIdx >= 0 ) {
|
|
|
|
mqttGpio[watchIdx]->publish(value);
|
|
|
|
}
|
2016-03-22 20:01:05 +01:00
|
|
|
}
|
|
|
|
|
2016-03-24 14:54:55 +01:00
|
|
|
void MqttCheckSubscription() {
|
|
|
|
if (MqttConnect() == 0) {
|
2016-03-22 20:01:05 +01:00
|
|
|
Adafruit_MQTT_Subscribe *subscription;
|
2016-04-10 00:37:41 +02:00
|
|
|
while ((subscription = mqtt->readSubscription(0))) {
|
2016-03-22 20:01:05 +01:00
|
|
|
int gpio = getGpioFromSubscription(subscription);
|
2016-03-26 15:07:15 +01:00
|
|
|
SKETCH_DEBUG_PRINT("Got Subscription for gpio ");
|
|
|
|
SKETCH_DEBUG_PRINTLN(gpio);
|
2016-03-23 00:34:50 +01:00
|
|
|
if (gpio > 0 && getGpioWatchedIndex(gpio) >= 0) {
|
2016-03-22 20:01:05 +01:00
|
|
|
char *value = (char *) subscription->lastread;
|
2016-03-26 15:07:15 +01:00
|
|
|
SKETCH_DEBUG_PRINT("Receive data: ");
|
|
|
|
SKETCH_DEBUG_PRINTLN(value);
|
2016-03-24 14:54:55 +01:00
|
|
|
MqttChangeGpioValue(gpio, atoi(value));
|
2016-03-22 20:01:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|