On Dec 9, 2014, at 9:53 AM, David Higgs <hig...@gmail.com> wrote: > On Tue, Dec 9, 2014 at 9:40 AM, Stuart Henderson <st...@openbsd.org> wrote: >> >> I was thinking more that it might be better for sensorsd internally >> to treat state transitions of "indicator" sensors like it treats >> status changes, rather than change how the sensors themselves report. >> What do you think? > > Yes, that makes a lot of sense. I still think that some of them > should have an associated status for reporting purposes (AC power loss > or mfi(4) drive status), but indicators could automatically trigger on > value changes. User-specified high/low settings will be ignored or > rejected. The %l (above / below / within / etc) output may need > rethinking… >
Something like the following, maybe? Add a new ‘rvalues’ capability for sensorsd.conf(5) to report value changes. While most useful for indicator and drive sensors, it can provide granular output for *any* sensor that changes slowly enough for sensorsd(8) debouncing behavior. Also, ignore user-specified limits on indicator and drive sensors. These types of sensors are not actually intervals; using them as such was confusing, error-prone, and undocumented. Users should specify ‘rvalues’ with an optional ‘command=’ to implement more useful behavior. --david Index: sensorsd.c =================================================================== RCS file: /cvs/src/usr.sbin/sensorsd/sensorsd.c,v retrieving revision 1.53 diff -u -p -r1.53 sensorsd.c --- sensorsd.c 29 Jun 2014 00:58:45 -0000 1.53 +++ sensorsd.c 9 Dec 2014 23:53:34 -0000 @@ -50,20 +50,26 @@ struct limits_t { enum sensor_type type; /* sensor type */ int numt; /* sensor number */ int64_t last_val; + int64_t last_val2; int64_t lower; /* lower limit */ int64_t upper; /* upper limit */ char *command; /* failure command */ time_t astatus_changed; + time_t value_changed; time_t ustatus_changed; enum sensor_status astatus; /* last automatic status */ enum sensor_status astatus2; + int last_valid; /* last value validity */ + int last_valid2; enum sensorsd_s_status ustatus; /* last user-limit status */ enum sensorsd_s_status ustatus2; int acount; /* stat change counter */ + int vcount; /* value change counter */ int ucount; /* stat change counter */ u_int8_t flags; /* sensorsd limit flags */ #define SENSORSD_L_USERLIMIT 0x0001 /* user specified limit */ #define SENSORSD_L_ISTATUS 0x0002 /* ignore automatic status */ +#define SENSORSD_L_RVALUES 0x0004 /* report value changes */ }; struct sdlim_t { @@ -337,6 +343,7 @@ check_sdlim(struct sdlim_t *sdlim, time_ TAILQ_FOREACH(limit, &sdlim->limits, entries) { if ((limit->flags & SENSORSD_L_ISTATUS) && + !(limit->flags & SENSORSD_L_RVALUES) && !(limit->flags & SENSORSD_L_USERLIMIT)) continue; @@ -361,6 +368,28 @@ check_sdlim(struct sdlim_t *sdlim, time_ } } + if (limit->flags & SENSORSD_L_RVALUES) { + int newvalid = !(sensor.flags & SENSOR_FINVALID); + + if (limit->last_val != sensor.value || + limit->last_valid != newvalid) { + if (limit->last_val2 != sensor.value || + limit->last_valid2 != newvalid) { + limit->last_val2 = sensor.value; + limit->last_valid2 = newvalid; + limit->vcount = 0; + } else if (++limit->vcount >= 3) { + limit->last_val2 = + limit->last_val = sensor.value; + limit->last_valid2 = + limit->last_valid = newvalid; + limit->astatus2 = + limit->astatus = sensor.status; + limit->value_changed = this_check; + } + } + } + if (limit->flags & SENSORSD_L_USERLIMIT) { enum sensorsd_s_status newustatus; @@ -422,10 +451,12 @@ report_sdlim(struct sdlim_t *sdlim, time TAILQ_FOREACH(limit, &sdlim->limits, entries) { if ((limit->astatus_changed <= last_report) && + (limit->value_changed <= last_report) && (limit->ustatus_changed <= last_report)) continue; - if (limit->astatus_changed > last_report) { + if (limit->astatus_changed > last_report || + limit->value_changed > last_report) { const char *as = NULL; switch (limit->astatus) { @@ -717,6 +748,8 @@ parse_config_sdlim(struct sdlim_t *sdlim continue; if (cgetcap(buf, "istatus", ':')) p->flags |= SENSORSD_L_ISTATUS; + if (cgetcap(buf, "rvalues", ':')) + p->flags |= SENSORSD_L_RVALUES; if (cgetstr(buf, "low", &ebuf) < 0) ebuf = NULL; p->lower = get_val(ebuf, 0, p->type); @@ -729,7 +762,8 @@ parse_config_sdlim(struct sdlim_t *sdlim asprintf(&(p->command), "%s", ebuf); free(buf); buf = NULL; - if (p->lower != LLONG_MIN || p->upper != LLONG_MAX) + if ((p->lower != LLONG_MIN || p->upper != LLONG_MAX) && + p->type != SENSOR_INDICATOR && p->type != SENSOR_DRIVE) p->flags |= SENSORSD_L_USERLIMIT; } } @@ -741,7 +775,7 @@ get_val(char *buf, int upper, enum senso int64_t rval = 0; char *p; - if (buf == NULL) { + if (buf == NULL || type == SENSOR_INDICATOR || type == SENSOR_DRIVE) { if (upper) return (LLONG_MAX); else @@ -779,9 +813,7 @@ get_val(char *buf, int upper, enum senso case SENSOR_PERCENT: rval = val * 1000.0; break; - case SENSOR_INDICATOR: case SENSOR_INTEGER: - case SENSOR_DRIVE: case SENSOR_ANGLE: rval = val; break;