Example #1
0
void upsdrv_initinfo(void)
{
    int msglen, v;
    char *a,*p,avail_list[300];
 
    /* find out which variables/commands this UPS supports */
    msglen = 0;
    sec_cmd(SEC_POLLCMD, SEC_AVAILP1, avail_list, &msglen);
    p = avail_list + msglen;
    if (p != avail_list) *p++ = ',';
    msglen = 0;
    sec_cmd(SEC_POLLCMD, SEC_AVAILP2, p, &msglen);
    *(p+msglen) = '\0';
 
    
    if (strlen(avail_list) == 0){
     fatalx(EXIT_FAILURE, "No available variables found!");}
    a = avail_list;
   while ((p = strtok(a, ",")) != NULL) {  
    a = NULL;
    v = atoi(p);
    /* don't bother adding a write-only variable */
   if (sec_varlist[v].flags == FLAG_WONLY) continue;
    addquery(sec_varlist[v].cmd, sec_varlist[v].field, v, sec_varlist[v].poll);
    }  
    
    /* poll one time values */
    
   sec_poll(FLAG_POLLONCE);
   
   printf("UPS: %s %s\n", dstate_getinfo("ups.mfr"), dstate_getinfo("ups.model"));
    
    
}
Example #2
0
/* write the status_buf into the externally visible dstate storage */
void status_commit(void)
{
	while (ignorelb) {
		const char	*val, *low;

		val = dstate_getinfo("battery.charge");
		low = dstate_getinfo("battery.charge.low");

		if (val && low && (strtol(val, NULL, 10) < strtol(low, NULL, 10))) {
			snprintfcat(status_buf, sizeof(status_buf), " LB");
			upsdebugx(2, "%s: appending LB flag [charge '%s' below '%s']", __func__, val, low);
			break;
		}

		val = dstate_getinfo("battery.runtime");
		low = dstate_getinfo("battery.runtime.low");

		if (val && low && (strtol(val, NULL, 10) < strtol(low, NULL, 10))) {
			snprintfcat(status_buf, sizeof(status_buf), " LB");
			upsdebugx(2, "%s: appending LB flag [runtime '%s' below '%s']", __func__, val, low);
			break;
		}

		/* LB condition not detected */
		break;
	}

	if (alarm_active) {
		dstate_setinfo("ups.status", "ALARM %s", status_buf);
	} else {
		dstate_setinfo("ups.status", "%s", status_buf);
	}
}
Example #3
0
void upsdrv_initinfo(void)
{
	
	dstate_setinfo("ups.mfr", "%s", "PACE");
	dstate_setinfo("ups.model", "PACE  %s", "UPS7");
	printf("Detected %s %s on %s\n", dstate_getinfo("ups.mfr"), 
	dstate_getinfo("ups.model"), device_path);
	
}
Example #4
0
File: ivtscd.c Project: sbutler/nut
int upsdrv_initups(void)
{
	struct termios	tio;
	const char	*val;

	upsfd = ser_open(device_path);
	ser_set_speed(upsfd, device_path, B1200);

	if (tcgetattr(upsfd, &tio)) {
		fatal_with_errno(EXIT_FAILURE, "tcgetattr");
	}

	/*
	 * Use canonical mode input processing (to read reply line)
	 */
	tio.c_lflag |= ICANON;	/* Canonical input (erase and kill processing) */
	tio.c_iflag |= IGNCR;	/* Ignore CR */
	tio.c_iflag |= IGNBRK;	/* Ignore break condition */
	tio.c_oflag |= ONLCR;	/* Map NL to CR-NL on output */

	tio.c_cc[VEOF] = _POSIX_VDISABLE;
	tio.c_cc[VEOL] = _POSIX_VDISABLE;
	tio.c_cc[VERASE] = _POSIX_VDISABLE;
	tio.c_cc[VINTR]  = _POSIX_VDISABLE;
	tio.c_cc[VKILL]  = _POSIX_VDISABLE;
	tio.c_cc[VQUIT]  = _POSIX_VDISABLE;
	tio.c_cc[VSUSP]  = _POSIX_VDISABLE;
	tio.c_cc[VSTART] = _POSIX_VDISABLE;
	tio.c_cc[VSTOP]  = _POSIX_VDISABLE;

	if (tcsetattr(upsfd, TCSANOW, &tio)) {
		fatal_with_errno(EXIT_FAILURE, "tcsetattr");
	}

	/*
	 * Set DTR and clear RTS to provide power for the serial interface.
	 */
	ser_set_dtr(upsfd, 1);
	ser_set_rts(upsfd, 0);

	val = dstate_getinfo("battery.voltage.nominal");
	battery.voltage.nom = (val) ? strtod(val, NULL) : 12.00;

	val = dstate_getinfo("battery.voltage.low");
	battery.voltage.low = (val) ? strtod(val, NULL) : 10.80;

	if (battery.voltage.nom <= battery.voltage.low) {
		fatalx(EXIT_FAILURE, "Nominal battery voltage must be higher than low battery voltage!");
	}

	return 1;
}
Example #5
0
/* Set up all the funky shared memory stuff used to communicate with upsd */
void  upsdrv_initinfo (void)
{
	/* now set up room for all future variables that are supported */

	dstate_setinfo("ups.mfr", "%s", "Best Power");
	switch(fc.model) {
          case ME3100:
	    dstate_setinfo("ups.model", "Micro Ferrups (ME) %d", fc.va);
	    break;
          case MD1KVA:
	    dstate_setinfo("ups.model", "Micro Ferrups (MD) %d", fc.va);
	    break;
          case RE1800:
            dstate_setinfo("ups.model", "Micro Ferrups (RE) %d", fc.va);
            break;
          default:
	    fatalx(EXIT_FAILURE, "UPS model not matched!"); /* Will never get here, upsdrv_initups() will catch */
        } 
	fprintf(stderr, "Best Power %s detected\n", 
		dstate_getinfo("ups.model"));
	fprintf(stderr, "Battery voltages %5.1f nominal, %5.1f full, %5.1f empty\n", 
	 fc.idealbvolts,
	 fc.fullvolts,
	 fc.emptyvolts);
}
Example #6
0
/*
 * The battery voltage will quickly return to at least the nominal value after
 * discharging them. For overlapping battery.voltage.low/high ranges therefor
 * choose the one with the highest multiplier.
 */
static double blazer_packs(const char *ptr, char **endptr)
{
    const double packs[] = {
        120, 100, 80, 60, 48, 36, 30, 24, 18, 12, 8, 6, 4, 3, 2, 1, 0.5, -1
    };

    const char	*val;
    int		i;

    val = dstate_getinfo("battery.voltage.nominal");

    batt.volt.nom = strtod(val ? val : ptr, endptr);

    for (i = 0; packs[i] > 0; i++) {

        if (packs[i] * batt.volt.act > 1.2 * batt.volt.nom) {
            continue;
        }

        if (packs[i] * batt.volt.act < 0.8 * batt.volt.nom) {
            upslogx(LOG_INFO, "Can't autodetect number of battery packs [%.0f/%.2f]", batt.volt.nom, batt.volt.act);
            break;
        }

        batt.packs = packs[i];
        break;
    }

    return batt.volt.nom;
}
Example #7
0
/* Change a variable name in a table */
static void change_name(simple_t *sp,
		const char *oldname, const char *newname)
{
	while(sp->code) {
		if (sp->desc && !strcmp(sp->desc, oldname)) {
			sp->desc = strdup(newname);
			if (dstate_getinfo(oldname)) {
				dstate_setinfo(newname, "%s",
						dstate_getinfo(oldname));
			}
			dstate_delinfo(oldname);
			upsdebugx(1, "Changing name: %s => %s", oldname, newname);
			break;
		}
		sp++;
	}
}
Example #8
0
/* clean out the temp space for a new pass */
void status_init(void)
{
	if (dstate_getinfo("driver.flag.ignorelb")) {
		ignorelb = 1;
	}

	memset(status_buf, 0, sizeof(status_buf));
}
Example #9
0
void blazer_initups(void)
{
    const char	*val;

    val = getval("ondelay");
    if (val) {
        ondelay = strtol(val, NULL, 10);
    }

    if ((ondelay < 0) || (ondelay > 9999)) {
        fatalx(EXIT_FAILURE, "Start delay '%d' out of range [0..9999]", ondelay);
    }

    val = getval("offdelay");
    if (val) {
        offdelay = strtol(val, NULL, 10);
    }

    if ((offdelay < 12) || (offdelay > 600)) {
        fatalx(EXIT_FAILURE, "Shutdown delay '%d' out of range [12..600]", offdelay);
    }

    /* Truncate to nearest setable value */
    if (offdelay < 60) {
        offdelay -= (offdelay % 6);
    } else {
        offdelay -= (offdelay % 60);
    }

    val = dstate_getinfo("battery.voltage.high");
    if (val) {
        batt.volt.high = strtod(val, NULL);
    }

    val = dstate_getinfo("battery.voltage.low");
    if (val) {
        batt.volt.low = strtod(val, NULL);
    }
}
Example #10
0
/* returns statically allocated string - must not use it again before
   done with result! */
static const char *tripplite_chemistry_fun(double value)
{
	static char	buf[20];
	const char	*model;

	model = dstate_getinfo("ups.productid");

	/* Workaround for AVR 550U firmware bug */
	if (!strcmp(model, "1003")) {
		return "unknown";
	}

	/* Workaround for OMNI1000LCD firmware bug */
	if (!strcmp(model, "2005")) {
		return "unknown";
	}

	return HIDGetIndexString(udev, (int)value, buf, sizeof(buf));
}
Example #11
0
/*
 * Do whatever we think is needed when we read a battery voltage from the UPS.
 * Basically all it does now, is guestimating the battery charge, but this
 * could be extended.
 */
