Пример #1
0
/*
 * Generate status string from bitfield
 */
static void upsc_setstatus(unsigned int status)
{

	/*
	 * I'll look for all available statuses, even though they might not be
	 *  supported in the UPScode II protocol.
	 */

	status_init();

	if (status & UPSC_STAT_ONLINE)
		status_set("OL");
	if (status & UPSC_STAT_ONBATT)
		status_set("OB");
	if (status & UPSC_STAT_LOBATT)
		status_set("LB");
	if (status & UPSC_STAT_REPLACEBATT)
		status_set("RB");
	if (status & UPSC_STAT_BOOST)
		status_set("BOOST");
	if (status & UPSC_STAT_TRIM)
		status_set("TRIM");
	if (status & UPSC_STAT_OVERLOAD)
		status_set("OVER");
	if (status & UPSC_STAT_CALIBRATION)
		status_set("CAL");
	if (status & UPSC_STAT_OFF)
		status_set("OFF");
	if (status & UPSC_STAT_BYPASS)
		status_set("BYPASS");

	status_commit();
}
Пример #2
0
void upsdrv_updateinfo(void)
{
	if (ivt_status() < 7) {
		dstate_datastale();
		return;
	}

	dstate_setinfo("battery.voltage", "%.2f", battery.voltage.act);
	dstate_setinfo("battery.voltage.minimum", "%.2f", battery.voltage.min);
	dstate_setinfo("battery.voltage.maximum", "%.2f", battery.voltage.max);

	dstate_setinfo("battery.current", "%.1f", battery.current.act);
	dstate_setinfo("battery.current.minimum", "%.1f", battery.current.min);
	dstate_setinfo("battery.current.maximum", "%.1f", battery.current.max);

	dstate_setinfo("battery.temperature", "%.0f", battery.temperature);

	status_init();

	if (battery.current.act > 0) {
		status_set("OL");		/* charging */
	} else {
		status_set("OB");		/* discharging */
	}

	if (battery.voltage.act < battery.voltage.low) {
		status_set("LB");
	}

	status_commit();

	dstate_dataok();
}
Пример #3
0
static int setvar(const char *varname, const char *val)
{
	dummy_info_t *item;

	upsdebugx(2, "entering setvar(%s, %s)", varname, val);

	/* FIXME: the below is only valid if (mode == MODE_DUMMY)
	 * if (mode == MODE_REPEATER) => forward
	 * if (mode == MODE_META) => ?
	 */
	if (!strncmp(varname, "ups.status", 10))
	{
		status_init();
		 /* FIXME: split and check values (support multiple values), à la usbhid-ups */
		status_set(val);
		status_commit();

		return STAT_SET_HANDLED;
	}

	/* Check variable validity */
	if (!is_valid_data(varname))
	{
		upsdebugx(2, "setvar: invalid variable name (%s)", varname);
		return STAT_SET_UNKNOWN;
	}

	/* Check value validity */
	if (!is_valid_value(varname, val))
	{
		upsdebugx(2, "setvar: invalid value (%s) for variable (%s)", val, varname);
		return STAT_SET_UNKNOWN;
	}

	/* If value is empty, remove the variable (FIXME: do we need
	 * a magic word?) */
	if (strlen(val) == 0)
	{
		dstate_delinfo(varname);
	}
	else
	{
		dstate_setinfo(varname, "%s", val);

		if ( (item = find_info(varname)) != NULL)
		{
			dstate_setflags(item->info_type, item->info_flags);

			/* Set max length for strings, if needed */
			if (item->info_flags & ST_FLAG_STRING)
				dstate_setaux(item->info_type, item->info_len);
		}
	}
	return STAT_SET_HANDLED;
}
Пример #4
0
void upsdrv_updateinfo(void)
{
	char	reply[REPLY_PACKETSIZE];
	int	ret, online, battery_normal;

	if (!udev) {
		ret = usb_device_open(&udev, &usbdevice, &device_matcher, &driver_callback);

		if (ret < 0) {
			return;
		}
	}

	ret = query_ups(reply);

	if (ret < 4) {
		usb_comm_fail("Query to UPS failed");
		dstate_datastale();

		usb_device_close(udev);
		udev = NULL;

		return;
	}

	usb_comm_good();
	dstate_dataok();

	/*
	 * 3rd bit of 4th byte indicates whether the UPS is on line (1)
	 * or on battery (0)
	 */
	online = (reply[3]&4)>>2;

	/*
	 * 2nd bit of 4th byte indicates battery status; normal (1)
	 * or low (0)
	 */
	battery_normal = (reply[3]&2)>>1;

	status_init();

	if (online) {
	    status_set("OL");
	} else {
	    status_set("OB");
	}

	if (!battery_normal) {
	    status_set("LB");
	}

	status_commit();
}
Пример #5
0
void upsdrv_updateinfo(void)
{
	int r;
	int x,i=0,j,k,value;
	float value1;
	char ch;
	char data[10];
	int data_position = 4;
	
	test_EOL();
	
    	x= ser_get_buf_len(upsfd,buf, 64, SER_WAIT_SEC,SER_WAIT_USEC);
	printf("reading status is %d\n",x);
	printf("the reading data is %s\n",buf);

	ser_comm_good();
	r = test_CMD();
	if(r != TRUE){
	  printf("command error\n");
	  return;
	}
	i = data_position;
	for(j =0;j< _countof(pacefield);j++)
	{
	   
		 for(k=0;k<pacefield[j].len;k++)
		 {
			data[k] = buf[i+k];
			
		
		 }
		 data[k] = '\0';
		 printf("the reading data is %s\n",data);
		 value = atoi(data);
		 value1 = (float)value/pacefield[j].divident;
		 printf("value 1 = %f\n",value1);
		 dstate_setinfo(pacefield[j].name, "%0.2f",value1);
		 i = i+pacefield[j].len;
	    
	}
	status_init();
	update_err_status();
	update_charge_source_status();
	update_inverter_status();
	update_battery_status();
	update_load_status();
	update_battery_charge_dchrg_status();
	status_commit();
	dstate_dataok();
  
	
}
Пример #6
0
void update_pseudovars( void )
{
	
	status_init();
	
	if(strcmp(sec_varlist[9].value,"1")== 0) {
	status_set("OFF");
	}
	if(strcmp(sec_varlist[76].value,"0")== 0) {
	status_set("OL");
	}
	if(strcmp(sec_varlist[76].value,"1")== 0) {
	status_set("OB");
	}
	if(strcmp(sec_varlist[76].value,"2")== 0) {
	status_set("BYPASS");
	}
	if(strcmp(sec_varlist[76].value,"3")== 0) {
	status_set("TRIM");
	}
	if(strcmp(sec_varlist[76].value,"4")== 0) {
	status_set("BOOST");
	}
	if(strcmp(sec_varlist[10].value,"1")== 0) {
	status_set("OVER");
	}
	if(strcmp(sec_varlist[22].value,"1")== 0) {
	status_set("LB");
	}
	
	if(strcmp(sec_varlist[19].value,"2")== 0) {
	status_set("RB");
	}
	
	status_commit();


}
Пример #7
0
void upsdrv_updateinfo(void)
{

        getupdateinfo(); /* new package for updates */

	dstate_setinfo("output.voltage", "%03.1f", OutVoltage);
	dstate_setinfo("input.voltage", "%03.1f", InVoltage);
	dstate_setinfo("battery.voltage", "%02.1f", BattVoltage);

	/* output and bypass tests */
	if( OutputOn )
	  dstate_setinfo("outlet.switchable", "%s", "yes");
	else
	  dstate_setinfo("outlet.switchable", "%s", "no");

	if( BypassOn )
	  dstate_setinfo("outlet.1.switchable", "%s", "yes");
	else
	  dstate_setinfo("outlet.1.switchable", "%s", "no");

	status_init();

	if (!SourceFail )
	  status_set("OL");		/* on line */
	else
	  status_set("OB");		/* on battery */
	
	if (Autonomy < 5 )
	  status_set("LB");		/* low battery */
	
	status_commit();
	dstate_setinfo("ups.temperature", "%2.2f", Temperature);
	dstate_setinfo("input.frequency", "%2.1f", InFreq);
	dstate_dataok();

}
Пример #8
0
void upsdrv_updateinfo(void)
{
	uint8_t getextendedOK;
	static int countlost = 0;
	int stat;

	upsdebugx(1, "countlost %d",countlost);

	if (countlost > 0){
		upsdebugx(1, "Communication with UPS is lost: status read failed!");

		if (countlost == COUNTLOST) {
			dstate_datastale();
			upslogx(LOG_WARNING, "Communication with UPS is lost: status read failed!");
		}
	}

	if (typeRielloProtocol == DEV_RIELLOGPSER) 
		stat = get_ups_status();
	else
		stat = get_ups_sentr();

	if (stat < 0) {
		if (countlost < COUNTLOST)
			countlost++;
		return;
	}

	if (typeRielloProtocol == DEV_RIELLOGPSER) {
		if (get_ups_extended() == 0)
			getextendedOK = 1;
		else
			getextendedOK = 0;
	}
	else
		getextendedOK = 1;

	if (countlost == COUNTLOST)
		upslogx(LOG_NOTICE, "Communication with UPS is re-established!");

	dstate_setinfo("input.frequency", "%.2f", DevData.Finp/10.0);
	dstate_setinfo("input.bypass.frequency", "%.2f", DevData.Fbypass/10.0);
	dstate_setinfo("output.frequency", "%.2f", DevData.Fout/10.0);
	dstate_setinfo("battery.voltage", "%.1f", DevData.Ubat/10.0);
	dstate_setinfo("battery.charge", "%u", DevData.BatCap);
	dstate_setinfo("battery.runtime", "%u", DevData.BatTime*60);
	dstate_setinfo("ups.temperature", "%u", DevData.Tsystem);

	if (input_monophase) {
		dstate_setinfo("input.voltage", "%u", DevData.Uinp1);
		dstate_setinfo("input.bypass.voltage", "%u", DevData.Ubypass1);
	}
	else {
		dstate_setinfo("input.L1-N.voltage", "%u", DevData.Uinp1);
		dstate_setinfo("input.L2-N.voltage", "%u", DevData.Uinp2);
		dstate_setinfo("input.L3-N.voltage", "%u", DevData.Uinp3);
		dstate_setinfo("input.bypass.L1-N.voltage", "%u", DevData.Ubypass1);
		dstate_setinfo("input.bypass.L2-N.voltage", "%u", DevData.Ubypass2);
		dstate_setinfo("input.bypass.L3-N.voltage", "%u", DevData.Ubypass3);
	}

	if (output_monophase) {
		dstate_setinfo("output.voltage", "%u", DevData.Uout1);
		dstate_setinfo("output.power.percent", "%u", DevData.Pout1);
		dstate_setinfo("ups.load", "%u", DevData.Pout1);
	}
	else {
		dstate_setinfo("output.L1-N.voltage", "%u", DevData.Uout1);
		dstate_setinfo("output.L2-N.voltage", "%u", DevData.Uout2);
		dstate_setinfo("output.L3-N.voltage", "%u", DevData.Uout3);
		dstate_setinfo("output.L1.power.percent", "%u", DevData.Pout1);
		dstate_setinfo("output.L2.power.percent", "%u", DevData.Pout2);
		dstate_setinfo("output.L3.power.percent", "%u", DevData.Pout3);
		dstate_setinfo("ups.load", "%u", (DevData.Pout1+DevData.Pout2+DevData.Pout3)/3);
	}

	status_init();
	
	/* AC Fail */
	if (riello_test_bit(&DevData.StatusCode[0], 1))
		status_set("OB");
	else
		status_set("OL");

	/* LowBatt */
	if ((riello_test_bit(&DevData.StatusCode[0], 1)) &&
		(riello_test_bit(&DevData.StatusCode[0], 0)))
		status_set("LB");

	/* Standby */
	if (!riello_test_bit(&DevData.StatusCode[0], 3))
		status_set("OFF");

	/* On Bypass */
	if (riello_test_bit(&DevData.StatusCode[1], 3))
		status_set("BYPASS");

	/* Overload */
	if (riello_test_bit(&DevData.StatusCode[4], 2))
		status_set("OVER");

	/* Buck */
	if (riello_test_bit(&DevData.StatusCode[1], 0))
		status_set("TRIM");

	/* Boost */
	if (riello_test_bit(&DevData.StatusCode[1], 1))
		status_set("BOOST");

	/* Replace battery */
	if (riello_test_bit(&DevData.StatusCode[2], 0))
		status_set("RB");

	/* Charging battery */
	if (riello_test_bit(&DevData.StatusCode[2], 2))
		status_set("CHRG");

	status_commit();

	dstate_dataok();

	if (getextendedOK) {
		dstate_setinfo("output.L1.power", "%u", DevData.Pout1VA);
		dstate_setinfo("output.L2.power", "%u", DevData.Pout2VA);
		dstate_setinfo("output.L3.power", "%u", DevData.Pout3VA);
		dstate_setinfo("output.L1.realpower", "%u", DevData.Pout1W);
		dstate_setinfo("output.L2.realpower", "%u", DevData.Pout2W);
		dstate_setinfo("output.L3.realpower", "%u", DevData.Pout3W);
		dstate_setinfo("output.L1.current", "%u", DevData.Iout1);
		dstate_setinfo("output.L2.current", "%u", DevData.Iout2);
		dstate_setinfo("output.L3.current", "%u", DevData.Iout3);
	}

	poll_interval = 2;

	countlost = 0;
/*	if (get_ups_statuscode() != 0)
		upsdebugx(2, "Communication is lost");
	else {
	}*/

	/*
	 * poll_interval = 2;
	 */
}
Пример #9
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;
}
Пример #10
0
/* normal idle loop - keep up with the current state of the UPS */
void upsdrv_updateinfo(void)
{
	unsigned char	c;
	unsigned int	ob, lb;
	static	unsigned int	ob_state = 0, ob_last = 0, ob_ctr = 0;
	static	unsigned int	lb_state = 0, lb_last = 0, lb_ctr = 0;

	ob = lb = 0;

	/* the UPS connects RX to TX when on battery, so test for loopback */

	ser_flush_in(upsfd, "", 0);

	c = ML_ONBATTERY;
	ser_send_char(upsfd, c);
	if (ser_get_char(upsfd, &c, 1, 0) == 1) {
		while (ser_get_char(upsfd, &c, 1, 0) == 1)
			continue;
		if (c == ML_ONBATTERY)
			ob = 1;
	}
	
	if (ser_get_dcd(upsfd))
		lb = 1;

	/* state machine below to ensure status changes are debounced */

	/* OB/OL state change: reset counter */
	if (ob_last != ob)
		ob_ctr = 0;
	else
		ob_ctr++;

	upsdebugx(2, "OB: state %d last %d now %d ctr %d",
		ob_state, ob_last, ob, ob_ctr);

	if (ob_ctr >= DEBOUNCE) {

		if (ob != ob_state) {

			upsdebugx(2, "OB: toggling state");

			if (ob_state == 0)
				ob_state = 1;
			else
				ob_state = 0;
		}
	}

	ob_last = ob;

	/* now do it again for LB */

	/* state change: reset counter */
	if (lb_last != lb)
		lb_ctr = 0;
	else
		lb_ctr++;

	upsdebugx(2, "LB: state %d last %d now %d ctr %d",
		lb_state, lb_last, lb, lb_ctr);

	if (lb_ctr >= DEBOUNCE) {

		if (lb != lb_state) {

			upsdebugx(2, "LB: toggling state");

			if (lb_state == 0)
				lb_state = 1;
			else
				lb_state = 0;
		}
	}

	lb_last = lb;

	status_init();

	if (ob_state == 1)
		status_set("OB");	/* on battery */
	else
		status_set("OL");	/* on line */

	if (lb_state == 1)
		status_set("LB");	/* low battery */

	status_commit();
	dstate_dataok();
}
Пример #11
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();
}
Пример #12
0
void upsdrv_updateinfo(void)
{
	static int CommTry = COMM_TRIES;		/* Comm loss counter */
	char buffer[256];	/* Main response buffer */
	char buffer2[32];	/* Conversion buffer */
	char s;
	int RetValue;
	int timevalue;

	/* Start with EG/ON information */
	ser_flush_in(upsfd,"",0);  /*just in case*/
	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 != 0) && (CommTry == 0))
	{
		ser_comm_fail("Oneac UPS Comm failure continues on port %s",
																device_path);
	}	
	else if (RetValue != 0)
	{
		if (--CommTry == 0)
		{
			ser_comm_fail("Oneac UPS Comm failure on port %s",device_path);
			dstate_datastale();
		}
		upsdebugx(2,"Oneac: Update serial comm retry value: %d", CommTry);

		return;
	}
	else
	{
		CommTry = COMM_TRIES;			/* Reset serial retries */

		s = buffer[12];

		status_init();
		alarm_init();

		/*take care of the UPS status information*/
		if (s == '@')
		{
			status_set("OL");
		}
		else
		{
			if (s & 0x01)			/* On Battery */
			{
				status_set("OB");
			}
			else
			{
				status_set("OL");
			}
			
			if (s & 0x02)			/* Low Battery */
				status_set("LB");
			
			if (s & 0x04)			/* General fault */
			{
				dstate_setinfo("ups.test.result","UPS Internal Failure");
			}
			else
			{
				dstate_setinfo("ups.test.result","Normal");
			}

			if (s & 0x08)			/* Replace Battery */
				status_set("RB");

/*			if (s & 0x10)	*/		/* High Line */

			if (s & 0x20)			/* Unit is hot */
				alarm_set("OVERHEAT");
		}

		/*take care of the reason why the UPS last transferred to battery*/
		switch (buffer[13]) {
			case XFER_BLACKOUT :
				dstate_setinfo("input.transfer.reason",	"Blackout");
				break;
			case XFER_LOW_VOLT :
				dstate_setinfo("input.transfer.reason",
					"Low Input Voltage");
				break;
			case XFER_HI_VOLT :
				dstate_setinfo("input.transfer.reason",
					"High Input Voltage");
				break;
			case NO_VALUE_YET :
				dstate_setinfo("input.transfer.reason", 
					"No transfer yet.");
				break;
			default :
				upslogx(LOG_INFO,"Oneac: Unknown reason for UPS battery"
										" transfer [%c]", buffer[13]);
		}

		/* now update info for only the non-EG families of UPS*/

		if (strncmp(UpsFamily, FAMILY_EG, FAMILY_SIZE) != 0)
		{
			dstate_setinfo("ups.load", "0%.2s",buffer+31);

			/* Output ON or OFF? */
			if(buffer[27] == NO_VALUE_YET)
				status_set("OFF");

			/*battery charge*/
			if(buffer[10] == YES)
				dstate_setinfo("battery.charge", "0%.2s",buffer+33);
			else 
				dstate_setinfo("battery.charge", "100");

			EliminateLeadingZeroes (buffer+35, 3, buffer2, sizeof(buffer2));
			dstate_setinfo("input.voltage", "%s",buffer2);

			EliminateLeadingZeroes (buffer+38, 3, buffer2, sizeof(buffer2));
			dstate_setinfo("input.voltage.minimum", "%s",buffer2);

			EliminateLeadingZeroes (buffer+41, 3, buffer2, sizeof(buffer2));
			dstate_setinfo("input.voltage.maximum", "%s",buffer2);

			EliminateLeadingZeroes (buffer+44, 3, buffer2, sizeof(buffer2));
			dstate_setinfo("output.voltage", "%s",buffer2);

			if (buffer[15] == NO_VALUE_YET)
			{
				dstate_delinfo("ups.timer.shutdown");
			}
			else
			{
				/* A shutdown is underway! */
				status_set("FSD");
				
				if(buffer[15] != HIGH_COUNT)
				{
					EliminateLeadingZeroes (buffer+15, 3, buffer2, 
															sizeof(buffer2));
					dstate_setinfo("ups.timer.shutdown", "%s", buffer2);
				}
				else
				{
					dstate_setinfo("ups.timer.shutdown", "999");
				}
			}

			if (buffer[47] == YES) 
				status_set("BOOST");
		}

		/* Now update info for only the OZ/OB families of UPS */

		if ((strncmp(UpsFamily, FAMILY_OZ, FAMILY_SIZE) == 0) ||
			(strncmp(UpsFamily, FAMILY_OB, FAMILY_SIZE) == 0)) 
		{
			ser_flush_in(upsfd,"",0);  /*just in case*/
			ser_send (upsfd,"%c%s",GETX_ALL_1,COMMAND_END);
			RetValue = OneacGetResponse (buffer, sizeof(buffer), 
														GETX_ALL1_RESP_SIZE);

			if(RetValue)
			{
				if (--CommTry == 0)
				{
					ser_comm_fail("Oneac (OZ) UPS Comm failure on port %s",
																device_path);
					dstate_datastale();
				}

				upsdebugx(2,"Oneac: "
					"Update (OZ) serial comm retry value: %d", CommTry);
			}
			else
			{
				CommTry = COMM_TRIES;		/* Reset count */

				EliminateLeadingZeroes (buffer+57, 5, buffer2, sizeof(buffer2));
				dstate_setinfo("ups.realpower", "%s",buffer2);

				dstate_setinfo("input.frequency", "%.2s.%c",
														buffer+42,buffer[44]);
				dstate_setinfo("output.frequency", "%.2s.%c",
														buffer+76, buffer[78]);

				EliminateLeadingZeroes (buffer+29, 3, buffer2, sizeof(buffer2));
				dstate_setinfo("battery.voltage", "%s.%c",buffer2, buffer[32]);

				dstate_setinfo("ups.temperature", "%.2s",buffer+13);
				dstate_setinfo("ups.load", "%.3s",buffer+73);

				strncpy(buffer2, buffer+19, 4);
				buffer2[4]='\0';
				timevalue = atoi(buffer2) * 60;		/* Change mins to secs */
				dstate_setinfo("battery.runtime", "%d",timevalue);

				/* Now some individual requests... */

				/* Battery replace date */
				ser_send (upsfd,"%c%s",GETX_BATT_REPLACED,COMMAND_END);
				if(!OneacGetResponse (buffer, sizeof(buffer), 
														GETX_DATE_RESP_SIZE))
					dstate_setinfo("battery.date", "%.6s (yymmdd)", buffer);

				/* Low and high output trip points */
				ser_send (upsfd,"%c%s",GETX_LOW_OUT_ALLOW,COMMAND_END);
				if(!OneacGetResponse (buffer, sizeof(buffer), 
														GETX_ALLOW_RESP_SIZE))
				{
					EliminateLeadingZeroes (buffer, 3, buffer2,sizeof(buffer2));
					dstate_setinfo("input.transfer.low", "%s", buffer2);
				}

				ser_send (upsfd,"%c%s",GETX_HI_OUT_ALLOW,COMMAND_END);
				if(!OneacGetResponse (buffer, sizeof(buffer), 
														GETX_ALLOW_RESP_SIZE))
					dstate_setinfo("input.transfer.high", "%s", buffer);

				/* Restart delay */
				ser_send (upsfd,"%c%s",GETX_RESTART_DLY,COMMAND_END);
				if(!OneacGetResponse (buffer, sizeof(buffer), 
														GETX_RSTRT_RESP_SIZE))
				{
					EliminateLeadingZeroes (buffer, 4, buffer2, 
															sizeof(buffer2));
					dstate_setinfo("ups.delay.start", "%s", buffer2);
				}

				/* Buzzer state */
				ser_send (upsfd,"%s%s",GETX_BUZZER_WHAT,COMMAND_END);
				if(!OneacGetResponse (buffer, sizeof(buffer), 1))
				{
					switch (buffer[0]) 
					{
						case BUZZER_ENABLED :
							dstate_setinfo("ups.beeper.status",	"enabled");
							break;
						case BUZZER_DISABLED :
							dstate_setinfo("ups.beeper.status",	"disabled");
							break;
						case BUZZER_MUTED :
							dstate_setinfo("ups.beeper.status",	"muted");
							break;
						default :
							dstate_setinfo("ups.beeper.status",	"enabled");
					}
				}

				/* Auto start setting */
				ser_send (upsfd,"%s%s",GETX_AUTO_START,COMMAND_END);
				if(!OneacGetResponse (buffer, sizeof(buffer), 1))
				{
					if (buffer[0] == '0')
						dstate_setinfo("ups.start.auto", "yes");
					else
						dstate_setinfo("ups.start.auto", "no");
				}

				/* Low Batt at time */
				ser_send (upsfd,"%c%s",GETX_LOW_BATT_TIME,COMMAND_END);
				if(!OneacGetResponse (buffer, sizeof(buffer), 2))
				{
					strncpy(buffer2, buffer, 2);
					buffer2[2]='\0';
					timevalue = atoi(buffer2) * 60;		/* Mins to secs */
					dstate_setinfo("battery.runtime.low", "%d",timevalue);
				}

				/* Shutdown timer */
				ser_send (upsfd,"%c%s",GETX_SHUTDOWN,COMMAND_END);
				if(!OneacGetResponse (buffer, sizeof(buffer), 
													GETX_SHUTDOWN_RESP_SIZE))
				{
					/* ON would have handled NO_VALUE_YET and setting FSD 
					 *  above so only deal with counter value here.
					 */
					if (buffer[0] != NO_VALUE_YET)
					{
						EliminateLeadingZeroes (buffer, 5, buffer2, 
															sizeof(buffer2));
						dstate_setinfo("ups.timer.shutdown", "%s", buffer2);
					}
				}

				/* Restart timer */
				ser_send (upsfd,"%s%s",GETX_RESTART_COUNT,COMMAND_END);
				if(!OneacGetResponse (buffer, sizeof(buffer), 
														GETX_RSTRT_RESP_SIZE))
				{
					if (atoi(buffer) == 0)
					{
						dstate_delinfo("ups.timer.start");
					}
					else
					{
						EliminateLeadingZeroes (buffer, 4, buffer2, 
															sizeof(buffer2));
						dstate_setinfo("ups.timer.start", "%s", buffer2);
					}
				}
			}
		}

		alarm_commit();
		status_commit();

		/* If the comm retry counter is zero then datastale has been set.
		 *  We don't want to set dataok or ser_comm_good if that is the case.
		 */

		if (CommTry != 0)
		{
			dstate_dataok();
			ser_comm_good();
		}
	}
}
Пример #13
0
void upsdrv_updateinfo(void)
{
  char fstring[512];

  if (! fc.valid) {
    fprintf(stderr, 
	    "upsupdate run before ups_ident() read ups config\n");
    assert(0);
  }

  if (execute("f\r", fstring, sizeof(fstring)) > 0) {
    int inverter=0, charger=0, vin=0, vout=0, btimeleft=0, linestat=0, 
      alstat=0, vaout=0;
    double ampsout=0.0, vbatt=0.0, battpercent=0.0, loadpercent=0.0,
      hstemp=0.0, acfreq=0.0, ambtemp=0.0;
    char tmp[16];

    /* Inverter status.  0=off 1=on */
    memcpy(tmp, fstring+16, 2);
    tmp[2] = '\0';
    inverter = atoi(tmp);

    /* Charger status.  0=off 1=on */
    memcpy(tmp, fstring+18, 2);
    tmp[2] = '\0';
    charger = atoi(tmp);
    
    /* Input Voltage. integer number */
    memcpy(tmp, fstring+24, 4);
    tmp[4] = '\0';
    vin = atoi(tmp);

    /* Output Voltage. integer number */
    memcpy(tmp, fstring+28, 4);
    tmp[4] = '\0';
    vout = atoi(tmp);

    /* Iout.  int times 10 */
    memcpy(tmp, fstring+36, 4);
    tmp[4] = '\0';
    ampsout = ((double)(atoi(tmp)) / 10.0);

    /* Battery voltage.  int times 10 */
    memcpy(tmp, fstring+50, 4);
    tmp[4] = '\0';
    vbatt = ((double)(atoi(tmp)) / 10.0);

    /* Volt-amps out.  int  */
    memcpy(tmp, fstring+40, 6);
    tmp[6] = '\0';
    vaout = atoi(tmp);

    /* Line status.  Bitmask */
    memcpy(tmp, fstring+72, 2);
    tmp[2] = '\0';
    linestat = atoi(tmp);

    /* Alarm status reg 1.  Bitmask */
    memcpy(tmp, fstring+20, 2);
    tmp[2] = '\0';
    alstat = atoi(tmp);

    /* Alarm status reg 2.  Bitmask */
    memcpy(tmp, fstring+22, 2);
    tmp[2] = '\0';
    alstat = alstat | (atoi(tmp) << 8);

    /* AC line frequency */
    memcpy(tmp, fstring+54, 4);
    tmp[4]= '\0';
    acfreq = ((double)(atoi(tmp)) / 100.0);

    /* Runtime remaining */
    memcpy(tmp, fstring+58, 4);
    tmp[4]= '\0';
    btimeleft = atoi(tmp);

    /* UPS Temperature */
    memcpy(tmp, fstring+62, 4);
    tmp[4]= '\0';
    ambtemp = (double)(atoi(tmp));

    /* Percent Load */
    switch(fc.model) {
      case ME3100:
        if (execute("d 16\r", fstring, sizeof(fstring)) > 0) {
          int l;
          sscanf(fstring, "16 FullLoad%% %d", &l);
          loadpercent = (double) l;
        }
	break;
      case RE1800:
        if (execute("d 16\r", fstring, sizeof(fstring)) > 0) {
          int l;
          sscanf(fstring, "16 FullLoad%% %d", &l);
          loadpercent = (double) l;
        }
        if (execute("d 12\r", fstring, sizeof(fstring)) > 0) {
          int l;
          sscanf(fstring, "12 HS Temp  %dC", &l);
          hstemp = (double) l;
        }
        break;
      case MD1KVA:
        if (execute("d 22\r", fstring, sizeof(fstring)) > 0) {
          int l;
          sscanf(fstring, "22 FullLoad%% %d", &l);
          loadpercent = (double) l;
        }
	break;
      default: /* Will never happen, caught in upsdrv_initups() */
        fatalx(EXIT_FAILURE, "Unknown model in upsdrv_updateinfo()");
    }
    /* Compute battery percent left based on battery voltages. */
    battpercent = ((vbatt - fc.emptyvolts) 
		   / (fc.fullvolts - fc.emptyvolts) * 100.0);
    if (battpercent < 0.0) 
      battpercent = 0.0;
    else if (battpercent > 100.0)
      battpercent = 100.0;
    
    /* Compute status string */
    {
	int lowbatt, overload, replacebatt, boosting, trimming;

	lowbatt = alstat & (1<<1);
	overload = alstat & (1<<6);
	replacebatt = alstat & (1<<10);
	boosting = inverter && (linestat & (1<<2)) && (vin < 115);
	trimming = inverter && (linestat & (1<<2)) && (vin > 115);

	status_init();
      
	if (inverter) 
		status_set("OB");
	else
		status_set("OL");

	if (lowbatt)
		status_set("LB");

	if (trimming)
		status_set("TRIM");

	if (boosting)
		status_set("BOOST");

	if (replacebatt)
		status_set("RB");

	if (overload)
		status_set("OVER");

	status_commit();
    }

    if (debugging) {
      fprintf(stderr,
	      "Poll: inverter %d charger %d vin %d vout %d vaout %d btimeleft %d\n",
	      inverter, charger, vin, vout, vaout, btimeleft);
      fprintf(stderr,
	      "      ampsout %5.1f vbatt %5.1f batpcnt %5.1f loadpcnt %5.1f upstemp %5.1f acfreq %5.2f ambtemp %5.1f\n",
	      ampsout, vbatt, battpercent, loadpercent, hstemp, acfreq, ambtemp);

    }

    /* Stuff information into info structures */

    dstate_setinfo("input.voltage", "%05.1f", (double)vin);
    dstate_setinfo("output.voltage", "%05.1f", (double)vout);
    dstate_setinfo("battery.charge", "%02.1f", battpercent);
    dstate_setinfo("ups.load", "%02.1f", loadpercent);
    dstate_setinfo("battery.voltage", "%02.1f", vbatt);
    dstate_setinfo("input.frequency", "%05.2f", (double)acfreq);
    dstate_setinfo("ups.temperature", "%05.1f", (double)hstemp);
    dstate_setinfo("battery.runtime", "%d", btimeleft);
    dstate_setinfo("ambient.temperature", "%05.1f", (double)ambtemp);

    dstate_dataok();
    /* Tim: With out this return, it always falls over to the
        datastate() at the end of the function */
    return;
  } else {

    dstate_datastale();  

  } /* if (execute("f\r", fstring, sizeof(fstring)) > 0) */

  dstate_datastale();
  return;
}
Пример #14
0
void upsdrv_updateinfo(void)
{
	char response[MAX_RESPONSE_LENGTH];
	char *ptr, *ptr2;
	int i;
	int flags;
	int contacts_set;
	int low_battery;

	status_init();
	if (do_command(POLL, STATUS_OUTPUT, "", response) <= 0) {
		dstate_datastale();
		return;
	}
	ptr = field(response, 0);
	/* require output status field to exist */
	if (!ptr) {
		dstate_datastale();
		return;
	}
	switch (atoi(ptr)) {
	case 0:
		status_set("OL");
		break;
	case 1:
		status_set("OB");
		break;
	case 2:
		status_set("BYPASS");
		break;
	case 3:
		status_set("OL");
		status_set("TRIM");
		break;
	case 4:
		status_set("OL");
		status_set("BOOST");
		break;
	case 5:
		status_set("BYPASS");
		break;
	case 6:
		break;
	case 7:
		status_set("OFF");
		break;
	default:
		break;
	}
	ptr = field(response, 6);
	if (ptr)
		dstate_setinfo("ups.load", "%d", atoi(ptr));
	ptr = field(response, 3);
	if (ptr)
		dstate_setinfo("output.voltage", "%03.1f",
		               (double) atoi(ptr) / 10.0);
	ptr = field(response, 1);
	if (ptr)
		dstate_setinfo("output.frequency", "%03.1f",
		               (double) atoi(ptr) / 10.0);
	ptr = field(response, 4);
	if (ptr)
		dstate_setinfo("output.current", "%03.1f",
		               (double) atoi(ptr) / 10.0);

	low_battery = 0;
	if (do_command(POLL, STATUS_BATTERY, "", response) <= 0) {
		dstate_datastale();
		return;
	}
	ptr = field(response, 0);
	if (ptr && atoi(ptr) == 2)
		status_set("RB");
	ptr = field(response, 1);
	if (ptr && atoi(ptr))
		low_battery = 1;
	ptr = field(response, 8);
	if (ptr)
		dstate_setinfo("battery.temperature", "%d", atoi(ptr));
	ptr = field(response, 9);
	if (ptr) {
		dstate_setinfo("battery.charge", "%d", atoi(ptr));
		ptr2 = getval("lowbatt");
		if (ptr2 && atoi(ptr2) > 0 && atoi(ptr2) <= 99 &&
		    atoi(ptr) <= atoi(ptr2))
			low_battery = 1;
	}
	ptr = field(response, 6);
	if (ptr)
		dstate_setinfo("battery.voltage", "%03.1f",
		               (double) atoi(ptr) / 10.0);
	ptr = field(response, 7);
	if (ptr)
		dstate_setinfo("battery.current", "%03.1f",
		               (double) atoi(ptr) / 10.0);
	if (low_battery)
		status_set("LB");

	if (do_command(POLL, STATUS_ALARM, "", response) <= 0) {
		dstate_datastale();
		return;
	}
	ptr = field(response, 3);
	if (ptr && atoi(ptr))
		status_set("OVER");

	if (do_command(POLL, STATUS_INPUT, "", response) > 0) {
		ptr = field(response, 2);
		if (ptr)
			dstate_setinfo("input.voltage", "%03.1f",
			               (double) atoi(ptr) / 10.0);
		ptr = field(response, 1);
		if (ptr)
			dstate_setinfo("input.frequency",
				       "%03.1f", (double) atoi(ptr) / 10.0);
	}

	if (do_command(POLL, TEST_RESULT, "", response) > 0) {
		int	r;
		size_t	trsize;

		r = atoi(response);
		trsize = sizeof(test_result_names) / 
			sizeof(test_result_names[0]);

		if ((r < 0) || (r >= (int) trsize))
			r = 0;

		dstate_setinfo("ups.test.result", "%s", test_result_names[r]);
	}

	if (do_command(POLL, ENVIRONMENT_INFORMATION, "", response) > 0) {
		ptr = field(response, 0);
		if (ptr)
			dstate_setinfo("ambient.temperature", "%d", atoi(ptr));
		ptr = field(response, 1);
		if (ptr)
			dstate_setinfo("ambient.humidity", "%d", atoi(ptr));
		flags = 0;
		contacts_set = 0;
		for (i = 0; i < 4; i++) {
			ptr = field(response, 2 + i);
			if (ptr) {
				contacts_set = 1;
				if (*ptr == '1')
					flags |= 1 << i;
			}
		}
		if (contacts_set)
			dstate_setinfo("ups.contacts", "%02X", flags);
	}

	/* if we are here, status is valid */
	status_commit();
	dstate_dataok();
}
Пример #15
0
void upsdrv_updateinfo(void)
{
	CFPropertyListRef power_dictionary;
	CFStringRef power_source_state;
	CFNumberRef battery_voltage, battery_runtime;
	CFNumberRef current_capacity;
	CFBooleanRef is_charging;
	double max_capacity_value = 100.0, current_capacity_value;

	upsdebugx(1, "upsdrv_updateinfo()");

	power_dictionary = copy_power_dictionary( g_power_key );
	assert(power_dictionary); /* TODO: call dstate_datastale()? */

	status_init();

	/* Retrieve OL/OB state */
	power_source_state = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSPowerSourceStateKey));
	assert(power_source_state);
	CFRetain(power_source_state);

	upsdebugx(3, "Power Source State:");
	if(nut_debug_level >= 3) CFShow(power_source_state);

	if(!CFStringCompare(power_source_state, CFSTR(kIOPSACPowerValue), 0)) {
		status_set("OL");
	} else {
		status_set("OB");
	}

	CFRelease(power_source_state);

	/* Retrieve CHRG state */
	is_charging = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSIsChargingKey));
        if(is_charging) {
		Boolean is_charging_value;

		is_charging_value = CFBooleanGetValue(is_charging);
		if(is_charging_value) {
			status_set("CHRG");
		}
	}

	status_commit();

	/* Retrieve battery voltage */

	battery_voltage = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSVoltageKey));
	if(battery_voltage) {
		int battery_voltage_value;

		CFNumberGetValue(battery_voltage, kCFNumberIntType, &battery_voltage_value);
		upsdebugx(2, "battery_voltage = %d mV", battery_voltage_value);
		dstate_setinfo("battery.voltage", "%.3f", battery_voltage_value/1000.0);
	}

	/* Retrieve battery runtime */
	battery_runtime = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSTimeToEmptyKey));
	if(battery_runtime) {
		double battery_runtime_value;

		CFNumberGetValue(battery_runtime, kCFNumberDoubleType, &battery_runtime_value);

		upsdebugx(2, "battery_runtime = %.f minutes", battery_runtime_value);
		if(battery_runtime_value > 0) {
			dstate_setinfo("battery.runtime", "%d", (int)(battery_runtime_value*60));
		} else {
			dstate_delinfo("battery.runtime");
		}
	} else {
		dstate_delinfo("battery.runtime");
	}

	/* Retrieve current capacity */
	current_capacity = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSCurrentCapacityKey));
	if(current_capacity) {
		CFNumberGetValue(current_capacity, kCFNumberDoubleType, &current_capacity_value);

		upsdebugx(2, "Current Capacity = %.f/%.f units", current_capacity_value, max_capacity_value);
		if(max_capacity_value > 0) {
			dstate_setinfo("battery.charge", "%.f", 100.0 * current_capacity_value / max_capacity_value);
		}
	}

	/* TODO: it should be possible to set poll_interval (and maxage in the
	 * server) to an absurdly large value, and use notify(3) to get
	 * updates.
         */

	/*
	 * poll_interval = 2;
	 */

	dstate_dataok();
	CFRelease(power_dictionary);
}
Пример #16
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();
}
Пример #17
0
void upsdrv_updateinfo(void)
{
	int res, int_num;
#ifdef EXTRADATA
	int day, hour, minute;
#endif
	float float_num;
	long int long_num;
	unsigned char my_answer[255];
	
	/* GET Output data */
	res = command_read_sequence(UPS_OUTPUT_DATA, my_answer);
	if (res < 0) {
		printf("Could not communicate with the ups");
		dstate_datastale();
	} else {
		/* Active power */
		int_num = get_word(&my_answer[1]);
		if (nominal_power != 0) {
			float_num = (float)((int_num * 100)/nominal_power);
			dstate_setinfo("ups.load", "%2.1f", float_num);
		} else {
			dstate_setinfo("ups.load", "%s", "not available");
		}	
#ifdef EXTRADATA
		dstate_setinfo("output.power", "%d", int_num);
#endif
		/* voltage */
		int_num = get_word(&my_answer[3]);
		if (int_num > 0) dstate_setinfo("output.voltage", "%d", int_num);
		if (int_num == -1) dstate_setinfo("output.voltage", "%s", "overrange");
		if (int_num == -2) dstate_setinfo("output.voltage", "%s", "not available");
		/* current */
		float_num = get_word(&my_answer[5]);
		if (float_num == -1) dstate_setinfo("output.current", "%s", "overrange");
		if (float_num == -2) dstate_setinfo("output.current", "%s", "not available");
		if (float_num > 0) {
			float_num = (float)(float_num/10);
			dstate_setinfo("output.current", "%2.2f", float_num);
		}
#ifdef EXTRADATA
		/* peak current */
		float_num = get_word(&my_answer[7]);
		if (float_num == -1) dstate_setinfo("output.current.peak", "%s", "overrange");
		if (float_num == -2) dstate_setinfo("output.current.peak", "%s", "not available");
		if (float_num > 0) {
			float_num = (float)(float_num/10);
			dstate_setinfo("output.current.peak", "%2.2f", float_num);
		}
		
#endif
	}
		
	/* GET Input data */
	res = command_read_sequence(UPS_INPUT_DATA, my_answer);
	if (res < 0){
		printf("Could not communicate with the ups");
		dstate_datastale();
	} else {
#ifdef EXTRADATA
		/* Active power */
		int_num = get_word(&my_answer[1]);
		if (int_num > 0) dstate_setinfo("input.power", "%d", int_num);
		if (int_num == -1) dstate_setinfo("input.power", "%s", "overrange");
		if (int_num == -2) dstate_setinfo("input.power", "%s", "not available");
#endif
		/* voltage */
		int_num = get_word(&my_answer[3]);
		if (int_num > 0) dstate_setinfo("input.voltage", "%d", int_num);
		if (int_num == -1) dstate_setinfo("input.voltage", "%s", "overrange");
		if (int_num == -2) dstate_setinfo("input.voltage", "%s", "not available");
#ifdef EXTRADATA
		/* current */
		float_num = get_word(&my_answer[5]);
		if (float_num == -1) dstate_setinfo("input.current", "%s", "overrange");
		if (float_num == -2) dstate_setinfo("input.current", "%s", "not available");
		if (float_num > 0) {
			float_num = (float)(float_num/10);
			dstate_setinfo("input.current", "%2.2f", float_num);
		}
		/* peak current */
		float_num = get_word(&my_answer[7]);
		if (float_num == -1) dstate_setinfo("input.current.peak", "%s", "overrange");
		if (float_num == -2) dstate_setinfo("input.current.peak", "%s", "not available");
		if (float_num > 0) {
			float_num = (float)(float_num/10);
			dstate_setinfo("input.current.peak", "%2.2f", float_num);
		}
#endif
	}
	
	
	/* GET Battery data */
	res = command_read_sequence(UPS_BATTERY_DATA, my_answer);
	if (res < 0) {
		printf("Could not communicate with the ups");
		dstate_datastale();
	} else {
		/* Actual value */
		float_num = get_word(&my_answer[1]);
		float_num = (float)(float_num/10);
		dstate_setinfo("battery.voltage", "%2.2f", float_num);
#ifdef EXTRADATA
		/* reserve threshold */
		float_num = get_word(&my_answer[3]);
		float_num = (float)(float_num/10);
		dstate_setinfo("battery.voltage.low", "%2.2f", float_num);
		/* exhaust threshold */
		float_num = get_word(&my_answer[5]);
		float_num = (float)(float_num/10);
		dstate_setinfo("battery.voltage.exhaust", "%2.2f", float_num);
#endif
	}
	
#ifdef EXTRADATA
	/* GET history data */
	res = command_read_sequence(UPS_HISTORY_DATA, my_answer);
	if (res < 0) {
		printf("Could not communicate with the ups");
		dstate_datastale();
	} else {
		/* ups total runtime */
		long_num = get_long(&my_answer[1]);
		day = (int)(long_num / 86400);
		long_num -= (long)(day*86400);
		hour = (int)(long_num / 3600);
		long_num -= (long)(hour*3600);
		minute = (int)(long_num / 60);
		long_num -= (minute*60);
		dstate_setinfo("ups.total.runtime", "%d days %dh %dm %lds", day, hour, minute, long_num);
		
		/* ups inverter runtime */
		long_num = get_long(&my_answer[5]);
		day = (int)(long_num / 86400);
		long_num -= (long)(day*86400);
		hour = (int)(long_num / 3600);
		long_num -= (long)(hour*3600);
		minute = (int)(long_num / 60);
		long_num -= (minute*60);
		dstate_setinfo("ups.inverter.runtime", "%d days %dh %dm %lds", day, hour, minute, long_num);
		/* ups inverter interventions */
		dstate_setinfo("ups.inverter.interventions", "%d", get_word(&my_answer[9]));
		/* battery full discharges */
		dstate_setinfo("battery.full.discharges", "%d", get_word(&my_answer[11]));
		/* ups bypass / stabilizer interventions */
		int_num = get_word(&my_answer[13]);
		if (int_num == -2) dstate_setinfo("ups.bypass.interventions", "%s", "not avaliable");
		if (int_num >= 0) dstate_setinfo("ups.bypass.interventions", "%d", int_num);
		/* ups overheatings */
		int_num = get_word(&my_answer[15]);
		if (int_num == -2) dstate_setinfo("ups.overheatings", "%s", "not avalilable");
		if (int_num >= 0) dstate_setinfo("ups.overheatings", "%d", int_num);
	}
#endif
	
	/* GET times on battery */
	res = command_read_sequence(UPS_GET_TIMES_ON_BATTERY, my_answer);
	if (res < 0) {
		printf("Could not communicate with the ups");
		dstate_datastale();
	} else {
		autorestart = my_answer[5];
	}
	
	
	/* GET schedule */
	res = command_read_sequence(UPS_GET_SCHEDULING, my_answer);
	if (res < 0) {
		printf("Could not communicate with the ups");
		dstate_datastale();
	} else {
		/* time remaining to shutdown */
		long_num = get_long(&my_answer[1]);
		if (long_num == -1) {
			dstate_setinfo("ups.delay.shutdown", "%d", 120);	
		} else {
			dstate_setinfo("ups.delay.shutdown", "%ld", long_num);
		}
		/* time remaining to restart  */
		long_num = get_long(&my_answer[5]);
		if (long_num == -1) {
			dstate_setinfo("ups.delay.start", "%d", 0);	
		} else {
			dstate_setinfo("ups.delay.start", "%ld", long_num);
		}	
	}
	
	
	/* GET ups status */
	res = command_read_sequence(UPS_STATUS, my_answer);
	if (res < 0) {
		printf("Could not communicate with the ups");
		dstate_datastale();
	} else {
		/* ups temperature */
		my_answer[3] -=128;
		if (my_answer[3] > 0) {
			dstate_setinfo("ups.temperature", "%d", my_answer[3]);
		} else {
			dstate_setinfo("ups.temperature", "%s", "not available");
		}	
		/* Status */
		status_init();
		switch (my_answer[1]) {	/* byte 1 = STATUS */
			case 0x00:
				status_set("OL"); /* running on mains power */
				break;
			case 0x01:
				status_set("OB"); /* running on battery power */
				break;
			case 0x02:
				status_set("LB"); /* battery reserve */
				break;
			case 0x03:			/* bypass engaged */
			case 0x04:			/* manual bypass engaged */
				status_set("BY");
				break;
			default:
				printf("status unknown \n");
				break;
		} 
		switch (my_answer[2]) {		/* byte 2 = FAULTS */
			case 0x00:				/* all right */
				break;
			case 0x01:				/* overload */
				status_set("OVER");
				break;
			case 0x02:				/* overheat */
				break;
			case 0x03:				/* hardware fault */
				break;
			case 0x04:				/* battery charger failure (overcharging) */
				break;
			case 0x05:				/* replace batteries */
				status_set("RB");
				break;
			default:
				printf("status unknown \n");
				break;
		}
		status_commit();
		dstate_dataok();
	}
	return;
}
Пример #18
0
/* for dummy mode
 * parse the definition file and process its content
 */ 
