示例#1
0
文件: upscode2.c 项目: alicaccs/nut
static void upsc_flush_input(void)
{
/*
	char buf[UPSC_BUFLEN];

	do {
		upscrecv(buf);
		if (strlen(buf) > 0)
			upsdebugx(1, "Skipping input: %s", buf);
	} while (strlen(buf) > 0);
*/
	ser_flush_in(upsfd, "", nut_debug_level);
}
示例#2
0
文件: metasys.c 项目: sbutler/nut
/* send a write command and try get the answer, if something fails, it retries (5 times max)
   if it is on the 4th or 5th retry, it will flush the serial before sending commands
   it returns the length of the received answer or -1 in case of failure */
int command_write_sequence(unsigned char *command, int command_length, unsigned char *answer) {
	int bytes_read = 0;
	int retry = 0;
	
	while ((bytes_read < 1) && (retry < 5)) {
		send_write_command(command, command_length);
		bytes_read = get_answer(answer);
		if (retry > 2) ser_flush_in(upsfd, "", 0);
		retry += 1;
	}
	if ((answer[0] != command[0]) || (retry == 5)) {
		ser_comm_fail("Error executing command N.%d\n", command[0]);
		dstate_datastale();
		return -1;
	}
	ser_comm_good();
	return bytes_read;
}
示例#3
0
文件: metasys.c 项目: sbutler/nut
/* send a read command and try get the answer, if something fails, it retries (5 times max)
   if it is on the 4th or 5th retry, it will flush the serial before sending commands
   it returns the length of the received answer or -1 in case of failure */
int command_read_sequence(unsigned char command, unsigned char *data) {
	int bytes_read = 0;
	int retry = 0;

	while ((bytes_read < 1) && (retry < 5)) {
		send_read_command(command);
		bytes_read = get_answer(data);
		if (retry > 2) ser_flush_in(upsfd, "", 0);
		retry += 1;
	}
	if ((data[0] != command) || (retry == 5)) {
		ser_comm_fail("Error executing command %d\n", command);
		dstate_datastale();
		return -1;
	}
	ser_comm_good();
	return bytes_read;
}
示例#4
0
文件: microdowell.c 项目: AlexLov/nut
void SendCmdToSerial(unsigned char *Buff, int Len)
{
	int i;
	unsigned char Tmp[20], Xor ;

	Tmp[0] = STX_CHAR ;
	Xor = Tmp[1] = (unsigned char) (Len & 0x1f) ;
	for (i=0 ; i < Tmp[1] ; i++)
	{
		Tmp[i+2] = Buff[i] ;
		Xor ^= Buff[i] ;
	}
	Tmp[Len+2] = Xor ;

	upsdebug_hex(4, "->UPS", Tmp, Len+3) ;

	/* flush serial port */
	ser_flush_in(upsfd, "", 0) ; /* empty input buffer */
	ser_send_buf(upsfd, Tmp, Len+3) ; /* send data to the UPS */
}
示例#5
0
static int command_sequence(unsigned char *command, int command_length, unsigned char *answer)
{
	int	bytes_read, retry = 0;

	while (retry++ < PW_MAX_TRY) {

		if (retry == PW_MAX_TRY) {
			ser_flush_in(upsfd, "", 0);
		}

		send_write_command(command, command_length);

		bytes_read = get_answer(answer, *command);

		if (bytes_read > 0) {
			return bytes_read;
		}
	}

	return -1;
}
示例#6
0
文件: oneac.c 项目: sbutler/nut
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();
		}
	}
}
示例#7
0
文件: oneac.c 项目: 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:
					;

			}
		}
	}
}
示例#8
0
文件: liebert.c 项目: AlexLov/nut
/* 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();
}
示例#9
0
文件: rhino.c 项目: AlexLov/nut
static void
CommReceive(const unsigned char *bufptr,  int size)
{

  int i, i_end, CheckSum, chk;
  
  if(  ( size==37 ) )
    Waiting = 0;
  
  printf("CommReceive size = %d waiting = %d\n", size, Waiting );

  switch( Waiting )
    {
      /* normal package */
    case 0:
      {
	if(  size == 37 )
	  {
	    i_end = 37;
	    for( i = 0 ; i < i_end ; ++i )
	      {
		RecPack[i] = *bufptr;
		bufptr++;
	      }
	    
	    /* CheckSum verify */
	    CheckSum = 0;
	    i_end = 36;
	    for( i = 0 ; i < i_end ; ++i )
	      {
		chk =  RecPack[ i ];
		CheckSum = CheckSum + chk;
	      }

	    CheckSum = CheckSum % 256;

	    ser_flush_in(upsfd,"",0); /* clean port */

	    /* correct package */
	    if(  ( RecPack[0] == 0xC0 || RecPack[0] == 0xC1 || RecPack[0] == 0xC2 || RecPack[0] == 0xC3 )
		  && ( RecPack[ 36 ] == CheckSum ) )
	       {

		 if(!(detected))
		   {
		     RhinoModel = RecPack[0];
		     detected = true;
		   }

		 switch( RhinoModel )
		   {
		   case 0xC0:
		   case 0xC1:
		   case 0xC2:
		   case 0xC3:
		     {
		       ScanReceivePack();
		       break;
		     }
		   default:
		     {
		       printf( M_UNKN );
		       break;
		     }
		   }
	       }

           }
	
	 break;
       }
       
     case 1:
       {
	 /* dumping package, nothing to do yet */
	 Waiting = 0;
	 break;
       }

    }

   Waiting =0;

}