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); |
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"); |