391 */ |
393 */ |
392 int devices_detect(void) |
394 int devices_detect(void) |
393 { |
395 { |
394 struct dirent *de; |
396 struct dirent *de; |
395 DIR *fd; |
397 DIR *fd; |
|
398 w1_list *dev_w1; |
396 devices_list *device, *ndev; |
399 devices_list *device, *ndev; |
397 int found, subdevices, ival, i, rc = 0; |
400 int found, subdevices, i, rc = 0; |
398 char buf[40]; |
|
399 uuid_t uu; |
401 uuid_t uu; |
400 #ifdef HAVE_WIRINGPI_H |
402 #ifdef HAVE_WIRINGPI_H |
401 int pin; |
403 int pin; |
402 #endif |
404 #endif |
403 |
405 |
404 /* |
406 /* |
405 * Scan for 1-wire devices |
407 * Scan for 1-wire devices. These are already detected by the |
|
408 * one-wire thread that is already running. So we just check |
|
409 * these detected devices. |
406 */ |
410 */ |
407 if ((fd = opendir((char *)"/sys/bus/w1/devices"))) { |
411 for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) { |
408 while ((de = readdir(fd))) { |
412 found = FALSE; |
409 if (de->d_name[0] != '.') { |
413 for (device = Config.devices; device; device = device->next) { |
410 found = FALSE; |
414 if (strcmp(device->address, dev_w1->address) == 0) { |
411 for (device = Config.devices; device; device = device->next) { |
415 found = TRUE; |
412 if (strcmp(device->address,de->d_name) == 0) { |
416 break; |
413 found = TRUE; |
417 } |
414 break; |
418 } |
|
419 |
|
420 if (found == FALSE) { |
|
421 for (i = 0; i < dev_w1->subdevices; i++) { |
|
422 ndev = (devices_list *)malloc(sizeof(devices_list)); |
|
423 ndev->next = NULL; |
|
424 ndev->uuid = malloc(37); |
|
425 uuid_generate(uu); |
|
426 uuid_unparse(uu, ndev->uuid); |
|
427 ndev->type = DEVTYPE_W1; |
|
428 ndev->direction = DEVDIR_IN_ANALOG; |
|
429 if (strcmp(dev_w1->family, (char *)"10") == 0) { |
|
430 ndev->description = xstrcpy((char *)"DS18S20 Digital thermometer"); |
|
431 } else if (strcmp(dev_w1->family, (char *)"22") == 0) { |
|
432 ndev->description = xstrcpy((char *)"DS1822 Digital thermometer"); |
|
433 } else if (strcmp(dev_w1->family, (char *)"28") == 0) { |
|
434 ndev->description = xstrcpy((char *)"DS18B20 Digital thermometer"); |
|
435 } else if (strcmp(dev_w1->family, (char *)"3a") == 0) { |
|
436 ndev->description = xstrcpy((char *)"DS2413 Dual channel addressable switch"); |
|
437 ndev->direction = DEVDIR_IN_BIN; |
|
438 } else if (strcmp(dev_w1->family, (char *)"3b") == 0) { |
|
439 ndev->description = xstrcpy((char *)"DS1825 Digital thermometer"); |
|
440 } else if (strcmp(dev_w1->family, (char *)"42") == 0) { |
|
441 ndev->description = xstrcpy((char *)"DS28EA00 Digital thermometer"); |
|
442 } else { |
|
443 ndev->description = xstrcpy((char *)"Unknown device family "); |
|
444 ndev->direction = DEVDIR_UNDEF; |
|
445 } |
|
446 ndev->value = ndev->offset = ndev->inuse = 0; |
|
447 ndev->present = DEVPRESENT_YES; |
|
448 ndev->address = xstrcpy(dev_w1->address); |
|
449 ndev->subdevice = i; |
|
450 ndev->gpiopin = -1; |
|
451 ndev->comment = xstrcpy((char *)"Auto detected device"); |
|
452 ndev->timestamp = time(NULL); |
|
453 |
|
454 syslog(LOG_NOTICE, "New W1 device %s, subdevice %d, %s", ndev->address, ndev->subdevice, ndev->description); |
|
455 |
|
456 if (Config.devices == NULL) { |
|
457 Config.devices = ndev; |
|
458 } else { |
|
459 for (device = Config.devices; device; device = device->next) { |
|
460 if (device->next == NULL) { |
|
461 device->next = ndev; |
|
462 break; |
|
463 } |
415 } |
464 } |
416 } |
465 } |
417 |
466 rc++; |
418 if (found == FALSE) { |
467 } |
419 strncpy(buf, de->d_name, 2); |
468 } |
420 buf[2] = '\0'; |
|
421 sscanf(buf, "%02x", &ival); |
|
422 subdevices = 0; |
|
423 |
|
424 /* |
|
425 * ival is zero when a ghost sensor is detected. |
|
426 */ |
|
427 if (ival > 0) |
|
428 subdevices = 1; |
|
429 if (strcmp(buf, (char *)"3a") == 0) |
|
430 subdevices = 2; |
|
431 for (i = 0; i < subdevices; i++) { |
|
432 ndev = (devices_list *)malloc(sizeof(devices_list)); |
|
433 ndev->next = NULL; |
|
434 ndev->uuid = malloc(37); |
|
435 uuid_generate(uu); |
|
436 uuid_unparse(uu, ndev->uuid); |
|
437 ndev->type = DEVTYPE_W1; |
|
438 ndev->direction = DEVDIR_UNDEF; |
|
439 if (strcmp(buf, (char *)"10") == 0) { |
|
440 ndev->direction = DEVDIR_IN_ANALOG; |
|
441 ndev->description = xstrcpy((char *)"DS18S20 Digital thermometer"); |
|
442 } else if (strcmp(buf, (char *)"22") == 0) { |
|
443 ndev->direction = DEVDIR_IN_ANALOG; |
|
444 ndev->description = xstrcpy((char *)"DS1822 Digital thermometer"); |
|
445 } else if (strcmp(buf, (char *)"28") == 0) { |
|
446 ndev->direction = DEVDIR_IN_ANALOG; |
|
447 ndev->description = xstrcpy((char *)"DS18B20 Digital thermometer"); |
|
448 } else if (strcmp(buf, (char *)"3a") == 0) { |
|
449 ndev->direction = DEVDIR_IN_BIN; |
|
450 ndev->description = xstrcpy((char *)"DS2413 Dual channel addressable switch"); |
|
451 } else if (strcmp(buf, (char *)"3b") == 0) { |
|
452 ndev->direction = DEVDIR_IN_ANALOG; |
|
453 ndev->description = xstrcpy((char *)"DS1825 Digital thermometer"); |
|
454 } else if (strcmp(buf, (char *)"42") == 0) { |
|
455 ndev->direction = DEVDIR_IN_ANALOG; |
|
456 ndev->description = xstrcpy((char *)"DS28EA00 Digital thermometer"); |
|
457 } else if (strcmp(buf, (char *)"w1") == 0) { |
|
458 ndev->description = xstrcpy((char *)"Master System device"); |
|
459 } else { |
|
460 ndev->description = xstrcpy((char *)"Unknown device family "); |
|
461 ndev->description = xstrcat(ndev->description, buf); |
|
462 } |
|
463 ndev->value = ndev->offset = ndev->inuse = 0; |
|
464 ndev->present = DEVPRESENT_YES; |
|
465 ndev->address = xstrcpy(de->d_name); |
|
466 ndev->subdevice = i; |
|
467 ndev->gpiopin = -1; |
|
468 ndev->comment = xstrcpy((char *)"Auto detected device"); |
|
469 ndev->timestamp = time(NULL); |
|
470 |
|
471 syslog(LOG_NOTICE, "New W1 device %s, subdevice %d, %s", ndev->address, ndev->subdevice, ndev->description); |
|
472 |
|
473 if (Config.devices == NULL) { |
|
474 Config.devices = ndev; |
|
475 } else { |
|
476 for (device = Config.devices; device; device = device->next) { |
|
477 if (device->next == NULL) { |
|
478 device->next = ndev; |
|
479 break; |
|
480 } |
|
481 } |
|
482 } |
|
483 rc++; |
|
484 } |
|
485 } |
|
486 } |
|
487 } |
|
488 closedir(fd); |
|
489 } |
469 } |
490 |
470 |
491 /* |
471 /* |
492 * DHT11 as kernel module. The number after the @ is the hexadecimal |
472 * DHT11 as kernel module. The number after the @ is the hexadecimal |
493 * number of the BCM gpio pin. Since we use pin 22 at connector pin 15 |
473 * number of the BCM gpio pin. Since we use pin 22 at connector pin 15 |