- #ifndef MYDS7400_COM_H
- #define MYDS7400_COM_H
- #include <QObject>
- #include "qextserialport.h"
- #include <QTimer>
- #include <QDateTime>
- /* 说明:DS7400主机操作头文件
- * 功能:动态识别主机上线下线及布防撤防报警等信号
- * 作者:刘典武 QQ:517216493
- * 时间:2014-1-5 检查:2014-1-10
- */
- class myDS7400_COM : public QObject
- {
- Q_OBJECT
- public:
- explicit myDS7400_COM(QObject *parent = 0);
- //设置和获取主机类型
- void SetHostType(QString hostType){this->hostType=hostType;}
- QString HostType()const{return hostType;}
- //设置和获取主机ID
- void SetHostID(QString hostID){this->hostID=hostID;}
- QString HostID()const{return hostID;}
- //设置和获取主机名称
- void SetHostName(QString hostName){this->hostName=hostName;}
- QString HostName()const{return hostName;}
- //设置和获取主机通讯参数1
- void SetHostConnectValue1(QString hostConnectValue1){this->hostConnectValue1=hostConnectValue1;}
- QString HostConnectValue1()const{return hostConnectValue1;}
- //设置和获取主机通讯参数2
- void SetHostConnectValue2(QString hostConnectValue2){this->hostConnectValue2=hostConnectValue2;}
- QString HostConnectValue2()const{return hostConnectValue2;}
- bool Open();
- bool IsOpen()const{return isOpen;}
- void Close();
- private:
- QextSerialPort *hostCOM;
- bool isOpen; //打开状态
- QTimer *timerRead; //定时器读取数据
- bool isOnLine; //在线状态,初始值为假
- bool isCheckOnline; //检测下线状态,初始值为真
- QDateTime lastHeartTime; //存储最后一次心跳时间
- QTimer *timerOnLine; //定时器检测主机上线
- QString hostType; //主机类型
- QString hostID; //主机编号
- QString hostName; //主机名称
- QString hostConnectValue1; //主机参数1
- QString hostConnectValue2; //主机参数2
- void CheckCode(QString code);
- QString GetDefenceID(int tempID);
- QString StrHexToStrBin(QString strHex);
- int StrHexToDecimal(QString strHex);
- void Sleep(int sec);
- private slots:
- void ReadData(); //读取数据槽函数
- void CheckOnLine(); //检测在线状态槽函数
- signals:
- void HostConnect(QString hostID,QString hostName); //主机上线
- void HostDisConnect(QString hostID,QString hostName); //主机下线
- void HostError(QString hostID,QString hostName,QString error); //主机错误,例如电池掉电
- void HostBuFangSubSystem(QString hostID,QString hostName,int subSystem); //主机子系统布防
- void HostCheFangSubSystem(QString hostID,QString hostName,int subSystem);//主机子系统撤防
- void DefenceBaoJing(QString hostID,QString hostName,QString defenceID); //防区报警
- void DefencePangLu(QString hostID,QString hostName,QString defenceID); //防区旁路
- void DefenceGuZhang(QString hostID,QString hostName,QString defenceID); //防区故障
- void DefenceHuiFu(QString hostID,QString hostName,QString defenceID); //防区恢复
- public slots:
- };
- #endif // MYDS7400_COM_H
- #include "myds7400_com.h"
- #include <QCoreApplication>
- /* 说明:DS7400主机操作实现文件
- * 功能:动态识别主机上线下线及布防撤防报警等信号
- * 作者:刘典武 QQ:517216493
- * 时间:2014-1-5 检查:2014-1-10
- */
- myDS7400_COM::myDS7400_COM(QObject *parent) :
- QObject(parent)
- {
- isOnLine=false;
- isCheckOnline=true;
- lastHeartTime=QDateTime::currentDateTime();
- isOpen=false;
- //启动定时器读取串口数据
- timerRead=new QTimer(this);
- timerRead->setInterval(500);
- connect(timerRead,SIGNAL(timeout()),this,SLOT(ReadData()));
- //启动定时器判断在线状态
- timerOnLine=new QTimer(this);
- timerOnLine->setInterval(1000);
- connect(timerOnLine,SIGNAL(timeout()),this,SLOT(CheckOnLine()));
- }
- bool myDS7400_COM::Open()
- {
- hostCOM=new QextSerialPort(this->hostConnectValue1);
- bool IsOpen=hostCOM->open(QIODevice::ReadWrite);
- if (IsOpen){
- hostCOM->flush();//清空串口缓冲区
- hostCOM->setBaudRate(BAUD2400);
- hostCOM->setDataBits(DATA_8);
- hostCOM->setParity(PAR_NONE);
- hostCOM->setStopBits(STOP_1);
- hostCOM->setFlowControl(FLOW_OFF);
- hostCOM->setTimeout(10);
- //开启定时器读取数据和判断主机上线下线
- timerRead->start();
- timerOnLine->start();
- isOpen=true;
- }
- return IsOpen;
- }
- void myDS7400_COM::Close()
- {
- hostCOM->close();
- timerRead->stop();
- timerOnLine->stop();
- isOpen=false;
- }
- void myDS7400_COM::CheckOnLine()
- {
- //计算最后心跳时间到现在相差多少,如果小于18秒,说明有过心跳,还活着,不做下线处理
- //主机定时16秒向串口发送消息
- QDateTime timeNow=QDateTime::currentDateTime();
- int timeValue=lastHeartTime.secsTo(timeNow);
- if (timeValue<=18){return;}
- //如果当前主机状态为在线,并且还没有检测过下线状态,说明现在主机下线
- if (isOnLine && !isCheckOnline){
- isOnLine=false;
- isCheckOnline=true;
- emit this->HostDisConnect(this->hostID,this->hostName);
- }
- }
- bool ErrorAC=false; //交流电源故障
- bool ErrorDC=false; //备用电池故障
- bool ErrorCode=false; //报告发送故障
- bool ErrorControl=false; //控制故障
- bool Error485=false; //总线故障
- bool ErrorWifi=false; //无线接收故障
- bool ErrorPower=false; //辅助电源故障
- bool ErrorDevice=false; //设备故障
- void myDS7400_COM::ReadData()
- {
- //这个判断尤为重要,否则的话直接延时再接收数据,空闲时和会出现高内存占用
- if (hostCOM->bytesAvailable()<=0){return;}
- //将心跳时间改为当前时间,将在线状态置为真
- lastHeartTime=QDateTime::currentDateTime();
- isOnLine=true;
- //如果处于下线状态,说明是首次收到数据,代表主机上线
- if (isCheckOnline){
- isCheckOnline=false;
- emit this->HostConnect(hostID,hostName);
- }
- //延时100毫秒保证接收到的是一条完整的数据,而不是脱节的,当有N个防区同时报警时,数据比较长
- Sleep(100);
- QByteArray data=hostCOM->readAll();
- int len=data.length();
- int index=0;
- //转换为16进制字符串
- QString tempBuffer=data.toHex().toUpper();
- QList<QString> buffer;
- int tempLen=tempBuffer.count();
- for (int i=0;i<tempLen;i=i+2){
- buffer<<tempBuffer.mid(i,2);
- }
- while(index<len)
- {
- //A0 01 5E(系统状态代码,每隔16秒钟一个数据包)
- //85 0E 00 74用户操作主机时发送的事件代码
- if (buffer[index]!="A0" && buffer[index]!="85"){
- index++;//移动指针到下一个数据头部
- continue;//返回,执行下一个循环
- }
- if (buffer[index]=="A0"){
- QString code=StrHexToStrBin(buffer[index+1]);
- this->CheckCode(code);
- index=index+3;//移动指针到下一个数据头部
- }else{
- QString code=buffer[index+1];
- QString codex=buffer[index+2];
- int tempID=StrHexToDecimal(codex)+1;//这里0开始编号,所以要+1
- //0E为主机布防
- //0D为撤防/0C为消警
- //07为盗警/01为火警
- //0F为强制旁路/10为防区旁路
- //18为防区开路/0A为火警防区故障/0B为盗警防区故障
- //17为防区短路状态/19为防区正常状态
- if (code=="0E"){
- emit this->HostBuFangSubSystem(hostID,hostName,tempID);
- }else if(code=="0D" || code=="0C"){
- emit this->HostCheFangSubSystem(hostID,hostName,tempID);
- }else if(code=="07" || code=="01"){
- emit this->DefenceBaoJing(hostID,hostName,GetDefenceID(tempID));
- }else if(code=="0F" || code=="10"){
- emit this->DefencePangLu(hostID,hostName,GetDefenceID(tempID));
- }else if(code=="18" || code=="0A" || code=="0B"){
- emit this->DefenceGuZhang(hostID,hostName,GetDefenceID(tempID));
- }else if(code=="17" || code=="19"){
- emit this->DefenceHuiFu(hostID,hostName,GetDefenceID(tempID));
- }
- index=index+4;//移动指针到下一个数据头部
- }
- }
- }
- void myDS7400_COM::Sleep(int sec)
- {
- QTime dieTime = QTime::currentTime().addMSecs(sec);
- while( QTime::currentTime() < dieTime )
- QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
- }
- int myDS7400_COM::StrHexToDecimal(QString strHex)
- {
- bool ok;
- return strHex.toInt(&ok,16);
- }
- QString myDS7400_COM::StrHexToStrBin(QString strHex)
- {
- uchar decimal=StrHexToDecimal(strHex);
- QString bin=QString::number(decimal,2);
- uchar len=bin.length();
- if (len<8){
- for (int i=0;i<8-len;i++){
- bin="0"+bin;
- }
- }
- return bin;
- }
- QString myDS7400_COM::GetDefenceID(int tempID)
- {
- QString defenceID;
- if (tempID<10){
- defenceID=QString("00%1").arg(tempID);
- }else if (tempID<100){
- defenceID=QString("0%1").arg(tempID);
- }
- return defenceID;
- }
- void myDS7400_COM::CheckCode(QString code)
- {
- if (code.mid(7,1)=="1"){
- if (!ErrorAC){
- emit this->HostError(this->hostID,this->hostName,"交流电源故障");
- ErrorAC=true;
- }
- }else{
- ErrorAC=false;
- }
- if (code.mid(6,1)=="1"){
- if (!ErrorDC){
- emit this->HostError(this->hostID,this->hostName,"备用电池故障");
- ErrorDC=true;
- }
- }else{
- ErrorDC=false;
- }
- if (code.mid(5,1)=="1"){
- if (!ErrorCode){
- emit this->HostError(this->hostID,this->hostName,"报告故障");
- ErrorCode=true;
- }
- }else{
- ErrorCode=false;
- }
- if (code.mid(4,1)=="1"){
- if (!ErrorControl){
- emit this->HostError(this->hostID,this->hostName,"控制故障");
- ErrorControl=true;
- }
- }else{
- ErrorControl=false;
- }
- if (code.mid(3,1)=="1"){
- if (!Error485){
- emit this->HostError(this->hostID,this->hostName,"总线故障");
- Error485=true;
- }
- }else{
- Error485=false;
- }
- if (code.mid(2,1)=="1"){
- if (!ErrorWifi){
- emit this->HostError(this->hostID,this->hostName,"无线接收故障");
- ErrorWifi=true;
- }
- }else{
- ErrorWifi=false;
- }
- if (code.mid(1,1)=="1"){
- if (!ErrorPower){
- emit this->HostError(this->hostID,this->hostName,"辅助电源故障");
- ErrorPower=true;
- }
- }else{
- ErrorPower=false;
- }
- if (code.mid(0,1)=="1"){
- if (!ErrorDevice){
- emit this->HostError(this->hostID,this->hostName,"设备故障");
- ErrorDevice=true;
- }
- }else{
- ErrorDevice=false;
- }
- }
- //该片段来自于http://www.codesnippet.cn/detail/1509201410404.html
来源: http://www.codesnippet.cn/detail/1509201410404.html