Beispiel #1
0
/* get limits and parameters */
static int upsc_getparams(const char *cmd, const simple_t *table)
{
	char var[UPSC_BUFLEN];
	char val[UPSC_BUFLEN];
	int first = 1;

	upsc_flush_input();

	upscsend(cmd);
	buffer_empty = 0;
	while (!buffer_empty) {
		upscrecv(var);
		if (strlen(var) == 0) {
			if (first)
				upscrecv(var);
			if (strlen(var) == 0) {
				ser_comm_fail("Empty string from UPS for %s!",
					cmd);
				break;
			}
		}
		first = 0;
		upscrecv(val);
		if (strlen(val) == 0) {
			ser_comm_fail("Empty value from UPS for %s %s!", cmd, var);
			break;
		}
		upsdebugx(2, "Parameter %s %s", var, val);
		if (!upsc_simple(table, var, val))
			upslogx(LOG_ERR, "Unknown response to %s: %s %s",
				cmd, var, val);
	}
	return buffer_empty;
}
Beispiel #2
0
/* Sends a setup command (length > 1) */
int command_write_sequence(unsigned char *command, int command_length, unsigned	char *answer)
{
	int	bytes_read;

	bytes_read = command_sequence(command, command_length, answer);

	if (bytes_read < 1) {
		ser_comm_fail("Error executing command");
	}

	return bytes_read;
}
Beispiel #3
0
/* Sends a single command (length=1). and get the answer */
int command_read_sequence(unsigned char command, unsigned char *answer)
{
	int	bytes_read;

	bytes_read = command_sequence(&command, 1, answer);

	if (bytes_read < 1) {
		ser_comm_fail("Error executing command");
	}

	return bytes_read;
}
Beispiel #4
0
/* 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;
}
Beispiel #5
0
/* 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;
}
Beispiel #6
0
void upsdrv_updateinfo(void)
{
	static int	retry = 0;

	if (subdriver[mode]->updateinfo() < 0) {
		ser_comm_fail("Status read failed!");

		if (retry < 3) {
			retry++;
		} else {
			dstate_datastale();
		}

		return;
	}

	retry = 0;

	ser_comm_good();

	dstate_dataok();
}
Beispiel #7
0
/* get the answer of a command from the ups */
int get_answer(unsigned char *data) {
	unsigned char my_buf[255];	/* packet has a maximum length of 256 bytes */
	int packet_length, checksum, i, res;
	/* Read STX byte */
	res = ser_get_char(upsfd, my_buf, 1, 0);
	if (res < 1) {
		ser_comm_fail("Receive error (STX): %d!!!\n", res);
		return -1;	
	}
	if (my_buf[0] != 0x02) {
		ser_comm_fail("Receive error (STX): packet not on start!!\n");
		return -1;	
	}
	/* Read data length byte */
	res = ser_get_char(upsfd, my_buf, 1, 0);
	if (res < 1) {
		ser_comm_fail("Receive error (length): %d!!!\n", res);
		return -1;	
	}
	packet_length = my_buf[0];
	if (packet_length < 2) {
		ser_comm_fail("Receive error (length): packet length %d!!!\n", packet_length);
		return -1;	
	}
	/* Try to read all the remainig bytes (packet_length) */
	res = ser_get_buf_len(upsfd, my_buf, packet_length, 1, 0);
	if (res != packet_length) {
		ser_comm_fail("Receive error (data): got %d bytes instead of %d!!!\n", res, packet_length);
		return -1;	
	}

	/* now we have the whole answer from the ups, we can checksum it 
	   checksum byte is equal to the sum modulus 256 of all the data bytes + packet_length
	   (no STX no checksum byte itself) */
	checksum = packet_length;
	for (i = 0; i < (packet_length - 1); i++) checksum += my_buf[i];  
	checksum = checksum % 256;
	if (my_buf[packet_length-1] != checksum) {
		ser_comm_fail("checksum error! got %x instad of %x, received %d bytes \n", my_buf[packet_length - 1], checksum, packet_length);
		dump_buffer(my_buf, packet_length);
		return -1;
	}
	packet_length-=1;		/* get rid of the checksum byte */
	memcpy(data, my_buf, packet_length);
	return packet_length;
}
Beispiel #8
0
/* get the answer of a command from the ups. And check that the answer is for this command */
int get_answer(unsigned char *data, unsigned char command)
{
	unsigned char	my_buf[128];	/* packet has a maximum length of 121+5 bytes */
	int		length, end_length = 0, res, endblock = 0, start = 0;
	unsigned char	block_number, sequence, pre_sequence = 0;

	while (endblock != 1){

		do {
			/* Read PW_COMMAND_START_BYTE byte */
			res = ser_get_char(upsfd, my_buf, 1, 0);

			if (res != 1) {
				upsdebugx(1,"Receive error (PW_COMMAND_START_BYTE): %d, cmd=%x!!!\n", res, command);
				return -1;
			}

			start++;

		} while ((my_buf[0] != PW_COMMAND_START_BYTE) && (start < 128));
		
		if (start == 128) {
			ser_comm_fail("Receive error (PW_COMMAND_START_BYTE): packet not on start!!%x\n", my_buf[0]);
			return -1;
		}

		/* Read block number byte */
		res = ser_get_char(upsfd, my_buf+1, 1, 0);

		if (res != 1) {
			ser_comm_fail("Receive error (Block number): %d!!!\n", res);
			return -1;
		}

		block_number = (unsigned char)my_buf[1];

		if (command <= 0x43) {
			if ((command - 0x30) != block_number){
				ser_comm_fail("Receive error (Request command): %x!!!\n", block_number);
				return -1;
			}
		}

		if (command >= 0x89) {
			if ((command == 0xA0) && (block_number != 0x01)){
				ser_comm_fail("Receive error (Requested only mode command): %x!!!\n", block_number);
				return -1;
			}

			if ((command != 0xA0) && (block_number != 0x09)){
				ser_comm_fail("Receive error (Control command): %x!!!\n", block_number);
				return -1;
			}
		}

		/* Read data length byte */
		res = ser_get_char(upsfd, my_buf+2, 1, 0);

		if (res != 1) {
			ser_comm_fail("Receive error (length): %d!!!\n", res);
			return -1;
		}

		length = (unsigned char)my_buf[2];

		if (length < 1) {
			ser_comm_fail("Receive error (length): packet length %x!!!\n", length);
			return -1;
		}

		/* Read sequence byte */
		res = ser_get_char(upsfd, my_buf+3, 1, 0);

		if (res != 1) {
			ser_comm_fail("Receive error (sequence): %d!!!\n", res);
			return -1;
		}

		sequence = (unsigned char)my_buf[3];

		if ((sequence & 0x80) == 0x80) {
			endblock = 1;
		}

		if ((sequence & 0x07) != (pre_sequence + 1)) {
			ser_comm_fail("Not the right sequence received %x!!!\n", sequence);
			return -1;
		}

		pre_sequence = sequence;

		/* Try to read all the remainig bytes */
		res = ser_get_buf_len(upsfd, my_buf+4, length, 1, 0);

		if (res != length) {
			ser_comm_fail("Receive error (data): got %d bytes instead of %d!!!\n", res, length);
			return -1;
		}

		/* Get the checksum byte */
		res = ser_get_char(upsfd, my_buf+(4+length), 1, 0);

		if (res != 1) {
			ser_comm_fail("Receive error (checksum): %x!!!\n", res);
			return -1;
		}

		/* now we have the whole answer from the ups, we can checksum it */
		if (!checksum_test(my_buf)) {
			ser_comm_fail("checksum error! ");
			return -1;
		}

		memcpy(data+end_length, my_buf+4, length);
		end_length += length;

	}

	upsdebug_hex (5, "get_answer", data, end_length);
	ser_comm_good();

	return end_length;
}
Beispiel #9
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();
		}
	}
}