/* 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; }