Переглянути джерело

1)rewrite megatec protocol
2)add support Voltronic UPS

balbekova 6 роки тому
батько
коміт
9c766b384b
2 змінених файлів з 340 додано та 40 видалено
  1. 323 38
      modules/MegaTec/megatec.c
  2. 17 2
      modules/MegaTec/megatec.h

+ 323 - 38
modules/MegaTec/megatec.c

@@ -33,6 +33,7 @@ uint16_t TimeParam = 0;
 uint16_t TimeParam2 = 0;
 bool megatec_send = true;
 UPS_value_t UPS;
+uint8_t type_ups = ups_kestar;
 
 enum {
 	NORMAL = 0x00,
@@ -63,7 +64,15 @@ const char* MegaTecCMD[] =
 		"CT\r",
 		"I\r",
 		"F\r",
-		"Q2\r"
+		"Q2\r",
+		"QGS\r",
+		"QBV\r",
+		"QMD\r",
+		"QVFW\r",
+		"QID\r",
+		"QPI\r",
+		"QS\r",
+		"M\r",
 };
 
 extern bool flUpdateLog;
@@ -137,7 +146,7 @@ bool ups_megatec_rx_pdu(void)
 	ups_pdu.len = 0;
 
 	while ((ups_pdu.len < UPS_PDU_MAX_LEN) && (c != 0x0d)) {
-		c = ups_getchar(500);//portMAX_DELAY
+		c = ups_getchar(100);//portMAX_DELAY
 		if(c < 0)
 		{
 			ups_pdu.len = 0;
@@ -160,11 +169,11 @@ int8_t get_ups_param(char *buf, char *param, char *val)
 	char *endValue;
 	int8_t param_len;
 
-	memset(val, 0, 10);
+	memset(val, 0, 20);
 	endValue = strpbrk(buf, param);
 	if(endValue != NULL){
 		param_len = endValue - buf;
-		if(param_len < 10){
+		if(param_len < 16){
 			strncpy(val, buf, param_len);
 		}
 		else{
@@ -182,7 +191,7 @@ int8_t get_ups_param(char *buf, char *param, char *val)
 void ups_status_response(char *data)
 {
 	uint8_t i;
-	char value[10];
+	char value[20];
 	float tmp;
 	uint8_t len = 0;
 	DBG printf("ups_status_response: %s\r\n", data);
@@ -234,15 +243,17 @@ void ups_status_response(char *data)
 	//TODO
 	len = get_ups_param(data, " ", value);
 	data += (len + 1);
-	if(len > 0){
-		//UPS.SOC = round(100*(((atof(value))/6) - 1.85)/0.4166666667); // 1.85 - минимальное напряжение на ячейки АКБ; 2.266666667 - максимальное напряжение на ячейки АКБ; (2.266666667 - 1.85) = 0.4166666667
-		//UPS.SOC = round(100*((atof(value)) - 1.67)/0.58); // 1.667 - минимальное напряжение на ячейки АКБ; 2.267 - максимальное напряжение на ячейки АКБ; (2.267 - 1.667) = 0.6
-		tmp = atof(value);
-		if(tmp < 10){
-			UPS.SOC = round(100*(tmp - sSettings.UPS_Setting.Ucellmin)/(sSettings.UPS_Setting.Ucellmax - sSettings.UPS_Setting.Ucellmin));
-		}
-		else{
-			UPS.SOC = round(100*(tmp/6 - sSettings.UPS_Setting.Ucellmin)/(sSettings.UPS_Setting.Ucellmax - sSettings.UPS_Setting.Ucellmin));
+	if(type_ups == ups_kestar){
+		if(len > 0){
+			//UPS.SOC = round(100*(((atof(value))/6) - 1.85)/0.4166666667); // 1.85 - минимальное напряжение на ячейки АКБ; 2.266666667 - максимальное напряжение на ячейки АКБ; (2.266666667 - 1.85) = 0.4166666667
+			//UPS.SOC = round(100*((atof(value)) - 1.67)/0.58); // 1.667 - минимальное напряжение на ячейки АКБ; 2.267 - максимальное напряжение на ячейки АКБ; (2.267 - 1.667) = 0.6
+			tmp = atof(value);
+			if(tmp < 10){
+				UPS.SOC = round(100*(tmp - sSettings.UPS_Setting.Ucellmin)/(sSettings.UPS_Setting.Ucellmax - sSettings.UPS_Setting.Ucellmin));
+			}
+			else{
+				UPS.SOC = round(100*(tmp/6 - sSettings.UPS_Setting.Ucellmin)/(sSettings.UPS_Setting.Ucellmax - sSettings.UPS_Setting.Ucellmin));
+			}
 		}
 	}
 	len = get_ups_param(data, " ", value);
@@ -263,6 +274,88 @@ void ups_status_response(char *data)
 	}
 }
 
+void ups_general_status_response(char *data)
+{
+	uint8_t i;
+	char value[20];
+	float tmp;
+	uint8_t len = 0;
+	DBG printf("ups_status_response: %s\r\n", data);
+	if(data[0] != '(')
+		return;
+	DBG printf("ups_status_parser_start\r\n");
+	UPS.Present = true;
+	UPS.Flag_Present = true;
+	UPS.cnt_err_ups = 0;
+
+	if(flUpdateLog){
+		flUpdateLog = false;
+		log_add(data);
+	}
+
+	data++;
+
+	DBG printf("UPS ups_status_parser_startr: %s\r\n", data);
+
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+	if(len > 0){
+		tmp  =atof(value);
+		if(tmp > 20)
+			UPS.VAC_in = tmp;
+		else
+			UPS.VAC_in = 0;
+	}
+
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+	if(len > 0)
+		UPS.Freq_in = atof(value);
+
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+	if(len > 0)
+		UPS.VAC_out = atof(value);
+
+	//TODO
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+
+	//TODO
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+	if(len > 0)
+		UPS.Load = atoi(value);
+
+	//TODO
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+
+	//TODO
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+	if(len > 0)
+		UPS.Temp = atof(value);
+
+
+	len = get_ups_param(data, "\r", value);
+	data += (len + 1);
+	if(len > 0){
+		uint8_t stat = 0;
+		for(i = 2; i < (len - 2); i ++)
+		{
+			stat |= (value[i] - 0x30) << (7-i);
+		}
+		UPS.Status = stat;
+	}
+}
+
 void ups_info_response(char *data)
 {
 	uint8_t i = 0;
@@ -315,7 +408,7 @@ void ups_info_response(char *data)
 
 void ups_remain_time_response(char *data)
 {
-	char value[10];
+	char value[20];
 	if(data[0] != '(')
 		return;
 
@@ -338,11 +431,163 @@ void ups_remain_time_response(char *data)
 		UPS.work_time = 0;
 }
 
+void ups_akb_info_response(char *data)
+{
+	char value[20];
+	uint8_t len = 0;
+	DBG printf("ups_akb_info_response: %s\r\n", data);
+	if(data[0] != '(')
+		return;
+	DBG printf("ups_akb_info_parser_start\r\n");
+	UPS.Present = true;
+	UPS.Flag_Present = true;
+	UPS.cnt_err_ups = 0;
+
+	data++;
+
+	DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
+
+	//TODO
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+
+	//TODO
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+
+	//TODO
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+
+	len = get_ups_param(data, " ", value);
+	data += (len + 1);
+	if(len > 0)
+		UPS.SOC = atoi(value);
+
+	len = get_ups_param(data, "\r", value);
+	data += (len + 1);
+	if(len > 0)
+		UPS.work_time = atoi(value);
+}
+
+void ups_model_response(char *data)
+{
+	char value[20];
+	uint8_t len = 0;
+	uint8_t j = 0;
+	DBG printf("ups_akb_info_response: %s\r\n", data);
+	if(data[0] != '(')
+		return;
+	DBG printf("ups_akb_info_parser_start\r\n");
+	UPS.Present = true;
+	UPS.Flag_Present = true;
+	UPS.cnt_err_ups = 0;
+
+	data++;
+
+	DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
+
+	len = get_ups_param(data, " ", value);
+	if(UPS.model[0] == 0){
+		for(uint8_t i = 0; i < len; i ++){
+			if(value[i] != '#'){
+				UPS.model[j] = value[i];
+				j ++;
+			}
+		}
+		SNMP_SetObjDescr();
+	}
+	else{
+		j = 0;
+		for(uint8_t i = 0; i < len; i ++){
+			if(value[i] != '#'){
+				UPS.model[j] = value[i];
+				j ++;
+			}
+		}
+	}
+}
+
+void ups_version_response(char *data)
+{
+	char value[20];
+	uint8_t len = 0;
+	DBG printf("ups_akb_info_response: %s\r\n", data);
+	if(data[0] != '(')
+		return;
+	DBG printf("ups_akb_info_parser_start\r\n");
+	UPS.Present = true;
+	UPS.Flag_Present = true;
+	UPS.cnt_err_ups = 0;
+
+	data++;
+
+	DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
+
+	//TODO
+	len = get_ups_param(data, ".", value);
+	data += (len + 1);
+
+	len = get_ups_param(data, "\r", value);
+	if(UPS.vertion[0] == 0){
+		strncpy(UPS.vertion, value, 2);
+		SNMP_SetObjDescr();
+	}
+	else{
+		strncpy(UPS.vertion, value, len);
+	}
+}
+
+void ups_serial_response(char *data)
+{
+	char value[20];
+	uint8_t len = 0;
+	DBG printf("ups_serialresponse: %s\r\n", data);
+	if(data[0] != '(')
+		return;
+	DBG printf("ups_serial_parser_start\r\n");
+	UPS.Present = true;
+	UPS.Flag_Present = true;
+	UPS.cnt_err_ups = 0;
+
+	data++;
+
+	DBG printf("UPS ups_serial_parser_start: %s\r\n", data);
+
+	len = get_ups_param(data, "\r", value);
+	strncpy(UPS.serial, &value[9], 5);
+}
+
+void ups_protocol_id_response(char *data)
+{
+
+	DBG printf("ups_protocol_id_response: %s\r\n", data);
+
+	DBG printf("ups_protocol_id_parser_start\r\n");
+	UPS.Present = true;
+	UPS.Flag_Present = true;
+	UPS.cnt_err_ups = 0;
+
+	if(data[0] != '('){
+		if(strncmp(data, "NAK", 3) == 0){
+			type_ups = ups_kestar;
+		}
+		return;
+	}
+
+	data++;
+	type_ups = ups_voltronic;
+
+	DBG printf("UPS ups_protocol_id_parser_start: %s\r\n", data);
+
+}
+
 void ups_megatec_process_pdu(cmdMegaTecEnums_t command)
 {
 	switch(command)
 	{
 	case ups_status_req:
+	case ups_offline_status_req:
 		ups_status_response(ups_pdu.data);
 		break;
 	case ups_info:
@@ -354,6 +599,24 @@ void ups_megatec_process_pdu(cmdMegaTecEnums_t command)
 	case ups_remain_time_reg:
 		ups_remain_time_response(ups_pdu.data);
 		break;
+	case ups_general_status_req:
+			ups_general_status_response(ups_pdu.data);
+		break;
+	case ups_akb_info:
+		ups_akb_info_response(ups_pdu.data);
+		break;
+	case ups_model_req:
+		ups_model_response(ups_pdu.data);
+	break;
+	case ups_version_req:
+		ups_version_response(ups_pdu.data);
+		break;
+	case ups_serial_req:
+		ups_serial_response(ups_pdu.data);
+		break;
+	case ups_protocol_id_req:
+		ups_protocol_id_response(ups_pdu.data);
+		break;
 	default:
 		break;
 	}
@@ -366,17 +629,27 @@ int ups_metac_service_pdu(cmdMegaTecEnums_t command)
 		{
 			vTaskDelay(50);
 		}
+		memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
 		megatec_send = false;
 		send_MegaTec_cmd(command);
 		if (ups_megatec_rx_pdu())
 		{
 			megatec_send = true;
-			if(strncmp(ups_pdu.data, "ACK", 3) == 0)
-				return 1;
-			else if(strncmp(ups_pdu.data, "NAK", 3) == 0)
-				return 0;
+			if(type_ups == ups_kestar){
+				if(strncmp(ups_pdu.data, "ACK", 3) == 0)
+					return 1;
+				else if(strncmp(ups_pdu.data, "NAK", 3) == 0)
+					return 0;
+			}
+			else if(type_ups == ups_voltronic){
+				if(strncmp(ups_pdu.data, "(ACK", 4) == 0)
+					return 1;
+				else if(strncmp(ups_pdu.data, "(NAK", 4) == 0)
+					return 0;
+			}
 
 		}
+		megatec_send = true;
 	}
 	return -1;
 }
@@ -385,7 +658,10 @@ int ups_metac_service_pdu(cmdMegaTecEnums_t command)
 //void request_task(void)
 void request_task(void* params)
 {
-
+	uint8_t kestar_req[3] = {ups_status_req, ups_remain_time_reg, ups_info};
+	uint8_t voltronic_req[5] = {ups_status_req, ups_akb_info, ups_model_req, ups_version_req, ups_serial_req};
+	uint8_t num_req = 0;
+	uint8_t *req;
 		for(;;)
 		{
 			if(UPS.Present == true){
@@ -410,33 +686,42 @@ void request_task(void* params)
 					}
 				}
 			}
-			if(megatec_send){
-				megatec_send= false;
-				UPS.Flag_Present = false;
-				send_MegaTec_cmd(ups_status_req);
-				if (ups_megatec_rx_pdu())
-					ups_megatec_process_pdu(ups_status_req);
 
-				megatec_send=true;
-			}
 			if(megatec_send){
 				memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
 				megatec_send= false;
 				UPS.Flag_Present = false;
-				send_MegaTec_cmd(ups_remain_time_reg);
+				send_MegaTec_cmd(ups_protocol_id_req);
 				if (ups_megatec_rx_pdu())
-					ups_megatec_process_pdu(ups_remain_time_reg);
+					ups_megatec_process_pdu(ups_protocol_id_req);
 
 				megatec_send=true;
 			}
-			//vTaskDelay(100);
-			if(megatec_send){
-				megatec_send = false;
-				UPS.Flag_Present = false;
-				 send_MegaTec_cmd(ups_info);
-				if (ups_megatec_rx_pdu())
-					ups_megatec_process_pdu(ups_info);
-				megatec_send = true;
+
+			switch(type_ups){
+			case ups_kestar:
+				num_req = sizeof(kestar_req);
+				req = kestar_req;
+				break;
+			case ups_voltronic:
+				num_req = sizeof(voltronic_req);
+				req = voltronic_req;
+				break;
+			default:
+				break;
+			}
+
+			for(uint8_t i = 0; i < num_req; i++){
+				if(megatec_send){
+					memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
+					megatec_send= false;
+					UPS.Flag_Present = false;
+					send_MegaTec_cmd(req[i]);
+					if (ups_megatec_rx_pdu())
+						ups_megatec_process_pdu(req[i]);
+
+					megatec_send=true;
+				}
 			}
 
 	        vTaskDelay(1000);

+ 17 - 2
modules/MegaTec/megatec.h

@@ -12,6 +12,13 @@
 #include <stdint.h>
 #include <stdlib.h>
 
+typedef enum{
+	ups_kestar,
+	ups_voltronic,
+
+	type_ups_max
+} typeUPSEnums_t;
+
 typedef enum{
 	ups_status_req,
 	ups_test_10sec,
@@ -25,6 +32,14 @@ typedef enum{
 	ups_info,
 	ups_rating_info,
 	ups_remain_time_reg,
+	ups_general_status_req,
+	ups_akb_info,
+	ups_model_req,
+	ups_version_req,
+	ups_serial_req,
+	ups_protocol_id_req,
+	ups_offline_status_req,
+	ups_passw_req,
 
 	MegaTec_cmd_max
 } cmdMegaTecEnums_t;
@@ -39,8 +54,8 @@ typedef struct{
 	uint8_t work_time;
 	uint8_t Status;
 	uint8_t Alarm;
-	char model[11];
-	char vertion[3];
+	char model[16];
+	char vertion[5];
 	char serial[9];
 	uint8_t cnt_err_ups;
 	bool Present;