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;


Reply via email to