#include "OutilModbus.h" #include "ProtocolDefs.h" #include COutilModbus::COutilModbus(QObject *parent) : QObject(parent) { mModbusSEIEmulator = new CModbusSlave(&mSEIModbusRepo); mModbusCCEmulator = new CModbusMaster(&mCCModbusRepo); w = new MainWindow(0,this); mAutoRequestTimer = new QTimer(); mAutoRequestTimer->setSingleShot(false); connect(mAutoRequestTimer,SIGNAL(timeout()),this,SLOT(AutoRequestTimeExpired())); mWatchdogEnabled = true; mWatchdog = 0; mWatchdogTimer = new QTimer(); mWatchdogTimer->setSingleShot(false); connect(mWatchdogTimer,SIGNAL(timeout()),this,SLOT(WatchdogTimerExpired())); mWatchdogTimer->setInterval(MODBUS_CC_WATCHDOG_TIMEOUT); mSEIWatchdogTimer = new QTimer(); mSEIWatchdogTimer->setSingleShot(false); mSEIWatchdogTimer->setInterval(MODBUS_SEI_WATCHDOG_TIMEOUT); connect(mSEIWatchdogTimer,SIGNAL(timeout()),this,SLOT(SEIWatchdogExpired())); mZTAlarmGenerator = new CZTAlarmGenerator; mZTAlarmGenerator->mAlarmGeneratorPageHandle = w->mZTAlarmGeneratorPage; w->mZTAlarmGeneratorPage->mProgramHandle = mZTAlarmGenerator; mHistorienMaster = new CModbusHistorienMaster(&mHistorienRepo); w->mHistorianPage->mProgramHandle = mHistorienMaster; mSEIWatchdogValue = 0; } COutilModbus::~COutilModbus() { delete mModbusSEIEmulator; delete mAutoRequestTimer; delete mWatchdogTimer; delete w; delete mSEIWatchdogTimer; delete mZTAlarmGenerator; } int COutilModbus::Start() { w->resize(1024,768); w->show(); mModbusPageHandle = w->mModbusPage; mSEIModbusPageHandle = w->mSEIModbusPage; mHistorienMaster->mPageHandle = w->mHistorianPage; mCCModbusRepo.AddHRDataMap(2000,128); //mModbusSEIEmulator->StartSlaveServer(502); mModbusSEIEmulator->SetServerPort(502); mSEIModbusRepo.AddHRDataMap(2000,128); mSEIModbusRepo.AddHRDataMap(3000,128); connect(mModbusCCEmulator,SIGNAL(ModbusMasterConnected(CModbusMaster*)),this,SLOT(ModbusMasterConnected(CModbusMaster*))); connect(mModbusCCEmulator,SIGNAL(ModbusMasterDisconnected(CModbusMaster*)),this,SLOT(ModbusMasterDisconnected(CModbusMaster*))); connect(mModbusCCEmulator,SIGNAL(ModbusMasterRepositoryUpdated()),this,SLOT(ModbusMasterRepositoryUpdated())); connect(mModbusCCEmulator,SIGNAL(ModbusRX()),mModbusPageHandle,SLOT(ModbusActivity())); connect(mModbusSEIEmulator,SIGNAL(ModbusSlaveConnected(CModbusSlave*)),this,SLOT(SEIModbusConnected(CModbusSlave*))); connect(mModbusSEIEmulator,SIGNAL(ModbusSlaveDisconnected(CModbusSlave*)),this,SLOT(SEIModbusDisconnected(CModbusSlave*))); connect(mModbusSEIEmulator,SIGNAL(ModbusSlaveRepoUpdated()),this,SLOT(SEIRepositoryUpdated())); mHistorienRepo.AddHRDataMap(2000,128); return 1; } void COutilModbus::ModbusMasterConnected(CModbusMaster *Master) { mModbusPageHandle->MasterConnected(); mAutoRequestTimer->stop(); if(mWatchdogEnabled) { mWatchdogTimer->start(); } } void COutilModbus::ModbusMasterDisconnected(CModbusMaster *Master) { mModbusPageHandle->MasterDisconnected(); mWatchdogTimer->stop(); mAutoRequestTimer->stop(); } void COutilModbus::ModbusMasterRepositoryUpdated() { if(UpdateZTInfo(&mCurZTInfo,&mCCModbusRepo) == RET_OK) { mModbusPageHandle->UpdateZTInfo(&mCurZTInfo); } } void COutilModbus::SEIModbusConnected(CModbusSlave *Slave) { mSEIModbusPageHandle->SetConnected(true); } void COutilModbus::SEIModbusDisconnected(CModbusSlave *Slave) { mSEIModbusPageHandle->SetConnected(false); } void COutilModbus::SEIRepositoryUpdated() { if(UpdateZTInfo(&mCurZTInfo, &mSEIModbusRepo) == RET_OK) { mSEIModbusPageHandle->UpdateZTInfo(&mCurZTInfo); } } int COutilModbus::ConnectCCToZTButtonPressed(QString IP, int Port) { mModbusCCEmulator->ConnectToSlave(IP,Port); return 1; } int COutilModbus::DisconnectCCFromZTButtonPressed() { return mModbusCCEmulator->DisconnectFromSlave(); } int COutilModbus::SetCCReqDelay(int delay) { return 1; } int COutilModbus::SendMasterReadCommand() { return mModbusCCEmulator->ReadModbusRegisters(); } int COutilModbus::UpdateZTInfo(CZTInfo *DataStruct, CModbusRepository *SourceRepo) { bool OK = false; // quint16 data = mCCModbusRepo.GetSingleReg(MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD,&OK); quint16 data = SourceRepo->GetSingleReg(MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD,&OK); if(OK == true) { DataStruct->mZT1PPIAlarmFlag1 = (data & ZT1_PP_INT_FLAG_MASK_1) != 0; DataStruct->mZT1PPIAlarmFlag2 = (data & ZT1_PP_INT_FLAG_MASK_2) != 0; DataStruct->mZT1PPIAlarmFlag3 = (data & ZT1_PP_INT_FLAG_MASK_3) != 0; DataStruct->mZT1PPIAlarmFlag4 = (data & ZT1_PP_INT_FLAG_MASK_4) != 0; DataStruct->mZT1PPEAlarmFlag1 = (data & ZT1_PP_EXT_FLAG_MASK_1) != 0; DataStruct->mZT1PPEAlarmFlag2 = (data & ZT1_PP_EXT_FLAG_MASK_2) != 0; DataStruct->mZT1PPEAlarmFlag3 = (data & ZT1_PP_EXT_FLAG_MASK_3) != 0; DataStruct->mZT1PPEAlarmFlag4 = (data & ZT1_PP_EXT_FLAG_MASK_4) != 0; DataStruct->mZT1PGAlarmFlag1 = (data & ZT1_PG_FLAG_MASK_1) != 0; DataStruct->mZT1PGAlarmFlag2 = (data & ZT1_PG_FLAG_MASK_2) != 0; DataStruct->mZT1PGAlarmFlag3 = (data & ZT1_PG_FLAG_MASK_3) != 0; DataStruct->mZT1PGAlarmFlag4 = (data & ZT1_PG_FLAG_MASK_4) != 0; DataStruct->mZT1FNAlarmFlag1 = (data & ZT1_FN_FLAG_MASK_1) != 0; DataStruct->mZT1FNAlarmFlag2 = (data & ZT1_FN_FLAG_MASK_2) != 0; DataStruct->mZT1FNAlarmFlag3 = (data & ZT1_FN_FLAG_MASK_3) != 0; DataStruct->mZT1FNAlarmFlag4 = (data & ZT1_FN_FLAG_MASK_4) != 0; } else { qDebug("GetSingleReg failed in UpdateZTInfo (MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD)"); return RET_ERROR; } QList RankData; RankData = SourceRepo->GetRegs(MODBUS_ZT1_ALARM_RANKS_BASE_ADD,16,&OK); if(OK == true) { DataStruct->mZT1Ranks = RankData; } else { qDebug("GetSingleReg failed in UpdateZTInfo (MODBUS_ZT1_ALARM_RANKS_BASE_ADD)"); return RET_ERROR; } data = SourceRepo->GetSingleReg(MODBUS_ZT2_ALARM_DATA_BASE_REG_ADD,&OK); if(OK == true) { DataStruct->mZT2PPIAlarmFlag1 = (data & ZT2_PP_INT_FLAG_MASK_1) != 0; DataStruct->mZT2PPIAlarmFlag2 = (data & ZT2_PP_INT_FLAG_MASK_2) != 0; DataStruct->mZT2PPIAlarmFlag3 = (data & ZT2_PP_INT_FLAG_MASK_3) != 0; DataStruct->mZT2PPIAlarmFlag4 = (data & ZT2_PP_INT_FLAG_MASK_4) != 0; DataStruct->mZT2PPEAlarmFlag1 = (data & ZT2_PP_EXT_FLAG_MASK_1) != 0; DataStruct->mZT2PPEAlarmFlag2 = (data & ZT2_PP_EXT_FLAG_MASK_2) != 0; DataStruct->mZT2PPEAlarmFlag3 = (data & ZT2_PP_EXT_FLAG_MASK_3) != 0; DataStruct->mZT2PPEAlarmFlag4 = (data & ZT2_PP_EXT_FLAG_MASK_4) != 0; } else { qDebug("GetSingleReg failed in UpdateZTInfo (MODBUS_ZT2_ALARM_DATA_BASE_REG_ADD)"); return RET_ERROR; } RankData.clear(); RankData = SourceRepo->GetRegs(MODBUS_ZT2_ALARM_RANKS_BASE_ADD,8,&OK); if(OK == true) { DataStruct->mZT2Ranks = RankData; } else { qDebug("GetSingleReg failed in UpdateZTInfo (MODBUS_ZT2_ALARM_RANKS_BASE_ADD)"); return RET_ERROR; } data = SourceRepo->GetSingleReg(MODBUS_MISC_DATA_BASE_REG_ADD,&OK); if(OK == true) { DataStruct->mZT1V00AlarmFlag = (data & ZT1_V00_ALARM_FLAG_MASK) != 0; DataStruct->mZT1PEQ1AlarmFlag = (data & ZT1_PEQ1_ALARM_FLAG_MASK) != 0; DataStruct->mZT2V02AlarmFlag = (data & ZT2_V02_ALARM_FLAG_MASK) != 0; DataStruct->mZT2PEQ2AlarmFlag = (data & ZT2_PEQ2_ALARM_FLAG_MASK) != 0; DataStruct->mITI10_12Flag = (data & ZT1_ALARM_ITI_FLAG_MASK) != 0; } else { qDebug("GetSingleReg failed in UpdateZTInfo (MODBUS_PANNES_DATA_BASE_REG_ADD)"); return RET_ERROR; } DataStruct->mWatchdogZT = SourceRepo->GetSingleReg(MODBUS_ZT_WATCHDOG_REG_ADD,&OK); return RET_OK; } int COutilModbus::SendAN1Request() //FCYCLE { bool OK = false; quint16 AN1; quint16 CurValue = mCCModbusRepo.GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD,&OK); AN1 = CurValue & MODBUS_CC_FCYCLE_ZT1_FLAG_MASK; if(OK == true) { if(AN1 == 0) { CurValue |= MODBUS_CC_FCYCLE_ZT1_FLAG_MASK; mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue); qDebug("Setting FCYCLE in repo"); } else { CurValue &= ~MODBUS_CC_FCYCLE_ZT1_FLAG_MASK; mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue); qDebug("Clearing FCYCLE in repo"); } mModbusCCEmulator->SendAN1ToZT(); } return RET_OK; } int COutilModbus::SendAN2Request() { bool OK = false; quint16 AN2; quint16 CurValue = mCCModbusRepo.GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD,&OK); AN2 = CurValue & MODBUS_CC_FCYCLE_ZT2_FLAG_MASK; if(OK == true) { if(AN2 == 0) { CurValue |= MODBUS_CC_FCYCLE_ZT2_FLAG_MASK; mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue); qDebug("Setting FCYCLE in repo"); } else { CurValue &= ~MODBUS_CC_FCYCLE_ZT2_FLAG_MASK; mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue); qDebug("Clearing FCYCLE in repo"); } mModbusCCEmulator->SendAN2ToZT(); } return RET_OK; } int COutilModbus::SendZTCZT1Request() { bool OK = false; quint16 ZTC1; quint16 CurValue = mCCModbusRepo.GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD,&OK); ZTC1 = CurValue & MODBUS_CC_FCYCLE_ZT1_FLAG_MASK; if(OK == true) { if(ZTC1 == 0) { CurValue |= MODBUS_CC_FCYCLE_ZT1_FLAG_MASK; mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue); qDebug("Setting ZTC1 in repo"); } else { CurValue ^= MODBUS_CC_FCYCLE_ZT1_FLAG_MASK; mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue); qDebug("Clearing ZTC1 in repo"); } mModbusCCEmulator->SendAN2ToZT(); } return RET_OK; } int COutilModbus::SendZTCZT2Request() { bool OK = false; quint16 ZTC2; quint16 CurValue = mCCModbusRepo.GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD,&OK); ZTC2 = CurValue & MODBUS_CC_FCYCLE_ZT2_FLAG_MASK; if(OK == true) { if(ZTC2 == 0) { CurValue |= MODBUS_CC_FCYCLE_ZT2_FLAG_MASK; mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue); qDebug("Setting ZTC2 in repo"); } else { CurValue ^= MODBUS_CC_FCYCLE_ZT2_FLAG_MASK; mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue); qDebug("Clearing ZTC2 in repo"); } mModbusCCEmulator->SendAN2ToZT(); } return RET_OK; } int COutilModbus::SetAutoRequestMode(bool Auto, int Delay) { if(Auto == false) { mAutoRequestTimer->stop(); } else { mAutoRequestTimer->setInterval(Delay); mAutoRequestTimer->start(); } return RET_OK; } void COutilModbus::AutoRequestTimeExpired() { SendMasterReadCommand(); } int COutilModbus::EnableWatchdog(bool Enabled) { mWatchdogEnabled = Enabled; if(Enabled) { mWatchdogTimer->start(); } else { mWatchdogTimer->stop(); } return RET_OK; } void COutilModbus::WatchdogTimerExpired() { if(mWatchdog == 0) { mWatchdog = 1; } else { mWatchdog = 0; } mCCModbusRepo.WriteSingleReg(MODBUS_CC_WATCHDOG_BASE_REG_ADD,mWatchdog); // qDebug("Watchdog: %d",mWatchdog); mModbusCCEmulator->SendWatchdog(); } int COutilModbus::SendDateTime() { QList DateTimeData; QDateTime CurDateTime = QDateTime::currentDateTime().toUTC(); qint16 tmpWord; qint8 tmpByte; DateTimeData.append(MODBUS_CC_CLK_UPDATE_FLAG_MASK); tmpByte = DecToBCDByte((qint8)CurDateTime.time().second()); tmpWord = (qint16)tmpByte << 8; DateTimeData.append(tmpWord); tmpByte = DecToBCDByte((qint8)CurDateTime.time().hour()); tmpWord = (qint16)tmpByte << 8; tmpByte = DecToBCDByte((qint8)CurDateTime.time().minute()); tmpWord += tmpByte; DateTimeData.append(tmpWord); tmpByte = DecToBCDByte((qint8)CurDateTime.date().month()); tmpWord = (qint16)tmpByte << 8; tmpByte = DecToBCDByte((qint8)CurDateTime.date().day()); tmpWord += tmpByte; DateTimeData.append(tmpWord); tmpWord = DecToBCDWord((qint16)CurDateTime.date().year()); DateTimeData.append(tmpWord); mCCModbusRepo.WriteMultipleRegs(MODBUS_CC_CLK_UPDATE_BASE_REG_ADD,DateTimeData); mModbusCCEmulator->SendDateTime(); return RET_OK; } int COutilModbus::SendTrainInfo(QList TrainInfo) { mCCModbusRepo.WriteMultipleRegs(MODBUS_CC_ZT1_TRAIN_TYPE_REG_ADD,TrainInfo); mModbusCCEmulator->SendTrainData(); return RET_OK; } int COutilModbus::SendInhibitZT(qint16 InhibZT1, qint16 InhibZT2) { bool OK = false; qint16 Register = mCCModbusRepo.GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD,&OK); if(OK) { if(InhibZT1 == 0) { Register &= ~MODBUS_CC_INHIBIT_ZT1_FLAG_MASK; } else { Register |= MODBUS_CC_INHIBIT_ZT1_FLAG_MASK; } if(InhibZT2 == 0) { Register &= ~MODBUS_CC_INHIBIT_ZT2_FLAG_MASK; } else { Register |= MODBUS_CC_INHIBIT_ZT2_FLAG_MASK; } mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,Register); mModbusCCEmulator->SendZTInhibitionData(); return RET_OK; } return RET_ERROR; } quint8 COutilModbus::DecToBCDByte(const quint8 byte) { quint8 out = 0; out = ((byte/10) << 4) + (byte%10); return out; } quint16 COutilModbus::DecToBCDWord(const quint16 word) { quint16 out = 0; quint16 temp = 0; out = word % 10; temp = (((word /10) % 10) << 4); out += temp; temp = (((word / 100) % 10) << 8); out += temp; temp = (((word / 1000) % 10) << 12); out += temp; return out; } int COutilModbus::ToggleSEIServerState() { return mModbusSEIEmulator->ToggleServerState(); } bool COutilModbus::IsSEIServerOpened() { return mModbusSEIEmulator->IsSlaveServerOpened(); } int COutilModbus::SEIWatchdogEnable(bool Enabled) { if(Enabled) { mSEIWatchdogTimer->start(); } else { mSEIWatchdogTimer->stop(); } return RET_OK; } void COutilModbus::SEIWatchdogExpired() { if(mSEIWatchdogValue == 0) { mSEIWatchdogValue = SEI_MODBUS_SEI_WATCHDOG_MASK; } else { mSEIWatchdogValue = 0; } mSEIModbusRepo.WriteSingleReg(SEI_MODBUS_SEI_WATCHDOG_REG,mSEIWatchdogValue); } int COutilModbus::SEIAN1Toggle(bool Enabled) { qint16 temp; bool OK; temp = mSEIModbusRepo.GetSingleReg(SEI_MODBUS_SEI_ALARMS_RESET_REG,&OK); if(OK == false) { qDebug("SEIAN1Toggle(): logic error in modbus table assignment. Can't read address %d",SEI_MODBUS_SEI_ALARMS_RESET_REG); return RET_ERROR; } if(Enabled) { temp |= SEI_MODBUS_SEI_ZT1_ALARM_RESET_MASK; } else { temp &= ~SEI_MODBUS_SEI_ZT1_ALARM_RESET_MASK; } mSEIModbusRepo.WriteSingleReg(SEI_MODBUS_SEI_ALARMS_RESET_REG,temp); return RET_OK; } int COutilModbus::SEIAN2Toggle(bool Enabled) { qint16 temp; bool OK; temp = mSEIModbusRepo.GetSingleReg(SEI_MODBUS_SEI_ALARMS_RESET_REG,&OK); if(OK == false) { qDebug("SEIAN2Toggle(): logic error in modbus table assignment. Can't read address %d",SEI_MODBUS_SEI_ALARMS_RESET_REG); return RET_ERROR; } if(Enabled) { temp |= SEI_MODBUS_SEI_ZT2_ALARM_RESET_MASK; } else { temp &= ~SEI_MODBUS_SEI_ZT2_ALARM_RESET_MASK; } mSEIModbusRepo.WriteSingleReg(SEI_MODBUS_SEI_ALARMS_RESET_REG,temp); return RET_OK; }