From fbb173b6b5d81b979fcbeb3155fdf74f7c7f3a99 Mon Sep 17 00:00:00 2001 From: zonetest Date: Thu, 24 Aug 2017 11:28:07 -0400 Subject: [PATCH] Continue dev -> train info from modbus --- Configuration/ZTSettings.ztc | Bin 30 -> 30 bytes sources/GuiElements/ZT1StatsZone.cpp | 151 +++++++++++++++++++-------- sources/GuiElements/ZT1StatsZone.h | 6 +- sources/GuiElements/ZTPage.cpp | 7 ++ sources/GuiElements/ZTPage.h | 6 +- sources/Modbus/ModbusCCMgr.cpp | 24 ++++- sources/Stations/DuCollege.cpp | 8 ++ sources/Stations/DuCollege.h | 6 +- sources/TrainLogFileMgr.cpp | 2 +- sources/ZTStateMachine.cpp | 30 +++--- sources/ZTStateMachine.h | 8 +- sources/Zonetest.cpp | 4 +- 12 files changed, 176 insertions(+), 76 deletions(-) diff --git a/Configuration/ZTSettings.ztc b/Configuration/ZTSettings.ztc index c64b1cd203e6cee44817ff0723a018c56f1fbe83..519bf109c82936f1506d601708d548a072c556ee 100644 GIT binary patch literal 30 ZcmdnB_A~<{BLfga00Rir0&xn60RTqV10DbX literal 30 VcmdnB_A~<{5?}ysetPos(0,12); + mModbusEnabled = false; + + + +} + +unsigned int CZT1StatsZone::Init(bool ModbusEnabled) +{ + mModbusEnabled = ModbusEnabled; + int textpos = 12; + QFont font; + font.setPointSize(15); + + mTrainSpeedText = new QGraphicsTextItem(this); + mTrainSpeedText->setPos(0,textpos); // mTrainSpeedText->setPlainText("Vitesse du train: 0"); - mTrainSpeedText->setFont(font); + mTrainSpeedText->setFont(font); - mBogieCountText = new QGraphicsTextItem(this); - mBogieCountText->setPos(0,34); + textpos += 22; + mBogieCountText = new QGraphicsTextItem(this); + mBogieCountText->setPos(0,textpos); // mBogieCountText->setPlainText("Compte Bogie: 0"); - mBogieCountText->setFont(font); + mBogieCountText->setFont(font); - mS1CountText = new QGraphicsTextItem(this); - mS1CountText->setPos(0,56); + textpos += 22; + mS1CountText = new QGraphicsTextItem(this); + mS1CountText->setPos(0,textpos); // mS1CountText->setPlainText("Compte S1: 0"); - mS1CountText->setFont(font); + mS1CountText->setFont(font); - mS2CountText = new QGraphicsTextItem(this); - mS2CountText->setPos(0,78); + textpos += 22; + mS2CountText = new QGraphicsTextItem(this); + mS2CountText->setPos(0,textpos); // mS2CountText->setPlainText("Compte S2: 0"); - mS2CountText->setFont(font); + mS2CountText->setFont(font); - mFNCountText = new QGraphicsTextItem(this); - mFNCountText->setPos(0,100); + textpos += 22; + mFNCountText = new QGraphicsTextItem(this); + mFNCountText->setPos(0,textpos); // mFNCountText->setPlainText("Compte FN: 0"); - mFNCountText->setFont(font); + mFNCountText->setFont(font); - mActualRankText = new QGraphicsTextItem(this); - mActualRankText->setPos(0,122); + textpos += 22; + mActualRankText = new QGraphicsTextItem(this); + mActualRankText->setPos(0,textpos); // mActualRankText->setPlainText("Rang: 0"); - mActualRankText->setFont(font); + mActualRankText->setFont(font); - mTrainTypeText = new QGraphicsTextItem(this); - mTrainTypeText->setPos(0,144); + textpos += 22; + mTrainTypeText = new QGraphicsTextItem(this); + mTrainTypeText->setPos(0,textpos); // mTrainTypeText->setPlainText("Train Détecté: Aucun"); - mTrainTypeText->setFont(font); + mTrainTypeText->setFont(font); + if(mModbusEnabled == true) + { + textpos += 22; + mTrainCompositionText = new QGraphicsTextItem(this); + mTrainCompositionText->setPos(0,textpos); + mTrainCompositionText->setFont(font); + } + + textpos += 22; mPIValueText = new QGraphicsTextItem(this); - mPIValueText->setPos(0,166); + mPIValueText->setPos(0,textpos); // mTrainTypeText->setPlainText("Train Détecté: Aucun"); mPIValueText->setFont(font); + textpos += 22; mPEValueText = new QGraphicsTextItem(this); - mPEValueText->setPos(0,188); + mPEValueText->setPos(0,textpos); // mTrainTypeText->setPlainText("Train Détecté: Aucun"); mPEValueText->setFont(font); - mLastActivationDateTime = new QGraphicsTextItem(this); - mLastActivationDateTime->setPos(0,210); - mLastActivationDateTime->setFont(font); - mLastActivationDateTime->setPlainText("Dernier passage : "); + textpos += 22; + mLastActivationDateTime = new QGraphicsTextItem(this); + mLastActivationDateTime->setPos(0,textpos); + mLastActivationDateTime->setFont(font); + mLastActivationDateTime->setPlainText("Dernier passage : "); - Reset(); + Reset(); + return RET_OK; } unsigned int CZT1StatsZone::UpdateStats(CZT1ThreadData *DataPtr) @@ -148,14 +173,17 @@ unsigned int CZT1StatsZone::UpdateStats(CZT1ThreadData *DataPtr) mTrainSpeedText->setPlainText(temp); } - if(mTrainType != DataPtr->mTrainType) - { - mTrainType = DataPtr->mTrainType; - temp.clear(); - temp = "Train détecté: "; - temp += CZTData::GetTrainTypeString(mTrainType); - mTrainTypeText->setPlainText(temp); - } + if(mModbusEnabled == false) + { + if(mTrainType != DataPtr->mTrainType) + { + mTrainType = DataPtr->mTrainType; + temp.clear(); + temp = "Train détecté: "; + temp += CZTData::GetTrainTypeString(mTrainType); + mTrainTypeText->setPlainText(temp); + } + } if(mPIValue != DataPtr->mPGIntValue) { mPIValue = DataPtr->mPGIntValue; @@ -201,8 +229,43 @@ unsigned int CZT1StatsZone::Reset() mFNCountText->setPlainText("Compte FN: 0"); mActualRankText->setPlainText("Rang: 0"); mTrainTypeText->setPlainText("Train Détecté: Aucun"); + if(mTrainCompositionText != 0) + { + mTrainCompositionText->setPlainText("Composition : Inconnue"); + } mPIValueText->setPlainText("Pneu Guidage Int.: ?"); mPEValueText->setPlainText("Pneu Guidage Ext.: ?"); return RET_OK; } + +unsigned int CZT1StatsZone::SetTrainParameters(int TrainType, QList TrainComposition) +{ + if(mTrainType != (unsigned)TrainType) + { + mTrainType = TrainType; +// temp.clear(); +// temp = "Train détecté: "; +// temp += CZTData::GetTrainTypeString(mTrainType); + mTrainTypeText->setPlainText(QString("Train détecté : %1").arg(CZTData::GetTrainTypeString(mTrainType))); + } + + if(TrainComposition.size() != 3) + { + //Invalid composition + mTrainCompositionText->setPlainText("Composition: Inconnue"); + } + else if((TrainComposition[0] == 0) || + (TrainComposition[1] == 0) || + (TrainComposition[2] == 0)) + { + //Composition invalide... + mTrainCompositionText->setPlainText("Composition: Inconnue"); + } + else + { + mTrainCompositionText->setPlainText(QString("Composition : %1-%2-%3").arg(TrainComposition[0]).arg(TrainComposition[1]).arg(TrainComposition[2])); + } + + return RET_OK; +} diff --git a/sources/GuiElements/ZT1StatsZone.h b/sources/GuiElements/ZT1StatsZone.h index 04769c3..80967f5 100644 --- a/sources/GuiElements/ZT1StatsZone.h +++ b/sources/GuiElements/ZT1StatsZone.h @@ -31,6 +31,7 @@ #include #include #include "ZTData.h" +#include class CZT1StatsZone : public QGraphicsWidget { @@ -40,15 +41,18 @@ public: // unsigned int UpdateStats(unsigned int BogieCount, unsigned int S1Count, unsigned int S2Count, unsigned int FNCount, unsigned int Rank, unsigned int Bogie, unsigned int TrainType, float TrainSpeed); unsigned int UpdateStats(CZT1ThreadData *DataPtr); + unsigned int SetTrainParameters(int TrainType, QList TrainComposition); unsigned int Reset(); unsigned int SetLastActivationDateTime(); + unsigned int Init(bool ModbusEnabled); private: unsigned int mBogieCount,mS1Count,mS2Count,mFNCount,mActualRank,mActualBogie,mTrainType; float mTrainSpeed; int mPIValue, mPEValue; + bool mModbusEnabled; - QGraphicsTextItem *mTrainSpeedText, *mBogieCountText, *mS1CountText, *mS2CountText, *mFNCountText, *mActualRankText, *mActualBogieText, *mTrainTypeText, *mPIValueText, *mPEValueText, *mLastActivationDateTime; + QGraphicsTextItem *mTrainSpeedText, *mBogieCountText, *mS1CountText, *mS2CountText, *mFNCountText, *mActualRankText, *mActualBogieText, *mTrainTypeText, *mTrainCompositionText, *mPIValueText, *mPEValueText, *mLastActivationDateTime; }; #endif // ZT1STATSZONE_H diff --git a/sources/GuiElements/ZTPage.cpp b/sources/GuiElements/ZTPage.cpp index 15d4351..481d494 100644 --- a/sources/GuiElements/ZTPage.cpp +++ b/sources/GuiElements/ZTPage.cpp @@ -341,6 +341,13 @@ unsigned int CZTPage::SetZT1Data(CZT1ThreadData *Data, bool ForceDisplay) } +unsigned int CZTPage::SetZT1TrainData(int TrainType, QList TrainComposition) +{ + //This is a low frequency stats update (only once for every train), so no timer filtering is necessary. + mZT1Stats->SetTrainParameters(TrainType,TrainComposition); + return RET_OK; +} + unsigned int CZTPage::SetZT2Data(CZT2ThreadData *Data) { if(Data == 0) diff --git a/sources/GuiElements/ZTPage.h b/sources/GuiElements/ZTPage.h index 17bda8e..92c814f 100644 --- a/sources/GuiElements/ZTPage.h +++ b/sources/GuiElements/ZTPage.h @@ -55,6 +55,8 @@ public: CZTPage(QGraphicsWidget *Parent = 0); CPushButton *mToolsPushButton; CPushButton *mZTLogPushButton; + CZT1StatsZone *mZT1Stats; + CZT2StatsZone *mZT2Stats; CZoneTest *mProgramHandle; @@ -67,6 +69,7 @@ public: unsigned int UpdateCDVDisplay(int CDVIndex = -1); unsigned int SetZTStatus(unsigned int NbPass, unsigned int NbTriggers, unsigned int ZT1Active, unsigned int ZT2Active); unsigned int SetZT1Data(CZT1ThreadData *Data, bool ForceDisplay = false); + unsigned int SetZT1TrainData(int TrainType, QList TrainComposition); unsigned int SetZT2Data(CZT2ThreadData *Data); unsigned int SetZT1ActivationState(bool ZT1Activated); unsigned int SetZT2ActivationSTate(bool ZT2Activated); @@ -86,8 +89,7 @@ private: CStatusBar *mStatusBar; CZT1EquipmentWidget *mZT1EquipmentWidget; CZT2EquipmentWidget *mZT2EquipmentWidget; - CZT1StatsZone *mZT1Stats; - CZT2StatsZone *mZT2Stats; + CEventsBar *mEventsBar; QElapsedTimer mZT1DisplayTimer; bool mIsZT2Present; diff --git a/sources/Modbus/ModbusCCMgr.cpp b/sources/Modbus/ModbusCCMgr.cpp index 5f7a7cd..252cd5e 100644 --- a/sources/Modbus/ModbusCCMgr.cpp +++ b/sources/Modbus/ModbusCCMgr.cpp @@ -3,7 +3,7 @@ #include "EngLog.h" #include "ModbusCCDefs.h" #include - +#include "ZTData.h" CModbusCCMgr::CModbusCCMgr(CModbusRepository *Repo, int ModbusPort, int DevID) : CModbusBackend(Repo) @@ -132,8 +132,6 @@ void CModbusCCMgr::RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length } - - emit RepoHasChanged(); } @@ -229,11 +227,27 @@ qint16 CModbusCCMgr::GetZT1TrainType() { bool OK = false; qint16 Reg = mModbusRepo->GetSingleReg(MODBUS_CC_ZT1_TRAIN_TYPE_REG_ADD,&OK); + int Type = TRAIN_TYPE_UNKNOWN; if(OK) { - return Reg; + if(Reg == 63) + { + Type = TRAIN_TYPE_MR63; + } + else if(Reg == 73) + { + Type = TRAIN_TYPE_MR73; + } + else if(Reg == 10) + { + Type = TRAIN_TYPE_MPM10; + } + else + { + Type = TRAIN_TYPE_UNKNOWN; + } } - return 0; + return Type; } qint16 CModbusCCMgr::GetZT2TrainType() diff --git a/sources/Stations/DuCollege.cpp b/sources/Stations/DuCollege.cpp index 9037958..3a275f0 100644 --- a/sources/Stations/DuCollege.cpp +++ b/sources/Stations/DuCollege.cpp @@ -54,16 +54,24 @@ CDuCollegeStation::CDuCollegeStation() mStationInputMasks.InputZT1PIMask = DUCOLLEGE_ZT1_PI_MASK; mStationInputMasks.InputZT1PEMask = DUCOLLEGE_ZT1_PE_MASK; mStationInputMasks.InputZT1FNMask = DUCOLLEGE_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = DUCOLLEGE_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = DUCOLLEGE_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = DUCOLLEGE_ZT2_PE_MASK; //External (ethernet) input module masks mStationInputMasks.InputZT1ITIMask = DUCOLLEGE_IN_ZT1_ITI_MASK; mStationInputMasks.InputZT1ANMask = DUCOLLEGE_IN_ZT1_AN_MASK; mStationInputMasks.InputZT1ARFMask = DUCOLLEGE_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ITIMask = DUCOLLEGE_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT2ANMask = DUCOLLEGE_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT2ARFMask = DUCOLLEGE_IN_ZT2_ARF_MASK; mStationInputMasks.InputStationIDMask = DUCOLLEGE_IN_STATION_ID_MASK; //Logic input masks mStationInputMasks.InputCDVZT1ApproachMask = DUCOLLEGE_IN_CDV_12B_MASK; mStationInputMasks.InputCDVZT1Mask = DUCOLLEGE_IN_CDV_13A_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = 0; + mStationInputMasks.InputCDVZT2Mask = 0; //Output masks mStationOutputMasks.OutputVP1Mask = DUCOLLEGE_OUT_VP1_MASK; diff --git a/sources/Stations/DuCollege.h b/sources/Stations/DuCollege.h index aaf8d89..319ff6f 100644 --- a/sources/Stations/DuCollege.h +++ b/sources/Stations/DuCollege.h @@ -58,11 +58,11 @@ #define DUCOLLEGE_IN_CDV_14B_MASK 0x00000080 #define DUCOLLEGE_IN_CDV_14C_MASK 0x00000100 #define DUCOLLEGE_IN_ZT1_ITI_MASK 0x00000200 -//#define DUCOLLEGE_IN_ZT2_ITI_MASK 0x00000400 +#define DUCOLLEGE_IN_ZT2_ITI_MASK 0x00000400 #define DUCOLLEGE_IN_ZT1_AN_MASK 0x00000800 -//#define DUCOLLEGE_IN_ZT2_AN_MASK 0x00001000 +#define DUCOLLEGE_IN_ZT2_AN_MASK 0x00001000 #define DUCOLLEGE_IN_ZT1_ARF_MASK 0x00002000 -//#define DUCOLLEGE_IN_ZT2_ARF_MASK 0x00004000 +#define DUCOLLEGE_IN_ZT2_ARF_MASK 0x00004000 #define DUCOLLEGE_IN_STATION_ID_MASK 0x00078000 //External (ethernet) output module masks for DUCOLLEGE diff --git a/sources/TrainLogFileMgr.cpp b/sources/TrainLogFileMgr.cpp index 2b5baab..d9bb07f 100644 --- a/sources/TrainLogFileMgr.cpp +++ b/sources/TrainLogFileMgr.cpp @@ -66,7 +66,7 @@ unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName, CZT1Log *ZT quint32 TrainType = 0; quint32 NbElements = 0; quint64 ThreadDataStartTime = 0, ThreadDataEndTime = 0; - qreal MeanSpeed = 0; + qreal MeanSpeed = 0; QDateTime DateTime; diff --git a/sources/ZTStateMachine.cpp b/sources/ZTStateMachine.cpp index 875063f..da04e61 100644 --- a/sources/ZTStateMachine.cpp +++ b/sources/ZTStateMachine.cpp @@ -36,7 +36,7 @@ #include "math.h" #include "MaintenancePage.h" #include "RamMonitor.h" -#include "ModbusCCDefs.h" +//#include "ModbusCCDefs.h" CZTStateMachine::CZTStateMachine(QObject *parent) : QObject(parent) @@ -56,7 +56,7 @@ CZTStateMachine::CZTStateMachine(QObject *parent) : mZtSimPtr = 0; mLogMgr = 0; mCalibrationPassagesCount = 0; - mCCModbusRepo = 0; + mModbusCCMgr = 0; //mExtIOInterface = 0; mNbPassages = 0; @@ -167,22 +167,12 @@ unsigned int CZTStateMachine::ZTStateMachine(unsigned int Event, unsigned int Su mCIZT2Active = ((mCurInputs & mZTInputMasks->InputZT2ITIMask) != 0); bool AN1State, AN2State; - //If the mCCModbusRepo is not 0, then it has to be used (Modbus connection is used as CC interface) - if(mCCModbusRepo == 0) + //If the ModbusCCPtr pointer is not 0, then we are using Modbus and AN states will come from there. + if(mModbusCCMgr == 0) { AN1State = (mCurInputs & mZTInputMasks->InputZT1ANMask) != 0; AN2State = (mCurInputs &mZTInputMasks->InputZT2ANMask) != 0; } -// else -// { -// AN1State = (mCCModbusRepo->GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD) & MODBUS_CC_AN1_FLAG_MASK) != 0; -// AN2State = (mCCModbusRepo->GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD) & MODBUS_CC_AN2_FLAG_MASK) != 0; -// } - -// mTKGenerator->SetInputStates((mCurInputs & mZTInputMasks->InputZT1ANMask) != 0, -// mZTStationPtr->IsZT1AlarmAutoAcquireCDVOccupied(), -// (mCurInputs &mZTInputMasks->InputZT2ANMask) != 0, -// mZTStationPtr->IsZT2AlarmAutoAcquireCDVOccupied()); mTKGenerator->SetInputStates(AN1State,mZTStationPtr->IsZT1AlarmAutoAcquireCDVOccupied(), AN2State,mZTStationPtr->IsZT2AlarmAutoAcquireCDVOccupied()); } @@ -356,6 +346,14 @@ unsigned int CZTStateMachine::ZT1StateMachine(unsigned int Event, unsigned int S mZTPagePTr->SetZT1ActivationState(true); mZTPagePTr->ResetZT1Stats(); + if(mModbusCCMgr != 0) + { + //update train info received from the CC Modbus interface + mTrainTypeDetected = (unsigned)mModbusCCMgr->GetZT1TrainType(); + mZT1TrainComposition = mModbusCCMgr->GetZT1TrainComposition(); + mZTPagePTr->SetZT1TrainData(mTrainTypeDetected,mZT1TrainComposition); + } + InsertZT1LogItem(); mZT1WorkerThread->UpdateDetectionConfig(mZTDetectionConfig); @@ -1332,9 +1330,9 @@ void CZTStateMachine::BindPointers(CStation *ptr,CInputModule *InputModule,COutp mTKGenerator = TKTransport; } -void CZTStateMachine::BindCCRepoPtr(CModbusRepository *RepoPtr) +void CZTStateMachine::BindModbusCCMgrPtr(CModbusCCMgr *ModbusCCPtr) { - mCCModbusRepo = RepoPtr; + mModbusCCMgr = ModbusCCPtr; } unsigned int CZTStateMachine::SetPGTreshold(qint32 PGTreshold) diff --git a/sources/ZTStateMachine.h b/sources/ZTStateMachine.h index 4b0db81..d008afa 100644 --- a/sources/ZTStateMachine.h +++ b/sources/ZTStateMachine.h @@ -43,8 +43,9 @@ #include "LogMgr.h" #include "InputModule.h" #include "MixedModule.h" -#include "ModbusRepository.h" +//#include "ModbusRepository.h" #include "TKTransportInterface.h" +#include "ModbusCCMgr.h" #define ZT_SM_DEFAULT_LOG_DELAY 10 //millilseconds @@ -105,7 +106,7 @@ public: ~CZTStateMachine(); unsigned int ZTStateMachine(unsigned int Event, unsigned int SubEvent = 0); //Exécution de la SM principale void BindPointers(CStation *ptr,CInputModule *InputModule,COutputModule *OutputModule,CZTPage *ZTPagePTr,CPCIIOMgr *PCIIOPtr,CAbstractLazerProbe *PGIntProbePtr, CAbstractLazerProbe *PGExtProbePTr,CLogMgr *LogMgr,CTKTransportInterface *TKTransport,CZTSimulator *ZTSimPtr = 0,CAnalogInputModule *DataQInterface = 0); //Assignation de pointeurs - void BindCCRepoPtr(CModbusRepository *RepoPtr); + void BindModbusCCMgrPtr(CModbusCCMgr *ModbusCCPtr); CZTDetectionFunctionConfig *mZTDetectionConfig; CTKGenerator *mTKGenerator; //pointeur vers la classe qui gère les alarmes au PCC @@ -173,7 +174,8 @@ private: CStation *mZTStationPtr; CAnalogInputModule *mSDFAnalogMonitorInterface; CInputModule *mInputModule; - CModbusRepository *mCCModbusRepo; + // CModbusRepository *mCCModbusRepo; + CModbusCCMgr *mModbusCCMgr; CPCIIOMgr *mPCIIOPtr; diff --git a/sources/Zonetest.cpp b/sources/Zonetest.cpp index 7011b2c..6e86136 100644 --- a/sources/Zonetest.cpp +++ b/sources/Zonetest.cpp @@ -504,18 +504,20 @@ unsigned int CZoneTest::InitZT() mTKTransportInterface = (CTKTransportInterface*)TransportInterface; connect(mModbusCCMgr,SIGNAL(RepoHasChanged()),TransportInterface,SLOT(ModbusCCUpdated())); - mZTStateMachine->BindCCRepoPtr(mCCModbusRepository); + mZTStateMachine->BindModbusCCMgrPtr(mModbusCCMgr); // connect(mModbusCCMgr,SIGNAL(RepoHasChanged()),mZTStateMachine,SLOT(ModbusCCANUpdate())); connect(mModbusCCMgr,SIGNAL(ModbusCCConnected()),panel.mZTMainPage,SLOT(ModbusCCConnected())); connect(mModbusCCMgr,SIGNAL(ModbusCCDisconnected()),panel.mZTMainPage,SLOT(ModbusCCDisconnected())); connect(mModbusCCMgr,SIGNAL(ModbusDateTimeReceived(QDateTime*)),this,SLOT(ModbusDateTimeUpdate(QDateTime*))); panel.mZTMainPage->ModbusCCDisconnected(); + panel.mZTMainPage->mZT1Stats->Init(true); } else { CDiscreteTKTransport *TransportInterface = new CDiscreteTKTransport; mTKTransportInterface = (CTKTransportInterface*)TransportInterface; TransportInterface->BindPointers(mZTStation->GetOutputMasks(),mExtIOWorkerThread); + panel.mZTMainPage->mZT1Stats->Init(false); } connect(mTKTransportInterface,SIGNAL(TKOutputStatesChanged(bool,bool)),panel.mMaintenancePage,SLOT(TKOutputChanged(bool,bool)));