diff -r 78744b7e6021 -r da038d0bed04 thermferm/one-wire.c --- a/thermferm/one-wire.c Sat May 04 19:10:03 2024 +0200 +++ b/thermferm/one-wire.c Sun May 05 15:49:03 2024 +0200 @@ -62,6 +62,9 @@ payload = xstrcat(payload, (char *)"\",\"value\":"); snprintf(vbuf, 63, "%d", dev_w1->value); payload = xstrcat(payload, vbuf); + payload = xstrcat(payload, (char *)",\"resolution\":"); + snprintf(vbuf, 63, "%d", dev_w1->resolution); + payload = xstrcat(payload, vbuf); payload = xstrcat(payload, (char *)",\"timestamp\":"); snprintf(vbuf, 63, "%ld", (long)dev_w1->timestamp); payload = xstrcat(payload, vbuf); @@ -180,6 +183,7 @@ syslog(LOG_NOTICE, "One-wire device %s is back", buffer); pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]); dev_w1->present = DEVPRESENT_YES; + dev_w1->resolution = 0; /* Might be wrong, so reset */ dev_w1->timestamp = time(NULL); pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]); changed = true; @@ -197,6 +201,7 @@ n_w1->family[2] = '\0'; n_w1->present = DEVPRESENT_YES; n_w1->value = (strcmp(w1type, (char *)"3a") == 0) ? 3:-1; + n_w1->resolution = 0; n_w1->timestamp = time(NULL); changed = true; @@ -250,6 +255,7 @@ devfile = NULL; } + mDelay(40); SM_PROCEED(Read2413); SM_STATE(Read2413) @@ -338,6 +344,7 @@ } } + mDelay(40); SM_PROCEED(ReadTemp); SM_STATE(ReadTemp) @@ -352,57 +359,73 @@ if (cur_w1 != NULL) { if (((strcmp(cur_w1->family, (char *)"10") == 0) || (strcmp(cur_w1->family, (char *)"22") == 0) || (strcmp(cur_w1->family, (char *)"28") == 0) || - (strcmp(cur_w1->family, (char *)"3b") == 0) || (strcmp(cur_w1->family, (char *)"42") == 0)) && - (cur_w1->present == DEVPRESENT_YES)) { + (strcmp(cur_w1->family, (char *)"3b") == 0) || (strcmp(cur_w1->family, (char *)"42") == 0)) && (cur_w1->present == DEVPRESENT_YES)) { + + /* + * Check and correct resolution. Only do this for new sensors + * or known sensors that are plugged in again. + */ + if (cur_w1->resolution != W1_TEMP_RESOLUTION) { + devfile = xstrcpy((char *)"/sys/bus/w1/devices/"); + devfile = xstrcat(devfile, cur_w1->address); + devfile = xstrcat(devfile, (char *)"/resolution"); + if ((fp = fopen(devfile, "r+"))) { + if ((fgets(buffer, 25, fp))) { + sscanf(buffer, "%d", &value); + /* If device is removed, value is negative (errno?) */ + if ((value > 0) && (value != W1_TEMP_RESOLUTION)) { + syslog(LOG_NOTICE, "One-wire device %s set resolution from %d to %d", cur_w1->address, value, W1_TEMP_RESOLUTION); + fseek(fp, 0L, SEEK_SET); + sprintf(buffer, "%d", W1_TEMP_RESOLUTION); + fputs(buffer, fp); + } + cur_w1->resolution = W1_TEMP_RESOLUTION; + } + fclose(fp); + } else { + syslog(LOG_NOTICE, "One-wire device %s open: %s", cur_w1->address, strerror(errno)); + } + free(devfile); + } + + /* + * Set conversion wait time. Skip this?? + */ + conv_time = 760; devfile = xstrcpy((char *)"/sys/bus/w1/devices/"); devfile = xstrcat(devfile, cur_w1->address); - devfile = xstrcat(devfile, (char *)"/resolution"); - if ((fp = fopen(devfile, "r+"))) { - if ((fgets(buffer, 25, fp))) { - sscanf(buffer, "%d", &value); - /* If device is removed, value is negative (errno?) */ - if ((value > 0) && (value != W1_TEMP_RESOLUTION)) { - syslog(LOG_NOTICE, "One-wire device %s set resolution from %d to %d", cur_w1->address, value, W1_TEMP_RESOLUTION); - fseek(fp, 0L, SEEK_SET); - sprintf(buffer, "%d", W1_TEMP_RESOLUTION); - fputs(buffer, fp); - } - } - fclose(fp); - free(devfile); + devfile = xstrcat(devfile, (char *)"/conv_time"); + if ((fp = fopen(devfile, "r"))) { + if ((fgets(buffer, 25, fp))) { + sscanf(buffer, "%d", &conv_time); + } + fclose(fp); + } + free(devfile); - conv_time = 760; - devfile = xstrcpy((char *)"/sys/bus/w1/devices/"); - devfile = xstrcat(devfile, cur_w1->address); - devfile = xstrcat(devfile, (char *)"/conv_time"); - if ((fp = fopen(devfile, "r"))) { - if ((fgets(buffer, 25, fp))) { - sscanf(buffer, "%d", &conv_time); + /* + * Read temperature for one sensor. + * Bulk read does not work for unknown reason. + * It may be because there are also DS2413 devices. + */ + devfile = xstrcpy((char *)"/sys/bus/w1/devices/"); + devfile = xstrcat(devfile, cur_w1->address); + devfile = xstrcat(devfile, (char *)"/temperature"); + if ((fp = fopen(devfile, "r"))) { + mDelay(conv_time); + if ((fgets(buffer, 25, fp))) { + sscanf(buffer, "%d", &value); + if (cur_w1->value != value) { + cur_w1->timestamp = time(NULL); + changed = true; + if (debug) + syslog(LOG_NOTICE, "One-wire device %s temperature read %d => %d", cur_w1->address, cur_w1->value, value); } - fclose(fp); - } - free(devfile); - - devfile = xstrcpy((char *)"/sys/bus/w1/devices/"); - devfile = xstrcat(devfile, cur_w1->address); - devfile = xstrcat(devfile, (char *)"/temperature"); - if ((fp = fopen(devfile, "r"))) { - mDelay(conv_time); - if ((fgets(buffer, 25, fp))) { - sscanf(buffer, "%d", &value); - if (cur_w1->value != value) { - cur_w1->timestamp = time(NULL); - changed = true; - if (debug) - syslog(LOG_NOTICE, "One-wire device %s temperature read %d => %d", cur_w1->address, cur_w1->value, value); - } - cur_w1->value = value; /* devices.c will pick this up */ - } else { - syslog(LOG_NOTICE, "One-wire device %s temperature read error", cur_w1->address); - } - fclose(fp); - } - + cur_w1->value = value; /* devices.c will pick this up */ + } else { + syslog(LOG_NOTICE, "One-wire device %s temperature read error", cur_w1->address); + } + fclose(fp); } else { syslog(LOG_NOTICE, "One-wire device %s open: %s", cur_w1->address, strerror(errno)); }