|
//---------------------------------------------------------------------
|
#include <QApplication>
|
#include <QDateTime>
|
#include "SlaveCtrl.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
|
|
QList<MASTER_CMD> master_cmd;
|
|
SlaveCtrl::SlaveCtrl(Working_Page *page)
|
{
|
work_page = page;
|
IF_CLOSEServer = IF_CLOSEClient = false;
|
connect(this,SIGNAL(SendInterface(int)),work_page->work_thread,SLOT(RecvInterface(int)));
|
|
connect(this,SIGNAL(sendParam(int)),work_page,SLOT(operatorCMD_Work(int)));
|
|
connect(work_page,SIGNAL(senddeleteSocket()),this,SLOT(deleteSocket()));
|
|
ServerFlag = ClientFlag = 0;
|
|
}
|
|
SlaveCtrl::~SlaveCtrl()
|
{
|
quit();
|
wait();
|
}
|
|
bool SlaveCtrl::CheckLen(FRAME_DATA *recv)
|
{
|
if(recv->Len >= 18)
|
{
|
return true;
|
}
|
return false;
|
}
|
bool SlaveCtrl::CheckSYNCode(FRAME_DATA *recv)
|
{
|
if(recv->SYNCode == SYSCODE)
|
{
|
return true;
|
}
|
return false;
|
}
|
bool SlaveCtrl::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 SlaveCtrl::WriteFrameData(FRAME_DATA *Sent)
|
{
|
QByteArray arrTest;
|
arrTest.append(reinterpret_cast<char *>(Sent),Sent->Len);
|
//qDebug()<<arrTest.toHex();
|
if(ServerFlag)
|
{
|
if(tcpSocket->write(arrTest)==Sent->Len)
|
{
|
tcpSocket->flush();
|
tcpSocket->waitForBytesWritten(1000);
|
return true;
|
}
|
else
|
return false;
|
}
|
else if(ClientFlag)
|
{
|
if(tcpClient->write(arrTest)==Sent->Len)
|
{
|
tcpClient->flush();
|
tcpClient->waitForBytesWritten(1000);
|
return true;
|
}
|
else
|
return false;
|
}
|
else
|
return false;
|
}
|
|
bool SlaveCtrl::ReadFrameHead(FRAME_DATA *recv, FRAME_DATA *Sent)
|
{
|
if(CheckSYNCode(recv) == true)
|
{
|
if(CheckLen(recv) == false)
|
{
|
Sent->RecState = LEN_ERR;
|
}
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
bool SlaveCtrl::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 SlaveCtrl::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->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 SlaveCtrl::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&(IGBT_VALUE_X);
|
memcpy(info,&testdata,sizeof(TEST_DATA));
|
|
return sizeof(TEST_DATA);
|
}
|
quint8 *SlaveCtrl::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 SlaveCtrl::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 SlaveCtrl::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 SlaveCtrl::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 SlaveCtrl::getfileName(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
quint16 batt_index = recv.RecState*256+recv.type;//FF
|
quint16 file_index = recv.workState*256+recv.Alarm;//0
|
QStringList batt_list = FileManage::getDirs();
|
quint16 batt_total = batt_list.count();
|
if(batt_index >= batt_total)
|
{
|
Sent.RecState = FILE_DATA_ERR;
|
return 0;
|
}
|
QStringList file_List = FileManage::getFiles(batt_list.at(batt_index)+"/",".FBO");
|
quint16 file_total = file_List.count();
|
if(file_index >= file_total)
|
{
|
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 SlaveCtrl::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 SlaveCtrl::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 SlaveCtrl::SaveTestParam(const QString &fname,TEST_PARAM_XML &test_param)
|
{
|
if(ClassXML::CreateTestParamXml(fname,test_param)) //新建的
|
{
|
|
}
|
else //原有的
|
{
|
ClassXML::ModifyTestParamXml(fname,test_param);
|
}
|
}
|
|
void SlaveCtrl::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 SlaveCtrl::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 SlaveCtrl::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 SlaveCtrl::SlaveClearHeart()
|
{
|
work_page->work_thread->localData.tcp_ctrl.heart_cnt = 0;
|
}
|
|
void SlaveCtrl::SlaveDisposeCMD(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
if((work_page->work_thread->localData.tcp_ctrl.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.tcp_ctrl.Enter_ctrl = 0;
|
break;
|
case EnterSlave:
|
if(work_page->work_thread->localData.tcp_ctrl.Enter_ctrl)
|
{
|
break;
|
}
|
// qDebug("get CMD = %x",recv.CMD);
|
work_page->work_thread->localData.tcp_ctrl.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 ||
|
work_page->work_thread->localData.SysWorkState == WaitForCharging )
|
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 SlaveCtrl::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 = work_page->work_thread->localData.tcp_ctrl.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 SlaveCtrl::SlaveResponse(FRAME_DATA &recv,FRAME_DATA &Sent)
|
{
|
if(Sent.RecState == SUCCEED)
|
{
|
SlaveClearHeart();//任何有效指令都当作心跳指令
|
SlaveDisposeCMD(recv,Sent);
|
}
|
SlaveSentFrame(recv,Sent);
|
}
|
|
//---------------------------------------------------------------------
|
void SlaveCtrl::SlaveMode(FRAME_DATA &recv,FRAME_DATA &Sent)
|
{
|
if(ReadFrameData(recv,Sent) == true)
|
{
|
//qDebug("recv.CMD = %x",recv.CMD);
|
SlaveResponse(recv,Sent);
|
}
|
}
|
|
/******************************************************************************************/
|
bool SlaveCtrl::MasterSentFrame(MASTER_CMD cmd_data)
|
{
|
FRAME_DATA Sent;
|
|
memset(&Sent,0,sizeof(Sent));
|
|
Sent.SYNCode = SYSCODE;
|
Sent.CMD = cmd_data.CMD;
|
Sent.Len = 18;
|
|
switch (cmd_data.CMD) {
|
case Heartbea:
|
case ExitSlave:
|
break;
|
case EnterSlave:
|
Sent.RecState = 1;
|
break;
|
case GetDischargeParam:
|
case GetChargeParam:
|
case GetCycleParam:
|
Sent.Db1 = cmd_data.Cid1;
|
break;
|
case SetDischargeParam:
|
case SetChargeParam:
|
case SetCycleParam:
|
Sent.Db1 = cmd_data.Cid1;
|
//Sent.info = (quint8 *)&testParam;
|
getTestCommParam(work_page->test_param_xml,Sent.info);
|
// memcpy(Sent.info,&testParam,sizeof());
|
|
Sent.Len += sizeof(COMM_TEST_PARAM);
|
break;
|
case GetBattName:
|
case GetFileName:
|
case GetSelectFile:
|
case GetCellData:
|
case GetDischargeData:
|
case GetChargeData:
|
case GetAdjustData:
|
case StartCharge:
|
case PauseCharge:
|
case Adjust_StartDischarge:
|
case Adjust_StartCharge:
|
case Adjust_Stop:
|
case StopDischarge:
|
case StopCharge:
|
case ChangedBatt:
|
case DelBatt:
|
case ClearAlarm:
|
case StartCycle:
|
case PauseCycle:
|
case StopCycle:
|
break;
|
case NewBatt:
|
memcpy(Sent.info,work_page->batteryName.toUtf8().data(),work_page->batteryName.toUtf8().length());
|
Sent.Len += work_page->batteryName.toUtf8().length();
|
break;
|
case GetFileInfo:
|
Sent.Db1 = cmd_data.Cid1;
|
break;
|
case GetFile:
|
Sent.RecState = cmd_data.RecState;
|
Sent.type = cmd_data.Cid1;
|
Sent.workState = cmd_data.Cid2;
|
Sent.Alarm = cmd_data.Alarm;
|
break;
|
case StartDischarge:
|
case PausetDischarge:
|
Sent.RecState = cmd_data.Cid1;
|
break;
|
case SetAdjustParm:
|
Sent.RecState = cmd_data.Cid1;
|
Sent.type = cmd_data.Cid2;
|
Sent.workState = cmd_data.Alarm;
|
break;
|
|
case EnterHome:
|
Sent.RecState = cmd_data.RecState;
|
break;
|
default:
|
break;
|
}
|
|
Sent.CRC = CRC16::CalCRC16(Sent.info, Sent.Len);
|
|
return WriteFrameData(&Sent);
|
}
|
void SlaveCtrl::MasterDisposeCMD(FRAME_DATA &recv)
|
{
|
work_page->work_thread->localData.master_data.Interface = recv.type;
|
work_page->work_thread->localData.master_data.workState = recv.workState;
|
work_page->work_thread->localData.master_data.Alarm = recv.Alarm;
|
work_page->work_thread->localData.master_data.heart_cnt = 0;
|
|
if(recv.RecState == SLAVEMODE_ERR)
|
{
|
work_page->work_thread->localData.master_data.Enter_ctrl = 0;
|
return;
|
}
|
if(work_page->work_thread->localData.SysWorkState == WorkStopped)
|
{
|
if(work_page->work_thread->localData.master_data.workState == Discharging)
|
{
|
if(master_cmd.count() == 0)
|
setMasterCmd(SlaveCtrl::StopDischarge);
|
}
|
}
|
|
switch (recv.CMD) {
|
case Heartbea:
|
//work_page->work_thread->localData.master_data.heart_cnt = 0;
|
//work_page->work_thread->localData.master_data.battname = QString::fromUtf8((const char *)recv.info,recv.Len-18);
|
break;
|
case ExitSlave:
|
work_page->work_thread->localData.master_data.Enter_ctrl = 0;
|
break;
|
case EnterSlave:
|
work_page->work_thread->localData.master_data.Enter_ctrl = 1;
|
break;
|
case GetBattName:
|
case GetFileName:
|
case GetSelectFile:
|
case StartDischarge:
|
case PausetDischarge:
|
case StartCharge:
|
case PauseCharge:
|
case Adjust_StartDischarge:
|
case Adjust_StartCharge:
|
case Adjust_Stop:
|
case SetAdjustParm:
|
case SetDischargeParam:
|
case SetChargeParam:
|
case SetCycleParam:
|
case GetDischargeParam:
|
case GetChargeParam:
|
case GetCycleParam:
|
case StartCycle:
|
case PauseCycle:
|
case StopCycle:
|
break;
|
case GetCellData:
|
if((quint16)(recv.Len-18) <= sizeof(MON_DATA))
|
{
|
memcpy(&work_page->work_thread->localData.master_data.Cell_data,recv.info,recv.Len-18);
|
}
|
break;
|
case GetDischargeData:
|
case GetChargeData:
|
if((quint16)(recv.Len-18) <= sizeof(TEST_DATA))
|
{
|
memcpy(&work_page->work_thread->localData.master_data.test_data,recv.info,recv.Len-18);
|
}
|
break;
|
|
case GetAdjustData:
|
if((quint16)(recv.Len-18) <= sizeof(ADJ_DATA))
|
{
|
memcpy(&work_page->work_thread->localData.master_data.adj_data,recv.info,recv.Len-18);
|
}
|
break;
|
case GetFileInfo:
|
case GetFile:
|
case EnterHome:
|
case StopDischarge:
|
case StopCharge:
|
case NewBatt:
|
case ChangedBatt:
|
case DelBatt:
|
case ClearAlarm:
|
break;
|
default:
|
break;
|
}
|
}
|
|
void SlaveCtrl::MasterMode(FRAME_DATA &recv, FRAME_DATA &Sent)
|
{
|
if(waitRecvCnt)
|
{
|
--waitRecvCnt;
|
if(ReadFrameData(recv,Sent) == true)
|
{
|
waitRecvCnt = 0;
|
if(Sent.RecState == SUCCEED)
|
{
|
MasterDisposeCMD(recv);
|
}
|
}
|
//qDebug("----%d",waitRecvCnt);
|
}
|
else
|
{
|
if(master_cmd.count() > 0)
|
{
|
if(MasterSentFrame(master_cmd.first()) == true)
|
{
|
waitRecvCnt = 5;
|
master_cmd.removeFirst();
|
}
|
}
|
else if(work_page->work_thread->localData.master_data.Enter_ctrl)
|
{
|
setMasterCmd(GetDischargeData);
|
}
|
else
|
{
|
ReadFrameData(recv,Sent);
|
}
|
}
|
}
|
|
void SlaveCtrl::setMasterCmd(CMD_TYPE CMD, quint8 status, quint8 Cid1, quint8 Cid2,quint8 arm)
|
{
|
MASTER_CMD temp;
|
temp.CMD = CMD;
|
temp.RecState = status;
|
temp.Cid1 = Cid1;
|
temp.Cid2 = Cid2;
|
temp.Alarm = arm;
|
|
master_cmd.append(temp);
|
}
|
|
void SlaveCtrl::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;
|
if(((COMM_TEST_PARAM *)comm_param)->preset_cur>=MinCur)
|
test_param.preset_cur = ((COMM_TEST_PARAM *)comm_param)->preset_cur;
|
else
|
test_param.preset_cur = MinCur;
|
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 SlaveCtrl::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 SlaveCtrl::dataReceived()
|
{
|
QByteArray buffer;
|
//读取缓冲区数据
|
if(ServerFlag)
|
buffer = tcpSocket->readAll();
|
else if(ClientFlag)
|
buffer = tcpClient->readAll();
|
// qDebug()<<buffer.toHex();
|
if(!buffer.isEmpty())
|
{
|
FRAME_DATA frame_sent;
|
memset(&frame_sent,0x00,sizeof(FRAME_DATA));
|
FRAME_DATA *frame_recv = (FRAME_DATA*)buffer.data();
|
SlaveMode(*frame_recv,frame_sent);
|
}
|
}
|
|
void SlaveCtrl::deleteSocket()
|
{
|
IF_CLOSEServer = IF_CLOSEClient = true;
|
}
|
|
void SlaveCtrl::Restartlisten(void)
|
{
|
if(ClientFlag || NULL != tcpSocket)
|
IF_CLOSEClient = true;
|
qDebug("---Restartlisten-");
|
}
|
|
bool SlaveCtrl::isConnect(void)
|
{
|
return (ServerFlag || ClientFlag);
|
}
|
|
void SlaveCtrl::sentClientConnect(const QString &hostName, quint16 port)
|
{
|
if(tcpServer->isListening()||
|
ServerFlag ||
|
tcpServer->hasPendingConnections())
|
IF_CLOSEServer = true;
|
qDebug()<<hostName<<port;
|
ClienthostName = hostName;
|
Clientport = port;
|
}
|
|
void SlaveCtrl::run()
|
{
|
tcpServer = new QTcpServer();
|
tcpServer->setMaxPendingConnections(1);
|
tcpSocket = new QTcpSocket();
|
tcpClient = new QTcpSocket();
|
Restartlisten();
|
|
bool timeOut = true;
|
while(true)
|
{
|
if(work_page->work_thread->localData.tcp_ctrl.mode==0)//服务端
|
{
|
if(!tcpServer->isListening())//开启监听
|
tcpServer->listen(QHostAddress::Any, 6666);
|
if(tcpServer->waitForNewConnection(5000, &timeOut)&&(!IF_CLOSEServer))
|
{
|
tcpSocket = tcpServer->nextPendingConnection();
|
if(NULL != tcpSocket)
|
{
|
ServerFlag = 1;
|
while(1)
|
{
|
if(tcpSocket->waitForReadyRead(30000)&&(!IF_CLOSEServer))
|
{
|
dataReceived();
|
}
|
else
|
{
|
work_page->work_thread->localData.tcp_ctrl.heart_cnt = 0;
|
work_page->work_thread->localData.tcp_ctrl.Enter_ctrl = 0;
|
break;
|
}
|
}
|
}
|
}
|
ServerFlag = 0;
|
IF_CLOSEServer = false;
|
tcpSocket->close();
|
tcpServer->close();
|
msleep(500);
|
}
|
else//客户端
|
{
|
tcpClient->connectToHost(ClienthostName,Clientport);
|
if(tcpClient->waitForConnected(5000)&&(!IF_CLOSEClient))
|
{
|
if(NULL != tcpClient)
|
{
|
ClientFlag = 1;
|
while(1)
|
{
|
if(tcpClient->waitForReadyRead(30000)&&(!IF_CLOSEClient))
|
{
|
dataReceived();
|
}
|
else
|
{
|
work_page->work_thread->localData.tcp_ctrl.heart_cnt = 0;
|
work_page->work_thread->localData.tcp_ctrl.Enter_ctrl = 0;
|
break;
|
}
|
}
|
}
|
}
|
ClientFlag = 0;
|
IF_CLOSEClient = false;
|
tcpClient->close();
|
msleep(500);
|
}
|
}
|
}
|
//***********************************************************************************
|