24 #include "delay.h" |
24 #include "delay.h" |
25 #include "devices.h" |
25 #include "devices.h" |
26 #include "rc-switch.h" |
26 #include "rc-switch.h" |
27 #include "panel.h" |
27 #include "panel.h" |
28 #include "xutil.h" |
28 #include "xutil.h" |
|
29 #include "websocket.h" |
29 |
30 |
30 |
31 |
31 int my_devices_shutdown = 0; |
32 int my_devices_shutdown = 0; |
32 int my_devices_state = 0; |
33 int my_devices_state = 0; |
33 |
34 |
34 extern sys_config Config; |
35 extern sys_config Config; |
35 extern pthread_mutex_t mutexes[5]; |
36 extern pthread_mutex_t mutexes[5]; |
36 extern w1_list *w1_devices; |
37 extern w1_list *w1_devices; |
|
38 |
|
39 extern const char DEVTYPE[8][6]; |
|
40 extern const char DEVPRESENT[4][6]; |
|
41 extern const char DEVDIR[7][11]; |
37 |
42 |
38 |
43 |
39 #ifdef USE_SIMULATOR |
44 #ifdef USE_SIMULATOR |
40 |
45 |
41 extern int SIMcooling; |
46 extern int SIMcooling; |
358 } |
363 } |
359 |
364 |
360 return DEVPRESENT_NO; |
365 return DEVPRESENT_NO; |
361 } |
366 } |
362 |
367 |
|
368 |
|
369 /* |
|
370 * Return json data for one device. |
|
371 */ |
|
372 char *device_json(devices_list *device, bool full) |
|
373 { |
|
374 char *payload; |
|
375 char vbuf[64]; |
|
376 |
|
377 payload = xstrcpy((char *)"{\"uuid\":\""); |
|
378 payload = xstrcat(payload, device->uuid); |
|
379 payload = xstrcat(payload, (char *)"\",\"type\":\""); |
|
380 payload = xstrcat(payload, (char *)DEVTYPE[device->type]); |
|
381 payload = xstrcat(payload, (char *)"\",\"direction\":\""); |
|
382 payload = xstrcat(payload, (char *)DEVDIR[device->direction]); |
|
383 payload = xstrcat(payload, (char *)"\",\"address\":\""); |
|
384 payload = xstrcat(payload, device->address); |
|
385 payload = xstrcat(payload, (char *)"\",\"subdevice\":"); |
|
386 snprintf(vbuf, 63, "%d", device->subdevice); |
|
387 payload = xstrcat(payload, vbuf); |
|
388 payload = xstrcat(payload, (char *)",\"value\":"); |
|
389 snprintf(vbuf, 63, "%d", device->value); |
|
390 payload = xstrcat(payload, vbuf); |
|
391 if (full) { |
|
392 payload = xstrcat(payload, (char *)",\"offset\":"); |
|
393 snprintf(vbuf, 63, "%d", device->offset); |
|
394 payload = xstrcat(payload, vbuf); |
|
395 } |
|
396 payload = xstrcat(payload, (char *)",\"present\":\""); |
|
397 payload = xstrcat(payload, (char *)DEVPRESENT[device->present]); |
|
398 payload = xstrcat(payload, (char *)"\""); |
|
399 if (full) { |
|
400 payload = xstrcat(payload, (char *)",\"gpiopin\":"); |
|
401 snprintf(vbuf, 63, "%d", device->gpiopin); |
|
402 payload = xstrcat(payload, vbuf); |
|
403 } |
|
404 payload = xstrcat(payload, (char *)",\"inuse\":"); |
|
405 snprintf(vbuf, 63, "%d", device->inuse); |
|
406 payload = xstrcat(payload, vbuf); |
|
407 payload = xstrcat(payload, (char *)",\"description\":\""); |
|
408 payload = xstrcat(payload, device->description); |
|
409 if (full) { |
|
410 payload = xstrcat(payload, (char *)"\",\"comment\":\""); |
|
411 payload = xstrcat(payload, device->comment); |
|
412 } |
|
413 payload = xstrcat(payload, (char *)"\",\"timestamp\":"); |
|
414 snprintf(vbuf, 63, "%ld", (long)device->timestamp); |
|
415 payload = xstrcat(payload, vbuf); |
|
416 payload = xstrcat(payload, (char *)"}"); |
|
417 |
|
418 return payload; |
|
419 } |
|
420 |
|
421 |
|
422 |
|
423 void devices_ws(void) |
|
424 { |
|
425 bool comma = false; |
|
426 char *payload = NULL, *payloadu = NULL; |
|
427 devices_list *device; |
|
428 |
|
429 payload = xstrcpy((char *)"{\"type\":\"device\",\"metric\":["); |
|
430 for (device = Config.devices; device; device = device->next) { |
|
431 if (comma) |
|
432 payload = xstrcat(payload, (char *)","); |
|
433 payloadu = device_json(device, false); |
|
434 payload = xstrcat(payload, payloadu); |
|
435 comma = true; |
|
436 free(payloadu); |
|
437 payloadu = NULL; |
|
438 } |
|
439 payload = xstrcat(payload, (char *)"]}"); |
|
440 syslog(LOG_NOTICE, "%s", payload); |
|
441 ws_broadcast(payload); |
|
442 free(payload); |
|
443 payload = NULL; |
|
444 } |
363 |
445 |
364 |
446 |
365 |
447 |
366 /* |
448 /* |
367 * Auto detect hotplugged or known to be present devices |
449 * Auto detect hotplugged or known to be present devices |
731 found = TRUE; |
815 found = TRUE; |
732 if ((dev_w1->value == -1) || (dev_w1->value < -55000)) { |
816 if ((dev_w1->value == -1) || (dev_w1->value < -55000)) { |
733 if (device->present != DEVPRESENT_ERROR) |
817 if (device->present != DEVPRESENT_ERROR) |
734 syslog(LOG_NOTICE, "sensor %s value error %d, keep %d", device->address, dev_w1->value, device->value); |
818 syslog(LOG_NOTICE, "sensor %s value error %d, keep %d", device->address, dev_w1->value, device->value); |
735 device->present = DEVPRESENT_ERROR; |
819 device->present = DEVPRESENT_ERROR; |
|
820 changed = true; |
736 } else { |
821 } else { |
737 if (device->present != DEVPRESENT_YES) |
822 if (device->present != DEVPRESENT_YES) { |
738 syslog(LOG_NOTICE, "sensor %s value ok %d", device->address, dev_w1->value); |
823 syslog(LOG_NOTICE, "sensor %s value ok %d", device->address, dev_w1->value); |
739 device->value = dev_w1->value; |
824 changed = true; |
740 device->timestamp = time(NULL); |
825 device->present = DEVPRESENT_YES; |
741 device->present = DEVPRESENT_YES; |
826 } |
|
827 if (device->value != dev_w1->value) { |
|
828 changed = true; |
|
829 device->value = dev_w1->value; |
|
830 device->timestamp = time(NULL); |
|
831 } |
742 } |
832 } |
743 } |
833 } |
744 } |
834 } |
745 |
835 |
746 if (found == FALSE) { |
836 if (found == FALSE) { |
747 if (device->present != DEVPRESENT_NO) { |
837 if (device->present != DEVPRESENT_NO) { |
748 syslog(LOG_NOTICE, "sensor %s is missing", device->address); |
838 syslog(LOG_NOTICE, "sensor %s is missing", device->address); |
749 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
839 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
750 device->present = DEVPRESENT_NO; |
840 device->present = DEVPRESENT_NO; |
|
841 changed = true; |
751 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
842 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
752 } |
843 } |
753 } |
844 } |
754 |
845 |
755 } /* if temperature sensor */ |
846 } /* if temperature sensor */ |
768 /* Read once during subdevice 0 */ |
859 /* Read once during subdevice 0 */ |
769 dht11Read(device->address); |
860 dht11Read(device->address); |
770 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
861 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
771 device->present = dht11_state; |
862 device->present = dht11_state; |
772 if (dht11_state == DEVPRESENT_YES) { |
863 if (dht11_state == DEVPRESENT_YES) { |
773 device->value = dht11_temperature; |
864 if (device->value != dht11_temperature) { |
774 device->timestamp = time(NULL); |
865 changed = true; |
|
866 device->value = dht11_temperature; |
|
867 device->timestamp = time(NULL); |
|
868 } |
775 } |
869 } |
776 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
870 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
777 } else if (device->subdevice == 1) { |
871 } else if (device->subdevice == 1) { |
778 /* Data already present, valid or not. */ |
872 /* Data already present, valid or not. */ |
779 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
873 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
780 device->present = dht11_state; |
874 device->present = dht11_state; |
781 if (dht11_state == DEVPRESENT_YES) { |
875 if (dht11_state == DEVPRESENT_YES) { |
782 device->value = dht11_humidity; |
876 if (device->value != dht11_humidity) { |
783 device->timestamp = time(NULL); |
877 changed = true; |
|
878 device->value = dht11_humidity; |
|
879 device->timestamp = time(NULL); |
|
880 } |
784 dht11_next = now + 29; |
881 dht11_next = now + 29; |
785 } else { |
882 } else { |
786 dht11_next = now + 1; |
883 dht11_next = now + 1; |
787 } |
884 } |
788 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
885 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
792 |
889 |
793 #ifdef HAVE_WIRINGPI_H |
890 #ifdef HAVE_WIRINGPI_H |
794 case DEVTYPE_GPIO: |
891 case DEVTYPE_GPIO: |
795 if (device->direction == DEVDIR_IN_BIN) { |
892 if (device->direction == DEVDIR_IN_BIN) { |
796 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
893 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
797 device->value = digitalRead(device->gpiopin); |
894 if (device->value != digitalRead(device->gpiopin)) { |
798 device->offset = 0; |
895 changed = true; |
799 device->timestamp = time(NULL); |
896 device->value = digitalRead(device->gpiopin); |
|
897 device->offset = 0; |
|
898 device->timestamp = time(NULL); |
|
899 } |
800 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
900 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
801 } |
901 } |
802 break; |
902 break; |
803 |
903 |
804 #endif |
904 #endif |
805 #ifdef USE_SIMULATOR |
905 #ifdef USE_SIMULATOR |
806 case DEVTYPE_SIM: |
906 case DEVTYPE_SIM: |
807 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
907 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
808 if (Config.simulators) { |
908 if (Config.simulators) { |
|
909 int val; |
|
910 |
809 simulator = Config.simulators; |
911 simulator = Config.simulators; |
810 if (device->subdevice == 0) { |
912 if (device->subdevice == 0) { |
811 device->value = (int)((int)(simulator->room_temperature * 1000) / 500) * 500; |
913 val = (int)((int)(simulator->room_temperature * 1000) / 500) * 500; |
812 device->timestamp = time(NULL); |
914 if (device->value != val) { |
|
915 device->value = val; |
|
916 device->timestamp = time(NULL); |
|
917 changed = true; |
|
918 } |
813 } else if (device->subdevice == 1) { |
919 } else if (device->subdevice == 1) { |
814 device->value = (int)((int)(simulator->air_temperature * 1000) / 62.5) * 62.5; |
920 val = (int)((int)(simulator->air_temperature * 1000) / 62.5) * 62.5; |
815 device->timestamp = time(NULL); |
921 if (device->value != val) { |
|
922 device->value = val; |
|
923 device->timestamp = time(NULL); |
|
924 changed = true; |
|
925 } |
816 } else if (device->subdevice == 2) { |
926 } else if (device->subdevice == 2) { |
817 device->value = (int)((int)(simulator->beer_temperature * 1000) / 62.5) * 62.5; |
927 val = (int)((int)(simulator->beer_temperature * 1000) / 62.5) * 62.5; |
818 device->timestamp = time(NULL); |
928 if (device->value != val) { |
|
929 device->value = val; |
|
930 device->timestamp = time(NULL); |
|
931 changed = true; |
|
932 } |
819 } else if (device->subdevice == 5) { |
933 } else if (device->subdevice == 5) { |
820 device->value = (int)((int)(simulator->room_humidity * 1000) / 500) * 500; |
934 val = (int)((int)(simulator->room_humidity * 1000) / 500) * 500; |
821 device->timestamp = time(NULL); |
935 if (device->value != val) { |
|
936 device->value = val; |
|
937 device->timestamp = time(NULL); |
|
938 changed = true; |
|
939 } |
822 } else if (device->subdevice == 6) { |
940 } else if (device->subdevice == 6) { |
823 device->value = (int)((int)(simulator->chiller_temperature * 1000) / 62.5) * 62.5; |
941 val = (int)((int)(simulator->chiller_temperature * 1000) / 62.5) * 62.5; |
824 device->timestamp = time(NULL); |
942 if (device->value != val) { |
|
943 device->value = val; |
|
944 device->timestamp = time(NULL); |
|
945 changed = true; |
|
946 } |
825 } |
947 } |
826 } |
948 } |
827 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
949 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
828 break; |
950 break; |
829 #endif |
951 #endif |