On 02/12/2010 10:54, Arjen de Korte wrote:
Citeren John Bayly <[email protected]>:

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 :-)


_______________________________________________
Nut-upsuser mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/nut-upsuser

Reply via email to