--- a/thermferm/devices.c Mon Mar 25 11:44:45 2024 +0100 +++ b/thermferm/devices.c Mon Mar 25 17:14:56 2024 +0100 @@ -50,101 +50,88 @@ int dht11_temperature = -1; int dht11_humidity = -1; int dht11_state = DEVPRESENT_UNDEF; -time_t dht11_last = (time_t)0; +time_t dht11_next; /* * DHT11 sensor read. + * Called at 30 seconds interval if all is well. + * If last read was an error, the interval is 2 seconds. */ void dht11Read(char *address) { - int tries = 5, temp, hum; - int fd, rc, err; - char buffer[25], *dhtpath = NULL; + int temp, hum; + int fd, rc, err; + char buffer[25], *dhtpath = NULL; + + dht11_temperature = -1; + dht11_humidity = -1; + dht11_state = DEVPRESENT_UNDEF; + dhtpath = xstrcpy((char *)"/sys/bus/iio/devices/"); + dhtpath = xstrcat(dhtpath, address); + dhtpath = xstrcat(dhtpath, (char *)"/in_temp_input"); + + fd = open(dhtpath, O_RDONLY); + if (fd < 0) { + /* + * The sensor is gone. + */ + err = errno; + syslog(LOG_NOTICE, "DHT11 open temperature: %d %s", err, strerror(err)); + free(dhtpath); + dht11_state = DEVPRESENT_NO; + return; + } - while (tries) { + rc = read(fd, buffer, 25); + if (rc == -1) { + err = errno; + if (err == 110) { + dht11_state = DEVPRESENT_NO; /* Device is gone */ + } else { + dht11_state = DEVPRESENT_ERROR; + } + syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err)); + } else { + sscanf(buffer, "%d", &temp); + dht11_temperature = temp; + dht11_state = DEVPRESENT_YES; + } + close(fd); + free(dhtpath); + dhtpath = NULL; - dht11_temperature = -1; - dht11_humidity = -1; - dht11_state = DEVPRESENT_UNDEF; + /* + * Only read humidity if state is DEVPRESENT_YES + */ + if (dht11_state == DEVPRESENT_YES) { dhtpath = xstrcpy((char *)"/sys/bus/iio/devices/"); dhtpath = xstrcat(dhtpath, address); - dhtpath = xstrcat(dhtpath, (char *)"/in_temp_input"); + dhtpath = xstrcat(dhtpath, (char *)"/in_humidityrelative_input"); fd = open(dhtpath, O_RDONLY); - if (fd < 0) { - /* - * The sensor is gone. - */ - err = errno; - syslog(LOG_NOTICE, "DHT11 open temperature: %d %s", err, strerror(err)); - free(dhtpath); - dht11_state = DEVPRESENT_NO; - goto retry; -// break; - } rc = read(fd, buffer, 25); if (rc == -1) { err = errno; if (err == 110) { - dht11_state = DEVPRESENT_NO; /* Device is gone */ - break; + dht11_state = DEVPRESENT_NO; } else { - dht11_state = DEVPRESENT_ERROR; + dht11_state = DEVPRESENT_ERROR; } - syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err)); - dht11_temperature = -1; + syslog(LOG_NOTICE, "DHT11 read humidity: %d %s", err, strerror(err)); + dht11_temperature = -1; /* Make invalid */ } else { - sscanf(buffer, "%d", &temp); - dht11_temperature = temp; + sscanf(buffer, "%d", &hum); + dht11_humidity = hum; dht11_state = DEVPRESENT_YES; } close(fd); free(dhtpath); dhtpath = NULL; - - /* - * Only read humidity if state is DEVPRESENT_YES - */ - if (dht11_state == DEVPRESENT_YES) { - dhtpath = xstrcpy((char *)"/sys/bus/iio/devices/"); - dhtpath = xstrcat(dhtpath, address); - dhtpath = xstrcat(dhtpath, (char *)"/in_humidityrelative_input"); - - fd = open(dhtpath, O_RDONLY); - rc = read(fd, buffer, 25); - if (rc == -1) { - err = errno; - if (err == 110) { - dht11_state = DEVPRESENT_NO; - break; - } else { - dht11_state = DEVPRESENT_ERROR; - } - syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err)); - dht11_humidity = -1; - } else { - sscanf(buffer, "%d", &hum); - dht11_humidity = hum; - dht11_state = DEVPRESENT_YES; - } - close(fd); - free(dhtpath); - dhtpath = NULL; - } - - if (dht11_state == DEVPRESENT_YES) { - break; - } -retry: - if (tries > 0) { - tries--; - usleep(400000); - } } - syslog(LOG_NOTICE, "dht11 t:%d h:%d tries:%d state:%d", dht11_temperature, dht11_humidity, 6-tries, dht11_state); + syslog(LOG_NOTICE, "dht11 t:%d h:%d state:%d", dht11_temperature, dht11_humidity, dht11_state); } @@ -762,6 +749,8 @@ syslog(LOG_NOTICE, "my_devices_loop: piHiPri(50) rc=%d", rc); #endif + dht11_next = time(NULL); + /* * Set the temperature sensors to 12 bits resolution and write it in EEPROM */ @@ -932,10 +921,11 @@ case DEVTYPE_DHT: /* * Don't read these to often, 2 seconds minimum delay. - * But we use 30 seconds interval. + * Delay 30 seconds if last update was successfull, + * else delay 2 seconds. */ now = time(NULL); - if ((int)(now - dht11_last) > 30) { + if ((int)(now >= dht11_next)) { if (device->subdevice == 0) { /* Read once during subdevice 0 */ dht11Read(device->address); @@ -947,15 +937,17 @@ } pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); } else if (device->subdevice == 1) { - /* Data already present */ + /* Data already present, valid or not. */ pthread_mutex_lock(&mutexes[LOCK_DEVICES]); device->present = dht11_state; if (dht11_state == DEVPRESENT_YES) { device->value = dht11_humidity; device->timestamp = time(NULL); - } + dht11_next = now + 29; + } else { + dht11_next = now + 1; + } pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); - dht11_last = now; /* Okay for a new reading. */ } } break;