Newer
Older
WH1080 / mqtt.c
/* 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;
}