thermferm/one-wire.c

changeset 693
3518c07737d8
parent 692
6d97eb820cc1
child 694
0f1ef5e6418e
equal deleted inserted replaced
692:6d97eb820cc1 693:3518c07737d8
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);
372 442
373 if (my_one_wire_shutdown) { 443 if (my_one_wire_shutdown) {
374 SM_SUCCESS; 444 SM_SUCCESS;
375 } 445 }
376 446
377 sleep(1); 447 SM_PROCEED(Websocket);
448
449 SM_STATE(Websocket)
450
451 for (i = 0; i < 10; i++) {
452 if (my_one_wire_shutdown) {
453 SM_SUCCESS;
454 }
455
456 mDelay(100);
457 if (changed && i == 5)
458 one_wire_ws();
459 }
378 SM_PROCEED(ScanNew); 460 SM_PROCEED(ScanNew);
379 461
380 SM_END 462 SM_END
381 SM_RETURN 463 SM_RETURN
382 464

mercurial