23 #include "thermferm.h" |
23 #include "thermferm.h" |
24 #include "statetbl.h" |
24 #include "statetbl.h" |
25 #include "one-wire.h" |
25 #include "one-wire.h" |
26 #include "devices.h" |
26 #include "devices.h" |
27 #include "delay.h" |
27 #include "delay.h" |
|
28 #include "websocket.h" |
28 #include "futil.h" |
29 #include "futil.h" |
29 #include "xutil.h" |
30 #include "xutil.h" |
30 |
31 |
31 #define W1_TEMP_RESOLUTION 12 |
32 #define W1_TEMP_RESOLUTION 12 |
32 |
33 |
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]; |
|
37 extern const char DEVPRESENT[4][6]; |
|
38 |
36 |
39 |
37 int my_one_wire_state = 0; |
40 int my_one_wire_state = 0; |
38 int my_one_wire_shutdown = 0; |
41 int my_one_wire_shutdown = 0; |
39 w1_list *w1_devices = NULL; |
42 w1_list *w1_devices = NULL; |
40 |
43 |
41 |
44 |
42 static int one_wire(void); |
45 static int one_wire(void); |
|
46 |
|
47 |
|
48 /* |
|
49 * Return json data for one device. |
|
50 */ |
|
51 char *one_wire_json(w1_list *dev_w1) |
|
52 { |
|
53 char *payload; |
|
54 char vbuf[64]; |
|
55 |
|
56 payload = xstrcpy((char *)"{\"address\":\""); |
|
57 payload = xstrcat(payload, dev_w1->address); |
|
58 payload = xstrcat(payload, (char *)"\",\"family\":\""); |
|
59 payload = xstrcat(payload, dev_w1->family); |
|
60 payload = xstrcat(payload, (char *)"\",\"present\":\""); |
|
61 payload = xstrcat(payload, (char *)DEVPRESENT[dev_w1->present]); |
|
62 payload = xstrcat(payload, (char *)"\",\"value\":"); |
|
63 snprintf(vbuf, 63, "%d", dev_w1->value); |
|
64 payload = xstrcat(payload, vbuf); |
|
65 payload = xstrcat(payload, (char *)"\",\"timestamp\":"); |
|
66 snprintf(vbuf, 63, "%ld", (long)dev_w1->timestamp); |
|
67 payload = xstrcat(payload, vbuf); |
|
68 payload = xstrcat(payload, (char *)"}"); |
|
69 |
|
70 return payload; |
|
71 } |
|
72 |
|
73 |
|
74 void one_wire_ws(void) |
|
75 { |
|
76 bool comma = false; |
|
77 char *payload = NULL, *payloadu = NULL; |
|
78 w1_list *dev_w1; |
|
79 |
|
80 payload = xstrcpy((char *)"{\"type\":\"onewire\",\"metric\":["); |
|
81 for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) { |
|
82 if (comma) |
|
83 payload = xstrcat(payload, (char *)","); |
|
84 payloadu = one_wire_json(dev_w1); |
|
85 payload = xstrcat(payload, payloadu); |
|
86 comma = true; |
|
87 free(payloadu); |
|
88 payloadu = NULL; |
|
89 } |
|
90 payload = xstrcat(payload, (char *)"]}"); |
|
91 syslog(LOG_NOTICE, "%s", payload); |
|
92 ws_broadcast(payload); |
|
93 free(payload); |
|
94 payload = NULL; |
|
95 } |
|
96 |
|
97 |
43 |
98 |
44 void *my_one_wire_loop(void *threadid) |
99 void *my_one_wire_loop(void *threadid) |
45 { |
100 { |
46 my_one_wire_state = 1; |
101 my_one_wire_state = 1; |
47 syslog(LOG_NOTICE, "Thread my_one_wire_loop started"); |
102 syslog(LOG_NOTICE, "Thread my_one_wire_loop started"); |
67 SM_STATES |
122 SM_STATES |
68 ScanNew, |
123 ScanNew, |
69 ScanDel, |
124 ScanDel, |
70 Read2413, |
125 Read2413, |
71 ReadTemp, |
126 ReadTemp, |
72 Missing |
127 Missing, |
|
128 Websocket |
73 SM_NAMES |
129 SM_NAMES |
74 (char *)"ScanNew", |
130 (char *)"ScanNew", |
75 (char *)"ScanDel", |
131 (char *)"ScanDel", |
76 (char *)"Read2413", |
132 (char *)"Read2413", |
77 (char *)"ReadTemp", |
133 (char *)"ReadTemp", |
78 (char *)"Missing" |
134 (char *)"Missing", |
|
135 (char *)"Websocket" |
79 SM_EDECL |
136 SM_EDECL |
80 |
137 |
81 int found, i, rc, value, conv_time; |
138 int found, i, rc, value, conv_time; |
82 FILE *fp; |
139 FILE *fp; |
83 devices_list *device; |
140 devices_list *device; |
84 w1_list *dev_w1, *n_w1, *cur_w1 = NULL; |
141 w1_list *dev_w1, *n_w1, *cur_w1 = NULL; |
85 char buffer[25], w1type[10], *devfile = NULL; |
142 char buffer[25], w1type[10], *devfile = NULL; |
86 uint8_t state, output, newval; |
143 uint8_t state, output, newval; |
|
144 bool changed; |
87 |
145 |
88 SM_START(ScanNew) |
146 SM_START(ScanNew) |
89 |
147 |
90 SM_STATE(ScanNew) |
148 SM_STATE(ScanNew) |
91 |
149 |
92 if (my_one_wire_shutdown) { |
150 if (my_one_wire_shutdown) { |
93 SM_SUCCESS; |
151 SM_SUCCESS; |
94 } |
152 } |
95 |
153 |
|
154 changed = false; |
96 /* |
155 /* |
97 * Scan for current one-wire devices. |
156 * Scan for current one-wire devices. |
98 */ |
157 */ |
99 fp = fopen("/sys/devices/w1_bus_master1/w1_master_slaves", "r"); |
158 fp = fopen("/sys/devices/w1_bus_master1/w1_master_slaves", "r"); |
100 if (fp == NULL) { |
159 if (fp == NULL) { |
114 (strcmp(w1type, (char *)"3b") == 0) || (strcmp(w1type, (char *)"42") == 0)) { |
173 (strcmp(w1type, (char *)"3b") == 0) || (strcmp(w1type, (char *)"42") == 0)) { |
115 found = FALSE; |
174 found = FALSE; |
116 for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) { |
175 for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) { |
117 if (strcmp(dev_w1->address, buffer) == 0) { |
176 if (strcmp(dev_w1->address, buffer) == 0) { |
118 found = TRUE; |
177 found = TRUE; |
119 dev_w1->timestamp = time(NULL); |
|
120 if (dev_w1->present != DEVPRESENT_YES) { |
178 if (dev_w1->present != DEVPRESENT_YES) { |
121 syslog(LOG_NOTICE, "One-wire device %s is back", buffer); |
179 syslog(LOG_NOTICE, "One-wire device %s is back", buffer); |
122 pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]); |
180 pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]); |
123 dev_w1->present = DEVPRESENT_YES; |
181 dev_w1->present = DEVPRESENT_YES; |
|
182 dev_w1->timestamp = time(NULL); |
124 pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]); |
183 pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]); |
|
184 changed = true; |
125 for (device = Config.devices; device; device = device->next) { |
185 for (device = Config.devices; device; device = device->next) { |
126 if (strcmp(dev_w1->address, device->address) == 0) { |
186 if (strcmp(dev_w1->address, device->address) == 0) { |
127 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
187 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
128 device->present = DEVPRESENT_YES; |
188 device->present = DEVPRESENT_YES; |
129 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
189 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
141 strncpy(n_w1->family, buffer, 2); |
201 strncpy(n_w1->family, buffer, 2); |
142 n_w1->family[2] = '\0'; |
202 n_w1->family[2] = '\0'; |
143 n_w1->present = DEVPRESENT_YES; |
203 n_w1->present = DEVPRESENT_YES; |
144 n_w1->value = (strcmp(w1type, (char *)"3a") == 0) ? 3:-1; |
204 n_w1->value = (strcmp(w1type, (char *)"3a") == 0) ? 3:-1; |
145 n_w1->timestamp = time(NULL); |
205 n_w1->timestamp = time(NULL); |
|
206 changed = true; |
146 |
207 |
147 pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]); |
208 pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]); |
148 if (w1_devices == NULL) { |
209 if (w1_devices == NULL) { |
149 w1_devices = n_w1; |
210 w1_devices = n_w1; |
150 cur_w1 = w1_devices; /* Point to first device */ |
211 cur_w1 = w1_devices; /* Point to first device */ |
183 * Gone missing |
244 * Gone missing |
184 */ |
245 */ |
185 syslog(LOG_NOTICE, "One-wire device %s is missing", dev_w1->address); |
246 syslog(LOG_NOTICE, "One-wire device %s is missing", dev_w1->address); |
186 pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]); |
247 pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]); |
187 dev_w1->present = DEVPRESENT_NO; |
248 dev_w1->present = DEVPRESENT_NO; |
|
249 dev_w1->timestamp = time(NULL); |
188 pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]); |
250 pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]); |
|
251 changed = true; |
189 for (device = Config.devices; device; device = device->next) { |
252 for (device = Config.devices; device; device = device->next) { |
190 if (strcmp(dev_w1->address, device->address) == 0) { |
253 if (strcmp(dev_w1->address, device->address) == 0) { |
191 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
254 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
192 device->present = DEVPRESENT_NO; |
255 device->present = DEVPRESENT_NO; |
193 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
256 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
237 |
300 |
238 newval = ((state & 0x04) >> 1) + (state & 0x01); |
301 newval = ((state & 0x04) >> 1) + (state & 0x01); |
239 if (newval != dev_w1->value) { |
302 if (newval != dev_w1->value) { |
240 syslog(LOG_NOTICE, "One-wire device %s-%d in %02x value %d => %d", dev_w1->address, i, state, dev_w1->value, newval); |
303 syslog(LOG_NOTICE, "One-wire device %s-%d in %02x value %d => %d", dev_w1->address, i, state, dev_w1->value, newval); |
241 dev_w1->value = newval; |
304 dev_w1->value = newval; |
|
305 dev_w1->timestamp = time(NULL); |
|
306 changed = true; |
242 } |
307 } |
243 |
308 |
244 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
309 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
245 /* |
310 /* |
246 * Read PIOA or PIOB pin state bits |
311 * Read PIOA or PIOB pin state bits |
271 |
336 |
272 if (output != newval) { |
337 if (output != newval) { |
273 if ((write_w1(dev_w1->address, (char *)"output", newval)) == 0) { |
338 if ((write_w1(dev_w1->address, (char *)"output", newval)) == 0) { |
274 syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, newval); |
339 syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, newval); |
275 dev_w1->value = newval; |
340 dev_w1->value = newval; |
|
341 dev_w1->timestamp = time(NULL); |
|
342 changed = true; |
276 } |
343 } |
277 } |
344 } |
278 } |
345 } |
279 } |
346 } |
280 } /* for (device = Config.devices; ... */ |
347 } /* for (device = Config.devices; ... */ |
333 if ((fp = fopen(devfile, "r"))) { |
400 if ((fp = fopen(devfile, "r"))) { |
334 // syslog(LOG_NOTICE, "One-wire device %s temperature is open, delay %d", cur_w1->address, conv_time); |
401 // syslog(LOG_NOTICE, "One-wire device %s temperature is open, delay %d", cur_w1->address, conv_time); |
335 mDelay(conv_time); |
402 mDelay(conv_time); |
336 if ((fgets(buffer, 25, fp))) { |
403 if ((fgets(buffer, 25, fp))) { |
337 sscanf(buffer, "%d", &value); |
404 sscanf(buffer, "%d", &value); |
338 // if (cur_w1->value != value) |
405 if (cur_w1->value != value) { |
|
406 dev_w1->timestamp = time(NULL); |
|
407 changed = true; |
339 // syslog(LOG_NOTICE, "One-wire device %s temperature read %d => %d", cur_w1->address, cur_w1->value, value); |
408 // syslog(LOG_NOTICE, "One-wire device %s temperature read %d => %d", cur_w1->address, cur_w1->value, value); |
|
409 } |
340 cur_w1->value = value; /* devices.c will pick this up */ |
410 cur_w1->value = value; /* devices.c will pick this up */ |
341 } else { |
411 } else { |
342 syslog(LOG_NOTICE, "One-wire device %s temperature read error", cur_w1->address); |
412 syslog(LOG_NOTICE, "One-wire device %s temperature read error", cur_w1->address); |
343 } |
413 } |
344 fclose(fp); |
414 fclose(fp); |