//---------------------------------------------------------------------
|
#include <QApplication>
|
#include <QDateTime>
|
#include <stdio.h> /*标准输入输出定义*/
|
#include <stdlib.h> /*标准函数库定义*/
|
#include <string.h>
|
#include <unistd.h> /*Unix 标准函数定义*/
|
#include <sys/types.h>
|
#include <sys/stat.h>
|
#include <fcntl.h> /*文件控制定义*/
|
#include <termios.h> /*PPSIX 终端控制定义*/
|
#include <errno.h> /*错误号定义*/
|
#include "slavepc.h"
|
#include "crc16.h"
|
#include "filemanage.h"
|
#include "classxml.h"
|
|
#define SYSCODE 0xAAAAAAAA
|
#define Version 12
|
|
#define ADJ_VOL 0
|
#define ADJ_DIS 1
|
#define ADJ_CHR 2
|
|
|
|
//#define EN_THREAD_WORK_DEBUG
|
#ifdef EN_THREAD_WORK_DEBUG
|
#define THREAD_WORK_DEBUG qDebug
|
#else
|
#define THREAD_WORK_DEBUG(...)
|
#endif
|
|
SlavePC::SlavePC(Working_Page *page)
|
{
|
work_page = page;
|
RUN_EN = false;
|
|
this->OpenDev(PCCommPort);
|
this->SetDevAttr(19200,8,1,'N');
|
|
connect(this,SIGNAL(SendInterface(int)),work_page->work_thread,SLOT(RecvInterface(int)));
|
connect(this,SIGNAL(sendParam(int)),work_page,SLOT(operatorCMD_Work(int)));
|
|
}
|
|
SlavePC::~SlavePC()
|
{
|
RUN_EN = false;
|
quit();
|
wait();
|
}
|
|
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
/**
|
*@brief 设置串口通信速率
|
*@param fd 类型 int 打开串口的文件句柄
|
*@param speed 类型 int 串口速度
|
*@return void
|
*/
|
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
static int speed_arr[] = { B115200, B57600, B38400, B19200, B9600};
|
static int name_arr[] = { 115200, 57600, 38400, 19200, 9600};
|
void SlavePC::set_speed(int fd, int speed)
|
{
|
int status;
|
struct termios Opt;
|
tcgetattr(fd, &Opt);
|
for ( unsigned int i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
|
{
|
if(speed == name_arr[i])
|
{
|
tcflush(fd, TCIOFLUSH);
|
cfsetispeed(&Opt, speed_arr[i]);
|
cfsetospeed(&Opt, speed_arr[i]);
|
status = tcsetattr(fd, TCSANOW, &Opt);
|
if(status != 0)
|
{
|
perror("tcsetattr fd1");
|
return;
|
}
|
tcflush(fd,TCIOFLUSH);
|
}
|
}
|
}
|
//---------------------------------------------------------------------
|
/**
|
*@brief 设置串口数据位,停止位和效验位
|
*@param fd 类型 int 打开的串口文件句柄
|
*@param databits 类型 int 数据位 取值 为 7 或者8
|
*@param stopbits 类型 int 停止位 取值为 1 或者2
|
*@param parity 类型 int 效验类型 取值为N,E,O,,S
|
*/
|
//---------------------------------------------------------------------
|
int SlavePC::set_Parity(int fd,int databits,int stopbits,int parity)
|
{
|
struct termios options;
|
if(tcgetattr(fd, &options) != 0)
|
{
|
perror("SetupSerial 1");
|
return(-1);
|
}
|
|
//--------------- 二进制传输模式 -------------------------
|
options.c_iflag = 0;
|
options.c_oflag = 0;
|
//------------------------------------------------------
|
|
options.c_cflag &= ~CSIZE;
|
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);/*Input*/
|
options.c_oflag &= ~OPOST;/*Output*/
|
switch (databits) /*设置数据位数*/
|
{
|
case 7:
|
options.c_cflag |= CS7;
|
break;
|
case 8:
|
options.c_cflag |= CS8;
|
break;
|
default:
|
fprintf(stderr,"Unsupported data size\n");
|
return (-1);
|
}
|
switch (parity)
|
{
|
case 'n':
|
case 'N':
|
options.c_cflag &= ~PARENB; /* Clear parity enable */
|
options.c_iflag &= ~INPCK; /* Enable parity checking */
|
break;
|
case 'o':
|
case 'O':
|
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
|
options.c_iflag |= INPCK; /* Disnable parity checking */
|
break;
|
case 'e':
|
case 'E':
|
options.c_cflag |= PARENB; /* Enable parity */
|
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
|
options.c_iflag |= INPCK; /* Disnable parity checking */
|
break;
|
case 'S':
|
case 's': /*as no parity*/
|
options.c_cflag &= ~PARENB;
|
options.c_cflag &= ~CSTOPB;
|
break;
|
default:
|
fprintf(stderr,"Unsupported parity\n");
|
return (-1);
|
}
|
/* 设置停止位*/
|
switch (stopbits)
|
{
|
case 1:
|
options.c_cflag &= ~CSTOPB;
|
break;
|
case 2:
|
options.c_cflag |= CSTOPB;
|
break;
|
default:
|
fprintf(stderr,"Unsupported stop bits\n");
|
return (-1);
|
}
|
/* Set input parity option */
|
if (parity != 'n')
|
options.c_iflag |= INPCK;
|
|
tcflush(fd, TCIFLUSH);
|
options.c_cc[VTIME] = 0; /* 0.1S */
|
options.c_cc[VMIN] = 0;
|
/* Update the options and do it NOW */
|
if (tcsetattr(fd,TCSANOW,&options) != 0)
|
{
|
perror("SetupSerial 3");
|
return (-1);
|
}
|
return (0);
|
}
|
//---------------------------------------------------------------------
|
int SlavePC::OpenDev(const char *Dev)
|
{
|
FD = open(Dev, O_RDWR|O_NOCTTY|O_NDELAY);
|
|
return FD;
|
}
|
//---------------------------------------------------------------------
|
void SlavePC::SetDevAttr(int bitrate, char bitlen,
|
char stopbitlen, char checktype)
|
{
|
if(FD < 0)
|
return;
|
|
set_speed(FD, bitrate);
|
|
if(set_Parity(FD, bitlen, stopbitlen, checktype) < 0)
|
{
|
qDebug("Set Parity Error\n");
|
}
|
|
if(fcntl(FD, F_SETFL, FNDELAY) < 0)//非阻塞,覆盖前面open的属性
|
{
|
qDebug("fcntl failed\n");
|
}
|
}
|
//---------------------------------------------------------------------
|
int SlavePC::WriteDev(void *buf, int len)
|
{
|
if(FD < 0)
|
return 0;
|
|
return write(FD, (char *)buf, len);
|
}
|
//---------------------------------------------------------------------
|
int SlavePC::ReadDev(void *buf, int len)
|
{
|
if(FD < 0)
|
return 0;
|
|
char *pbuff = (char *)buf;
|
return (read(FD, pbuff, len));
|
}
|
|
bool SlavePC::CheckLen(FRAME_DATA *recv)
|
{
|
if(recv->Len >= 18)
|
{
|
return true;
|
}
|
return false;
|
}
|
bool SlavePC::CheckSYNCode(FRAME_DATA *recv)
|
{
|
if(recv->SYNCode == SYSCODE)
|
{
|
return true;
|
}
|
return false;
|
}
|
bool SlavePC::CheckCRC(FRAME_DATA *recv)
|
{
|
unsigned short Temp = recv->CRC;
|
recv->CRC =0;
|
recv->CRC = CRC16::CalCRC16(recv,recv->Len);
|
if(recv->CRC == Temp)
|
{
|
return true;
|
}
|
return false;
|
}
|
bool SlavePC::WriteFrameData(FRAME_DATA *Sent)
|
{
|
if(Sent->Len == WriteDev(Sent,Sent->Len))
|
return true;
|
else
|
return false;
|
}
|
|
bool SlavePC::ReadFrameHead(FRAME_DATA *recv, FRAME_DATA *Sent)
|
{
|
if(ReadDev(recv,18)==18)
|
{
|
if(CheckSYNCode(recv) == true)
|
{
|
if(CheckLen(recv) == false)
|
{
|
Sent->RecState = LEN_ERR;
|
}
|
return true;
|
}
|
}
|
return false;
|
}
|
|
bool SlavePC::ReadFrameData(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
if(ReadFrameHead(&recv,&Sent) == true)
|
{
|
if(Sent.RecState == SUCCEED)
|
{
|
if(CheckCRC(&recv) == false)
|
{
|
Sent.RecState = CRC_ERR;
|
}
|
}
|
return true;
|
}
|
return false;
|
}
|
//----------------------------------------------------------------------------------
|
|
quint16 SlavePC::getMonData(quint8 *info,quint16 MonNum)
|
{
|
static quint8 cnt = 0;
|
static quint8 bak_state = 0;
|
MON_DATA mondata;
|
memset(&mondata,0,sizeof(MON_DATA));
|
for(int i=0;i<4;i++)
|
{
|
mondata.GroupVol[i] = work_page->work_thread->fboData.SumVoltage;
|
mondata.GroupCur[i] = work_page->work_thread->fboData.SubCurrent[i];
|
mondata.reserved[0] = work_page->work_thread->fboData.OnlineVol;
|
if(work_page->work_thread->DATAVERSION == 0x05)
|
mondata.reserved[3] = work_page->work_thread->DATAVERSION<<8;
|
if(work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Paused_Dischg)
|
{
|
bak_state = work_page->work_thread->localData.SysWorkState;
|
cnt = 5;
|
}
|
else
|
cnt = 0;
|
|
if((cnt > 0) && (work_page->work_thread->localData.SysWorkState == WorkStopped))
|
{
|
cnt--;
|
mondata.BattStatus[0] = bak_state + 0x80;
|
mondata.GroupCur[0] = 0;
|
}
|
else
|
{
|
mondata.BattStatus[0] = work_page->work_thread->localData.SysWorkState + 0x80;
|
bak_state = work_page->work_thread->localData.SysWorkState;
|
if(work_page->work_thread->localData.SysWorkState == WorkStopped/* && work_page->work_thread->localData.deviceTestType != TYPE_ON_LINE*/)
|
mondata.GroupCur[0] = 0;
|
}
|
}
|
mondata.BattStatus[1] = 0x80;
|
mondata.BattStatus[2] = 0x80;
|
mondata.BattStatus[3] = 0x80;
|
if(MonNum>300)
|
MonNum = 100;
|
memcpy(mondata.MonomerVol,work_page->work_thread->fboData.SingleVol,MonNum*2);
|
memcpy(info,&mondata,32 + MonNum*2);
|
|
return 32 + MonNum*2;
|
}
|
|
//quint16 SlaveCtrl::getAdjData(quint8 *info)
|
//{
|
// ADJ_DATA adjdata;
|
// memset(&adjdata,0,sizeof(adjdata));
|
// adjdata.OnlineVol = work_page->work_thread->fboData.OnlineVol;
|
// adjdata.GroupVol = 0.1*work_page->work_thread->fboData.SumVoltage;
|
// adjdata.dis_cur = 0.1*work_page->work_thread->fboData.SumCurrent;
|
// adjdata.chr_cur = 0.1*work_page->work_thread->fboData.SumCurrent;
|
// adjdata.out_cur = 0;
|
|
// memcpy(info,&adjdata,sizeof(ADJ_DATA));
|
// return sizeof(ADJ_DATA);
|
//}
|
|
quint16 SlavePC::getTestData(quint8 *info)
|
{
|
TEST_DATA testdata;
|
memset(&testdata,0,sizeof(testdata));
|
testdata.OnlineVol = work_page->work_thread->fboData.OnlineVol;
|
testdata.GroupVol = work_page->work_thread->fboData.SumVoltage;
|
testdata.CurrTime = work_page->work_thread->getTestFileTime();
|
testdata.testtime = work_page->work_thread->fboData.m_TestTime;
|
|
if(work_page->work_thread->localData.SysWorkState == Paused_Dischg ||
|
work_page->work_thread->localData.SysWorkState == Paused_charge)
|
{
|
testdata.KeyState = 1;
|
}
|
else if(work_page->work_thread->localData.SysWorkState == Charging ||
|
work_page->work_thread->localData.SysWorkState == WaitForCharging)
|
{
|
testdata.KeyState = work_page->work_thread->localData.SysWorkState-1;
|
}
|
else
|
{
|
testdata.KeyState = work_page->work_thread->localData.SysWorkState;
|
}
|
if(work_page->work_thread->localData.SysWorkState == Discharging)
|
testdata.monomerCount = work_page->work_thread->localData.monomerLowCount;
|
// else if(work_page->work_thread->localData.SysWorkState == Charging)
|
// testdata.monomerCount = work_page->work_thread->localData.monomerHighCount;
|
|
testdata.curr_cur = work_page->work_thread->fboData.SumCurrent;//*0.1
|
testdata.AllCap = work_page->work_thread->fboData.AllCap;
|
testdata.SMaxIndex = work_page->work_thread->localData.SMaxIndex[0];
|
testdata.SMaxVol = work_page->work_thread->localData.SMaxVol[0];
|
testdata.SMinIndex = work_page->work_thread->localData.SMinIndex[0];
|
testdata.SMinVol = work_page->work_thread->localData.SMinVol[0];
|
testdata.dischgTimes = work_page->work_thread->localData.dischgTimes;
|
//testdata.HighTemp = work_page->work_thread->GetBYDInfo()->temp_hight;
|
//testdata.LowTTemp = work_page->work_thread->GetBYDInfo()->temp_low;
|
if(work_page->work_thread->localData.SysWorkState == WorkStopped/* && work_page->work_thread->localData.deviceTestType != TYPE_ON_LINE*/)
|
testdata.curr_cur = 0;
|
if(work_page->work_thread->fboData.SumVoltage<F0VOL)
|
{
|
testdata.reserved[0] = work_page->work_thread->localData.RLY_OK&(~IGBT_VALUE);
|
}
|
else
|
testdata.reserved[0] = work_page->work_thread->localData.RLY_OK;
|
|
memcpy(info,&testdata,sizeof(TEST_DATA));
|
|
return sizeof(TEST_DATA);
|
}
|
quint8 *SlavePC::getFileDataHead(FILE_LIST_DATA &data,TEST_DATA_INFO &test_info,quint8 total,quint8 Index)
|
{
|
data.TotalFileNum = total;
|
data.CurrFileIndex = Index;
|
data.TestStartTime = test_info.fbo_data_head_start.TestStartTime;
|
data.TestTimeLong = test_info.fbo_data_head_stop.TestTimeLong;
|
data.DataType = test_info.fbo_data_head_start.DataType;
|
data.TestCur = test_info.fbo_data_head_start.TestCur;
|
data.TestCap = test_info.fbo_data_head_stop.TestCap;
|
data.STDCap = test_info.fbo_data_head_start.STDCap;
|
data.MVLLimit = test_info.fbo_data_head_start.MVLLimit;
|
data.SumVLLimit = test_info.fbo_data_head_start.SumVLLimit;
|
data.BattSum = test_info.fbo_data_head_start.BattSum;
|
data.BattGroup = test_info.fbo_data_head_start.BattGroup;
|
data.StopType = test_info.fbo_data_head_stop.StopType;
|
data.MonomerVol = test_info.fbo_data_head_start.MonomerVol;
|
|
return (quint8 *)&data;
|
}
|
|
quint16 SlavePC::getPageFileData(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
quint8 i;
|
quint8 page = recv.Db1;
|
quint16 j=0;
|
FileManage fileManage;
|
QStringList nameList = fileManage.getFiles(work_page->batteryName+"/",".FBO");
|
|
TEST_DATA_INFO test_info;
|
FILE_LIST_DATA file_data;
|
|
if(page*8 > nameList.count())
|
{
|
Sent.RecState = FILE_DATA_ERR;
|
return 0;
|
}
|
|
for(i=0;i<8 && i+page*8<nameList.count();i++)
|
{
|
if(ClassXML::AnalysisDataFBO(dataDir+work_page->batteryName+"/"+nameList.at(i+page*8),test_info))
|
{
|
getFileDataHead(file_data,test_info,nameList.count(),i+page*8);
|
memcpy(Sent.info+j,&file_data,sizeof(FILE_LIST_DATA));
|
j += sizeof(FILE_LIST_DATA);
|
}
|
}
|
return j;
|
}
|
|
quint16 SlavePC::getFileSmallBlock(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
quint16 Cnt_len=0;
|
quint16 total_block=0;
|
quint16 file_index = recv.RecState*256+recv.type;
|
quint16 smallBlock = recv.workState*256+recv.Alarm;
|
FileManage fileManage;
|
QStringList nameList = fileManage.getFiles(work_page->batteryName+"/",".FBO");
|
|
if(file_index >= nameList.count())
|
{
|
Sent.RecState = FILE_DATA_ERR;
|
return 0;
|
}
|
if(ClassXML::ReadsmallBlockDataFBO(dataDir+work_page->batteryName+"/"+nameList.at(file_index),
|
Sent.info,Cnt_len,total_block,smallBlock))
|
{
|
Sent.Db1 = (total_block>>8)&0xFF;
|
Sent.Db2 = (total_block)&0xFF;
|
Sent.Db3 = (smallBlock>>8)&0xFF;
|
Sent.Db4 = (smallBlock)&0xFF;
|
return Cnt_len;
|
}
|
return 0;
|
}
|
quint16 SlavePC::getBattName(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
quint16 batt_index = recv.RecState*256+recv.type;
|
QStringList batt_list = FileManage::getDirs();
|
quint16 batt_total = batt_list.count();
|
|
if(batt_index >= batt_total)
|
{
|
Sent.RecState = FILE_DATA_ERR;
|
return 0;
|
}
|
Sent.Db1 = (batt_total>>8)&0xFF;
|
Sent.Db2 = batt_total&0xFF;
|
Sent.Db3 = recv.RecState;
|
Sent.Db4 = recv.type;
|
|
QString battname = batt_list.at(batt_index);
|
memcpy(Sent.info,battname.toUtf8().data(),battname.toUtf8().length());
|
return battname.toUtf8().length();
|
}
|
quint16 SlavePC::getfileName(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
quint16 batt_index = recv.RecState*256+recv.type;
|
quint16 file_index = recv.workState*256+recv.Alarm;
|
QStringList batt_list = FileManage::getDirs();
|
QStringList file_List = FileManage::getFiles(batt_list.at(batt_index)+"/",".FBO");
|
quint16 batt_total = batt_list.count();
|
quint16 file_total = file_List.count();
|
if(batt_index >= batt_total || file_index >= file_total)
|
{
|
if(file_index > 0)
|
{
|
Sent.RecState = FILE_DATA_ERR;
|
}
|
return 0;
|
}
|
|
Sent.Db1 = (file_total>>8)&0xFF;
|
Sent.Db2 = file_total&0xFF;
|
Sent.Db3 = recv.workState;
|
Sent.Db4 = recv.Alarm;
|
|
QString filename = file_List.at(file_index);
|
memcpy(Sent.info,filename.toUtf8().data(),filename.toUtf8().length());
|
return filename.toUtf8().length();
|
}
|
quint16 SlavePC::getSelectFile(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
QString path_name = QString::fromUtf8((const char *)recv.info,recv.Len-18);
|
//qDebug()<<"111111"<<path_name;
|
quint16 Cnt_len=0;
|
quint16 total_block=0;
|
quint16 smallBlock = recv.RecState*256+recv.type;
|
|
if(ClassXML::ReadsmallBlockDataFBO(dataDir+path_name,
|
Sent.info,Cnt_len,total_block,smallBlock))
|
{
|
if(smallBlock >= total_block)
|
{
|
Sent.RecState = FILE_DATA_ERR;
|
}
|
Sent.Db1 = (total_block>>8)&0xFF;
|
Sent.Db2 = (total_block)&0xFF;
|
Sent.Db3 = (smallBlock>>8)&0xFF;
|
Sent.Db4 = (smallBlock)&0xFF;
|
return Cnt_len;
|
}
|
Sent.RecState = OTHER_ERR;
|
return 0;
|
}
|
|
quint16 SlavePC::getVersion(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
Sent.RecState = recv.RecState;
|
QString battname = phoneVersion;
|
memcpy(Sent.info,battname.toUtf8().data(),battname.toUtf8().length());
|
return battname.toUtf8().length();
|
}
|
|
void SlavePC::SaveTestParam(const QString &fname,TEST_PARAM_XML &test_param)
|
{
|
if(ClassXML::CreateTestParamXml(fname,test_param)) //新建的
|
{
|
|
}
|
else //原有的
|
{
|
ClassXML::ModifyTestParamXml(fname,test_param);
|
}
|
}
|
|
void SlavePC::NewBattFile(quint8 *info)
|
{
|
QString newname((const char *)info);
|
if(work_page->batteryName != newname)
|
{
|
ClassXML::ModifyNewestPNameXml(newname);
|
work_page->batteryName = newname;
|
SaveTestParam(newname,work_page->test_param_xml);
|
}
|
}
|
bool SlavePC::SelectBatt(quint8 *info)
|
{
|
QString newname((const char *)info);
|
TEST_PARAM_XML testParam;
|
if(true == ClassXML::ReadTestParamXml(newname, testParam))
|
{
|
ClassXML::ModifyNewestPNameXml(newname);
|
work_page->batteryName = newname;
|
emit sendParam(PARAM_PAGE_CMD_PARAM);
|
return true;
|
}
|
return false;
|
}
|
void SlavePC::DeleteBatt(quint8 *info)
|
{
|
QString newname((const char *)info);
|
FileManage fileManage;
|
|
if(newname == Default_Battery)
|
{
|
fileManage.clearDirectoryFiles(Default_Battery,fileManage.getFiles(Default_Battery,".FBO"));
|
}
|
else
|
{
|
fileManage.removeDir(dataDir+newname);
|
}
|
|
if(work_page->batteryName == newname)
|
{
|
newname = Default_Battery;
|
ClassXML::ModifyNewestPNameXml(newname);
|
work_page->batteryName = newname;
|
emit sendParam(PARAM_PAGE_CMD_PARAM);
|
}
|
}
|
|
//----------------------------------------------------------------------------------
|
void SlavePC::SlaveClearHeart()
|
{
|
work_page->work_thread->localData.rs485_pc.heart_cnt = 0;
|
}
|
|
void SlavePC::SlaveDisposeCMD(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
if((work_page->work_thread->localData.rs485_pc.Enter_ctrl == 0)&&(recv.CMD != EnterSlave))
|
{
|
Sent.RecState = SLAVEMODE_ERR;
|
return;
|
}
|
|
switch (recv.CMD) {
|
case Heartbea:
|
//SlaveClearHeart(dev);
|
break;
|
case ExitSlave:
|
work_page->work_thread->localData.rs485_pc.Enter_ctrl = 0;
|
break;
|
case EnterSlave:
|
if(work_page->work_thread->localData.rs485_pc.Enter_ctrl)
|
{
|
break;
|
}
|
qDebug("get CMD = %x",recv.CMD);
|
work_page->work_thread->localData.rs485_pc.Enter_ctrl = 1;
|
if(work_page->work_thread->localData.SysWorkState == WorkStopped && work_page->work_thread->localData.pauseBtnState == 0)
|
{
|
emit SendInterface(FACE_HOME);
|
}
|
else
|
{
|
Sent.RecState = SLAVEMODE_ERR;
|
}
|
break;
|
case StartDischarge:
|
if((work_page->work_thread->localData.SysWorkState == WorkStopped||work_page->work_thread->localData.SysWorkState == Paused_Dischg)&&
|
work_page->work_thread->localData.pauseBtnState!=2)
|
emit sendParam(PARAM_PAGE_CMD_START_DIS);//emit sendStart(work_page->work_thread->CMD_StartDischarge,work_page->batteryName);
|
else
|
Sent.RecState = START_ERR;
|
break;
|
case PausetDischarge:
|
if(work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Paused_Dischg)
|
emit sendParam(PARAM_PAGE_CMD_PAUSE);//emit sendStart(work_page->work_thread->CMD_PauseDischarge,work_page->batteryName);
|
else
|
Sent.RecState = START_ERR;
|
break;
|
case StopDischarge:
|
if(work_page->work_thread->localData.SysWorkState == Paused_Dischg || work_page->work_thread->localData.SysWorkState == Discharging)
|
emit sendParam(PARAM_PAGE_CMD_STOP);//emit sendStart(work_page->work_thread->CMD_StopDischarge,work_page->batteryName);
|
else
|
Sent.RecState = START_ERR;
|
break;
|
case StartCharge:
|
if(work_page->work_thread->localData.SysWorkState == WorkStopped ||work_page->work_thread->localData.SysWorkState == Paused_charge)
|
emit sendParam(PARAM_PAGE_CMD_START_CHR);//emit sendStart(work_page->work_thread->CMD_StartCharge,work_page->batteryName);
|
else
|
Sent.RecState = START_ERR;
|
break;
|
case PauseCharge:
|
if(work_page->work_thread->localData.SysWorkState == Charging)
|
emit sendParam(PARAM_PAGE_CMD_PAUSE);//emit sendStart(work_page->work_thread->CMD_PauseCharge,work_page->batteryName);
|
else
|
Sent.RecState = START_ERR;
|
break;
|
case StopCharge:
|
if(work_page->work_thread->localData.SysWorkState == Paused_charge || work_page->work_thread->localData.SysWorkState == Charging)
|
emit sendParam(PARAM_PAGE_CMD_STOP);//emit sendStart(work_page->work_thread->CMD_StopCharge,work_page->batteryName);
|
else
|
Sent.RecState = START_ERR;
|
break;
|
// case StartCycle:
|
// if(work_page->work_thread->localData.SysWorkState == WorkStopped && work_page->work_thread->localData.deviceTestType == TYPE_CYCLE_TEST)
|
// {
|
// if(START_DISCHG == testParam.cycle_start)
|
// emit sendParam(PARAM_PAGE_CMD_START_DIS);
|
// else if(START_CHARGE == testParam.cycle_start)
|
// emit sendParam(PARAM_PAGE_CMD_START_CHR);
|
// else
|
// Sent.RecState = START_ERR;
|
// }
|
// else
|
// Sent.RecState = START_ERR;
|
// break;
|
// case PauseCycle:
|
// if(work_page->work_thread->localData.SysWorkState != WorkStopped && work_page->work_thread->localData.deviceTestType == TYPE_CYCLE_TEST)
|
// emit sendParam(PARAM_PAGE_CMD_PAUSE);
|
// else
|
// Sent.RecState = START_ERR;
|
// break;
|
// case StopCycle:
|
// if(work_page->work_thread->localData.SysWorkState != WorkStopped && work_page->work_thread->localData.deviceTestType == TYPE_CYCLE_TEST)
|
// emit sendParam(PARAM_PAGE_CMD_STOP);
|
// else
|
// Sent.RecState = START_ERR;
|
// break;
|
// case Adjust_StartDischarge:
|
// if(work_page->work_thread->localData.SysWorkState == WorkStopped)
|
// emit sendStart(work_page->work_thread->CMD_Adj_StartDis,work_page->batteryName);
|
// else
|
// Sent.RecState = START_ERR;
|
// break;
|
// case Adjust_StartCharge:
|
// if(work_page->work_thread->localData.SysWorkState == WorkStopped)
|
// emit sendStart(work_page->work_thread->CMD_Adj_StartChr,work_page->batteryName);
|
// else
|
// Sent.RecState = START_ERR;
|
// break;
|
// case Adjust_Stop:
|
// if(work_page->work_thread->localData.SysWorkState == Discharging)
|
// emit sendStart(work_page->work_thread->CMD_Adj_StopDis,work_page->batteryName);
|
// else if(work_page->work_thread->localData.SysWorkState == Charging)
|
// emit sendStart(work_page->work_thread->CMD_Adj_StopChr,work_page->batteryName);
|
// else
|
// Sent.RecState = START_ERR;
|
// break;
|
// case SetAdjustParm:
|
// if(recv.RecState == ADJ_VOL)
|
// emit SendCurrAdjCMD(work_page->work_thread->CMD_SetGroupVol,
|
// (recv.type*256+recv.workState-work_page->work_thread->localData.sim_buf.ADCVdin));
|
// else if(recv.RecState == ADJ_DIS)
|
// emit SendCurrAdjCMD(work_page->work_thread->CMD_SetDisChargCur,
|
// (recv.type*256+recv.workState-work_page->work_thread->localData.sim_buf.ADCId));
|
// else if(recv.RecState == ADJ_CHR)
|
// emit SendCurrAdjCMD(work_page->work_thread->CMD_SetChargCur,
|
// (recv.type*256+recv.workState-work_page->work_thread->localData.sim_buf.ADCIc));
|
// else
|
// Sent.RecState = START_ERR;
|
// break;
|
|
case SetDischargeParam:
|
case SetChargeParam:
|
case SetCycleParam:
|
if(sizeof(COMM_TEST_PARAM) == (recv.Len - 18))
|
{
|
TEST_PARAM_XML testParam;
|
setTestCommParam(testParam,recv.info);
|
//memcpy(addr,recv.info,sizeof(testParam));
|
SaveTestParam(work_page->batteryName,testParam);
|
emit sendParam(PARAM_PAGE_CMD_PARAM);
|
}
|
break;
|
|
case EnterHome:
|
{
|
quint8 pageIndex = 0;
|
if(recv.Len > 18)
|
{
|
pageIndex = recv.info[0];
|
}
|
else
|
{
|
pageIndex = recv.RecState;
|
}
|
//qDebug("pageIndex = %d,work_page->work_thread->localData.Interface=%d",pageIndex,work_page->work_thread->localData.Interface);
|
if(pageIndex != work_page->work_thread->localData.Interface)
|
{
|
if(work_page->work_thread->localData.SysWorkState == Paused_Dischg ||
|
work_page->work_thread->localData.SysWorkState == Paused_charge ||
|
work_page->work_thread->localData.SysWorkState == Discharging ||
|
work_page->work_thread->localData.SysWorkState == Charging ||
|
work_page->work_thread->localData.SysWorkState == WaitForCharging)
|
Sent.RecState = SYSTEM_WORKING;
|
else
|
{
|
emit SendInterface(pageIndex);
|
}
|
}
|
break;
|
}
|
case NewBatt:
|
NewBattFile(recv.info);
|
break;
|
case ChangedBatt:
|
if(!SelectBatt(recv.info))
|
Sent.RecState = OTHER_ERR;
|
break;
|
case DelBatt:
|
DeleteBatt(recv.info);
|
break;
|
case ClearAlarm:
|
work_page->work_thread->localData.popBox = 0;
|
emit sendParam(PARAM_PAGE_CLOSE_BOX);
|
break;
|
case SetTKQState:
|
emit sendParam(PARAM_PAGE_CMD_START_PSW);
|
break;
|
case SetFanState:
|
emit sendParam(PARAM_PAGE_CMD_START_FAN);
|
break;
|
case GetBattName:
|
case GetFileName:
|
case GetSelectFile:
|
case GetCellData:
|
case GetDischargeParam:
|
case GetChargeParam:
|
case GetDischargeData:
|
case GetChargeData:
|
case GetCycleParam:
|
case GetAdjustData:
|
case GetFileInfo:
|
case GetFile:
|
|
default:
|
break;
|
}
|
}
|
|
void SlavePC::SlaveSentFrame(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
static quint8 cnt = 0;
|
static quint8 bak_state = 0;
|
Sent.SYNCode = SYSCODE;
|
Sent.CMD = recv.CMD;
|
|
Sent.Len = 18;
|
Sent.type = work_page->work_thread->localData.Interface + 0x80;
|
|
if(work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Paused_Dischg)
|
{
|
bak_state = work_page->work_thread->localData.SysWorkState;
|
cnt = 5;
|
}
|
else
|
cnt = 0;
|
|
if((cnt > 0) && (work_page->work_thread->localData.SysWorkState == WorkStopped))
|
{
|
cnt--;
|
Sent.workState = bak_state;
|
work_page->work_thread->fboData.SubCurrent[0] = 0;
|
work_page->work_thread->fboData.SumCurrent = 0;
|
}
|
else
|
{
|
Sent.workState = work_page->work_thread->localData.SysWorkState;
|
bak_state = work_page->work_thread->localData.SysWorkState;
|
}
|
if(work_page->work_thread->localData.TestType == TestTypeCharge)
|
Sent.Alarm = work_page->work_thread->localData.WPAlarmState + work_page->work_thread->localData.popBox + 0x40;
|
else
|
Sent.Alarm = work_page->work_thread->localData.WPAlarmState + work_page->work_thread->localData.popBox;
|
|
switch (recv.CMD) {
|
case Heartbea:
|
Sent.Db1 = 0;//work_page->work_thread->localData.rs485_pc.ID;
|
memcpy(Sent.info,work_page->batteryName.toUtf8().data(),work_page->batteryName.toUtf8().length());
|
Sent.Len += work_page->batteryName.toUtf8().length();
|
break;
|
case ExitSlave:
|
case StartDischarge:
|
case PausetDischarge:
|
case StartCharge:
|
case PauseCharge:
|
case SetAdjustParm:
|
case Adjust_StartDischarge:
|
case Adjust_StartCharge:
|
case Adjust_Stop:
|
case NewBatt:
|
case ChangedBatt:
|
case DelBatt:
|
case StopDischarge:
|
case StopCharge:
|
case ClearAlarm:
|
case StartCycle:
|
case PauseCycle:
|
case StopCycle:
|
case EnterHome:
|
break;
|
case EnterSlave:
|
Sent.Db1 = Version;
|
Sent.Db2 = 0;
|
Sent.Db3 = 0xF4;
|
break;
|
case GetDischargeParam:
|
case GetChargeParam:
|
case GetCycleParam:
|
// Sent.info = (quint8 *)&testParam;
|
// Sent.Len += sizeof(testParam);
|
getTestCommParam(work_page->test_param_xml,Sent.info);
|
Sent.Len += sizeof(COMM_TEST_PARAM);
|
break;
|
|
case GetCellData:
|
Sent.Db1 = work_page->test_param_xml.mon_number>>8;
|
Sent.Db2 = work_page->test_param_xml.mon_number & 0xFF;
|
|
Sent.Len += getMonData(Sent.info,work_page->work_thread->fboData.BattSum);
|
break;
|
case SetDischargeParam:
|
case SetChargeParam:
|
case SetCycleParam:
|
Sent.Db1 = recv.Db1;
|
break;
|
|
case GetDischargeData:
|
case GetChargeData:
|
if(work_page->work_thread->localData.waitTimeCount)
|
{
|
Sent.Db2 = 1;
|
quint16 timesec = work_page->work_thread->localData.waitTimeCount;
|
Sent.Db3 = timesec/256;
|
Sent.Db4 = timesec%256;
|
}
|
else if(((work_page->work_thread->localData.SysWorkState == Charging)&&(recv.CMD == GetDischargeData))
|
||((work_page->work_thread->localData.SysWorkState == Discharging)&&(recv.CMD == GetChargeData)))
|
{
|
Sent.Db2 = 2;
|
}
|
Sent.Len += getTestData(Sent.info);
|
break;
|
// case GetAdjustData:
|
// Sent.Len += getAdjData(Sent.info);
|
// break;
|
case GetFileInfo:
|
Sent.Len += getPageFileData(recv, Sent);
|
break;
|
case GetFile:
|
Sent.Len += getFileSmallBlock(recv,Sent);
|
break;
|
case GetBattName:
|
Sent.Len += getBattName(recv,Sent);
|
break;
|
case GetFileName:
|
Sent.Len += getfileName(recv,Sent);
|
break;
|
case GetSelectFile:
|
Sent.Len += getSelectFile(recv,Sent);
|
break;
|
case GetVersion:
|
Sent.Len += getVersion(recv,Sent);
|
default:
|
break;
|
}
|
|
Sent.CRC = CRC16::CalCRC16(&Sent,Sent.Len);
|
|
WriteFrameData(&Sent);
|
|
}
|
|
void SlavePC::SlaveResponse(FRAME_DATA &recv,FRAME_DATA &Sent)
|
{
|
if(Sent.RecState == SUCCEED)
|
{
|
SlaveClearHeart();//任何有效指令都当作心跳指令
|
SlaveDisposeCMD(recv,Sent);
|
}
|
SlaveSentFrame(recv,Sent);
|
}
|
|
//---------------------------------------------------------------------
|
void SlavePC::SlaveMode(FRAME_DATA &recv,FRAME_DATA &Sent)
|
{
|
if(ReadFrameData(recv,Sent) == true)
|
{
|
SlaveResponse(recv,Sent);
|
}
|
}
|
|
/******************************************************************************************/
|
void SlavePC::setTestCommParam(TEST_PARAM_XML &test_param,void *comm_param)
|
{
|
if(PageType == IDCE48CT)
|
test_param.test_mode = OFFline_working;
|
else if(PageType == FBI48CT)
|
test_param.test_mode = ONline_working;
|
else
|
test_param.test_mode = ((COMM_TEST_PARAM *)comm_param)->test_mode;
|
test_param.acstop_op = ((COMM_TEST_PARAM *)comm_param)->acstop_op;
|
test_param.nominal_cap = ((COMM_TEST_PARAM *)comm_param)->nominal_cap;
|
test_param.hourly_rate = ((COMM_TEST_PARAM *)comm_param)->hourly_rate;
|
test_param.preset_cur = ((COMM_TEST_PARAM *)comm_param)->preset_cur;
|
test_param.preset_cap = ((COMM_TEST_PARAM *)comm_param)->preset_cap;
|
test_param.preset_time = ((COMM_TEST_PARAM *)comm_param)->preset_time;
|
test_param.mon_lower = ((COMM_TEST_PARAM *)comm_param)->mon_lower;
|
test_param.group_lower = ((COMM_TEST_PARAM *)comm_param)->group_lower;
|
test_param.mon_number = ((COMM_TEST_PARAM *)comm_param)->mon_number;
|
test_param.group_number = ((COMM_TEST_PARAM *)comm_param)->group_number;
|
test_param.lower_number = ((COMM_TEST_PARAM *)comm_param)->lower_number;
|
test_param.mon_vol = ((COMM_TEST_PARAM *)comm_param)->mon_vol;
|
if(PageType == FBO48CT || TYPE_FBI_10480 || TYPE_FBI_4548 || TYPE_FBI_20240)
|
test_param.onlinevol_lowlimit = ((COMM_TEST_PARAM *)comm_param)->Reserved[0];
|
else
|
test_param.onlinevol_lowlimit = onlinevollow;
|
|
test_param.booster_ceiling = ((COMM_TEST_PARAM *)comm_param)->Reserved[1];
|
test_param.charge_limit = ((COMM_TEST_PARAM *)comm_param)->chrg_curr;
|
test_param.temp_High = ((COMM_TEST_PARAM *)comm_param)->chrg_temp;
|
test_param.discharge_mode = ((COMM_TEST_PARAM *)comm_param)->dischg_mode;
|
test_param.preset_power = ((COMM_TEST_PARAM *)comm_param)->pre_power;
|
|
if(test_param.group_number*test_param.mon_number > 300)
|
test_param.mon_number = 300/test_param.group_number;
|
if(test_param.group_number>4)
|
test_param.group_number = 4;
|
if(test_param.group_number*test_param.mon_number > 300)
|
test_param.mon_number = 300/test_param.group_number;
|
if(test_param.lower_number<=0)
|
test_param.lower_number = 1;
|
if(test_param.preset_time<=0)
|
test_param.preset_time = 1;
|
|
if(!(test_param.mon_vol == 20 || test_param.mon_vol == 40 ||
|
test_param.mon_vol == 60 || test_param.mon_vol == 120 ||
|
test_param.mon_vol == 12))
|
{
|
test_param.mon_vol = work_page->test_param_xml.mon_vol;
|
}
|
}
|
|
void SlavePC::getTestCommParam(TEST_PARAM_XML &test_param, void *comm_param)
|
{
|
memset(comm_param,0x00,sizeof(COMM_TEST_PARAM));
|
((COMM_TEST_PARAM *)comm_param)->test_mode = test_param.test_mode;
|
((COMM_TEST_PARAM *)comm_param)->acstop_op = test_param.acstop_op;
|
((COMM_TEST_PARAM *)comm_param)->nominal_cap = test_param.nominal_cap;
|
((COMM_TEST_PARAM *)comm_param)->hourly_rate = test_param.hourly_rate;
|
((COMM_TEST_PARAM *)comm_param)->preset_cur = test_param.preset_cur;
|
((COMM_TEST_PARAM *)comm_param)->preset_cap = test_param.preset_cap;
|
((COMM_TEST_PARAM *)comm_param)->preset_time = test_param.preset_time;
|
((COMM_TEST_PARAM *)comm_param)->mon_lower = test_param.mon_lower;
|
((COMM_TEST_PARAM *)comm_param)->group_lower = test_param.group_lower;
|
((COMM_TEST_PARAM *)comm_param)->mon_number = test_param.mon_number;
|
((COMM_TEST_PARAM *)comm_param)->group_number = test_param.group_number;
|
((COMM_TEST_PARAM *)comm_param)->lower_number = test_param.lower_number;
|
((COMM_TEST_PARAM *)comm_param)->mon_vol = test_param.mon_vol;
|
((COMM_TEST_PARAM *)comm_param)->Reserved[0] = test_param.onlinevol_lowlimit;//在线阈值
|
((COMM_TEST_PARAM *)comm_param)->Reserved[1] = test_param.booster_ceiling;//升压上限
|
((COMM_TEST_PARAM *)comm_param)->chrg_curr = test_param.charge_limit;
|
((COMM_TEST_PARAM *)comm_param)->chrg_temp = test_param.temp_High;
|
((COMM_TEST_PARAM *)comm_param)->dischg_mode = test_param.discharge_mode;
|
((COMM_TEST_PARAM *)comm_param)->pre_power = test_param.preset_power;
|
}
|
|
void SlavePC::run()
|
{
|
RUN_EN = true;
|
if(FD < 0)
|
RUN_EN = false;
|
|
FRAME_DATA frame_sent;
|
FRAME_DATA frame_recv;
|
|
while(RUN_EN)
|
{
|
memset(&frame_recv,0,sizeof(frame_recv));
|
memset(&frame_sent,0,sizeof(frame_sent));
|
SlaveMode(frame_recv,frame_sent);
|
msleep(50);
|
}
|
}
|
//***********************************************************************************
|