# HG changeset patch # User Michiel Broek # Date 1398345168 -7200 # Node ID f78f313b1d3483eb415c0bab07b51e50139b0f21 # Parent 5600a17896447589bdfdc04c389a72a7f9840d8b Working reading thermometers and sending data to a MQTT server. diff -r 5600a1789644 -r f78f313b1d34 thermometers/main.c --- a/thermometers/main.c Wed Apr 23 21:29:37 2014 +0200 +++ b/thermometers/main.c Thu Apr 24 15:12:48 2014 +0200 @@ -28,20 +28,15 @@ #define STATUS_CONNACK_RECVD 1 #define STATUS_WAITING 2 -/* Global variables for use in callbacks. See sub_client.c for an example of - * using a struct to hold variables for use in callbacks. */ -static char *topic = NULL; -//static char *message = NULL; -//static long msglen = 0; -static int qos = 0; -//static int retain = 0; -static int status = STATUS_CONNECTING; -static int mid_sent = 0; -static int last_mid = -1; -static int last_mid_sent = -1; -static bool connected = true; -static bool disconnect_sent = false; -static bool shutdown = false; +/* Global variables for use in callbacks. */ +static int qos = 0; +static int status = STATUS_CONNECTING; +static int mid_sent = 0; +static int last_mid = -1; +static int last_mid_sent = -1; +static bool connected = true; +static bool disconnect_sent = false; +static bool shutdown = false; extern bool debug; extern sys_config Config; @@ -108,8 +103,6 @@ void my_publish_callback(struct mosquitto *mosq, void *obj, int mid) { - fprintf(stdout, (char *)"my_publish_callback mid=%d\n", mid); - last_mid_sent = mid; } @@ -178,10 +171,12 @@ char *id = NULL, *state = NULL; struct mosquitto *mosq = NULL; char hostname[256], buf[1024]; - int rc, keepalive = 60; + int temp, rc, deviation, keepalive = 60; unsigned int max_inflight = 20; char err[1024]; w1_therm *tmp1, *old1; + char *device, *alias, line[60], *p = NULL; + FILE *fp; /* * Initialize mosquitto communication @@ -265,7 +260,6 @@ * Initialise is complete, report our presence state */ mosquitto_loop_start(mosq); - sprintf(buf, "1"); rc = mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, 1); @@ -273,17 +267,89 @@ do { if (status == STATUS_CONNACK_RECVD) { /* - * Sleep just log enough to keep the system load low. - */ -// usleep(1); - /* * Here send our sensors values */ for (tmp1 = Config.w1therms; tmp1; tmp1 = old1) { old1 = tmp1->next; - fprintf(stdout, "s: %s\n", tmp1->name); + + /* + * Build path and alias topic + */ + device = xstrcpy((char *)"/sys/bus/w1/devices/"); + device = xstrcat(device, tmp1->master); + device = xstrcat(device, (char *)"/"); + device = xstrcat(device, tmp1->name); + device = xstrcat(device, (char *)"/w1_slave"); + alias = xstrcpy((char *)"sensor/temperature/"); + alias = xstrcat(alias, hostname); + alias = xstrcat(alias, (char *)"/"); + alias = xstrcat(alias, tmp1->master); + alias = xstrcat(alias, (char *)"/"); + alias = xstrcat(alias, tmp1->alias); + + /* + * Read sensor data + */ + if ((fp = fopen(device, "r"))) { + /* + * The output looks like: + * 72 01 4b 46 7f ff 0e 10 57 : crc=57 YES + * 72 01 4b 46 7f ff 0e 10 57 t=23125 + */ + fgets(line, 50, fp); + line[strlen(line)-1] = '\0'; + if ((line[36] == 'Y') && (line[37] == 'E')) { + /* + * CRC is Ok, continue + */ + fgets(line, 50, fp); + line[strlen(line)-1] = '\0'; + strtok(line, (char *)"="); + p = strtok(NULL, (char *)"="); + rc = sscanf(p, "%d", &temp); + if ((rc == 1) && (tmp1->lastval != temp)) { + /* + * It is possible to have read errors or extreme values. + * This can happen with bad connections so we compare the + * value with the previous one. If the difference is too + * much, we don't send that value. That also means that if + * the next value is ok again, it will be marked invalid too. + */ + deviation = (temp + tmp1->lastval) / 10; + if ((tmp1->lastval == 0) || + (tmp1->lastval && (temp > (tmp1->lastval - deviation)) && (temp < (tmp1->lastval + deviation)))) { + /* + * Temperature is changed and valid, update and publish this. + */ + sprintf(buf, "%.1f", temp / 1000.0); + if ((rc = mosquitto_publish(mosq, &mid_sent, alias, strlen(buf), buf, qos, 0))) { + if (rc == MOSQ_ERR_NO_CONN) + mosquitto_reconnect(mosq); + else + syslog(LOG_NOTICE, "mainloop: error %d from mosquitto_publish", rc); + } + } else { + if (debug) + syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, tmp1->lastval, temp); + } + tmp1->lastval = temp; + } + } else { + syslog(LOG_NOTICE, "sensor %s/%s CRC error", tmp1->master, tmp1->name); + } + fclose(fp); + tmp1->present = 1; + } else { + tmp1->present = 0; + printf("sensor %s is missing\n", tmp1->name); + } + + free(device); + device = NULL; + free(alias); + alias = NULL; } - usleep(15000000); + usleep(1000000); if (shutdown) { /* @@ -291,7 +357,6 @@ */ sprintf(buf, "0"); mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, true); - free(topic); last_mid = mid_sent; status = STATUS_WAITING; }