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); |