thermferm/devices.c

changeset 347
0ab5c3fd7c77
parent 344
acd840c9fcc0
child 348
ffc4b8aa824f
equal deleted inserted replaced
346:1043bd00873c 347:0ab5c3fd7c77
160 } 160 }
161 161
162 #endif 162 #endif
163 163
164 164
165 int read_w1(char *address, char *file)
166 {
167 char *addr = NULL;
168 int fn = -1, rc = -1, retries = 5;
169 uint8_t val;
170
171 addr = xstrcpy((char *)"/sys/bus/w1/devices/");
172 addr = xstrcat(addr, address);
173 addr = xstrcat(addr, (char *)"/");
174 addr = xstrcat(addr, file);
175
176 if ((fn = open(addr, O_RDONLY)) >= 0) {
177
178 if ((lseek(fn, 0L, SEEK_SET)) == 0) {
179
180 while (retries--) {
181 if ((read(fn, &val, 1)) == 1) {
182 rc = (int)val;
183 goto leave;
184 // } else {
185 // syslog(LOG_NOTICE, "read_w1() read %s try=%d: %s", addr, retries, strerror(errno));
186 }
187 }
188 syslog(LOG_NOTICE, "read_w1() read %s fatal: %s", addr, strerror(errno));
189
190 } else {
191 syslog(LOG_NOTICE, "read_w1() lseek %s: %s", addr, strerror(errno));
192 }
193
194 } else {
195 syslog(LOG_NOTICE, "read_w1() open %s: %s", addr, strerror(errno));
196 }
197
198 leave:
199 if (fn != -1) {
200 if ((close(fn)) == -1) {
201 syslog(LOG_NOTICE, "read_w1() close %s: %s", addr, strerror(errno));
202 }
203 }
204
205 free(addr);
206 return rc;
207 }
208
209
210
211 int write_w1(char *address, char *file, uint8_t val)
212 {
213 char *addr = NULL;
214 int fn = -1, rc = -1, retries = 5;
215
216 addr = xstrcpy((char *)"/sys/bus/w1/devices/");
217 addr = xstrcat(addr, address);
218 addr = xstrcat(addr, (char *)"/");
219 addr = xstrcat(addr, file);
220
221 if ((fn = open(addr, O_WRONLY)) >= 0) {
222
223 if ((lseek(fn, 0L, SEEK_SET)) == 0) {
224
225 while (retries--) {
226 if ((write(fn, &val, 1)) == 1) {
227 rc = 0;
228 goto leave;
229 // } else {
230 // syslog(LOG_NOTICE, "write_w1() write %s try=%d: %s", addr, retries, strerror(errno));
231 }
232 }
233 syslog(LOG_NOTICE, "write_w1() write %s fatal: %s", addr, strerror(errno));
234
235 } else {
236 syslog(LOG_NOTICE, "write_w1() lseek %s: %s", addr, strerror(errno));
237 }
238
239 } else {
240 syslog(LOG_NOTICE, "write_w1() open %s: %s", addr, strerror(errno));
241 }
242
243 leave:
244 if (fn != -1) {
245 if ((close(fn)) == -1) {
246 syslog(LOG_NOTICE, "write_w1() close %s: %s", addr, strerror(errno));
247 }
248 }
249
250 free(addr);
251 return rc;
252 }
253
254
165 255
166 int device_out(char *uuid, int value) 256 int device_out(char *uuid, int value)
167 { 257 {
168 devices_list *device; 258 devices_list *device;
169 time_t now, my_timestamp; 259 time_t now, my_timestamp;
170 int my_value; 260 int my_value, test_value;
171 #ifdef HAVE_WIRINGPI_H 261 #ifdef HAVE_WIRINGPI_H
172 int i, rc; 262 int i, rc;
173 char buf[40]; 263 char buf[40];
174 #endif 264 #endif
175 265
189 * every 2 minutes because commands can have temporary 279 * every 2 minutes because commands can have temporary
190 * disconnects, or have radio problems. 280 * disconnects, or have radio problems.
191 */ 281 */
192 my_timestamp = device->timestamp; 282 my_timestamp = device->timestamp;
193 my_value = device->value; 283 my_value = device->value;
194 if ((value != my_value) || (((int)now - (int)my_timestamp) > 120)) { 284
285 if ((device->type == DEVTYPE_W1) && (device->direction == DEVDIR_OUT_BIN)) {
286 test_value = (value == 0) ? 0 : 1;
287 } else {
288 test_value = value;
289 }
290
291 if ((test_value != my_value) || (((int)now - (int)my_timestamp) > 120)) {
195 292
196 #ifdef HAVE_WIRINGPI_H 293 #ifdef HAVE_WIRINGPI_H
197 rc = 0; 294 rc = 0;
198 if ((device->type == DEVTYPE_RC433) && (device->gpiopin != -1) && (device->present == DEVPRESENT_YES)) { 295 if ((device->type == DEVTYPE_RC433) && (device->gpiopin != -1) && (device->present == DEVPRESENT_YES)) {
199 snprintf(buf, 39, "%s,%d", device->address, value ? 1:0); 296 snprintf(buf, 39, "%s,%d", device->address, value ? 1:0);
217 if ((device->type == DEVTYPE_GPIO) && (device->gpiopin != -1) && (device->present == DEVPRESENT_YES)) { 314 if ((device->type == DEVTYPE_GPIO) && (device->gpiopin != -1) && (device->present == DEVPRESENT_YES)) {
218 315
219 } 316 }
220 #endif 317 #endif
221 if ((device->type == DEVTYPE_W1) && (device->direction == DEVDIR_OUT_BIN) && (device->present == DEVPRESENT_YES)) { 318 if ((device->type == DEVTYPE_W1) && (device->direction == DEVDIR_OUT_BIN) && (device->present == DEVPRESENT_YES)) {
222 319 if (strncmp(device->address, (char *)"3a", 2) == 0) {
320 /*
321 * DS2413. First read state so that we can preserve the state of
322 * the "other" PIO channel. To make things a bit more complicated
323 * the bits in the state register differ from the output register.
324 */
325 uint8_t state, output;
326
327 if ((rc = read_w1(device->address, (char *)"state")) >= 0) {
328 state = (unsigned int)rc;
329 output = (state & 0x01) + ((state & 0x04) >> 1);
330
331 if (device->subdevice == 0) {
332 output = (output & 0xfe);
333 output |= (value == 0) ? 0x01 : 0x00;
334 } else if (device->subdevice == 1) {
335 output = (output & 0xfd);
336 output |= (value == 0) ? 0x02 : 0x00;
337 } else {
338 output = 0xff;
339 }
340
341 if ((write_w1(device->address, (char *)"output", output)) == 0) {
342 syslog(LOG_NOTICE, "DS2413 PIO%c value=%d", (device->subdevice == 0) ? 'A' : 'B', (value == 0) ? 0 : 1);
343 if (debug)
344 fprintf(stdout, "DS2413 PIO%c value=%d\n", (device->subdevice == 0) ? 'A' : 'B', (value == 0) ? 0 : 1);
345 device->value = (value == 0) ? 0 : 1;
346 device->timestamp = time(NULL);
347 }
348 }
349 }
223 } 350 }
351
224 #ifdef USE_SIMULATOR 352 #ifdef USE_SIMULATOR
225 if ((device->type == DEVTYPE_SIM) && (device->direction == DEVDIR_OUT_BIN) && (device->present == DEVPRESENT_YES)) { 353 if ((device->type == DEVTYPE_SIM) && (device->direction == DEVDIR_OUT_BIN) && (device->present == DEVPRESENT_YES)) {
226 354
227 } 355 }
228 #endif 356 #endif
647 addr = NULL; 775 addr = NULL;
648 } 776 }
649 /* 777 /*
650 * DS2413 Dual channel addressable switch 778 * DS2413 Dual channel addressable switch
651 */ 779 */
652 unsigned char state;
653
654 if (strncmp(device->address, (char *)"3a", 2) == 0) { 780 if (strncmp(device->address, (char *)"3a", 2) == 0) {
655 addr = xstrcpy((char *)"/sys/bus/w1/devices/"); 781 addr = xstrcpy((char *)"/sys/bus/w1/devices/");
656 addr = xstrcat(addr, device->address); 782 addr = xstrcat(addr, device->address);
657 addr = xstrcat(addr, (char *)"/state"); 783 addr = xstrcat(addr, (char *)"/state");
658 if ((fp = fopen(addr, "r"))) { 784
785 if ((access(addr, R_OK)) == 0) {
659 if (device->present != DEVPRESENT_YES) { 786 if (device->present != DEVPRESENT_YES) {
660 syslog(LOG_NOTICE, "DS2413 %s is back", device->address); 787 syslog(LOG_NOTICE, "DS2413 %s is back", device->address);
661 #ifdef HAVE_WIRINGPI_H 788 #ifdef HAVE_WIRINGPI_H
662 piLock(LOCK_DEVICES); 789 piLock(LOCK_DEVICES);
663 #endif 790 #endif
664 device->present = DEVPRESENT_YES; 791 device->present = DEVPRESENT_YES;
665 #ifdef HAVE_WIRINGPI_H 792 #ifdef HAVE_WIRINGPI_H
666 piUnlock(LOCK_DEVICES); 793 piUnlock(LOCK_DEVICES);
667 #endif 794 #endif
668 } 795 }
669 if ((fread(&state, 1, 1, fp)) == 1) { 796 if ((rc = read_w1(device->address, (char *)"state")) >= 0) {
670 #ifdef HAVE_WIRINGPI_H 797 #ifdef HAVE_WIRINGPI_H
671 piLock(LOCK_DEVICES); 798 piLock(LOCK_DEVICES);
672 #endif 799 #endif
673 /* 800 /*
674 * Read PIOA or PIOB pin state bits 801 * Read PIOA or PIOB pin state bits
675 */ 802 */
676 if (device->subdevice == 0) 803 if (device->subdevice == 0)
677 device->value = (state & 0x01) ? 0 : 1; 804 device->value = (rc & 0x01) ? 0 : 1;
678 else if (device->subdevice == 1) 805 else if (device->subdevice == 1)
679 device->value = (state & 0x04) ? 0 : 1; 806 device->value = (rc & 0x04) ? 0 : 1;
680 device->timestamp = time(NULL); 807 device->timestamp = time(NULL);
681 #ifdef HAVE_WIRINGPI_H 808 #ifdef HAVE_WIRINGPI_H
682 piUnlock(LOCK_DEVICES); 809 piUnlock(LOCK_DEVICES);
683 #endif 810 #endif
684 } 811 }
685 fclose(fp);
686 } else { 812 } else {
687 if (device->present != DEVPRESENT_NO) { 813 if (device->present != DEVPRESENT_NO) {
688 syslog(LOG_NOTICE, "DS2413 %s is missing", device->address); 814 syslog(LOG_NOTICE, "DS2413 %s is missing", device->address);
689 #ifdef HAVE_WIRINGPI_H 815 #ifdef HAVE_WIRINGPI_H
690 piLock(LOCK_DEVICES); 816 piLock(LOCK_DEVICES);

mercurial