/* Publish observations to a MQTT topic
*/
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <mosquitto.h>
struct mosquitto *mosq = NULL;
char * publish_topic = NULL;
bool MQTT_init(const char * hostname, int port, const char * username, const char * password, const char * topic) {
mosquitto_lib_init();
mosq = mosquitto_new (NULL, true, NULL);
if (!mosq) {
fprintf (stderr, "Can't initialize Mosquitto library\n");
return false;
}
if (username && password) {
mosquitto_username_pw_set (mosq, username, password);
}
int ret = mosquitto_connect (mosq, hostname, port, 0);
if (ret) {
fprintf (stderr, "Can't connect to Mosquitto server\n");
return false;
}
publish_topic = strdup(topic);
return true;
}
void MQTT_destroy() {
if (mosq) {
mosquitto_disconnect (mosq);
mosquitto_destroy (mosq);
}
if (publish_topic) {
free(publish_topic);
}
mosquitto_lib_cleanup();
}
bool MQTT_observation
(
double TemperatureC, // temperature in C
double Humidity, // as a percentage
double WindAveMs,
double WindGustMs,
char *WindDirection, // string "N", "NNE", "NE", "ENE", "E", etc.
double TotalRainMm, // total since battery change
double PressureHpa // pressure at sea level
)
{
char * msg;
int msglen = asprintf(&msg, "{\"temp\": %.1f, \"humidity\": %.1f, \"windAveMs\": %.1f, \"windGustMs\": %.1f, \"windDir\": \"%s\", \"totalRain\": %.f, \"pressure\": %.1f}",
TemperatureC, Humidity, WindAveMs, WindGustMs, WindDirection, TotalRainMm, PressureHpa);
if (msglen < 0) {
return false;
}
bool sent = false;
int retry = 0;
while (!sent && (retry < 10)) {
int ret = mosquitto_publish (mosq, NULL, publish_topic,
msglen, msg, 0, false);
if (ret == MOSQ_ERR_SUCCESS) {
sent = true;
} else if (retry < 9) {
fprintf(stderr, "Problem publishing to Mosquitto server.\n");
sleep(retry + 1);
mosquitto_reconnect(mosq);
}
retry ++;
}
free(msg);
return sent;
}