thermferm/devices.c

changeset 684
b2265c7e5707
parent 674
6cabc02f4c8d
child 685
819553a2b97e
equal deleted inserted replaced
683:d48733bf1529 684:b2265c7e5707
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
694 #ifdef USE_SIMULATOR 776 #ifdef USE_SIMULATOR
695 simulator_list *simulator; 777 simulator_list *simulator;
696 #endif 778 #endif
697 int found; 779 int found;
698 time_t now; 780 time_t now;
781 bool changed;
699 782
700 my_devices_state = 1; 783 my_devices_state = 1;
701 syslog(LOG_NOTICE, "Thread my_devices_loop started"); 784 syslog(LOG_NOTICE, "Thread my_devices_loop started");
702 dht11_next = time(NULL); 785 dht11_next = time(NULL);
703 786
704 /* 787 /*
705 * Loop forever until the external shutdown variable is set. 788 * Loop forever until the external shutdown variable is set.
706 */ 789 */
707 for (;;) { 790 for (;;) {
708 791
792 changed = false;
709 /* 793 /*
710 * Process all devices. 794 * Process all devices.
711 */ 795 */
712 for (device = Config.devices; device; device = device->next) { 796 for (device = Config.devices; device; device = device->next) {
713 797
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
841 if (my_devices_shutdown) 963 if (my_devices_shutdown)
842 break; 964 break;
843 /* 965 /*
844 * Delay a bit after all devices 966 * Delay a bit after all devices
845 */ 967 */
846 mDelay(100); 968 mDelay(50);
969 if (changed) {
970 devices_ws();
971 }
972 mDelay(50);
847 } 973 }
848 974
849 syslog(LOG_NOTICE, "Thread my_devices_loop stopped"); 975 syslog(LOG_NOTICE, "Thread my_devices_loop stopped");
850 my_devices_state = 0; 976 my_devices_state = 0;
851 return 0; 977 return 0;

mercurial