static double blazer_battery(const char *ptr, char **endptr)
{
    batt.volt.act = batt.packs * strtod(ptr, endptr);

    if ((!getval("runtimecal") || !dstate_getinfo("battery.charge")) &&
            (batt.volt.low > 0) && (batt.volt.high > batt.volt.low)) {
        batt.chrg.act = 100 * (batt.volt.act - batt.volt.low) / (batt.volt.high - batt.volt.low);

        if (batt.chrg.act < 0) {
            batt.chrg.act = 0;
        }

        if (batt.chrg.act > 100) {
            batt.chrg.act = 100;
        }

        dstate_setinfo("battery.charge", "%.0f", batt.chrg.act);
    }

    return batt.volt.act;
}
Example #12
0
File: clone.c Project: AlexLov/nut
static int instcmd(const char *cmdname, const char *extra)
{
	const char	*val;

	val = dstate_getinfo(getval("load.status"));
	if (val) {
		if (!strcasecmp(val, "off") || !strcasecmp(val, "no")) {
			outlet = 0;
		}

		if (!strcasecmp(val, "on") || !strcasecmp(val, "yes")) {
			outlet = 1;
		}
	}

	if (!strcasecmp(cmdname, "shutdown.return")) {
		if (outlet && (ups.timer.shutdown < 0)) {
			ups.timer.shutdown = offdelay;
			dstate_setinfo("ups.status", "FSD %s", ups.status);
		}
		ups.timer.start = ondelay;
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "shutdown.stayoff")) {
		if (outlet && (ups.timer.shutdown < 0)) {
			ups.timer.shutdown = offdelay;
			dstate_setinfo("ups.status", "FSD %s", ups.status);
		}
		ups.timer.start = -1;
		return STAT_INSTCMD_HANDLED;
	}

	upslogx(LOG_NOTICE, "instcmd: unknown command [%s]", cmdname);
	return STAT_INSTCMD_UNKNOWN;
}
Example #13
0
static void blazer_initbattery(void)
{
    const char	*val;

    /* If no values were provided by the user in ups.conf, try to guesstimate
     * battery.charge, but announce it! */
    if ((batt.volt.nom != 1) && ((batt.volt.high == -1) || (batt.volt.low == -1))) {
        upslogx(LOG_INFO, "No values provided for battery high/low voltages in ups.conf\n");

        /* Basic formula, which should cover most cases */
        batt.volt.low = 104 * batt.volt.nom / 120;
        batt.volt.high = 130 * batt.volt.nom / 120;

        /* Publish these data too */
        dstate_setinfo("battery.voltage.low", "%.2f", batt.volt.low);
        dstate_setinfo("battery.voltage.high", "%.2f", batt.volt.high);

        upslogx(LOG_INFO, "Using 'guestimation' (low: %f, high: %f)!", batt.volt.low, batt.volt.high);
    }

    val = getval("runtimecal");
    if (val) {
        double	rh, lh, rl, ll;

        time(&lastpoll);

        if (sscanf(val, "%lf,%lf,%lf,%lf", &rh, &lh, &rl, &ll) < 4) {
            fatalx(EXIT_FAILURE, "Insufficient parameters for runtimecal");
        }

        if ((rl < rh) || (rh <= 0)) {
            fatalx(EXIT_FAILURE, "Parameter out of range (runtime)");
        }

        if ((lh > 100) || (ll > lh) || (ll <= 0)) {
            fatalx(EXIT_FAILURE, "Parameter out of range (load)");
        }

        batt.runt.exp = log(rl / rh) / log(lh / ll);
        upsdebugx(2, "battery runtime exponent : %.3f", batt.runt.exp);

        batt.runt.nom = rh * pow(lh / 100, batt.runt.exp);
        upsdebugx(2, "battery runtime nominal  : %.1f", batt.runt.nom);

    } else {
        upslogx(LOG_INFO, "Battery runtime will not be calculated (runtimecal not set)");
        return;
    }

    if (batt.chrg.act < 0) {
        batt.volt.low = batt.volt.nom;
        batt.volt.high = 1.15 * batt.volt.nom;

        blazer_battery(dstate_getinfo("battery.voltage"), NULL);
    }

    val = dstate_getinfo("battery.charge");
    if (val) {
        batt.runt.est = batt.runt.nom * strtod(val, NULL) / 100;
        upsdebugx(2, "battery runtime estimate : %.1f", batt.runt.est);
    } else {
        fatalx(EXIT_FAILURE, "Initial battery charge undetermined");
    }

    val = getval("chargetime");
    if (val) {
        batt.chrg.time = strtol(val, NULL, 10);

        if (batt.chrg.time <= 0) {
            fatalx(EXIT_FAILURE, "Charge time out of range [1..s]");
        }

        upsdebugx(2, "battery charge time      : %ld", batt.chrg.time);
    } else {
        upslogx(LOG_INFO, "No charge time specified, using built in default [%ld seconds]", batt.chrg.time);
    }

    val = getval("idleload");
    if (val) {
        load.low = strtod(val, NULL) / 100;

        if ((load.low <= 0) || (load.low > 1)) {
            fatalx(EXIT_FAILURE, "Idle load out of range [0..100]");
        }

        upsdebugx(2, "minimum load used (idle) : %.3f", load.low);
    } else {
        upslogx(LOG_INFO, "No idle load specified, using built in default [%.1f %%]", 100 * load.low);
    }
}
Example #14
0
static int blazer_status(const char *cmd)
{
    const struct {
        const char	*var;
        const char	*fmt;
        double	(*conv)(const char *, char **);
    } status[] = {
        { "input.voltage", "%.1f", strtod },
        { "input.voltage.fault", "%.1f", strtod },
        { "output.voltage", "%.1f", strtod },
        { "ups.load", "%.0f", blazer_load },
        { "input.frequency", "%.1f", strtod },
        { "battery.voltage", "%.2f", blazer_battery },
        { "ups.temperature", "%.1f", strtod },
        { NULL }
    };

    char	buf[SMALLBUF], *val, *last = NULL;
    int	i;

    /*
     * > [Q1\r]
     * < [(226.0 195.0 226.0 014 49.0 27.5 30.0 00001000\r]
     *    01234567890123456789012345678901234567890123456
     *    0         1         2         3         4
     */
    if (blazer_command(cmd, buf, sizeof(buf)) < 46) {
        upsdebugx(2, "%s: short reply", __func__);
        return -1;
    }

    if (buf[0] != '(') {
        upsdebugx(2, "%s: invalid start character [%02x]", __func__, buf[0]);
        return -1;
    }

    for (i = 0, val = strtok_r(buf+1, " ", &last); status[i].var; i++, val = strtok_r(NULL, " \r\n", &last)) {

        if (!val) {
            upsdebugx(2, "%s: parsing failed", __func__);
            return -1;
        }

        if (strspn(val, "0123456789.") != strlen(val)) {
            upsdebugx(2, "%s: non numerical value [%s]", __func__, val);
            continue;
        }

        dstate_setinfo(status[i].var, status[i].fmt, status[i].conv(val, NULL));
    }

    if (!val) {
        upsdebugx(2, "%s: parsing failed", __func__);
        return -1;
    }

    if (strspn(val, "01") != 8) {
        upsdebugx(2, "Invalid status [%s]", val);
        return -1;
    }

    if (val[7] == '1') {	/* Beeper On */
        dstate_setinfo("ups.beeper.status", "enabled");
    } else {
        dstate_setinfo("ups.beeper.status", "disabled");
    }

    if (val[4] == '1') {	/* UPS Type is Standby (0 is On_line) */
        dstate_setinfo("ups.type", "offline / line interactive");
    } else {
        dstate_setinfo("ups.type", "online");
    }

    status_init();

    if (val[0] == '1') {	/* Utility Fail (Immediate) */
        status_set("OB");
        online = 0;
    } else {
        status_set("OL");
        online = 1;
    }

    if (val[1] == '1') {	/* Battery Low */
        status_set("LB");
    }

    if (val[2] == '1') {	/* Bypass/Boost or Buck Active */

        double	vi, vo;

        vi = strtod(dstate_getinfo("input.voltage"),  NULL);
        vo = strtod(dstate_getinfo("output.voltage"), NULL);

        if (vo < 0.5 * vi) {
            upsdebugx(2, "%s: output voltage too low", __func__);
        } else if (vo < 0.95 * vi) {
            status_set("TRIM");
        } else if (vo < 1.05 * vi) {
            status_set("BYPASS");
        } else if (vo < 1.5 * vi) {
            status_set("BOOST");
        } else {
            upsdebugx(2, "%s: output voltage too high", __func__);
        }
    }

    if (val[5] == '1') {	/* Test in Progress */
        status_set("CAL");
    }

    alarm_init();

    if (val[3] == '1') {	/* UPS Failed */
        alarm_set("UPS selftest failed!");
    }

    if (val[6] == '1') {	/* Shutdown Active */
        alarm_set("Shutdown imminent!");
        status_set("FSD");
    }

    alarm_commit();

    status_commit();

    return 0;
}
Example #15
0
void upsdrv_initinfo(void)
{
	unsigned char my_answer[255];
	char serial[13];
	int res, i;

	/* Initial setup of variables */
#ifdef EXTRADATA
	 dstate_setinfo("output.power", "%d", -1);
	dstate_setflags("output.power", ST_FLAG_RW);
#endif
	 dstate_setinfo("output.voltage", "%d", -1);
	dstate_setflags("output.voltage", ST_FLAG_RW);
	 dstate_setinfo("output.current", "%d", -1);
	dstate_setflags("output.current", ST_FLAG_RW);
#ifdef EXTRADATA
	 dstate_setinfo("output.current.peak", "%2.2f", -1);	
	dstate_setflags("output.current.peak", ST_FLAG_RW);
	 dstate_setinfo("input.power", "%d", -1);
	dstate_setflags("input.power", ST_FLAG_RW);
#endif
	 dstate_setinfo("input.voltage", "%d", -1);
	dstate_setflags("input.voltage", ST_FLAG_RW);
#ifdef EXTRADATA
	 dstate_setinfo("input.current", "%2.2f", -1);
	dstate_setflags("input.current", ST_FLAG_RW);
	 dstate_setinfo("input.current.peak", "%2.2f", -1);	
	dstate_setflags("input.current.peak", ST_FLAG_RW);
#endif
	 dstate_setinfo("battery.voltage", "%d", -1);
	dstate_setflags("battery.voltage", ST_FLAG_RW);
#ifdef EXTRADATA
	 dstate_setinfo("battery.voltage.low", "%2.2f", -1);
	dstate_setflags("battery.voltage.low", ST_FLAG_RW);
	 dstate_setinfo("battery.voltage.exhaust", "%2.2f", -1);
	dstate_setflags("battery.voltage.exhaust", ST_FLAG_RW);
	 dstate_setinfo("ups.total.runtime", "retrieving...");
	dstate_setflags("ups.total.runtime", ST_FLAG_STRING | ST_FLAG_RW);
	  dstate_setaux("ups.total.runtime", 20);
	 dstate_setinfo("ups.inverter.runtime", "retrieving...");
	dstate_setflags("ups.inverter.runtime", ST_FLAG_STRING | ST_FLAG_RW);
	  dstate_setaux("ups.inverter.runtime", 20);
	 dstate_setinfo("ups.inverter.interventions", "%d", -1);
	dstate_setflags("ups.inverter.interventions", ST_FLAG_RW);
	 dstate_setinfo("battery.full.discharges", "%d", -1);
	dstate_setflags("battery.full.discharges", ST_FLAG_RW);
	 dstate_setinfo("ups.bypass.interventions", "%d", -1);
	dstate_setflags("ups.bypass.interventions", ST_FLAG_RW);
	 dstate_setinfo("ups.overheatings", "%d", -1);
	dstate_setflags("ups.overheatings", ST_FLAG_RW);
#endif
	 dstate_setinfo("ups.load", "%d", -1);
	dstate_setflags("ups.load", ST_FLAG_RW);
	 dstate_setinfo("ups.delay.shutdown", "%d", -1);
	dstate_setflags("ups.delay.shutdown", ST_FLAG_RW);
	 dstate_setinfo("ups.delay.start", "%d", -1);
	dstate_setflags("ups.delay.start", ST_FLAG_RW);
	 dstate_setinfo("ups.temperature", "%d", -1);
	dstate_setflags("ups.temperature", ST_FLAG_RW);
	 dstate_setinfo("ups.test.result", "not yet done...");
	dstate_setflags("ups.test.result", ST_FLAG_STRING | ST_FLAG_RW);
	  dstate_setaux("ups.test.result", 20);
	
	/* UPS INFO READ */
	res = command_read_sequence(UPS_INFO, my_answer);
	if (res < 0) fatal_with_errno(EXIT_FAILURE, "Could not communicate with the ups");
	/* the manufacturer is hard coded into the driver, the model type is in the second 
		byte of the answer, the third byte identifies the model version */
	dstate_setinfo("ups.mfr", "Meta System");
	i = my_answer[1] * 10 + my_answer[2];
	switch (i) {	
		case 11:
			dstate_setinfo("ups.model", "%s", "HF Line (1 board)");
			nominal_power = 630;
			break;
		case 12:
			dstate_setinfo("ups.model", "%s", "HF Line (2 boards)");
			nominal_power = 1260;
			break;
		case 13:
			dstate_setinfo("ups.model", "%s", "HF Line (3 boards)");
			nominal_power = 1890;
			break;
		case 14:
			dstate_setinfo("ups.model", "%s", "HF Line (4 boards)");
			nominal_power = 2520;
			break;
		case 21:
			dstate_setinfo("ups.model", "%s", "ECO Network 750/1000");
			nominal_power = 500;
			break;	
		case 22:
			dstate_setinfo("ups.model", "%s", "ECO Network 1050/1500");
			nominal_power = 700;
			break;	
		case 23:
			dstate_setinfo("ups.model", "%s", "ECO Network 1500/2000");
			nominal_power = 1000;
			break;	
		case 24:
			dstate_setinfo("ups.model", "%s", "ECO Network 1800/2500");
			nominal_power = 1200;
			break;	
		case 25:
			dstate_setinfo("ups.model", "%s", "ECO Network 2100/3000");
			nominal_power = 1400;
			break;	
		case 31:
			dstate_setinfo("ups.model", "%s", "ECO 308");
			nominal_power = 500;
			break;	
		case 32:
			dstate_setinfo("ups.model", "%s", "ECO 311");
			nominal_power = 700;
			break;	
		case 44:
			dstate_setinfo("ups.model", "%s", "HF Line (4 boards)/2");
			nominal_power = 2520;
			break;
		case 45:
			dstate_setinfo("ups.model", "%s", "HF Line (5 boards)/2");
			nominal_power = 3150;
			break;
		case 46:
			dstate_setinfo("ups.model", "%s", "HF Line (6 boards)/2");
			nominal_power = 3780;
			break;
		case 47:
			dstate_setinfo("ups.model", "%s", "HF Line (7 boards)/2");
			nominal_power = 4410;
			break;
		case 48:
			dstate_setinfo("ups.model", "%s", "HF Line (8 boards)/2");
			nominal_power = 5040;
			break;
		case 51:
			dstate_setinfo("ups.model", "%s", "HF Millennium 810");
			nominal_power = 700;
			break;
		case 52:
			dstate_setinfo("ups.model", "%s", "HF Millennium 820");
			nominal_power = 1400;
			break;
		case 61:
			dstate_setinfo("ups.model", "%s", "HF TOP Line 910");
			nominal_power = 700;
			break;
		case 62:
			dstate_setinfo("ups.model", "%s", "HF TOP Line 920");
			nominal_power = 1400;
			break;
		case 63:
			dstate_setinfo("ups.model", "%s", "HF TOP Line 930");
			nominal_power = 2100;
			break;
		case 64:
			dstate_setinfo("ups.model", "%s", "HF TOP Line 940");
			nominal_power = 2800;
			break;
		case 74:
			dstate_setinfo("ups.model", "%s", "HF TOP Line 940/2");
			nominal_power = 2800;
			break;
		case 75:
			dstate_setinfo("ups.model", "%s", "HF TOP Line 950/2");
			nominal_power = 3500;
			break;
		case 76:
			dstate_setinfo("ups.model", "%s", "HF TOP Line 960/2");
			nominal_power = 4200;
			break;
		case 77:
			dstate_setinfo("ups.model", "%s", "HF TOP Line 970/2");
			nominal_power = 4900;
			break;
		case 78:
			dstate_setinfo("ups.model", "%s", "HF TOP Line 980/2");
			nominal_power = 5600;
			break;
		case 81:
			dstate_setinfo("ups.model", "%s", "ECO 508");
			nominal_power = 500;
			break;
		case 82:
			dstate_setinfo("ups.model", "%s", "ECO 511");
			nominal_power = 700;
			break;
		case 83:
			dstate_setinfo("ups.model", "%s", "ECO 516");
			nominal_power = 1000;
			break;
		case 84:
			dstate_setinfo("ups.model", "%s", "ECO 519");
			nominal_power = 1200;
			break;
		case 85:
			dstate_setinfo("ups.model", "%s", "ECO 522");
			nominal_power = 1400;
			break;
		case 91:
			dstate_setinfo("ups.model", "%s", "ECO 305 / Harviot 530 SX");
			nominal_power = 330;
			break;
		case 92:
			dstate_setinfo("ups.model", "%s", "ORDINATORE 2");
			nominal_power = 330;
			break;
		case 93:
			dstate_setinfo("ups.model", "%s", "Harviot 730 SX");
			nominal_power = 430;
			break;
		case 101:
			dstate_setinfo("ups.model", "%s", "ECO 308 SX / SX Interactive / Ordinatore");
			nominal_power = 500;
			break;
		case 102:
			dstate_setinfo("ups.model", "%s", "ECO 311 SX / SX Interactive");
			nominal_power = 700;
			break;
		case 111:
			dstate_setinfo("ups.model", "%s", "ally HF 800 / BI-TWICE 800");
			nominal_power = 560;
			break;
		case 112:
			dstate_setinfo("ups.model", "%s", "ally HF 1600");
			nominal_power = 1120;
			break;
		case 121:
			dstate_setinfo("ups.model", "%s", "ally HF 1000 / BI-TWICE 1000");
			nominal_power = 700;
			break;
		case 122:
			dstate_setinfo("ups.model", "%s", "ally HF 2000");
			nominal_power = 1400;
			break;
		case 131:
			dstate_setinfo("ups.model", "%s", "ally HF 1250 / BI-TWICE 1250");
			nominal_power = 875;
			break;
		case 132:
			dstate_setinfo("ups.model", "%s", "ally HF 2500");
			nominal_power = 1750;
			break;
		case 141:
			dstate_setinfo("ups.model", "%s", "Megaline 1250");
			nominal_power = 875;
			break;
		case 142:
			dstate_setinfo("ups.model", "%s", "Megaline 2500");
			nominal_power = 1750;
			break;
		case 143:
			dstate_setinfo("ups.model", "%s", "Megaline 3750");
			nominal_power = 2625;
			break;
		case 144:
			dstate_setinfo("ups.model", "%s", "Megaline 5000");
			nominal_power = 3500;
			break;
		case 154:
			dstate_setinfo("ups.model", "%s", "Megaline 5000 / 2");
			nominal_power = 3500;
			break;
		case 155:
			dstate_setinfo("ups.model", "%s", "Megaline 6250 / 2");
			nominal_power = 4375;
			break;
		case 156:
			dstate_setinfo("ups.model", "%s", "Megaline 7500 / 2");
			nominal_power = 5250;
			break;
		case 157:
			dstate_setinfo("ups.model", "%s", "Megaline 8750 / 2");
			nominal_power = 6125;
			break;
		case 158:
			dstate_setinfo("ups.model", "%s", "Megaline 10000 / 2");
			nominal_power = 7000;
			break;

		default:
			fatal_with_errno(EXIT_FAILURE, "Unknown UPS");
			break;
	} 
		
	/* Get the serial number */
	memcpy(serial, my_answer + 7, res - 7);
	/* serial number start from the 8th byte */
	serial[12]=0;		/* terminate string */
	dstate_setinfo("ups.serial", "%s", serial);
	
	/* get the ups firmware. The major number is in the 5th byte, the minor is in the 6th */
	dstate_setinfo("ups.firmware", "%u.%u", my_answer[5], my_answer[6]);

	printf("Detected %s [%s] v.%s on %s\n", dstate_getinfo("ups.model"), dstate_getinfo("ups.serial"), dstate_getinfo("ups.firmware"), device_path);
	
	/* Add instant commands */
	dstate_addcmd("shutdown.return");
	dstate_addcmd("shutdown.stayoff");
	dstate_addcmd("shutdown.stop");
	dstate_addcmd("test.failure.start");
	dstate_addcmd("test.failure.stop");
	dstate_addcmd("test.battery.start");
	dstate_addcmd("beeper.enable");
	dstate_addcmd("beeper.mute");
	dstate_addcmd("beeper.on");
	dstate_addcmd("beeper.off");
	upsh.instcmd = instcmd;
	return;
}
Example #16
0
void upsdrv_updateinfo(void)
{
	typedef struct {
		const unsigned char	cmd[6];
		const char	*var;
		const char	*fmt;
		const int	multindex;
	} cmd_s;

	static cmd_s vartab[] = { /* common vars */
		{ { 1,149,2,1,1,154 },	"battery.runtime", "%.0f", M_BAT_RUNTIME },
		{ { 1,149,2,1,2,155 },	"battery.voltage", "%.1f", M_VOLT_DC },
		{ { 1,149,2,1,3,156 },	"battery.current", "%.2f", M_CURRENT_DC },
		{ { 1,161,2,1,13,178 },	"battery.voltage.nominal", "%.1f", M_VOLT_DC },
		{ { 1,149,2,1,12,165 },	"battery.temperature", "%.1f", M_TEMPERATURE },
		{ { 1,149,2,1,14,167 },	"ups.temperature", "%.1f", M_TEMPERATURE },
		{ { 1,161,2,1,8,173 },	"ups.power.nominal", "%.0f", M_NOMPOWER },
		{ { 1,161,2,1,4,169 },	"ups.delay.start", "%.0f", M_10 },
		{ { 1,161,2,1,14,179  },"battery.runtime.low", "%.0f", M_BAT_RUNTIME },
		{ { 1,149,2,1,8,161 },	"input.frequency", "%.1f", M_FREQUENCY },
		{ { 1,149,2,1,10,163 },	"input.bypass.frequency", "%.1f", M_FREQUENCY },
		{ { 1,161,2,1,9,174 },	"input.frequency.nominal", "%.1f", M_FREQUENCY },
		{ { 1,149,2,1,9,162 },	"output.frequency", "%.1f", M_FREQUENCY },
		{ { 1,161,2,1,10,175 },	"output.frequency.nominal", "%.1f", M_FREQUENCY },
		{ { 0 }, NULL, NULL, 0 }
	};

	static cmd_s vartab1o[] = { /* 1-phase out */
		{ { 1,149,2,1,7,160 },	"ups.load", "%.0f", M_LOADPERC },
		{ { 1,149,2,1,6,159 },	"ups.power", "%.0f", M_POWER },
		{ { 1,149,2,1,5,158 },	"ups.realpower", "%.0f", M_POWER },
		{ { 1,144,2,1,3,151 },	"output.voltage", "%.1f", M_VOLTAGE_O },
		{ { 1,144,2,1,4,152 },	"output.current", "%.1f", M_CURRENT_O },
		{ { 0 }, NULL, NULL, 0 }
	};

	static cmd_s vartab1i[] = { /* 1-phase in*/
		{ { 1,144,2,1,1,149 },	"input.voltage", "%.1f", M_VOLTAGE_I },
		{ { 1,144,2,1,5,153 },	"input.bypass.voltage", "%.1f", M_VOLTAGE_B },
		{ { 1,144,2,1,6,154 },	"input.bypass.current", "%.1f", M_CURRENT_B },
		{ { 0 }, NULL, NULL, 0 }
	};

	static cmd_s vartab3o[] = { /*3-phase out */
		{ { 1,144,2,1,24,172 },	"ups.L1.load", "%.0f", M_LOADPERC },
		{ { 1,145,2,1,24,173 },	"ups.L2.load", "%.0f", M_LOADPERC },
		{ { 1,146,2,1,24,174 },	"ups.L3.load", "%.0f", M_LOADPERC },
		{ { 1,144,2,1,22,170 },	"ups.L1.power", "%.0f", M_POWER },
		{ { 1,145,2,1,22,171 },	"ups.L2.power", "%.0f", M_POWER },
		{ { 1,146,2,1,22,172 },	"ups.L3.power", "%.0f", M_POWER },
		{ { 1,144,2,1,21,169 },	"ups.L1.realpower", "%.0f", M_POWER },
		{ { 1,145,2,1,21,170 },	"ups.L2.realpower", "%.0f", M_POWER },
		{ { 1,146,2,1,21,171 },	"ups.L3.realpower", "%.0f", M_POWER },
		{ { 1,144,2,1,3,151 },	"output.L1-N.voltage", "%.1f", M_VOLTAGE_O },
		{ { 1,145,2,1,3,152 },	"output.L2-N.voltage", "%.1f", M_VOLTAGE_O },
		{ { 1,146,2,1,3,153 },	"output.L3-N.voltage", "%.1f", M_VOLTAGE_O },
		{ { 1,144,2,1,14,162 },	"output.L1.crestfactor", "%.1f", M_0_1 },
		{ { 1,145,2,1,14,163 },	"output.L2.crestfactor", "%.1f", M_0_1 },
		{ { 1,146,2,1,14,164 },	"output.L3.crestfactor", "%.1f", M_0_1 },
		{ { 0 }, NULL, NULL, 0 }
	};

	static cmd_s vartab3i[] = { /*3-phase in */
		{ { 1,144,2,1,1,149 },	"input.L1-N.voltage", "%.1f", M_VOLTAGE_I },
		{ { 1,145,2,1,1,150 },	"input.L2-N.voltage", "%.1f", M_VOLTAGE_I },
		{ { 1,146,2,1,1,151 },	"input.L3-N.voltage", "%.1f", M_VOLTAGE_I },

		{ { 1,144,2,1,5,153 },	"input.L1-N.bypass.voltage", "%.1f", M_VOLTAGE_B },
		{ { 1,145,2,1,5,154 },	"input.L2-N.bypass.voltage", "%.1f", M_VOLTAGE_B },
		{ { 1,146,2,1,5,155 },	"input.L3-N.bypass.voltage", "%.1f", M_VOLTAGE_B },

		{ { 1,144,2,1,6,154 },	"input.L1-N.bypass.current", "%.1f", M_CURRENT_B },
		{ { 1,145,2,1,6,155 },	"input.L2-N.bypass.current", "%.1f", M_CURRENT_B },
		{ { 1,146,2,1,6,156 },	"input.L3-N.bypass.current", "%.1f", M_CURRENT_B },

		{ { 1,144,2,1,2,150 },	"input.L1.current", "%.1f", M_CURRENT_I },
		{ { 1,145,2,1,2,151 },	"input.L2.current", "%.1f", M_CURRENT_I },
		{ { 1,146,2,1,2,152 },	"input.L3.current", "%.1f", M_CURRENT_I },
		{ { 0 }, NULL, NULL, 0 }
	};
	
	static cmd_s * cmdin_p;
	static cmd_s * cmdout_p;

	const char	*val;
	char	reply[8];
	int	ret, i;

	for (i = 0; vartab[i].var; i++) {
		int16_t	val;
		ret = do_command(vartab[i].cmd, reply, 6);
		if (ret < 8) {
			continue;
		}
		val = (unsigned char)reply[5];
		val <<= 8;
		val += (unsigned char)reply[6];
		dstate_setinfo(vartab[i].var, vartab[i].fmt, val * multi[vartab[i].multindex]);
	}

	if (num_inphases>1){
		cmdin_p=vartab3i;
	}
	else {
		cmdin_p=vartab1i;
	}

	if (num_outphases>1){
		cmdout_p=vartab3o;
	}
	else {
		cmdout_p=vartab1o;
	}

	for (i = 0; cmdin_p[i].var; i++) {
		int16_t	val;
		ret = do_command(cmdin_p[i].cmd, reply, 6);
		if (ret < 8) {
			continue;
		}
		val = (unsigned char)reply[5];
		val <<= 8;
		val += (unsigned char)reply[6];
		dstate_setinfo(cmdin_p[i].var, cmdin_p[i].fmt, val * multi[cmdin_p[i].multindex]);
	}

	for (i = 0; cmdout_p[i].var; i++) {
		int16_t	val;
		ret = do_command(cmdout_p[i].cmd, reply, 6);
		if (ret < 8) {
			continue;
		}
		val = (unsigned char)reply[5];
		val <<= 8;
		val += (unsigned char)reply[6];
		dstate_setinfo(cmdout_p[i].var, cmdout_p[i].fmt, val * multi[cmdout_p[i].multindex]);
	}

	status_init();

	ret = do_command(cmd_bitfield1, reply, 6);
	if (ret < 8) {
		upslogx(LOG_ERR, "Failed reading bitfield #1");
		dstate_datastale();
		return;
	}

	if (reply[5] & (1<<0)) {	/* ON_BATTERY */
		status_set("OB");
	} else {
		status_set("OL");
	}

	val = dstate_getinfo("battery.current");
	if (val) {
		if (atof(val) > 0.05) {
			status_set("CHRG");
		}
		if (atof(val) < -0.05) {
			status_set("DISCHRG");
		}
	}

	ret = do_command(cmd_bitfield2, reply, 6);
	if (ret < 8) {
		upslogx(LOG_ERR, "Failed reading bitfield #2");
		dstate_datastale();
		return;
	}

	if (reply[6] & (1<<0)) {	/* ON_BYPASS */
		status_set("BYPASS");
	}

	if (reply[6] & (1<<5)) {	/* REPLACE_BATTERY */
		status_set("RB");
	}

	if (reply[6] & (1<<6)) {	/* BOOST_ON */
		status_set("BOOST");
	}

	if (reply[5] & (1<<1)) {	/* BUCK_ON */
		status_set("TRIM");
	}

	ret = do_command(cmd_bitfield3, reply, 6);
	if (ret < 8) {
		upslogx(LOG_ERR, "Failed reading bitfield #3");
		dstate_datastale();
		return;
	}

	if (reply[6] & (1<<0) ) {	/* UPS_OVERLOAD */
		status_set("OVER");
	}

	if (reply[6] & (1<<5) ) {	/* LOW_BATTERY */
		status_set("LB");
	}

	status_commit();

	dstate_dataok();
}
/* Preprocess instant commands */
int	blazer_process_command(item_t *item, char *value, const size_t valuelen)
{
	if (!strcasecmp(item->info_type, "shutdown.return")) {

		/* Sn: Shutdown after n minutes and then turn on when mains is back
		 * SnRm: Shutdown after n minutes and then turn on after m minutes
		 * Accepted values for n: .2 -> .9 , 01 -> 10
		 * Accepted values for m: 0001 -> 9999
		 * Note: "S01R0001" and "S01R0002" may not work on early (GE) firmware versions.
		 * The failure mode is that the UPS turns off and never returns.
		 * The fix is to push the return value up by 2, i.e. S01R0003, and it will return online properly.
		 * (thus the default of ondelay=3 mins) */

		int	offdelay = strtol(dstate_getinfo("ups.delay.shutdown"), NULL, 10),
			ondelay = strtol(dstate_getinfo("ups.delay.start"), NULL, 10) / 60;
		char	buf[SMALLBUF] = "";

		if (ondelay == 0) {

			if (offdelay < 60) {
				snprintf(buf, sizeof(buf), ".%d", offdelay / 6);
			} else {
				snprintf(buf, sizeof(buf), "%02d", offdelay / 60);
			}

		} else if (offdelay < 60) {

			snprintf(buf, sizeof(buf), ".%dR%04d", offdelay / 6, ondelay);

		} else {

			snprintf(buf, sizeof(buf), "%02dR%04d", offdelay / 60, ondelay);

		}

		snprintf(value, valuelen, item->command, buf);

	} else if (!strcasecmp(item->info_type, "shutdown.stayoff")) {

		/* SnR0000
		 * Shutdown after n minutes and stay off
		 * Accepted values for n: .2 -> .9 , 01 -> 10 */

		int	offdelay = strtol(dstate_getinfo("ups.delay.shutdown"), NULL, 10);
		char	buf[SMALLBUF] = "";

		if (offdelay < 60) {
			snprintf(buf, sizeof(buf), ".%d", offdelay / 6);
		} else {
			snprintf(buf, sizeof(buf), "%02d", offdelay / 60);
		}

		snprintf(value, valuelen, item->command, buf);

	} else if (!strcasecmp(item->info_type, "test.battery.start")) {

		int	delay = strlen(value) > 0 ? strtol(value, NULL, 10) : 600;

		if ((delay < 60) || (delay > 5940)) {
			upslogx(LOG_ERR, "%s: battery test time '%d' out of range [60..5940] seconds", item->info_type, delay);
			return -1;
		}

		delay = delay / 60;

		snprintf(value, valuelen, item->command, delay);

	} else {

		/* Don't know what happened */
		return -1;

	}

	return 0;
}
Example #18
0
void upsdrv_updateinfo(void)
{
	time_t now;
	int ok;
	float load;

	if (status & UPSC_STAT_NOTINIT) {
		upsdrv_initinfo();
	}

	if (status & UPSC_STAT_NOTINIT) {
		return;
	}

	status = 0;

	ok = upsc_getparams("UPDS", simple);

	time(&now);
	if (ok && now - last_full > full_update_timer) {
		last_full = now;
		ok = upsc_getparams("UPDV", nominal);
		if (ok && can_upbs)
			ok = upsc_getparams("UPBS", battery);
	}

	if (!ok) {
		dstate_datastale();
		last_full = 0;
		return;
	}

	if (!inited_phaseinfo) {
		if (dstate_getinfo("input.L3-L1.voltage") ||
				dstate_getinfo("input.L3-N.voltage")) {
			num_inphases = 3;

			change_name(simple,
				"input.current", "input.L1.current");
			change_name(simple,
				"input.realpower", "input.L1.realpower");
			change_name(simple,
				"input.power", "input.L1.power");
			change_name(simple,
				"input.voltage", "input.L1-N.voltage");
		}
		if (dstate_getinfo("output.L3-L1.voltage") ||
				dstate_getinfo("output.L3-N.voltage")) {
			const char *s;

			num_outphases = 3;

			if ((s=dstate_getinfo("ups.model")) &&
					(!strncmp(s, "UPS9075", 7) ||
					!strncmp(s, "UPS9100", 7) ||
					!strncmp(s, "UPS9150", 7) ||
					!strncmp(s, "UPS9200", 7) ||
					!strncmp(s, "UPS9250", 7) ||
					!strncmp(s, "UPS9300", 7) ||
					!strncmp(s, "UPS9400", 7) ||
					!strncmp(s, "UPS9500", 7) ||
					!strncmp(s, "UPS9600", 7)) ) {
				/* Insert kludges for Fiskars UPS9000 here */
				upslogx(LOG_INFO, "Fiskars UPS9000 detected, protocol kludges activated");
				batt_volt_nom = 384;
				dstate_setinfo("battery.voltage.nominal", "%.0f", batt_volt_nom);

			}
			else {
				outpwr_factor *= 3;
			}

			change_name(simple,
				"output.current", "output.L1.current");
			change_name(simple,
				"output.current.peak", "output.L1.current.peak");
			change_name(simple,
				"output.realpower", "output.L1.realpower");
			change_name(simple,
				"output.power", "output.L1.power");
			change_name(simple,
				"output.voltage", "output.L1-N.voltage");
		}

		dstate_setinfo("input.phases", "%d", num_inphases);
		dstate_setinfo("output.phases", "%d", num_outphases);

		inited_phaseinfo=1;
	}

	load = calc_upsload();

	if (load >= 0) {
		upsdebugx(2, "ups.load: %.1f", load*100);
		dstate_setinfo("ups.load", "%.1f", load*100);
	}
	else {
		upsdebugx(2, "ups.load: No value");
	}

	/* TODO/FIXME: Set UPS date/time on startup and daily if needed */
	if (can_updt) {
		char dtbuf[UPSC_BUFLEN];
		if (upsc_getvalue("UPDT", "0", "ACDT", NULL, dtbuf)) {
			dstate_setinfo("ups.date", "%s", dtbuf);
		}
	}
	if (can_uptm) {
		char tmbuf[UPSC_BUFLEN];
		if (upsc_getvalue("UPTM", "0", "ACTM", NULL, tmbuf)) {
			dstate_setinfo("ups.time", "%s", tmbuf);
		}
	}


	if (batt_charge < 0) {
		if (batt_current < 0) {
			/* Reset battery current history if discharging */
			numbatthist = lastbatthist = 0;
		}
		batt_charge = batt_charge_pct();
	}
	if (batt_charge >= 0) {
		dstate_setinfo("battery.charge", "%.1f", batt_charge);
	}
	else {
		dstate_delinfo("battery.charge");
	}

	/* 9999 == unknown value */
	if (batt_runtime >= 0 && batt_runtime < 9999) {
		dstate_setinfo("battery.runtime", "%.0f", batt_runtime*60);
	}
	else if (load > 0 && batt_disch_curr_max != 0) {
		float est_battcurr = load * abs(batt_disch_curr_max);
		/* Peukert equation */
		float runtime = (batt_cap_nom*3600)/pow(est_battcurr, 1.35);

		upsdebugx(2, "Calculated runtime: %.0f seconds", runtime);
		if (batt_runtime_max > 0 && runtime > batt_runtime_max*60) {
			runtime = batt_runtime_max*60;
		}
		dstate_setinfo("battery.runtime", "%.0f", runtime);

	}
	else if (batt_runtime_max > 0) {
		/* Show max possible runtime as reported by UPS */
		dstate_setinfo("battery.runtime", "%.0f", batt_runtime_max*60);
	}
	else {
		dstate_delinfo("battery.runtime");
	}
	/* Some UPSen only provides this when on battery, so reset between
	 * each iteration to make sure we use the right value */
	batt_charge = -1;
	batt_runtime = -1;


	if (!(status & UPSC_STAT_ONBATT))
		status |= UPSC_STAT_ONLINE;

	upsc_setstatus(status);

	dstate_dataok();
	ser_comm_good();
}
Example #19
0
void upsdrv_initinfo(void)
{
	char response[MAX_RESPONSE_LENGTH];
	unsigned int min_low_transfer, max_low_transfer;
	unsigned int min_high_transfer, max_high_transfer;
	unsigned int i;
	char *ptr;

	if (!init_comm())
		fatalx(EXIT_FAILURE, "Unable to detect Tripp Lite SmartOnline UPS on port %s\n",
		        device_path);
	min_low_transfer = max_low_transfer = 0;
	min_high_transfer = max_high_transfer = 0;

	/* get all the read-only fields here */
	if (do_command(POLL, MANUFACTURER, "", response) > 0)
		dstate_setinfo("ups.mfr", "%s", response);
	if (do_command(POLL, MODEL, "", response) > 0)
		dstate_setinfo("ups.model", "%s", response);
	if (do_command(POLL, VERSION_CMD, "", response) > 0)
		dstate_setinfo("ups.firmware", "%s", response);
	if (do_command(POLL, RATINGS, "", response) > 0) {
		ptr = field(response, 0);
		if (ptr)
			dstate_setinfo("input.voltage.nominal", "%d",
			               atoi(ptr));
		ptr = field(response, 2);
		if (ptr) {
			dstate_setinfo("output.voltage.nominal", "%d",
			               atoi(ptr));
		}
		ptr = field(response, 14);
		if (ptr)
			dstate_setinfo("battery.voltage.nominal", "%d",
			               atoi(ptr));
		ptr = field(response, 10);
		if (ptr)
			min_low_transfer = atoi(ptr);
		ptr = field(response, 9);
		if (ptr)
			max_low_transfer = atoi(ptr);
		ptr = field(response, 12);
		if (ptr)
			min_high_transfer = atoi(ptr);
		ptr = field(response, 11);
		if (ptr)
			max_high_transfer = atoi(ptr);
	}
	if (do_command(POLL, OUTLET_RELAYS, "", response) > 0)
		ups.outlet_banks = atoi(response);
	/* define things that are settable */
	if (get_identification()) {
		dstate_setflags("ups.id", ST_FLAG_RW | ST_FLAG_STRING);
		dstate_setaux("ups.id", 100);
	}
	if (get_transfer_voltage_low() && max_low_transfer) {
		dstate_setflags("input.transfer.low", ST_FLAG_RW);
		for (i = min_low_transfer; i <= max_low_transfer; i++)
			dstate_addenum("input.transfer.low", "%d", i);
	}
	if (get_transfer_voltage_high() && max_low_transfer) {
		dstate_setflags("input.transfer.high", ST_FLAG_RW);
		for (i = min_high_transfer; i <= max_high_transfer; i++)
			dstate_addenum("input.transfer.high", "%d", i);
	}
	if (get_sensitivity()) {
		dstate_setflags("input.sensitivity", ST_FLAG_RW);
		for (i = 0; i < sizeof(sensitivity) / sizeof(sensitivity[0]);
		     i++)
			dstate_addenum("input.sensitivity", "%s",
			               sensitivity[i].name);
	}
	if (ups.outlet_banks) {
		dstate_addcmd("load.off");
		dstate_addcmd("load.on");
	}
	dstate_addcmd("shutdown.reboot");
	dstate_addcmd("shutdown.reboot.graceful");
	dstate_addcmd("shutdown.return");
#if 0 /* doesn't work */
	dstate_addcmd("shutdown.stayoff");
#endif
	dstate_addcmd("shutdown.stop");
	dstate_addcmd("test.battery.start");
	dstate_addcmd("test.battery.stop");

	/* add all the variables that change regularly */
	upsdrv_updateinfo();

	upsh.instcmd = instcmd;
	upsh.setvar = setvar;

	printf("Detected %s %s on %s\n", dstate_getinfo("ups.mfr"),
	       dstate_getinfo("ups.model"), device_path);
}
/* Process status bits */
int	blazer_process_status_bits(item_t *item, char *value, const size_t valuelen)
{
	char	*val = "";

	if (strspn(item->value, "01") != 1) {
		upsdebugx(3, "%s: unexpected value %s@%d->%s", __func__, item->value, item->from, item->value);
		return -1;
	}

	switch (item->from)
	{
	case 38:	/* Utility Fail (Immediate) */

		if (item->value[0] == '1')
			val = "!OL";
		else
			val = "OL";
		break;

	case 39:	/* Battery Low */

		if (item->value[0] == '1')
			val = "LB";
		else
			val = "!LB";
		break;

	case 40:	/* Bypass/Boost or Buck Active */

		if (item->value[0] == '1') {

			double	vi, vo;

			vi = strtod(dstate_getinfo("input.voltage"), NULL);
			vo = strtod(dstate_getinfo("output.voltage"), NULL);

			if (vo < 0.5 * vi) {
				upsdebugx(2, "%s: output voltage too low", __func__);
				return -1;
			} else if (vo < 0.95 * vi) {
				val = "TRIM";
			} else if (vo < 1.05 * vi) {
				val = "BYPASS";
			} else if (vo < 1.5 * vi) {
				val = "BOOST";
			} else {
				upsdebugx(2, "%s: output voltage too high", __func__);
				return -1;
			}

		}

		break;

	case 41:	/* UPS Failed - ups.alarm */

		if (item->value[0] == '1')
			val = "UPS selftest failed!";
		break;

	case 42:	/* UPS Type - ups.type */

		if (item->value[0] == '1')
			val = "offline / line interactive";
		else
			val = "online";
		break;

	case 43:	/* Test in Progress */

		if (item->value[0] == '1')
			val = "CAL";
		else
			val = "!CAL";
		break;

	case 44:	/* Shutdown Active */

		if (item->value[0] == '1')
			val = "FSD";
		else
			val = "!FSD";
		break;

	case 45:	/* Beeper status - ups.beeper.status */

		if (item->value[0] == '1')
			val = "enabled";
		else
			val = "disabled";
		break;

	default:
		/* Don't know what happened */
		return -1;
	}

	snprintf(value, valuelen, "%s", val);

	return 0;
}
Example #21
0
static float calc_upsload(void) {

	float 	load=-1, nom_out_power=-1, nom_out_realpower=-1, maxcurr, tmp;
	const char	*s;

	/* Some UPSen (Fiskars 9000 for example) only reports current, and
	 * only the max current */
	if (nom_out_current > 0) {
		maxcurr = nom_out_current;
	}
	else {
		maxcurr = max_out_current;
	}

	if (maxcurr > 0) {
		if ((s=dstate_getinfo("output.L1.current")) ||
				(s=dstate_getinfo("output.current"))) {
			if (sscanf(s, "%f", &tmp) == 1) {
				load = tmp/maxcurr;
			}
		}
		if ((s=dstate_getinfo("output.L2.current"))) {
			if (sscanf(s, "%f", &tmp) == 1) {
				tmp=tmp/maxcurr;
				if (tmp>load) {
					load = tmp;
				}
			}
		}
		if ((s=dstate_getinfo("output.L3.current"))) {
			if (sscanf(s, "%f", &tmp) == 1) {
				tmp=tmp/maxcurr;
				if (tmp>load) {
					load = tmp;
				}
			}
		}
	}

	/* This is aggregated (all phases) */
	if ((s=dstate_getinfo("ups.power.nominal"))) {
		if (sscanf(s, "%f", &nom_out_power) != 1) {
			nom_out_power = -1;
		}
	}

	if (nom_out_power > 0) {
		if ((s=dstate_getinfo("output.L1.power"))) {
			if (sscanf(s, "%f", &tmp) == 1) {
				tmp /= (nom_out_power/num_outphases);
				if (tmp>load) {
					load = tmp;
				}
				dstate_setinfo("output.L1.power.percent",
						"%.1f", tmp*100);
			}
		}
		if ((s=dstate_getinfo("output.L2.power"))) {
			if (sscanf(s, "%f", &tmp) == 1) {
				tmp /= (nom_out_power/num_outphases);
				if (tmp>load) {
					load = tmp;
				}
				dstate_setinfo("output.L2.power.percent",
						"%.1f", tmp*100);
			}
		}
		if ((s=dstate_getinfo("output.L3.power"))) {
			if (sscanf(s, "%f", &tmp) == 1) {
				tmp /= (nom_out_power/num_outphases);
				if (tmp>load) {
					load = tmp;
				}
				dstate_setinfo("output.L3.power.percent",
						"%.1f", tmp*100);
			}
		}
	}

	/* This is aggregated (all phases) */
	if ((s=dstate_getinfo("output.realpower.nominal"))) {
		if (sscanf(s, "%f", &nom_out_realpower) != 1) {
			nom_out_realpower = -1;
		}
	}
	if (nom_out_realpower >= 0) {
		if ((s=dstate_getinfo("output.L1.realpower"))) {
			if (sscanf(s, "%f", &tmp) == 1) {
				tmp /= (nom_out_realpower/num_outphases);
				if (tmp>load) {
					load = tmp;
				}
				dstate_setinfo("output.L1.realpower.percent",
						"%.1f", tmp*100);
			}
		}
		if ((s=dstate_getinfo("output.L2.realpower"))) {
			if (sscanf(s, "%f", &tmp) == 1) {
				tmp /= (nom_out_realpower/num_outphases);
				if (tmp>load) {
					load = tmp;
				}
				dstate_setinfo("output.L2.realpower.percent",
						"%.1f", tmp*100);
			}
		}
		if ((s=dstate_getinfo("output.L3.realpower"))) {
			if (sscanf(s, "%f", &tmp) == 1) {
				tmp /= (nom_out_realpower/num_outphases);
				if (tmp>load) {
					load = tmp;
				}
				dstate_setinfo("output.L3.realpower.percent",
						"%.1f", tmp*100);
			}
		}
	}

	return load;
}
Example #22
0
File: rhino.c Project: AlexLov/nut
static void getbaseinfo(void)
{
	unsigned char  temp[256];
	unsigned char Pacote[37];
	int  tam, i, j=0;
	time_t tmt;
	struct tm *now;
	const char *Model;

	time( &tmt );
	now = localtime( &tmt );
	dian = now->tm_mday;
	mesn = now->tm_mon+1;
	anon = now->tm_year+1900;
        weekn = now->tm_wday;

	/* trying detect rhino model */
	while ( ( !detected ) && ( j < 10 ) )
	  {

	    temp[0] = 0; /* flush temp buffer */
	    tam = ser_get_buf_len(upsfd, temp, pacsize, 3, 0);
	    if( tam == 37 )
	      {
		for( i = 0 ; i < tam ; i++ )
		  {
		    Pacote[i] = temp[i];
		  }
	      }

	    j++;
	    if( tam == 37)
	      CommReceive(Pacote, tam);
	     else
	      CommReceive(temp, tam);
	  }

	if( (!detected) )
	  {
	    fatalx(EXIT_FAILURE,  NO_RHINO );
	  }

	switch( RhinoModel )
	  {
	  case 0xC0:
	    {
	      Model =  "Rhino 20.0 kVA";
	      PotenciaNominal = 20000;
	      break;
	    }
	  case 0xC1:
	    {
	      Model = "Rhino 10.0 kVA";
	      PotenciaNominal = 10000;
	      break;
	    }
	  case 0xC2:
	    {
	      Model = "Rhino 6.0 kVA";
	      PotenciaNominal = 6000;
	      break;
	    }
	  case 0xC3:
	    {
	      Model = "Rhino 7.5 kVA";
	      PotenciaNominal = 7500;
	      break;
	    }
	  default:
	    {
	      Model = "Rhino unknown model";
	      PotenciaNominal = 0;
	      break;
	    }
	  }

	/* manufacturer and model */
	dstate_setinfo("ups.mfr", "%s", "Microsol");
	dstate_setinfo("ups.model", "%s", Model);
	/*
	dstate_setinfo("input.transfer.low", "%03.1f", InDownLim); LimInfBattInv ?
	dstate_setinfo("input.transfer.high", "%03.1f", InUpLim); LimSupBattInv ?
	*/

	dstate_addcmd("shutdown.stayoff");	/* CMD_SHUT */
	/* there is no reserved words for CMD_INON and CMD_INOFF yet */
	/* dstate_addcmd("input.on"); */	/* CMD_INON    = 1 */
	/* dstate_addcmd("input.off"); */	/* CMD_INOFF   = 2 */
	dstate_addcmd("load.on");	/* CMD_OUTON   = 3 */
	dstate_addcmd("load.off");	/* CMD_OUTOFF  = 4 */
	dstate_addcmd("bypass.start");	/* CMD_PASSON  = 5 */
	dstate_addcmd("bypass.stop");	/* CMD_PASSOFF = 6 */

	printf("Detected %s on %s\n", dstate_getinfo("ups.model"), device_path);

}
Example #23
0
File: oneac.c Project: sbutler/nut
void upsdrv_initinfo(void)
{
	int i,j, k;
	int VRange=0;
	int timevalue;
	int RetValue;
	char buffer[256], buffer2[32];

	/* All families should reply to this request so we can confirm that it is
	 *  an ONEAC UPS
	 */

	ser_flush_in(upsfd,"",0);
	ser_send(upsfd,"%c%s",GET_FAMILY,COMMAND_END);

	if(OneacGetResponse (buffer, sizeof(buffer), 2))
	{
		fatalx(EXIT_FAILURE, "Serial timeout with ONEAC UPS on %s\n",
																device_path);
	}
	else
	{
		if (strncmp(buffer,FAMILY_ON,FAMILY_SIZE) != 0 && 
			strncmp(buffer,FAMILY_OZ,FAMILY_SIZE) != 0 &&
			strncmp(buffer,FAMILY_OB,FAMILY_SIZE) != 0 && 
			strncmp(buffer,FAMILY_EG,FAMILY_SIZE) != 0)
		{
			fatalx(EXIT_FAILURE, "Did not find an ONEAC UPS on %s\n",
																device_path);	
		}
	}

	/* UPS Model (either EG, ON, OZ or OB series of UPS) */
	strncpy(UpsFamily, buffer, FAMILY_SIZE);
	UpsFamily[2] = '\0';
	dstate_setinfo("device.model", "%s",UpsFamily);
	printf("Found %s family of Oneac UPS\n", UpsFamily);

	dstate_setinfo("ups.type", "%s", "Line Interactive");
	
	dstate_addcmd("test.battery.start.quick");
	dstate_addcmd("test.battery.stop");
	dstate_addcmd("test.failure.start");
	dstate_addcmd("shutdown.return");
	dstate_addcmd("shutdown.stop");
	dstate_addcmd("shutdown.reboot");

	upsh.setvar = setcmd;
	upsh.instcmd = instcmd;

	/* set some stuff that shouldn't change after initialization */
	/* this stuff is common to all families of UPS */

	ser_send(upsfd,"%c%s",GET_ALL,COMMAND_END);

	if (strncmp(UpsFamily, FAMILY_EG, FAMILY_SIZE) == 0)
	{
		RetValue = OneacGetResponse (buffer, sizeof(buffer), 
														GETALL_EG_RESP_SIZE);
	}
	else
	{
		RetValue = OneacGetResponse (buffer, sizeof(buffer), GETALL_RESP_SIZE);
	}

	if(RetValue)
	{
		fatalx(EXIT_FAILURE, "Serial timeout(2) with ONEAC UPS on %s\n",
																device_path);
	}

	/* Manufacturer */
	dstate_setinfo("device.mfr", "%.5s", buffer);

	/*firmware revision*/
	dstate_setinfo("ups.firmware", "%.3s",buffer+7);

	/*nominal AC frequency setting --either 50 or 60*/
	dstate_setinfo("input.frequency.nominal", "%.2s", buffer+20);
	dstate_setinfo("output.frequency.nominal", "%.2s", buffer+20);

	/* Shutdown delay in seconds...can be changed by user */
	if (getval("offdelay") == NULL)
		dstate_setinfo("ups.delay.shutdown", "0");
	else
		dstate_setinfo("ups.delay.shutdown", "%s", getval("offdelay"));

	dstate_setflags("ups.delay.shutdown", ST_FLAG_STRING | ST_FLAG_RW);
	dstate_setaux("ups.delay.shutdown", GET_SHUTDOWN_RESP_SIZE);
	
	/* Setup some ON/OZ/OB only stuff ... i.e. not EG */

	if (strncmp(UpsFamily, FAMILY_EG, FAMILY_SIZE) != 0)
	{
		dstate_addcmd("reset.input.minmax");

		/*nominal input voltage*/

		VRange = buffer[26];			/* Keep for later use also */
		
		switch (VRange)					/* Will be '1' or '2' */
		{
			case V120AC:
				dstate_setinfo("input.voltage.nominal", "120");
				dstate_setinfo("output.voltage.nominal", "120");
				break;

			case V230AC:
				dstate_setinfo("input.voltage.nominal", "230");
				dstate_setinfo("output.voltage.nominal", "230");
				break;

			default:
				upslogx(LOG_INFO,"Oneac: "
					"Invalid nom voltage parameter from UPS [%c]", VRange);
		}
	}
		  
	/* Setup some OZ/OB only stuff */
	
	if ((strncmp (UpsFamily, FAMILY_OZ, FAMILY_SIZE) == 0) ||
		(strncmp (UpsFamily, FAMILY_OB, FAMILY_SIZE) == 0))
	{
		dstate_addcmd("test.panel.start");
		dstate_addcmd("test.battery.start.deep");
		dstate_addcmd("beeper.enable");
		dstate_addcmd("beeper.disable");
		dstate_addcmd("beeper.mute");
		
		dstate_setaux("ups.delay.shutdown", GETX_SHUTDOWN_RESP_SIZE);

		ser_flush_in(upsfd,"",0);
		ser_send(upsfd,"%c%s",GETX_ALL_2,COMMAND_END);
		if(OneacGetResponse (buffer, sizeof(buffer), GETX_ALL2_RESP_SIZE))
		{
			fatalx(EXIT_FAILURE, "Serial timeout(3) with ONEAC UPS on %s\n",
																device_path);
		}

		/* Low and high output trip points */
		EliminateLeadingZeroes (buffer+73, 3, buffer2, sizeof(buffer2));
		dstate_setinfo("input.transfer.low", "%s", buffer2);
		dstate_setflags("input.transfer.low", ST_FLAG_STRING | ST_FLAG_RW );
		dstate_setaux("input.transfer.low", 3);

		EliminateLeadingZeroes (buffer+76, 3, buffer2, sizeof(buffer2));
		dstate_setinfo("input.transfer.high", "%s", buffer2);
		dstate_setflags("input.transfer.high", ST_FLAG_STRING | ST_FLAG_RW);
		dstate_setaux("input.transfer.high", 3);

		/* Restart delay */
		EliminateLeadingZeroes (buffer+84, 4, buffer2, sizeof(buffer2));
		dstate_setinfo("ups.delay.start", "%s", buffer2);
		dstate_setflags("ups.delay.start", ST_FLAG_STRING | ST_FLAG_RW);
		dstate_setaux("ups.delay.start", 4);
		
		/* Low Batt at time */
		strncpy(buffer2, buffer+82, 2);
		buffer2[2]='\0';
		timevalue = atoi(buffer2) * 60;		/* Change minutes to seconds */
		dstate_setinfo("battery.runtime.low", "%d",timevalue);
		dstate_setflags("battery.runtime.low", ST_FLAG_STRING | ST_FLAG_RW);
		dstate_setaux("battery.runtime.low", 2);
		
		/*Get the actual model string for ON UPS reported as OZ/OB family*/

		/*UPS Model (full string)*/
		memset(buffer2, '\0', 32);
		strncpy(buffer2, buffer+5, 10);
		for (i = 9; i >= 0 && buffer2[i] == ' '; --i) 
		{
			buffer2[i] = '\0';
		}

		dstate_setinfo("device.model", "%s", buffer2);
		
		/* Serial number */
		dstate_setinfo("device.serial", "%.4s-%.4s", buffer+18, buffer+22);
		printf("Found %.10s UPS with serial number %.4s-%.4s\n", 
												buffer2, buffer+18, buffer+22);
		
		/* Manufacture Date */
		dstate_setinfo("ups.mfr.date", "%.6s (yymmdd)", buffer+38);

		/* Battery Replace Date */
		dstate_setinfo("battery.date", "%.6s (yymmdd)", buffer+44);
		dstate_setflags("battery.date", ST_FLAG_STRING | ST_FLAG_RW);
		dstate_setaux("battery.date", 6);
		
		/* Real power nominal */
		EliminateLeadingZeroes (buffer+55, 5, buffer2, sizeof(buffer2));
		dstate_setinfo("ups.realpower.nominal", "%s", buffer2);

		/* Set up ups.start.auto to be writable */
		dstate_setinfo("ups.start.auto", "yes");
		dstate_setflags("ups.start.auto", ST_FLAG_STRING | ST_FLAG_RW);
		dstate_setaux("ups.start.auto", 3);

		/* Get output window min/max points from OB or OZ v1.9 or later */
		if ((strncmp (UpsFamily, FAMILY_OB, FAMILY_SIZE) == 0) ||
			(strcmp (dstate_getinfo("ups.firmware"), MIN_ALLOW_FW) >= 0 ))
		{
			upsdebugx (2,"Can get output window min/max! (%s)", 
												dstate_getinfo("ups.firmware"));

			ser_send(upsfd,"%s%s",GETX_ALLOW_RANGE,COMMAND_END);
			if(OneacGetResponse (buffer, sizeof(buffer), GETX_RANGE_RESP_SIZE))
			{
				fatalx(EXIT_FAILURE, 
						"Serial timeout(4) with ONEAC UPS on %s\n",device_path);
			}

			strncpy(buffer2, buffer, 3);
			buffer2[3]='\0';
			i = atoi(buffer2);		/* Minimum voltage */
			
			strncpy(buffer2, buffer+4, 3);
			j = atoi(buffer2);		/* Maximum voltage */

			strncpy(buffer2, buffer+8, 2);
			buffer2[2]='\0';
			k = atoi(buffer2);		/* Spread between */
			
			dstate_setinfo("input.transfer.low.min", "%3d", i);
			dstate_setinfo("input.transfer.low.max", "%3d", j-k);
			dstate_setinfo("input.transfer.high.min", "%3d", i+k);
			dstate_setinfo("input.transfer.high.max", "%3d", j);

		}
		else
		{
			/* Use default values from firmware */
			upsdebugx (2,"Using trip defaults (%s)...", 
												dstate_getinfo("ups.firmware"));

			switch (VRange)				/* Held from initial use */
			{
				case V120AC:
					dstate_setinfo("input.transfer.low.min", "90");
					dstate_setinfo("input.transfer.low.max", "120");
					dstate_setinfo("input.transfer.high.min", "110");
					dstate_setinfo("input.transfer.high.max", "140");
					break;

				case V230AC:
					dstate_setinfo("input.transfer.low.min", "172");
					dstate_setinfo("input.transfer.low.max", "228");
					dstate_setinfo("input.transfer.high.min", "212");
					dstate_setinfo("input.transfer.high.max", "268");
					break;

				default:
					;

			}
		}
	}
}
Example #24
0
static int netxml_alarm_subscribe(const char *page)
{
	int	ret, port = -1, secret = -1;
	char	buf[LARGEBUF], *s;
	ne_request	*request;
	ne_sock_addr	*addr;
	const ne_inet_addr	*ai;
	char	resp_buf[LARGEBUF];

	/* Clear response buffer */
	memset(resp_buf, 0, sizeof(resp_buf));

	upsdebugx(2, "%s: %s", __func__, page);

	sock = ne_sock_create();

	if (gethostname(buf, sizeof(buf)) == 0) {
		dstate_setinfo("driver.hostname", "%s", buf);
	} else {
		dstate_setinfo("driver.hostname", "<unknown>");
	}

#ifdef HAVE_NE_SOCK_CONNECT_TIMEOUT
	ne_sock_connect_timeout(sock, timeout);
#endif
	ne_sock_read_timeout(sock, 1);

	netxml_get_page(subdriver->configure);

	snprintf(buf, sizeof(buf),	"<?xml version=\"1.0\"?>\n");
	snprintfcat(buf, sizeof(buf),	"<Subscribe>\n");
	snprintfcat(buf, sizeof(buf),		"<Class>%s v%s</Class>\n", progname, DRIVER_VERSION);
	snprintfcat(buf, sizeof(buf),		"<Type>connected socket</Type>\n");
	snprintfcat(buf, sizeof(buf),		"<HostName>%s</HostName>\n", dstate_getinfo("driver.hostname"));
	snprintfcat(buf, sizeof(buf),		"<XMLClientParameters>\n");
	snprintfcat(buf, sizeof(buf),		"<ShutdownDuration>%d</ShutdownDuration>\n", shutdown_duration);
	if( shutdown_timer > 0 ) {
		snprintfcat(buf, sizeof(buf),	"<ShutdownTimer>%d</ShutdownTimer>\r\n", shutdown_timer);
	}
	else {
		snprintfcat(buf, sizeof(buf),	"<ShutdownTimer>NONE</ShutdownTimer>\n");
	}
	snprintfcat(buf, sizeof(buf),			"<AutoConfig>LOCAL</AutoConfig>\n");
	snprintfcat(buf, sizeof(buf),			"<OutletGroup>1</OutletGroup>\n");
	snprintfcat(buf, sizeof(buf),		"</XMLClientParameters>\n");
	snprintfcat(buf, sizeof(buf),		"<Warning></Warning>\n");
	snprintfcat(buf, sizeof(buf),	"</Subscribe>\n");

	/* now send subscription message setting all the proper flags */
	request = ne_request_create(session, "POST", page);
	ne_set_request_body_buffer(request, buf, strlen(buf));

	/* as the NMC reply is not xml standard compliant let's parse it this way */
	do {
#ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT
		alarm(timeout+1);
#endif
		ret = ne_begin_request(request);

#ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT
		alarm(0);
#endif
		if (ret != NE_OK) {
			break;
		}

		ret = ne_read_response_block(request, resp_buf, sizeof(resp_buf));

		if (ret == NE_OK) {
			ret = ne_end_request(request);
		}

	} while (ret == NE_RETRY);

	ne_request_destroy(request);

	/* due to different formats used by the various NMCs, we need to\
	   break up the reply in lines and parse each one separately */
	for (s = strtok(resp_buf, "\r\n"); s != NULL; s = strtok(NULL, "\r\n")) {
		upsdebugx(2, "%s: parsing %s", __func__, s);

		if (!strncasecmp(s, "<Port>", 6) && (sscanf(s+6, "%u", &port) != 1)) {
			return NE_RETRY;
		}

		if (!strncasecmp(s, "<Secret>", 8) && (sscanf(s+8, "%u", &secret) != 1)) {
			return NE_RETRY;
		}
	}

	if ((port == -1) || (secret == -1)) {
		upsdebugx(2, "%s: parsing initial subcription failed", __func__);
		return NE_RETRY;
	}

	/* Resolve the given hostname.  'flags' must be zero.  Hex
	* string IPv6 addresses (e.g. `::1') may be enclosed in brackets
	* (e.g. `[::1]'). */
	addr = ne_addr_resolve(uri.host, 0);

	/* Returns zero if name resolution was successful, non-zero on
	* error. */
	if (ne_addr_result(addr) != 0) {
		upsdebugx(2, "%s: name resolution failure on %s: %s", __func__, uri.host, ne_addr_error(addr, buf, sizeof(buf)));
		ne_addr_destroy(addr);
		return NE_RETRY;
	}

	for (ai = ne_addr_first(addr); ai != NULL; ai = ne_addr_next(addr)) {

		upsdebugx(2, "%s: connecting to host %s port %d", __func__, ne_iaddr_print(ai, buf, sizeof(buf)), port);

#ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT
		alarm(timeout+1);
#endif
		ret = ne_sock_connect(sock, ai, port);

#ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT
		alarm(0);
#endif
		if (ret == NE_OK) {
			upsdebugx(2, "%s: connection to %s open on fd %d", __func__, uri.host, ne_sock_fd(sock));
			break;
		}
	}

	ne_addr_destroy(addr);

	if (ai == NULL) {
		upsdebugx(2, "%s: failed to create listening socket", __func__);
		return NE_RETRY;
	}

	snprintf(buf, sizeof(buf), "<Subscription Identification=\"%u\"></Subscription>", secret);
	ret = ne_sock_fullwrite(sock, buf, strlen(buf) + 1);

	if (ret != NE_OK) {
		upsdebugx(2, "%s: send failed: %s", __func__, ne_sock_error(sock));
		return NE_RETRY;
	}

	ret = ne_sock_read(sock, buf, sizeof(buf));

	if (ret < 1) {
		upsdebugx(2, "%s: read failed: %s", __func__, ne_sock_error(sock));
		return NE_RETRY;
	}

	if (strcasecmp(buf, "<Subscription Answer=\"ok\"></Subscription>")) {
		upsdebugx(2, "%s: subscription rejected", __func__);
		return NE_RETRY;
	}

	upslogx(LOG_INFO, "NSM connection to '%s' established", uri.host);
	return NE_OK;
}
Example #25
0
File: oneac.c Project: sbutler/nut
int instcmd(const char *cmdname, const char *extra)
{
	int i;

	upsdebugx(2, "In instcmd with %s and extra %s.", cmdname, extra);

	if (!strcasecmp(cmdname, "test.failure.start")) {
		ser_send(upsfd,"%s%s",SIM_PWR_FAIL,COMMAND_END);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "shutdown.return")) {

		i = atoi(dstate_getinfo("ups.delay.shutdown"));

		if ((strncmp (UpsFamily, FAMILY_OZ, FAMILY_SIZE) == 0) ||
			(strncmp (UpsFamily, FAMILY_OB, FAMILY_SIZE) == 0))
		{
			upsdebugx(3, "Shutdown using %c%d...", DELAYED_SHUTDOWN_PREFIX, i);
			ser_send(upsfd,"%c%d%s",DELAYED_SHUTDOWN_PREFIX, i, COMMAND_END);
		}
		else
		{
			upsdebugx(3, "Shutdown using %c%03d...",DELAYED_SHUTDOWN_PREFIX, i);
			ser_send(upsfd,"%c%03d%s",DELAYED_SHUTDOWN_PREFIX, i, COMMAND_END);
		}

		return STAT_INSTCMD_HANDLED;
	}
	
	if(!strcasecmp(cmdname, "shutdown.reboot")) {
		ser_send(upsfd, "%s", SHUTDOWN);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "shutdown.stop")) {
		ser_send(upsfd,"%c%s",DELAYED_SHUTDOWN_PREFIX,COMMAND_END);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "test.battery.start.quick")) {
		do_battery_test();
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "test.battery.start.deep")) {
		ser_send(upsfd, "%s%s", TEST_BATT_DEEP, COMMAND_END);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "test.battery.stop")) 
	{
		if ((strncmp (UpsFamily, FAMILY_EG, FAMILY_SIZE) == 0) ||
			(strncmp (UpsFamily, FAMILY_ON, FAMILY_SIZE) == 0))
		{
			ser_send(upsfd,"%s00%s",BAT_TEST_PREFIX,COMMAND_END);
		}
		else
		{
			ser_send(upsfd,"%c%s",TEST_ABORT,COMMAND_END);
		}			
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "reset.input.minmax")) {
		ser_send(upsfd,"%c%s",RESET_MIN_MAX, COMMAND_END);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "beeper.enable")) {
		ser_send(upsfd,"%c%c%s",SETX_BUZZER_PREFIX, BUZZER_ENABLED,COMMAND_END);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "beeper.disable")) {
		ser_send(upsfd,"%c%c%s",SETX_BUZZER_PREFIX,BUZZER_DISABLED,COMMAND_END);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "beeper.mute")) {
		ser_send(upsfd,"%c%c%s",SETX_BUZZER_PREFIX, BUZZER_MUTED, COMMAND_END);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "test.panel.start")) {
		ser_send(upsfd,"%s%s",TEST_INDICATORS, COMMAND_END);
		return STAT_INSTCMD_HANDLED;
	}

	upslogx(LOG_NOTICE, "instcmd: unknown command [%s]", cmdname);
	return STAT_INSTCMD_UNKNOWN;
}
Example #26
0
File: oneac.c Project: sbutler/nut
int setcmd(const char* varname, const char* setvalue)
{
	upsdebugx(2, "In setcmd for %s with %s...", varname, setvalue);

	if (!strcasecmp(varname, "ups.delay.shutdown"))
	{
		if ((strncmp (UpsFamily, FAMILY_OZ, FAMILY_SIZE) == 0) ||
			(strncmp (UpsFamily, FAMILY_OB, FAMILY_SIZE) == 0))
		{
			if (atoi(setvalue) > 65535)
			{
				upsdebugx(2, "Too big for OZ/OB (>65535)...(%s)", setvalue);
				return STAT_SET_UNKNOWN;
			}
		}
		else
		{
			if (atoi(setvalue) > 999)
			{
				upsdebugx(2, "Too big for EG/ON (>999)...(%s)", setvalue);
				return STAT_SET_UNKNOWN;
			}
		}

		dstate_setinfo("ups.delay.shutdown", "%s", setvalue);
		return STAT_SET_HANDLED;
	}

	if (!strcasecmp(varname, "input.transfer.low"))
	{
		if (SetOutputAllow(setvalue, dstate_getinfo("input.transfer.high")))
		{
			return STAT_SET_UNKNOWN;
		}
		else
		{
			dstate_setinfo("input.transfer.low" , "%s", setvalue);
			return STAT_SET_HANDLED;
		}
	}

	if (!strcasecmp(varname, "input.transfer.high"))
	{
		if (SetOutputAllow(dstate_getinfo("input.transfer.low"), setvalue))
		{
			return STAT_SET_UNKNOWN;
		}
		else
		{
			dstate_setinfo("input.transfer.high" , "%s", setvalue);
			return STAT_SET_HANDLED;
		}
	}

	if (!strcasecmp(varname, "battery.date"))
	{
		if(strlen(setvalue) == GETX_DATE_RESP_SIZE)		/* yymmdd (6 chars) */
		{
			ser_send(upsfd, "%s%s%s", SETX_BATTERY_DATE, setvalue, COMMAND_END);
			dstate_setinfo("battery.date", "%s (yymmdd)", setvalue);
			return STAT_SET_HANDLED;
		}
		else
		{
			return STAT_SET_UNKNOWN;
		}
	}

	if (!strcasecmp(varname, "ups.delay.start"))
	{
		if (atoi(setvalue) <= 9999)
		{
			ser_send(upsfd,"%s%s%s",SETX_RESTART_DELAY, setvalue, COMMAND_END);

			dstate_setinfo("ups.delay.start", "%s", setvalue);
			return STAT_SET_HANDLED;
		}
		else
		{
			return STAT_SET_UNKNOWN;
		}
	}

	if (!strcasecmp(varname, "battery.runtime.low"))
	{
		if (atoi(setvalue) <= 99)
		{
			ser_send(upsfd,"%s%s%s",SETX_LOWBATT_AT, setvalue, COMMAND_END);
	
			dstate_setinfo("battery.runtime.low", "%s", setvalue);
			return STAT_SET_HANDLED;
		}
		else
		{
			return STAT_SET_UNKNOWN;
		}
	}

	if (!strcasecmp(varname, "ups.start.auto"))
	{
		if (!strcasecmp(setvalue, "yes"))
		{
			ser_send(upsfd,"%c0%s",SETX_AUTO_START, COMMAND_END);
			dstate_setinfo("ups.start.auto", "yes");
			return STAT_SET_HANDLED;
		}
		else if (!strcasecmp(setvalue, "no"))
		{
			ser_send(upsfd,"%c1%s",SETX_AUTO_START, COMMAND_END);
			dstate_setinfo("ups.start.auto", "no");
			return STAT_SET_HANDLED;
		}
		
		return STAT_SET_UNKNOWN;
	}

	upslogx(LOG_NOTICE, "setcmd: unknown command [%s]", varname);

	return STAT_SET_UNKNOWN;
}
Example #27
0
int riello_instcmd(const char *cmdname, const char *extra)
{
	uint8_t length;
	uint16_t delay;
	const char	*delay_char;

	if (!riello_test_bit(&DevData.StatusCode[0], 1)) {
		if (!strcasecmp(cmdname, "load.off")) {
			delay = 0;
			riello_init_serial();

			if (typeRielloProtocol == DEV_RIELLOGPSER)
				length = riello_prepare_cs(bufOut, gpser_error_control, delay);
			else
				length = riello_prepare_shutsentr(bufOut, delay);

			if (ser_send_buf(upsfd, bufOut, length) == 0) {
				upsdebugx (3, "Command load.off communication error");
				return STAT_INSTCMD_FAILED;
			}

			riello_serialcomm(&bufIn[0], typeRielloProtocol);
			if (!wait_packet && foundbadcrc) {
				upsdebugx (3, "Command load.off Ko: bad CRC or Checksum");
				return STAT_INSTCMD_FAILED;
			}

			if (!wait_packet && foundnak) {
				upsdebugx (3, "Command load.off Ko: command not supported");
				return STAT_INSTCMD_FAILED;
			}

			upsdebugx (3, "Command load.off Ok");
			return STAT_INSTCMD_HANDLED;
		}

		if (!strcasecmp(cmdname, "load.off.delay")) {
			delay_char = dstate_getinfo("ups.delay.shutdown");
			delay = atoi(delay_char);
			riello_init_serial();

			if (typeRielloProtocol == DEV_RIELLOGPSER)
				length = riello_prepare_cs(bufOut, gpser_error_control, delay);
			else
				length = riello_prepare_shutsentr(bufOut, delay);

			if (ser_send_buf(upsfd, bufOut, length) == 0) {
				upsdebugx (3, "Command load.off delay communication error");
				return STAT_INSTCMD_FAILED;
			}

			riello_serialcomm(&bufIn[0], typeRielloProtocol);
			if (!wait_packet && foundbadcrc) {
				upsdebugx (3, "Command load.off.delay Ko: bad CRC or Checksum");
				return STAT_INSTCMD_FAILED;
			}

			if (!wait_packet && foundnak) {
				upsdebugx (3, "Command load.off.delay Ko: command not supported");
				return STAT_INSTCMD_FAILED;
			}

			upsdebugx (3, "Command load.off delay Ok");
			return STAT_INSTCMD_HANDLED;
		}

		if (!strcasecmp(cmdname, "load.on")) {
			delay = 0;
			riello_init_serial();

			if (typeRielloProtocol == DEV_RIELLOGPSER)
				length = riello_prepare_cr(bufOut, gpser_error_control, delay);
			else {
				length = riello_prepare_setrebsentr(bufOut, delay);
				
				if (ser_send_buf(upsfd, bufOut, length) == 0) {
					upsdebugx (3, "Command load.on communication error");
					return STAT_INSTCMD_FAILED;
				}

				riello_serialcomm(&bufIn[0], typeRielloProtocol);
				if (!wait_packet && foundbadcrc) {
					upsdebugx (3, "Command load.on Ko: bad CRC or Checksum");
					return STAT_INSTCMD_FAILED;
				}

				if (!wait_packet && foundnak) {
					upsdebugx (3, "Command load.on Ko: command not supported");
					return STAT_INSTCMD_FAILED;
				}

				length = riello_prepare_rebsentr(bufOut, delay);
			}

			if (ser_send_buf(upsfd, bufOut, length) == 0) {
				upsdebugx (3, "Command load.on communication error");
				return STAT_INSTCMD_FAILED;
			}

			riello_serialcomm(&bufIn[0], typeRielloProtocol);
			if (!wait_packet && foundbadcrc) {
				upsdebugx (3, "Command load.on Ko: bad CRC or Checksum");
				return STAT_INSTCMD_FAILED;
			}

			if (!wait_packet && foundnak) {
				upsdebugx (3, "Command load.on Ko: command not supported");
				return STAT_INSTCMD_FAILED;
			}

			upsdebugx (3, "Command load.on Ok");
			return STAT_INSTCMD_HANDLED;
		}

		if (!strcasecmp(cmdname, "load.on.delay")) {
			delay_char = dstate_getinfo("ups.delay.reboot");
			delay = atoi(delay_char);
			riello_init_serial();

			if (typeRielloProtocol == DEV_RIELLOGPSER)
				length = riello_prepare_cr(bufOut, gpser_error_control, delay);
			else {
				length = riello_prepare_setrebsentr(bufOut, delay);

				if (ser_send_buf(upsfd, bufOut, length) == 0) {
					upsdebugx (3, "Command load.on delay communication error");
					return STAT_INSTCMD_FAILED;
				}

				riello_serialcomm(&bufIn[0], typeRielloProtocol);
				if (!wait_packet && foundbadcrc) {
					upsdebugx (3, "Command load.on delay Ko: bad CRC or Checksum");
					return STAT_INSTCMD_FAILED;
				}

				if (!wait_packet && foundnak) {
					upsdebugx (3, "Command load.on delay Ko: command not supported");
					return STAT_INSTCMD_FAILED;
				}

				length = riello_prepare_rebsentr(bufOut, delay);
			}

			if (ser_send_buf(upsfd, bufOut, length) == 0) {
				upsdebugx (3, "Command load.on delay communication error");
				return STAT_INSTCMD_FAILED;
			}

			riello_serialcomm(&bufIn[0], typeRielloProtocol);
			if (!wait_packet && foundbadcrc) {
				upsdebugx (3, "Command load.on.delay Ko: bad CRC or Checksum");
				return STAT_INSTCMD_FAILED;
			}

			if (!wait_packet && foundnak) {
				upsdebugx (3, "Command load.on.delay Ko: command not supported");
				return STAT_INSTCMD_FAILED;
			}

			upsdebugx (3, "Command load.on delay Ok");
			return STAT_INSTCMD_HANDLED;
		}
	}
	else {
		if (!strcasecmp(cmdname, "shutdown.return")) {
			delay_char = dstate_getinfo("ups.delay.shutdown");
			delay = atoi(delay_char);
			riello_init_serial();

			if (typeRielloProtocol == DEV_RIELLOGPSER)
				length = riello_prepare_cs(bufOut, gpser_error_control, delay);
			else
				length = riello_prepare_shutsentr(bufOut, delay);

			if (ser_send_buf(upsfd, bufOut, length) == 0) {
				upsdebugx (3, "Command shutdown.return communication error");
				return STAT_INSTCMD_FAILED;
			}

			riello_serialcomm(&bufIn[0], typeRielloProtocol);
			if (!wait_packet && foundbadcrc) {
				upsdebugx (3, "Command shutdown.return Ko: bad CRC or Checksum");
				return STAT_INSTCMD_FAILED;
			}

			if (!wait_packet && foundnak) {
				upsdebugx (3, "Command shutdown.return Ko: command not supported");
				return STAT_INSTCMD_FAILED;
			}

			upsdebugx (3, "Command shutdown.return Ok");
			return STAT_INSTCMD_HANDLED;
		}
	}

	if (!strcasecmp(cmdname, "shutdown.stop")) {
		riello_init_serial();

		if (typeRielloProtocol == DEV_RIELLOGPSER) 
			length = riello_prepare_cd(bufOut, gpser_error_control);
		else
			length = riello_prepare_cancelsentr(bufOut);

		if (ser_send_buf(upsfd, bufOut, length) == 0) {
			upsdebugx (3, "Command shutdown.stop communication error");
			return STAT_INSTCMD_FAILED;
		}

		riello_serialcomm(&bufIn[0], typeRielloProtocol);
		if (!wait_packet && foundbadcrc) {
			upsdebugx (3, "Command shutdown.stop Ko: bad CRC or Checksum");
			return STAT_INSTCMD_FAILED;
		}

		if (!wait_packet && foundnak) {
			upsdebugx (3, "Command shutdown.stop Ko: command not supported");
			return STAT_INSTCMD_FAILED;
		}

		upsdebugx (3, "Command shutdown.stop Ok");
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "test.panel.start")) {
		riello_init_serial();
		length = riello_prepare_tp(bufOut, gpser_error_control);

		if (ser_send_buf(upsfd, bufOut, length) == 0) {
			upsdebugx (3, "Command test.panel.start communication error");
			return STAT_INSTCMD_FAILED;
		}

		riello_serialcomm(&bufIn[0], DEV_RIELLOGPSER);
		if (!wait_packet && foundbadcrc) {
			upsdebugx (3, "Command test.panel.start Ko: bad CRC or Checksum");
			return STAT_INSTCMD_FAILED;
		}

		if (!wait_packet && foundnak) {
			upsdebugx (3, "Command test.panel.start Ko: command not supported");
			return STAT_INSTCMD_FAILED;
		}

		upsdebugx (3, "Command test.panel.start Ok");
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "test.battery.start")) {
		riello_init_serial();
		if (typeRielloProtocol == DEV_RIELLOGPSER)
			length = riello_prepare_tb(bufOut, gpser_error_control);
		else
			length = riello_prepare_tbsentr(bufOut);

		if (ser_send_buf(upsfd, bufOut, length) == 0) {
			upsdebugx (3, "Command test.battery.start communication error");
			return STAT_INSTCMD_FAILED;
		}

		riello_serialcomm(&bufIn[0], typeRielloProtocol);
		if (!wait_packet && foundbadcrc) {
			upsdebugx (3, "Command battery.start Ko: bad CRC or Checksum");
			return STAT_INSTCMD_FAILED;
		}

		if (!wait_packet && foundnak) {
			upsdebugx (3, "Command battery.start Ko: command not supported");
			return STAT_INSTCMD_FAILED;
		}

		upsdebugx (3, "Command test.battery.start Ok");
		return STAT_INSTCMD_HANDLED;
	}

	upslogx(LOG_NOTICE, "instcmd: unknown command [%s]", cmdname);
	return STAT_INSTCMD_UNKNOWN;
}
Example #28
0
/* update information */
void upsdrv_updateinfo(void)
{
	char	val[32];
	
	if (!ups_getinfo()){
		return;
	}
	
	/* input.frequency */
	upsdebugx(3, "input.frequency   (raw data): [raw: %u]",
	                            raw_data[INPUT_FREQUENCY]);
	dstate_setinfo("input.frequency", "%02.2f", input_freq());
	upsdebugx(2, "input.frequency: %s", dstate_getinfo("input.frequency"));

	/* output.frequency */
	upsdebugx(3, "output.frequency   (raw data): [raw: %u]",
	                            raw_data[OUTPUT_FREQUENCY]);
	dstate_setinfo("output.frequency", "%02.2f", output_freq());
	upsdebugx(2, "output.frequency: %s", dstate_getinfo("output.frequency"));

	/* ups.load */	
	upsdebugx(3, "ups.load  (raw data): [raw: %u]",
	                            raw_data[UPS_LOAD]);
	dstate_setinfo("ups.load", "%03.1f", load_level());
	upsdebugx(2, "ups.load: %s", dstate_getinfo("ups.load"));

	/* battery.charge */
	upsdebugx(3, "battery.charge (raw data): [raw: %u]",
	                            raw_data[BATTERY_CHARGE]);
	dstate_setinfo("battery.charge", "%03.1f", batt_level());
	upsdebugx(2, "battery.charge: %s", dstate_getinfo("battery.charge"));

	/* input.voltage */	
	upsdebugx(3, "input.voltage (raw data): [raw: %u]",
	                            raw_data[INPUT_VOLTAGE]);
	dstate_setinfo("input.voltage", "%03.1f",input_voltage());
	upsdebugx(2, "input.voltage: %s", dstate_getinfo("input.voltage"));
	
	/* output.voltage */	
	upsdebugx(3, "output.voltage (raw data): [raw: %u]",
	                            raw_data[OUTPUT_VOLTAGE]);
	dstate_setinfo("output.voltage", "%03.1f",output_voltage());
	upsdebugx(2, "output.voltage: %s", dstate_getinfo("output.voltage"));

	status_init();
	
	*val = 0;
	if (!(raw_data[STATUS_A] & MAINS_FAILURE)) {
		!(raw_data[STATUS_A] & OFF) ? 
			status_set("OL") : status_set("OFF");
	} else {
		status_set("OB");
	}

	if (raw_data[STATUS_A] & LOW_BAT)  status_set("LB");

	if (raw_data[STATUS_A] & AVR_ON) {
		input_voltage() < linevoltage ? 
			status_set("BOOST") : status_set("TRIM");
	}

	if (raw_data[STATUS_A] & OVERLOAD)  status_set("OVER");

	if (raw_data[STATUS_B] & BAD_BAT)  status_set("RB");

	if (raw_data[STATUS_B] & TEST)  status_set("TEST");

	status_commit();

	upsdebugx(2, "STATUS: %s", dstate_getinfo("ups.status"));
	dstate_dataok();
}