[Nut-upsuser] Belkin Regulator Pro dropping connection and halting

John Bayly freebsd.ports at tipstrade.net
Thu Dec 2 12:03:09 UTC 2010


On 02/12/2010 10:54, Arjen de Korte wrote:
> Citeren John Bayly <freebsd.ports at tipstrade.net>:
>
>>> Last but not least, in most drivers, we allow a couple of missed 
>>> replies before we call dstate_datastale() so that glitches don't 
>>> lead to automatic reconnects.
>> Can you suggest what driver would be a good template to use?
>
> Take a look at the upsdrv_updateinfo() function in the 'blazer.c' 
> driver core.
>
> Best regards, Arjen

So, I've made the following changes:

In get_belkin_reply(), allow responses with no trailing data
-    if ((cnt < 1) || (cnt > 255))
+    if (cnt == 0) {    /* possible to have ~00R000, return empty 
response */
+        buf[0] = 0;
+        return 0;
+
+    } else if ((cnt < 1) || (cnt > 255))
          return -1;

Added method to return UPS status, NULL is returned if no status is 
available
static char *get_status()
{
     char    temp[SMALLBUF], st[SMALLBUF];
     int    res;
     const char    *status = NULL;

     send_belkin_command(STATUS,STAT_STATUS,"");
     res = get_belkin_reply(temp);
     if (res < 1)
         return NULL;

     get_belkin_field(temp, st, sizeof(st), 6);
     if (*st == '1') {
         status = "OFF";

     } else if (*st == '0') {    /* (OFF) and (OB | OL) are mutually 
exclusive */
         get_belkin_field(temp, st, sizeof(st), 2);
         if (*st == '1') {
             status = "OB";    /* on battery */

             send_belkin_command(STATUS,STAT_BATTERY,"");
             res = get_belkin_reply(temp);

             if (res < 1) {    /* no battery info, so no reliable status */
                 status = NULL;

             } else {
                 get_belkin_field(temp, st, sizeof(st), 10);
                 res = atoi(st);
                 get_belkin_field(temp, st, sizeof(st), 2);

                 if (*st == '1' || res < LOW_BAT)
                     status = "LB";    /* low battery */
             }

         } else if (*st == '0') {
             status = "OL";    /* on line */

         }
     }

     return status;
}

Modified do_status(), calls get_status() and allows for MAXTRIES (3)
static int do_status(void)
{
     /* fetch the UPS status, or null if unavailable */
     const char    *status = get_status();

     if (status) {
         if (retry)    /* previous attempt had failed */
             upslogx(LOG_WARNING, "Communications with UPS re-established");

         status_init();
         status_set(status);
         status_commit();
         dstate_dataok();
         retry = 0;
         return 1;

     } else {
         if (retry < MAXTRIES) {
             upslogx(LOG_WARNING, "Communications with UPS lost: status 
read failed!");
             retry++;

         } else {    /* too many retries */
             dstate_datastale();
         }
         return 0;
     }
}

C isn't my native language so I'd appreciate any feedback either 
negative, but preferably positive :-)




More information about the Nut-upsuser mailing list