brewco/devices.c

changeset 487
d5bc44183aa4
parent 486
5a237a99a793
child 488
bee1f70fb42b
equal deleted inserted replaced
486:5a237a99a793 487:d5bc44183aa4
1 /*****************************************************************************
2 * Copyright (C) 2014..2015
3 *
4 * Michiel Broek <mbroek at mbse dot eu>
5 *
6 * This file is part of the mbsePi-apps
7 *
8 * This is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * mbsePi-apps is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with thermferm; see the file COPYING. If not, write to the Free
20 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *****************************************************************************/
22
23 #include "brewco.h"
24 #include "devices.h"
25 #include "util.h"
26 #include "xutil.h"
27 #include "keyboard.h"
28 #include "slcd.h"
29
30
31 extern int debug;
32 extern sys_config Config;
33 extern int my_shutdown;
34 extern uint16_t leds;
35 extern int slcdHandle;
36
37 #ifdef USE_SIMULATOR
38
39 extern int SIM_hlt_value;
40 extern int SIM_mlt_value;
41
42 #endif
43
44
45
46 /*
47 * Read one byte from a 1-wire device like a DS2413
48 */
49 int read_w1(char *address, char *file)
50 {
51 char *addr = NULL;
52 int fn = -1, rc = -1, retries = 5;
53 uint8_t val;
54
55 addr = xstrcpy((char *)"/sys/bus/w1/devices/");
56 addr = xstrcat(addr, address);
57 addr = xstrcat(addr, (char *)"/");
58 addr = xstrcat(addr, file);
59
60 if ((fn = open(addr, O_RDONLY)) >= 0) {
61
62 if ((lseek(fn, 0L, SEEK_SET)) == 0) {
63
64 while (retries--) {
65 if ((read(fn, &val, 1)) == 1) {
66 rc = (int)val;
67 goto leave;
68 }
69 }
70 syslog(LOG_NOTICE, "read_w1() read %s fatal: %s", addr, strerror(errno));
71
72 } else {
73 syslog(LOG_NOTICE, "read_w1() lseek %s: %s", addr, strerror(errno));
74 }
75
76 } else {
77 syslog(LOG_NOTICE, "read_w1() open %s: %s", addr, strerror(errno));
78 }
79
80 leave:
81 if (fn != -1) {
82 if ((close(fn)) == -1) {
83 syslog(LOG_NOTICE, "read_w1() close %s: %s", addr, strerror(errno));
84 }
85 }
86
87 free(addr);
88 return rc;
89 }
90
91
92
93 /*
94 * Write a byte to a 1-wire device like a DS2413
95 */
96 int write_w1(char *address, char *file, uint8_t val)
97 {
98 char *addr = NULL;
99 int fn = -1, rc = -1, retries = 5;
100
101 addr = xstrcpy((char *)"/sys/bus/w1/devices/");
102 addr = xstrcat(addr, address);
103 addr = xstrcat(addr, (char *)"/");
104 addr = xstrcat(addr, file);
105
106 if ((fn = open(addr, O_WRONLY)) >= 0) {
107
108 if ((lseek(fn, 0L, SEEK_SET)) == 0) {
109
110 while (retries--) {
111 if ((write(fn, &val, 1)) == 1) {
112 rc = 0;
113 goto leave;
114 }
115 }
116 syslog(LOG_NOTICE, "write_w1() write %s fatal: %s", addr, strerror(errno));
117
118 } else {
119 syslog(LOG_NOTICE, "write_w1() lseek %s: %s", addr, strerror(errno));
120 }
121
122 } else {
123 syslog(LOG_NOTICE, "write_w1() open %s: %s", addr, strerror(errno));
124 }
125
126 leave:
127 if (fn != -1) {
128 if ((close(fn)) == -1) {
129 syslog(LOG_NOTICE, "write_w1() close %s: %s", addr, strerror(errno));
130 }
131 }
132
133 free(addr);
134 return rc;
135 }
136
137
138
139 void hlt_heater(int value)
140 {
141 if (value) {
142 leds |= SLED_HLTH;
143 } else {
144 leds &= ~SLED_HLTH;
145 }
146 slcdLEDs(slcdHandle);
147 }
148
149
150
151 void mlt_heater(int value)
152 {
153 if (value) {
154 leds |= SLED_MLTH;
155 } else {
156 leds &= ~SLED_MLTH;
157 }
158 slcdLEDs(slcdHandle);
159 }
160
161
162
163 void mlt_pump(int value)
164 {
165 pump_status(value);
166 if (value) {
167 leds |= SLED_MLTP;
168 } else {
169 leds &= ~SLED_MLTP;
170 }
171 slcdLEDs(slcdHandle);
172 }
173
174
175
176 int device_out(char *uuid, int value)
177 {
178 devices_list *device;
179 time_t now, my_timestamp;
180 int rc, my_value, test_value;
181
182 if (uuid == NULL)
183 return 0;
184
185 now = time(NULL);
186
187 #ifdef HAVE_WIRINGPI_H
188 piLock(LOCK_DEVICES);
189 #endif
190
191 for (device = Config.devices; device; device = device->next) {
192 if (! strcmp(uuid, device->uuid)) {
193 /*
194 * Execute command if different then the old value. But also
195 * every 2 minutes because commands can have temporary
196 * disconnects, or have radio problems.
197 */
198 my_timestamp = device->timestamp;
199 my_value = device->value;
200
201 if ((device->type == DEVTYPE_W1) && (device->direction == DEVDIR_OUT_BIN)) {
202 test_value = (value == 0) ? 0 : 1;
203 } else {
204 test_value = value;
205 }
206
207 if ((test_value != my_value) || (((int)now - (int)my_timestamp) >= 120)) {
208
209 #ifdef HAVE_WIRINGPI_H
210 rc = 0;
211 if ((device->type == DEVTYPE_GPIO) && (device->gpiopin != -1) && (device->present == DEVPRESENT_YES)) {
212
213 }
214 #endif
215 if ((device->type == DEVTYPE_W1) && (device->direction == DEVDIR_OUT_BIN) && (device->present == DEVPRESENT_YES)) {
216 if (strncmp(device->address, (char *)"3a", 2) == 0) {
217 /*
218 * DS2413. First read state so that we can preserve the state of
219 * the "other" PIO channel. To make things a bit more complicated
220 * the bits in the state register differ from the output register.
221 */
222 uint8_t state, output;
223
224 if ((rc = read_w1(device->address, (char *)"state")) >= 0) {
225 state = (unsigned int)rc;
226 output = (state & 0x01) + ((state & 0x04) >> 1);
227
228 if (device->subdevice == 0) {
229 output = (output & 0xfe);
230 output |= (value == 0) ? 0x01 : 0x00;
231 } else if (device->subdevice == 1) {
232 output = (output & 0xfd);
233 output |= (value == 0) ? 0x02 : 0x00;
234 } else {
235 output = 0xff;
236 }
237
238 if ((write_w1(device->address, (char *)"output", output)) == 0) {
239 syslog(LOG_NOTICE, "DS2413 PIO%c value=%d (%s)", (device->subdevice == 0) ? 'A' : 'B', (value == 0) ? 0 : 1, device->comment);
240 if (debug)
241 fprintf(stdout, "DS2413 PIO%c value=%d (%s)\n", (device->subdevice == 0) ? 'A' : 'B', (value == 0) ? 0 : 1, device->comment);
242 device->value = (value == 0) ? 0 : 1;
243 device->timestamp = time(NULL);
244 }
245 }
246 }
247 }
248
249 #ifdef USE_SIMULATOR
250 if ((device->type == DEVTYPE_SIM) && (device->direction == DEVDIR_OUT_BIN) && (device->present == DEVPRESENT_YES)) {
251 if ((strcmp((char *)"SimHLTheater", device->address) == 0) ||
252 (strcmp((char *)"SimMLTheater", device->address) == 0) ||
253 (strcmp((char *)"SimMLTpump", device->address) == 0)) {
254 device->value = value;
255 if (strcmp((char *)"SimHLTheater", device->address) == 0) {
256 SIM_hlt_value = value;
257 hlt_heater(value);
258 }
259 if (strcmp((char *)"SimMLTheater", device->address) == 0) {
260 SIM_mlt_value = value;
261 mlt_heater(value);
262 }
263 if (strcmp((char *)"SimMLTpump", device->address) == 0) {
264 mlt_pump(value);
265 }
266 }
267 }
268 #endif
269 } else {
270 #ifdef HAVE_WIRINGPI_H
271 piUnlock(LOCK_DEVICES);
272 #endif
273 return 0;
274 }
275 }
276 }
277 #ifdef HAVE_WIRINGPI_H
278 piUnlock(LOCK_DEVICES);
279 #endif
280
281 return 0;
282 }
283
284
285 /*
286 * Returns DEVPRESENT_NO if failed.
287 * Returns DEVPRESENT_YES if success, value contains new value.
288 */
289 int device_in(char *uuid, int *value)
290 {
291 devices_list *device;
292 int tmp, present;
293
294 if (uuid == NULL)
295 return 0;
296
297 #ifdef HAVE_WIRINGPI_H
298 piLock(LOCK_DEVICES);
299 #endif
300
301 for (device = Config.devices; device; device = device->next) {
302 if (! strcmp(uuid, device->uuid)) {
303 present = device->present;
304 if (present == DEVPRESENT_YES) {
305 tmp = device->value + device->offset;
306 } else {
307 tmp = 0;
308 }
309 #ifdef HAVE_WIRINGPI_H
310 piUnlock(LOCK_DEVICES);
311 #endif
312 *value = tmp;
313 return present;
314 }
315 }
316
317 #ifdef HAVE_WIRINGPI_H
318 piUnlock(LOCK_DEVICES);
319 #endif
320
321 return DEVPRESENT_NO;
322 }
323
324
325
326
327 /*
328 * Auto detect hotplugged or known to be present devices
329 */
330 int devices_detect(void)
331 {
332 struct dirent *de;
333 DIR *fd;
334 devices_list *device, *ndev;
335 int found, subdevices, ival, i, rc = 0;
336 char buf[40];
337 uuid_t uu;
338 #ifdef HAVE_WIRINGPI_H
339 int pin;
340 #endif
341
342 /*
343 * Scan for 1-wire devices
344 */
345 if ((fd = opendir((char *)"/sys/bus/w1/devices"))) {
346 while ((de = readdir(fd))) {
347 if (de->d_name[0] != '.') {
348 found = FALSE;
349 for (device = Config.devices; device; device = device->next) {
350 if (strcmp(device->address,de->d_name) == 0) {
351 found = TRUE;
352 break;
353 }
354 }
355
356 if (found == FALSE) {
357 strncpy(buf, de->d_name, 2);
358 buf[2] = '\0';
359 sscanf(buf, "%02x", &ival);
360 syslog(LOG_NOTICE, "Scan 1-wire %02x %d", ival, ival);
361 subdevices = 1;
362 if (strcmp(buf, (char *)"29") == 0)
363 subdevices = 8;
364 if (strcmp(buf, (char *)"3a") == 0)
365 subdevices = 2;
366 for (i = 0; i < subdevices; i++) {
367 ndev = (devices_list *)malloc(sizeof(devices_list));
368 ndev->next = NULL;
369 ndev->version = 1;
370 ndev->uuid = malloc(37);
371 uuid_generate(uu);
372 uuid_unparse(uu, ndev->uuid);
373 ndev->type = DEVTYPE_W1;
374 ndev->direction = DEVDIR_UNDEF;
375 if (strcmp(buf, (char *)"10") == 0) {
376 ndev->direction = DEVDIR_IN_ANALOG;
377 ndev->description = xstrcpy((char *)"DS18S20 Digital thermometer");
378 } else if (strcmp(buf, (char *)"22") == 0) {
379 ndev->direction = DEVDIR_IN_ANALOG;
380 ndev->description = xstrcpy((char *)"DS1820 Digital thermometer");
381 } else if (strcmp(buf, (char *)"28") == 0) {
382 ndev->direction = DEVDIR_IN_ANALOG;
383 ndev->description = xstrcpy((char *)"DS18B20 Digital thermometer");
384 } else if (strcmp(buf, (char *)"3a") == 0) {
385 ndev->description = xstrcpy((char *)"DS2413 Dual channel addressable switch");
386 ndev->direction = DEVDIR_IN_BIN;
387 } else if (strcmp(buf, (char *)"3b") == 0) {
388 ndev->direction = DEVDIR_IN_ANALOG;
389 ndev->description = xstrcpy((char *)"DS1825 Digital thermometer");
390 } else if (strcmp(buf, (char *)"42") == 0) {
391 ndev->direction = DEVDIR_IN_ANALOG;
392 ndev->description = xstrcpy((char *)"DS28EA00 Digital thermometer");
393 } else if (strcmp(buf, (char *)"w1") == 0) {
394 ndev->description = xstrcpy((char *)"Master System device");
395 } else {
396 ndev->description = xstrcpy((char *)"Unknown device family ");
397 ndev->description = xstrcat(ndev->description, buf);
398 }
399 ndev->value = ndev->offset = ndev->inuse = 0;
400 ndev->present = DEVPRESENT_YES;
401 ndev->address = xstrcpy(de->d_name);
402 ndev->subdevice = i;
403 ndev->gpiopin = -1;
404 ndev->comment = xstrcpy((char *)"Auto detected device");
405 ndev->timestamp = time(NULL);
406
407 if (Config.devices == NULL) {
408 Config.devices = ndev;
409 } else {
410 for (device = Config.devices; device; device = device->next) {
411 if (device->next == NULL) {
412 device->next = ndev;
413 break;
414 }
415 }
416 }
417 rc++;
418 }
419 }
420 }
421 }
422 closedir(fd);
423 }
424
425 #ifdef HAVE_WIRINGPI_H
426 if (piBoardRev() == 2) {
427 /*
428 * Support rev B and newer boards only
429 */
430 found = FALSE;
431 for (device = Config.devices; device; device = device->next) {
432 if (device->type == DEVTYPE_GPIO) {
433 found = TRUE;
434 break;
435 }
436 }
437
438 if (found == FALSE) {
439 /*
440 * There were no GPIO devices found.
441 */
442 subdevices = 12;
443 pin = 0;
444 for (i = 0; i < subdevices; i++) {
445 if (i == 8)
446 pin = 17;
447
448 ndev = (devices_list *)malloc(sizeof(devices_list));
449 ndev->next = NULL;
450 ndev->version = 1;
451 ndev->uuid = malloc(37);
452 uuid_generate(uu);
453 uuid_unparse(uu, ndev->uuid);
454 ndev->type = DEVTYPE_GPIO;
455 ndev->value = digitalRead(pin);
456 ndev->offset = 0;
457 ndev->present = DEVPRESENT_YES;
458 ndev->address = xstrcpy((char *)"GPIO");
459 snprintf(buf, 39, "Raspberry GPIO %d", i);
460 ndev->description = xstrcpy(buf);
461 ndev->subdevice = i;
462 ndev->gpiopin = pin;
463 ndev->timestamp = time(NULL);
464 switch (i) {
465 case 0:
466 ndev->direction = DEVDIR_OUT_ANALOG;
467 ndev->inuse = 1;
468 ndev->comment = xstrcpy((char *)"MLT heater SSR");
469 break;
470 case 1:
471 ndev->direction = DEVDIR_OUT_ANALOG;
472 ndev->inuse = 1;
473 ndev->comment = xstrcpy((char *)"MLT heater PWM");
474 break;
475 case 2:
476 ndev->direction = DEVDIR_OUT_ANALOG;
477 ndev->inuse = 1;
478 ndev->comment = xstrcpy((char *)"MLT pump relay");
479 break;
480 case PANEL_RETURN:
481 ndev->direction = DEVDIR_IN_BIN;
482 ndev->inuse = 1;
483 ndev->comment = xstrcpy((char *)"Frontpanel Return");
484 break;
485 case PANEL_ENTER:
486 ndev->direction = DEVDIR_IN_BIN;
487 ndev->inuse = 1;
488 ndev->comment = xstrcpy((char *)"Frontpanel Enter key");
489 break;
490 case PANEL_DOWN:
491 ndev->direction = DEVDIR_IN_BIN;
492 ndev->inuse = 1;
493 ndev->comment = xstrcpy((char *)"Frontpanel Down key");
494 break;
495 case PANEL_UP:
496 ndev->direction = DEVDIR_IN_BIN;
497 ndev->inuse = 1;
498 ndev->comment = xstrcpy((char *)"Frontpanel Up key");
499 break;
500 case 7:
501 ndev->direction = DEVDIR_INTERN;
502 ndev->inuse = 1;
503 ndev->comment = xstrcpy((char *)"1-Wire bus");
504 break;
505 case 8:
506 ndev->direction = DEVDIR_OUT_BIN;
507 ndev->inuse = 1;
508 ndev->comment = xstrcpy((char *)"Buzzer");
509 break;
510 default:
511 ndev->direction = DEVDIR_IN_BIN;
512 ndev->inuse = 0;
513 ndev->comment = xstrcpy((char *)"Raspberry GPIO");
514 }
515 pin++;
516
517 if (Config.devices == NULL) {
518 Config.devices = ndev;
519 } else {
520 for (device = Config.devices; device; device = device->next) {
521 if (device->next == NULL) {
522 device->next = ndev;
523 break;
524 }
525 }
526 }
527 rc++;
528 }
529 }
530 }
531 #endif
532
533 #ifdef USE_SIMULATOR
534 found = FALSE;
535 for (device = Config.devices; device; device = device->next) {
536 if (device->type == DEVTYPE_SIM) {
537 found = TRUE;
538 break;
539 }
540 }
541
542 if (found == FALSE) {
543 subdevices = 6;
544 for (i = 0; i < subdevices; i++) {
545 ndev = (devices_list *)malloc(sizeof(devices_list));
546 ndev->next = NULL;
547 ndev->version = 1;
548 ndev->uuid = malloc(37);
549 uuid_generate(uu);
550 uuid_unparse(uu, ndev->uuid);
551 ndev->type = DEVTYPE_SIM;
552 ndev->value = ndev->offset = 0;
553 ndev->present = DEVPRESENT_YES;
554 ndev->subdevice = i;
555 ndev->gpiopin = -1;
556 ndev->comment = xstrcpy((char *)"Auto detected device");
557 ndev->timestamp = time(NULL);
558 ndev->inuse = 0;
559 switch (i) {
560 case 0: ndev->direction = DEVDIR_IN_ANALOG;
561 ndev->address = xstrcpy((char *)"SimRoomtemp");
562 ndev->description = xstrcpy((char *)"Simulated room temperature");
563 break;
564 case 1: ndev->direction = DEVDIR_IN_ANALOG;
565 ndev->address = xstrcpy((char *)"SimHLTtemp");
566 ndev->description = xstrcpy((char *)"Simulated HLT temperature");
567 break;
568 case 2: ndev->direction = DEVDIR_IN_ANALOG;
569 ndev->address = xstrcpy((char *)"SimMLTtemp");
570 ndev->description = xstrcpy((char *)"Simulated MLT temperature");
571 break;
572 case 3: ndev->direction = DEVDIR_OUT_BIN;
573 ndev->address = xstrcpy((char *)"SimHLTheater");
574 ndev->description = xstrcpy((char *)"Simulated HLT heater");
575 break;
576 case 4: ndev->direction = DEVDIR_OUT_BIN;
577 ndev->address = xstrcpy((char *)"SimMLTheater");
578 ndev->description = xstrcpy((char *)"Simulated MLT heater");
579 break;
580 case 5: ndev->direction = DEVDIR_OUT_BIN;
581 ndev->address = xstrcpy((char *)"SimMLTpump");
582 ndev->description = xstrcpy((char *)"Simulated MLT pump");
583 break;
584 }
585
586 if (Config.devices == NULL) {
587 Config.devices = ndev;
588 } else {
589 for (device = Config.devices; device; device = device->next) {
590 if (device->next == NULL) {
591 device->next = ndev;
592 break;
593 }
594 }
595 }
596 rc++;
597 }
598 }
599 #endif
600
601 return rc;
602 }
603
604
605
606 #ifdef HAVE_WIRINGPI_H
607 PI_THREAD (my_devices_loop)
608 #else
609 void *my_devices_loop(void *threadid)
610 #endif
611 {
612 devices_list *device;
613 char *addr = NULL, line[60], *p = NULL;
614 FILE *fp;
615 int temp, rc;
616
617 syslog(LOG_NOTICE, "Thread my_devices_loop started");
618 if (debug)
619 fprintf(stdout, "Thread my_devices_loop started\n");
620
621 #ifdef HAVE_WIRINGPI_H
622 if ((rc = piHiPri(10)))
623 syslog(LOG_NOTICE, "my_devices_loop: piHiPri(10) rc=%d", rc);
624 #endif
625
626 /*
627 * Loop forever until the external shutdown variable is set.
628 */
629 for (;;) {
630
631 /*
632 * Process all devices.
633 */
634 for (device = Config.devices; device; device = device->next) {
635
636 if (my_shutdown)
637 break;
638
639 switch (device->type) {
640 case DEVTYPE_W1:
641 /*
642 * Only tested with DS18B20 but from the kernel source this
643 * should work with all 1-wire thermometer sensors.
644 */
645 if ((strncmp(device->address, (char *)"10", 2) == 0) ||
646 (strncmp(device->address, (char *)"22", 2) == 0) ||
647 (strncmp(device->address, (char *)"28", 2) == 0) ||
648 (strncmp(device->address, (char *)"3b", 2) == 0) ||
649 (strncmp(device->address, (char *)"42", 2) == 0)) {
650 addr = xstrcpy((char *)"/sys/bus/w1/devices/");
651 addr = xstrcat(addr, device->address);
652 addr = xstrcat(addr, (char *)"/w1_slave");
653 if ((fp = fopen(addr, "r"))) {
654 if (device->present != DEVPRESENT_YES) {
655 syslog(LOG_NOTICE, "sensor %s is back", device->address);
656 #ifdef HAVE_WIRINGPI_H
657 piLock(LOCK_DEVICES);
658 #endif
659 device->present = DEVPRESENT_YES;
660 #ifdef HAVE_WIRINGPI_H
661 piUnlock(LOCK_DEVICES);
662 #endif
663 }
664 /*
665 * The output looks like:
666 * 72 01 4b 46 7f ff 0e 10 57 : crc=57 YES
667 * 72 01 4b 46 7f ff 0e 10 57 t=23125
668 */
669 fgets(line, 50, fp);
670 line[strlen(line)-1] = '\0';
671 if ((line[36] == 'Y') && (line[37] == 'E')) {
672 /* CRC is Ok, continue */
673 fgets(line, 50, fp);
674 line[strlen(line)-1] = '\0';
675 strtok(line, (char *)"=");
676 p = strtok(NULL, (char *)"=");
677 rc = sscanf(p, "%d", &temp);
678 #ifdef HAVE_WIRINGPI_H
679 piLock(LOCK_DEVICES);
680 #endif
681 if ((rc == 1) && (device->value != temp)) {
682 device->value = temp;
683 device->timestamp = time(NULL);
684 }
685 #ifdef HAVE_WIRINGPI_H
686 piUnlock(LOCK_DEVICES);
687 #endif
688 } else {
689 syslog(LOG_NOTICE, "sensor %s CRC error", device->address);
690 #ifdef HAVE_WIRINGPI_H
691 piLock(LOCK_DEVICES);
692 #endif
693 device->present = DEVPRESENT_ERROR;
694 #ifdef HAVE_WIRINGPI_H
695 piUnlock(LOCK_DEVICES);
696 #endif
697 }
698 fclose(fp);
699 } else {
700 if (device->present != DEVPRESENT_NO) {
701 syslog(LOG_NOTICE, "sensor %s is missing", device->address);
702 #ifdef HAVE_WIRINGPI_H
703 piLock(LOCK_DEVICES);
704 #endif
705 device->present = DEVPRESENT_NO;
706 #ifdef HAVE_WIRINGPI_H
707 piUnlock(LOCK_DEVICES);
708 #endif
709 }
710 }
711 free(addr);
712 addr = NULL;
713 } /* if temperature sensor */
714 /*
715 * DS2413 Dual channel addressable switch
716 */
717 if (strncmp(device->address, (char *)"3a", 2) == 0) {
718 addr = xstrcpy((char *)"/sys/bus/w1/devices/");
719 addr = xstrcat(addr, device->address);
720 addr = xstrcat(addr, (char *)"/state");
721
722 if ((access(addr, R_OK)) == 0) {
723 if (device->present != DEVPRESENT_YES) {
724 syslog(LOG_NOTICE, "DS2413 %s is back", device->address);
725 #ifdef HAVE_WIRINGPI_H
726 piLock(LOCK_DEVICES);
727 #endif
728 device->present = DEVPRESENT_YES;
729 #ifdef HAVE_WIRINGPI_H
730 piUnlock(LOCK_DEVICES);
731 #endif
732 }
733 /*
734 * First make sure that if this device is configured as input
735 * to drive the output high.
736 */
737 if (device->direction == DEVDIR_IN_BIN) {
738 uint8_t state, output;
739
740 if ((rc = read_w1(device->address, (char *)"state")) >= 0) {
741 state = (unsigned int)rc;
742 output = ((state & 0x02) >> 1) + ((state & 0x08) >> 2); /* Both latch states */
743 if (device->subdevice == 0) {
744 output = (output & 0xfe);
745 output |= 0x01;
746 } else if (device->subdevice == 1) {
747 output = (output & 0xfd);
748 output |= 0x02;
749 } else {
750 output = 0xff;
751 }
752 write_w1(device->address, (char *)"output", output);
753 }
754 }
755 if ((rc = read_w1(device->address, (char *)"state")) >= 0) {
756 #ifdef HAVE_WIRINGPI_H
757 piLock(LOCK_DEVICES);
758 #endif
759 /*
760 * Read PIOA or PIOB pin state bits
761 */
762 if (device->subdevice == 0)
763 device->value = (rc & 0x01) ? 0 : 1;
764 else if (device->subdevice == 1)
765 device->value = (rc & 0x04) ? 0 : 1;
766 device->timestamp = time(NULL);
767 #ifdef HAVE_WIRINGPI_H
768 piUnlock(LOCK_DEVICES);
769 #endif
770 }
771 } else {
772 if (device->present != DEVPRESENT_NO) {
773 syslog(LOG_NOTICE, "DS2413 %s is missing", device->address);
774 #ifdef HAVE_WIRINGPI_H
775 piLock(LOCK_DEVICES);
776 #endif
777 device->present = DEVPRESENT_NO;
778 #ifdef HAVE_WIRINGPI_H
779 piUnlock(LOCK_DEVICES);
780 #endif
781 }
782 }
783 free(addr);
784 addr = NULL;
785 }
786
787 break;
788
789 #ifdef HAVE_WIRINGPI_H
790 case DEVTYPE_GPIO:
791 if (device->direction == DEVDIR_IN_BIN) {
792 piLock(LOCK_DEVICES);
793 device->value = digitalRead(device->gpiopin);
794 device->offset = 0;
795 device->timestamp = time(NULL);
796 piUnlock(LOCK_DEVICES);
797 }
798 break;
799
800 #endif
801 #ifdef USE_SIMULATOR
802 case DEVTYPE_SIM:
803 #ifdef HAVE_WIRINGPI_H
804 piLock(LOCK_DEVICES);
805 #endif
806 if (Config.simulator) {
807 if (device->subdevice == 0) {
808 device->value = (int)(Config.simulator->room_temperature * 1000);
809 device->timestamp = time(NULL);
810 } else if (device->subdevice == 1) {
811 device->value = (int)(Config.simulator->hlt_temperature * 1000);
812 device->timestamp = time(NULL);
813 } else if (device->subdevice == 2) {
814 device->value = (int)(Config.simulator->mlt_temperature * 1000);
815 device->timestamp = time(NULL);
816 }
817 }
818 #ifdef HAVE_WIRINGPI_H
819 piUnlock(LOCK_DEVICES);
820 #endif
821 break;
822 #endif
823 default:
824 break;
825 }
826
827 /*
828 * Delay a bit after procesing a device.
829 */
830 usleep(10000);
831 }
832
833 if (my_shutdown)
834 break;
835 /*
836 * Delay a bit after all devices
837 */
838 usleep(100000);
839 }
840
841 syslog(LOG_NOTICE, "Thread my_devices_loop stopped");
842 if (debug)
843 fprintf(stdout, "Thread my_devices_loop stopped\n");
844 return 0;
845 }
846
847
848

mercurial