thermometers/main.c

changeset 11
f78f313b1d34
parent 10
5600a1789644
child 12
102c44bb8c9d
equal deleted inserted replaced
10:5600a1789644 11:f78f313b1d34
26 26
27 #define STATUS_CONNECTING 0 27 #define STATUS_CONNECTING 0
28 #define STATUS_CONNACK_RECVD 1 28 #define STATUS_CONNACK_RECVD 1
29 #define STATUS_WAITING 2 29 #define STATUS_WAITING 2
30 30
31 /* Global variables for use in callbacks. See sub_client.c for an example of 31 /* Global variables for use in callbacks. */
32 * using a struct to hold variables for use in callbacks. */ 32 static int qos = 0;
33 static char *topic = NULL; 33 static int status = STATUS_CONNECTING;
34 //static char *message = NULL; 34 static int mid_sent = 0;
35 //static long msglen = 0; 35 static int last_mid = -1;
36 static int qos = 0; 36 static int last_mid_sent = -1;
37 //static int retain = 0; 37 static bool connected = true;
38 static int status = STATUS_CONNECTING; 38 static bool disconnect_sent = false;
39 static int mid_sent = 0; 39 static bool shutdown = false;
40 static int last_mid = -1;
41 static int last_mid_sent = -1;
42 static bool connected = true;
43 static bool disconnect_sent = false;
44 static bool shutdown = false;
45 40
46 extern bool debug; 41 extern bool debug;
47 extern sys_config Config; 42 extern sys_config Config;
48 43
49 int server(void); 44 int server(void);
106 101
107 102
108 103
109 void my_publish_callback(struct mosquitto *mosq, void *obj, int mid) 104 void my_publish_callback(struct mosquitto *mosq, void *obj, int mid)
110 { 105 {
111 fprintf(stdout, (char *)"my_publish_callback mid=%d\n", mid);
112
113 last_mid_sent = mid; 106 last_mid_sent = mid;
114 } 107 }
115 108
116 109
117 110
176 int server(void) 169 int server(void)
177 { 170 {
178 char *id = NULL, *state = NULL; 171 char *id = NULL, *state = NULL;
179 struct mosquitto *mosq = NULL; 172 struct mosquitto *mosq = NULL;
180 char hostname[256], buf[1024]; 173 char hostname[256], buf[1024];
181 int rc, keepalive = 60; 174 int temp, rc, deviation, keepalive = 60;
182 unsigned int max_inflight = 20; 175 unsigned int max_inflight = 20;
183 char err[1024]; 176 char err[1024];
184 w1_therm *tmp1, *old1; 177 w1_therm *tmp1, *old1;
178 char *device, *alias, line[60], *p = NULL;
179 FILE *fp;
185 180
186 /* 181 /*
187 * Initialize mosquitto communication 182 * Initialize mosquitto communication
188 */ 183 */
189 mosquitto_lib_init(); 184 mosquitto_lib_init();
263 258
264 /* 259 /*
265 * Initialise is complete, report our presence state 260 * Initialise is complete, report our presence state
266 */ 261 */
267 mosquitto_loop_start(mosq); 262 mosquitto_loop_start(mosq);
268
269 sprintf(buf, "1"); 263 sprintf(buf, "1");
270 rc = mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, 1); 264 rc = mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, 1);
271 265
272 fprintf(stdout, (char *)"Enter loop, connected %d\n", connected); 266 fprintf(stdout, (char *)"Enter loop, connected %d\n", connected);
273 do { 267 do {
274 if (status == STATUS_CONNACK_RECVD) { 268 if (status == STATUS_CONNACK_RECVD) {
275 /*
276 * Sleep just log enough to keep the system load low.
277 */
278 // usleep(1);
279 /* 269 /*
280 * Here send our sensors values 270 * Here send our sensors values
281 */ 271 */
282 for (tmp1 = Config.w1therms; tmp1; tmp1 = old1) { 272 for (tmp1 = Config.w1therms; tmp1; tmp1 = old1) {
283 old1 = tmp1->next; 273 old1 = tmp1->next;
284 fprintf(stdout, "s: %s\n", tmp1->name); 274
275 /*
276 * Build path and alias topic
277 */
278 device = xstrcpy((char *)"/sys/bus/w1/devices/");
279 device = xstrcat(device, tmp1->master);
280 device = xstrcat(device, (char *)"/");
281 device = xstrcat(device, tmp1->name);
282 device = xstrcat(device, (char *)"/w1_slave");
283 alias = xstrcpy((char *)"sensor/temperature/");
284 alias = xstrcat(alias, hostname);
285 alias = xstrcat(alias, (char *)"/");
286 alias = xstrcat(alias, tmp1->master);
287 alias = xstrcat(alias, (char *)"/");
288 alias = xstrcat(alias, tmp1->alias);
289
290 /*
291 * Read sensor data
292 */
293 if ((fp = fopen(device, "r"))) {
294 /*
295 * The output looks like:
296 * 72 01 4b 46 7f ff 0e 10 57 : crc=57 YES
297 * 72 01 4b 46 7f ff 0e 10 57 t=23125
298 */
299 fgets(line, 50, fp);
300 line[strlen(line)-1] = '\0';
301 if ((line[36] == 'Y') && (line[37] == 'E')) {
302 /*
303 * CRC is Ok, continue
304 */
305 fgets(line, 50, fp);
306 line[strlen(line)-1] = '\0';
307 strtok(line, (char *)"=");
308 p = strtok(NULL, (char *)"=");
309 rc = sscanf(p, "%d", &temp);
310 if ((rc == 1) && (tmp1->lastval != temp)) {
311 /*
312 * It is possible to have read errors or extreme values.
313 * This can happen with bad connections so we compare the
314 * value with the previous one. If the difference is too
315 * much, we don't send that value. That also means that if
316 * the next value is ok again, it will be marked invalid too.
317 */
318 deviation = (temp + tmp1->lastval) / 10;
319 if ((tmp1->lastval == 0) ||
320 (tmp1->lastval && (temp > (tmp1->lastval - deviation)) && (temp < (tmp1->lastval + deviation)))) {
321 /*
322 * Temperature is changed and valid, update and publish this.
323 */
324 sprintf(buf, "%.1f", temp / 1000.0);
325 if ((rc = mosquitto_publish(mosq, &mid_sent, alias, strlen(buf), buf, qos, 0))) {
326 if (rc == MOSQ_ERR_NO_CONN)
327 mosquitto_reconnect(mosq);
328 else
329 syslog(LOG_NOTICE, "mainloop: error %d from mosquitto_publish", rc);
330 }
331 } else {
332 if (debug)
333 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, tmp1->lastval, temp);
334 }
335 tmp1->lastval = temp;
336 }
337 } else {
338 syslog(LOG_NOTICE, "sensor %s/%s CRC error", tmp1->master, tmp1->name);
339 }
340 fclose(fp);
341 tmp1->present = 1;
342 } else {
343 tmp1->present = 0;
344 printf("sensor %s is missing\n", tmp1->name);
345 }
346
347 free(device);
348 device = NULL;
349 free(alias);
350 alias = NULL;
285 } 351 }
286 usleep(15000000); 352 usleep(1000000);
287 353
288 if (shutdown) { 354 if (shutdown) {
289 /* 355 /*
290 * Final publish 0 to clients/<hostname>/thermometers/state 356 * Final publish 0 to clients/<hostname>/thermometers/state
291 */ 357 */
292 sprintf(buf, "0"); 358 sprintf(buf, "0");
293 mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, true); 359 mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, true);
294 free(topic);
295 last_mid = mid_sent; 360 last_mid = mid_sent;
296 status = STATUS_WAITING; 361 status = STATUS_WAITING;
297 } 362 }
298 } else if (status == STATUS_WAITING) { 363 } else if (status == STATUS_WAITING) {
299 fprintf(stdout, (char *)"Waiting\n"); 364 fprintf(stdout, (char *)"Waiting\n");

mercurial