23 #include "thermferm.h" |
23 #include "thermferm.h" |
24 |
24 |
25 |
25 |
26 int debug = FALSE; |
26 int debug = FALSE; |
27 static char *mypath; |
27 static char *mypath; |
28 static char *k, *v; |
|
29 static int linecnt = 0; |
|
30 sys_config Config; /* System configuration */ |
28 sys_config Config; /* System configuration */ |
31 |
29 |
32 #define MY_ENCODING "utf-8" |
30 #define MY_ENCODING "utf-8" |
33 |
31 |
34 const char UNITMODE[5][8] = { "OFF", "NONE", "FRIDGE", "BEER", "PROFILE" }; |
32 const char UNITMODE[5][8] = { "OFF", "NONE", "FRIDGE", "BEER", "PROFILE" }; |
35 |
33 |
36 //static int getstr(char **); |
34 |
37 static int getw1(char **); |
|
38 #ifdef HAVE_WIRINGPI_H |
|
39 static int getint(char **); |
|
40 #endif |
|
41 static int getuch(char **); |
|
42 static int getfloat(char **); |
|
43 //static int getbyt(char **); |
|
44 //static int gethex(char **); |
|
45 |
|
46 #define XSTR(x) #x |
|
47 #define STR(x) XSTR(x) |
|
48 |
|
49 /* |
|
50 * System configuration table |
|
51 */ |
|
52 key_list keytab[] = { |
|
53 {(char *)"w1therm", getw1, (char **)&Config.w1therms}, |
|
54 #ifdef HAVE_WIRINGPI_H |
|
55 {(char *)"lcd_cols", getint, (char **)&Config.lcd_cols}, |
|
56 {(char *)"lcd_rows", getint, (char **)&Config.lcd_rows}, |
|
57 #endif |
|
58 {(char *)"cs_mode", getuch, (char **)&Config.cs_mode}, |
|
59 {(char *)"cs_beerSet", getfloat, (char **)&Config.cs_beerSet}, |
|
60 {(char *)"cs_fridgeSet", getfloat, (char **)&Config.cs_fridgeSet}, |
|
61 {(char *)"cs_heatEstimator", getfloat, (char **)&Config.cs_heatEstimator}, |
|
62 {(char *)"cs_coolEstimator", getfloat, (char **)&Config.cs_coolEstimator}, |
|
63 {(char *)"cc_tempFormat", getuch, (char **)&Config.tempFormat}, |
|
64 {(char *)"cc_tempSetMin", getfloat, (char **)&Config.cc_tempSetMin}, |
|
65 {(char *)"cc_tempSetMax", getfloat, (char **)&Config.cc_tempSetMax}, |
|
66 {(char *)"cc_idleRangeH", getfloat, (char **)&Config.cc_idleRangeH}, |
|
67 {(char *)"cc_idleRangeL", getfloat, (char **)&Config.cc_idleRangeL}, |
|
68 {NULL, NULL, NULL} |
|
69 }; |
|
70 |
35 |
71 |
36 |
72 |
37 |
73 void killconfig(void) |
38 void killconfig(void) |
74 { |
39 { |
121 defaultControlConstants(); |
86 defaultControlConstants(); |
122 } |
87 } |
123 |
88 |
124 |
89 |
125 |
90 |
126 int wrconfig(char *config, char *confxml) |
91 int wrconfig(char *confxml) |
127 { |
92 { |
128 int rc = 0; |
93 int rc = 0; |
129 FILE *fp; |
94 FILE *fp; |
130 xmlTextWriterPtr writer; |
95 xmlTextWriterPtr writer; |
131 xmlBufferPtr buf; |
96 xmlBufferPtr buf; |
132 w1_therm *tmp1; |
97 w1_therm *tmp1; |
133 units_list *tmp3; |
98 units_list *tmp3; |
134 |
|
135 if (getenv((char *)"USER") == NULL) { |
|
136 mypath = xstrcpy((char *)"/root"); |
|
137 } else { |
|
138 mypath = xstrcpy(getenv((char *)"HOME")); |
|
139 } |
|
140 mypath = xstrcat(mypath, (char *)"/mbsepi-apps/"); |
|
141 mypath = xstrcat(mypath, config); |
|
142 |
|
143 if (debug) |
|
144 fprintf(stdout, "Writing %s\n", mypath); |
|
145 |
|
146 if ((fp = fopen(mypath, "w")) == NULL) { |
|
147 syslog(LOG_NOTICE, "could not rewrite %s", mypath); |
|
148 return 1; |
|
149 } |
|
150 |
|
151 fprintf(fp, "# Configuration file for thermferm %s\n", VERSION); |
|
152 fprintf(fp, "\n"); |
|
153 |
|
154 #ifdef HAVE_WIRINGPI_H |
|
155 fprintf(fp, "# LCD display\n"); |
|
156 fprintf(fp, "#\n"); |
|
157 fprintf(fp, "lcd_cols %d\n", Config.lcd_cols); |
|
158 fprintf(fp, "lcd_rows %d\n", Config.lcd_rows); |
|
159 fprintf(fp, "\n"); |
|
160 #endif |
|
161 |
|
162 fprintf(fp, "# DS18B20 temperature sensors on the 1-wire bus.\n"); |
|
163 fprintf(fp, "#\n"); |
|
164 fprintf(fp, "# kwd master bus name alias\n"); |
|
165 for (tmp1 = Config.w1therms; tmp1; tmp1 = tmp1->next) { |
|
166 fprintf(fp, "w1therm %s %d %s %s\n", tmp1->master, tmp1->bus, tmp1->name, tmp1->alias); |
|
167 } |
|
168 fprintf(fp, "\n"); |
|
169 |
|
170 fprintf(fp, "# Control Settings.\n"); |
|
171 fprintf(fp, "#\n"); |
|
172 fprintf(fp, "cs_mode %c\n", Config.cs_mode); |
|
173 fprintf(fp, "cs_beerSet %.1f\n", Config.cs_beerSet); |
|
174 fprintf(fp, "cs_fridgeSet %.1f\n", Config.cs_fridgeSet); |
|
175 fprintf(fp, "cs_heatEstimator %.1f\n", Config.cs_heatEstimator); |
|
176 fprintf(fp, "cs_coolEstimator %.1f\n", Config.cs_coolEstimator); |
|
177 fprintf(fp, "\n"); |
|
178 |
|
179 fprintf(fp, "# Control Constants.\n"); |
|
180 fprintf(fp, "#\n"); |
|
181 fprintf(fp, "cc_tempFormat %c\n", Config.tempFormat); |
|
182 fprintf(fp, "cc_tempSetMin %.1f\n", Config.cc_tempSetMin); |
|
183 fprintf(fp, "cc_tempSetMax %.1f\n", Config.cc_tempSetMax); |
|
184 fprintf(fp, "cc_idleRangeH %.1f\n", Config.cc_idleRangeH); |
|
185 fprintf(fp, "cc_idleRangeL %.1f\n", Config.cc_idleRangeL); |
|
186 fprintf(fp, "\n"); |
|
187 |
|
188 fprintf(fp, "# End of generated configuration\n"); |
|
189 fclose(fp); |
|
190 syslog(LOG_NOTICE, "Written %s rc=%d", mypath, rc); |
|
191 free(mypath); |
|
192 mypath = NULL; |
|
193 |
|
194 |
99 |
195 /* |
100 /* |
196 * Create a new XML buffer, to which the XML document will be written |
101 * Create a new XML buffer, to which the XML document will be written |
197 */ |
102 */ |
198 if ((buf = xmlBufferCreate()) == NULL) { |
103 if ((buf = xmlBufferCreate()) == NULL) { |
797 mypath = xstrcpy(getenv((char *)"HOME")); |
698 mypath = xstrcpy(getenv((char *)"HOME")); |
798 } |
699 } |
799 mypath = xstrcat(mypath, (char *)"/mbsepi-apps/"); |
700 mypath = xstrcat(mypath, (char *)"/mbsepi-apps/"); |
800 mypath = xstrcat(mypath, config); |
701 mypath = xstrcat(mypath, config); |
801 if ((doc = xmlParseFile(mypath)) == NULL) { |
702 if ((doc = xmlParseFile(mypath)) == NULL) { |
802 //if ((fp = fopen(mypath, "r")) == NULL) { |
|
803 /* |
703 /* |
804 * Not in the users home directory |
704 * Not in the users home directory |
805 */ |
705 */ |
806 free(mypath); |
706 free(mypath); |
807 mypath = xstrcpy((char *)"/etc/mbsepi-apps/"); |
707 mypath = xstrcpy((char *)"/etc/mbsepi-apps/"); |
808 mypath = xstrcat(mypath, config); |
708 mypath = xstrcat(mypath, config); |
809 if ((doc = xmlParseFile(mypath)) == NULL) { |
709 if ((doc = xmlParseFile(mypath)) == NULL) { |
810 //if ((fp = fopen(mypath, "r")) == NULL) { |
|
811 /* |
710 /* |
812 * Try /usr/local/etc |
711 * Try /usr/local/etc |
813 */ |
712 */ |
814 free(mypath); |
713 free(mypath); |
815 mypath = xstrcpy((char *)"/usr/local/etc/mbsepi-apps/"); |
714 mypath = xstrcpy((char *)"/usr/local/etc/mbsepi-apps/"); |
816 mypath = xstrcat(mypath, config); |
715 mypath = xstrcat(mypath, config); |
817 if ((doc = xmlParseFile(mypath)) == NULL) { |
716 if ((doc = xmlParseFile(mypath)) == NULL) { |
818 //if ((fp = fopen(mypath, "r")) == NULL) { |
|
819 syslog(LOG_NOTICE, "rdconfig: could not parse %s", config); |
717 syslog(LOG_NOTICE, "rdconfig: could not parse %s", config); |
820 return 1; |
718 return 1; |
821 } |
719 } |
822 } |
720 } |
823 } |
721 } |
827 syslog(LOG_NOTICE, "XML file %s empty.", mypath); |
725 syslog(LOG_NOTICE, "XML file %s empty.", mypath); |
828 xmlFreeDoc(doc); |
726 xmlFreeDoc(doc); |
829 return 1; |
727 return 1; |
830 } |
728 } |
831 if (xmlStrcmp(cur->name, (const xmlChar*)"THERMFERM")) { |
729 if (xmlStrcmp(cur->name, (const xmlChar*)"THERMFERM")) { |
832 syslog(LOG_NOTICE, "XML file %s is not a valid configuration file.\n", mypath); |
730 syslog(LOG_NOTICE, "XML file %s is not a valid configuration file.", mypath); |
833 xmlFreeDoc(doc); |
731 xmlFreeDoc(doc); |
834 return 1; |
732 return 1; |
835 } |
733 } |
836 |
734 |
837 /* |
735 /* |
838 * Parse configuration |
736 * Parse configuration |
839 */ |
737 */ |
840 cur = cur->xmlChildrenNode; |
738 cur = cur->xmlChildrenNode; |
841 while (cur != NULL) { |
739 while (cur != NULL) { |
842 // VERSION LISTEN_PORT TEMPFORMAT LCDS FERMENTERS |
740 if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) { |
843 // if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) { |
741 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); |
844 // recipe->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); |
742 if (xmlStrcmp(key, (const xmlChar *)"1")) { |
845 // } |
743 xmlFree(key); |
|
744 syslog(LOG_NOTICE, "XML file %s is not a valid version", mypath); |
|
745 return 1; |
|
746 } |
|
747 xmlFree(key); |
|
748 } |
846 if ((!xmlStrcmp(cur->name, (const xmlChar *)"LISTEN_PORT"))) { |
749 if ((!xmlStrcmp(cur->name, (const xmlChar *)"LISTEN_PORT"))) { |
847 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); |
750 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); |
848 if (sscanf((const char *)key, "%d", &ival) == 1) |
751 if (sscanf((const char *)key, "%d", &ival) == 1) |
849 Config.my_port = ival; |
752 Config.my_port = ival; |
850 xmlFree(key); |
753 xmlFree(key); |
867 } |
770 } |
868 cur = cur->next; |
771 cur = cur->next; |
869 } |
772 } |
870 xmlFreeDoc(doc); |
773 xmlFreeDoc(doc); |
871 |
774 |
872 /* |
|
873 linecnt = 0; |
|
874 while (fgets(buf, sizeof(buf) -1, fp)) { |
|
875 linecnt++; |
|
876 if (*(p = buf + strlen(buf) -1) != '\n') { |
|
877 syslog(LOG_NOTICE, "rdconfig: %s(%d): \"%s\" - line too long", mypath, linecnt, buf); |
|
878 rc = 1; |
|
879 break; |
|
880 } |
|
881 *p-- = '\0'; |
|
882 while ((p >= buf) && isspace(*p)) |
|
883 *p-- = '\0'; |
|
884 k = buf; |
|
885 while (*k && isspace(*k)) |
|
886 k++; |
|
887 p = k; |
|
888 while (*p && !isspace(*p)) |
|
889 p++; |
|
890 *p++='\0'; |
|
891 v = p; |
|
892 while (*v && isspace(*v)) |
|
893 v++; |
|
894 |
|
895 if ((*k == '\0') || (*k == '#')) { |
|
896 continue; |
|
897 } |
|
898 |
|
899 for (i = 0; keytab[i].key; i++) |
|
900 if (strcasecmp(k,keytab[i].key) == 0) |
|
901 break; |
|
902 |
|
903 if (keytab[i].key == NULL) { |
|
904 syslog(LOG_NOTICE, "rdconfig: %s(%d): %s %s - unknown keyword", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); |
|
905 rc = 1; |
|
906 break; |
|
907 } else if ((keytab[i].prc(keytab[i].dest))) { |
|
908 rc = 1; |
|
909 break; |
|
910 } |
|
911 |
|
912 } |
|
913 fclose(fp); |
|
914 */ |
|
915 |
|
916 free(mypath); |
775 free(mypath); |
917 mypath = NULL; |
776 mypath = NULL; |
918 |
777 |
919 return rc; |
778 return rc; |
920 } |
779 } |
921 |
780 |
922 |
781 |
923 |
782 |
924 /* |
|
925 static int getstr(char **dest) |
|
926 { |
|
927 if (debug) |
|
928 syslog(LOG_NOTICE, "rdconfig: getstr: %s(%d): %s %s", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); |
|
929 |
|
930 *dest = xstrcpy(v); |
|
931 return 0; |
|
932 } |
|
933 */ |
|
934 |
|
935 |
|
936 |
|
937 #ifdef HAVE_WIRINGPI_H |
|
938 static int getint(char **dest) |
|
939 { |
|
940 if (debug) |
|
941 syslog(LOG_NOTICE, "rdconfig: getint: %s(%d): %s %s", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); |
|
942 |
|
943 if (strspn(v,"0123456789") != strlen(v)) |
|
944 syslog(LOG_NOTICE, "rdconfig: %s(%d): %s %s - bad numeric", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); |
|
945 else |
|
946 *((int*)dest)=atoi(v); |
|
947 return 0; |
|
948 } |
|
949 #endif |
|
950 |
|
951 |
|
952 |
|
953 static int getw1(char **dest) |
|
954 { |
|
955 char *p, *q = NULL, *r = NULL; |
|
956 w1_therm **tmpm; |
|
957 int rc = 0, tmpp; |
|
958 |
|
959 for (p = v; *p && !isspace(*p); p++); |
|
960 if (*p) |
|
961 *p++ = '\0'; |
|
962 while (*p && isspace(*p)) |
|
963 p++; |
|
964 if (*p == '\0') { |
|
965 syslog(LOG_NOTICE, "rdconfig: %s(%d): less then two tokens", mypath, linecnt); |
|
966 return 1; |
|
967 } |
|
968 |
|
969 for (q = p; *q && !isspace(*q); q++); |
|
970 if (*q && isspace(*q)) { |
|
971 if (*q) |
|
972 *q++ = '\0'; |
|
973 while (*q && isspace(*q)) |
|
974 q++; |
|
975 |
|
976 for (r = q; *r && !isspace(*r); r++); |
|
977 if (*r) |
|
978 *r++ = '\0'; |
|
979 rc = sscanf(p, "%d", &tmpp); |
|
980 if (rc != 1) { |
|
981 syslog(LOG_NOTICE, "rdconfig: getw1: %s(%d): %s is not a integer value", mypath, linecnt, p); |
|
982 return 1; |
|
983 } |
|
984 if (debug) |
|
985 syslog(LOG_NOTICE, "rdconfig: getw1: %s(%d): %s %d %s %s", mypath, linecnt, v, tmpp, q, r); |
|
986 } |
|
987 |
|
988 for (tmpm = (w1_therm**)dest; *tmpm; tmpm=&((*tmpm)->next)); |
|
989 (*tmpm) = (w1_therm *) xmalloc(sizeof(w1_therm)); |
|
990 (*tmpm)->next = NULL; |
|
991 (*tmpm)->master = xstrcpy(v); |
|
992 (*tmpm)->bus = tmpp; |
|
993 (*tmpm)->name = xstrcpy(q); |
|
994 (*tmpm)->alias = xstrcpy(r); |
|
995 (*tmpm)->present = 0; |
|
996 (*tmpm)->lastval = 0; |
|
997 (*tmpm)->update = 0; |
|
998 |
|
999 return 0; |
|
1000 } |
|
1001 |
|
1002 |
|
1003 |
|
1004 static int getuch(char **dest) |
|
1005 { |
|
1006 if (debug) |
|
1007 syslog(LOG_NOTICE, "rdconfig: getuch: %s(%d): %s %s", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); |
|
1008 |
|
1009 if (isalnum(v[0])) { |
|
1010 *((unsigned char*)dest) = v[0]; |
|
1011 } else { |
|
1012 syslog(LOG_NOTICE, "rdconfig: %s(%d): %s %s - bad character", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); |
|
1013 } |
|
1014 return 0; |
|
1015 } |
|
1016 |
|
1017 |
|
1018 |
|
1019 static int getfloat(char **dest) |
|
1020 { |
|
1021 float val = 0.0; |
|
1022 int rc; |
|
1023 |
|
1024 if (debug) |
|
1025 syslog(LOG_NOTICE, "rdconfig: getfloat: %s(%d): %s %s", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); |
|
1026 |
|
1027 rc = sscanf(v, "%f", &val); |
|
1028 if (rc != 1) { |
|
1029 syslog(LOG_NOTICE, "rdconfig: %s(%d): %s %s - bad float value", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); |
|
1030 return 1; |
|
1031 } |
|
1032 *((float*)dest) = val; |
|
1033 |
|
1034 return 0; |
|
1035 } |
|
1036 |
|
1037 |
|
1038 /* |
|
1039 static int getbyt(char **dest) |
|
1040 { |
|
1041 Log_Msg("[rdconfig] getbyt: %s(%d): %s %s", mypath, linecnt, k, v); |
|
1042 if (strspn(v,"0123456789") != strlen(v)) |
|
1043 Log_Msg("[rdconfig] %s(%d): %s %s - bad numeric", mypath, linecnt, S(k), S(v)); |
|
1044 else |
|
1045 *((Uint8*)dest)=atoi(v); |
|
1046 return 0; |
|
1047 } |
|
1048 */ |
|
1049 |
|
1050 |
|
1051 /* |
|
1052 static int gethex(char **dest) |
|
1053 { |
|
1054 unsigned int val = 0; |
|
1055 int rc; |
|
1056 |
|
1057 Log_Msg("[rdconfig] gethex: %s(%d): %s %s", mypath, linecnt, k, v); |
|
1058 rc = sscanf(v, "%08x", &val); |
|
1059 if (rc != 1) { |
|
1060 Log_Msg("[rdconfig] %s(%d): %s %s - bad hex value", mypath, linecnt, S(k), S(v)); |
|
1061 return 1; |
|
1062 } |
|
1063 *((int*)dest) = val; |
|
1064 |
|
1065 return 0; |
|
1066 } |
|
1067 */ |
|
1068 |
|
1069 |
|