static int parse_data_file(int upsfd)
{
	char	fn[SMALLBUF];
	char	*ptr, var_value[MAX_STRING_SIZE];
	int		value_args = 0, counter;
	time_t	now;

	time(&now);

	upsdebugx(1, "entering parse_data_file()");

	if (now < next_update)
	{
		upsdebugx(1, "leaving (paused)...");
		return 1;
	}

	/* initialise everything, to loop back at the beginning of the file */
	if (ctx == NULL)
	{
		ctx = (PCONF_CTX_t *)xmalloc(sizeof(PCONF_CTX_t));

		if (device_path[0] == '/')
			snprintf(fn, sizeof(fn), "%s", device_path);
		else
			snprintf(fn, sizeof(fn), "%s/%s", confpath(), device_path);

		pconf_init(ctx, upsconf_err);

		if (!pconf_file_begin(ctx, fn))
			fatalx(EXIT_FAILURE, "Can't open dummy-ups definition file %s: %s",
				fn, ctx->errmsg);
	}

	/* Reset the next call time, so that we can loop back on the file
	 * if there is no blocking action (ie TIMER) until the end of the file */
	next_update = -1;

	/* Now start or continue parsing... */
	while (pconf_file_next(ctx))
	{
		if (pconf_parse_error(ctx))
		{
			upsdebugx(2, "Parse error: %s:%d: %s",
				fn, ctx->linenum, ctx->errmsg);
			continue;
		}

		/* Check if we have something to process */
		if (ctx->numargs < 1)
			continue;

		/* Process actions (only "TIMER" ATM) */
		if (!strncmp(ctx->arglist[0], "TIMER", 5))
		{
			/* TIMER <seconds> will wait "seconds" before
			 * continuing the parsing */
			int delay = atoi (ctx->arglist[1]);
			time(&next_update);
			next_update += delay;
			upsdebugx(1, "suspending execution for %i seconds...", delay);
			break;
		}

		/* Remove ":" suffix, after the variable name */
		if ((ptr = strchr(ctx->arglist[0], ':')) != NULL)
			*ptr = '\0';

		upsdebugx(3, "parse_data_file: variable \"%s\" with %d args",
			ctx->arglist[0], (int)ctx->numargs);

		/* Skip the driver.* collection data */
		if (!strncmp(ctx->arglist[0], "driver.", 7))
		{
			upsdebugx(2, "parse_data_file: skipping %s", ctx->arglist[0]);
			continue;
		}

		/* From there, we get varname in arg[0], and values in other arg[1...x] */
		/* special handler for status */
		if (!strncmp( ctx->arglist[0], "ups.status", 10))
		{
			status_init();
			for (counter = 1, value_args = ctx->numargs ;
				counter < value_args ; counter++)
			{
				status_set(ctx->arglist[counter]);
			}
			status_commit();
		}
		else
		{
			for (counter = 1, value_args = ctx->numargs ;
				counter < value_args ; counter++)
			{
				if (counter == 1) /* don't append the first space separator */
					snprintf(var_value, sizeof(var_value), "%s", ctx->arglist[counter]);
				else
					snprintfcat(var_value, sizeof(var_value), " %s", ctx->arglist[counter]);
			}

			if (setvar(ctx->arglist[0], var_value) == STAT_SET_UNKNOWN)
			{
				upsdebugx(2, "parse_data_file: can't add \"%s\" with value \"%s\"\nError: %s",
					ctx->arglist[0], var_value, ctx->errmsg);
			}
			else
			{ 
				upsdebugx(3, "parse_data_file: added \"%s\" with value \"%s\"",
					ctx->arglist[0], var_value);
			}
		}
	}

	/* Cleanup parseconf if there is no pending action */
	if (next_update == -1)
	{
		pconf_finish(ctx);
		free(ctx);
		ctx=NULL;
	}
	return 1;
}
Пример #19
0
void upsdrv_updateinfo(void)
{
	int	ret, errors = 0;

	/* We really should be dealing with alarms through a separate callback, so that we can keep the
	 * processing of alarms and polling for data separated. Currently, this isn't supported by the
	 * driver main body, so we'll have to revert to polling each time we're called, unless the
	 * socket indicates we're no longer connected.
	 */
	if (testvar("subscribe")) {
		char	buf[LARGEBUF];

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

		if (ret > 0) {
			/* alarm message received */

			ne_xml_parser	*parser = ne_xml_create();
			upsdebugx(2, "%s: ne_sock_read(%d bytes) => %s", __func__, ret, buf);
			ne_xml_push_handler(parser, subdriver->startelm_cb, subdriver->cdata_cb, subdriver->endelm_cb, NULL);
			ne_xml_parse(parser, buf, strlen(buf));
			ne_xml_destroy(parser);
			time(&lastheard);

		} else if ((ret == NE_SOCK_TIMEOUT) && (difftime(time(NULL), lastheard) < 180)) {
			/* timed out */

			upsdebugx(2, "%s: ne_sock_read(timeout)", __func__);

		} else {
			/* connection closed or unknown error */

			upslogx(LOG_ERR, "NSM connection with '%s' lost", uri.host);

			upsdebugx(2, "%s: ne_sock_read(%d) => %s", __func__, ret, ne_sock_error(sock));
			ne_sock_close(sock);

			if (netxml_alarm_subscribe(subdriver->subscribe) == NE_OK) {
				extrafd = ne_sock_fd(sock);
				time(&lastheard);
				return;
			}

			dstate_datastale();
			extrafd = -1;
			return;
		}
	}

	/* get additional data */
	ret = netxml_get_page(subdriver->getobject);
	if (ret != NE_OK) {
		errors++;
	}

	ret = netxml_get_page(subdriver->summary);
	if (ret != NE_OK) {
		errors++;
	}

	if (errors > 1) {
		dstate_datastale();
		return;
	}

	status_init();

	alarm_init();
	netxml_alarm_set();
	alarm_commit();

	netxml_status_set();
	status_commit();

	dstate_dataok();
}