#include "ModbusCCMgr.h" #include "ZTLog.h" #include "EngLog.h" #include "ModbusCCDefs.h" #include CModbusCCMgr::CModbusCCMgr(CModbusRepository *Repo, int ModbusPort, int DevID) : CModbusBackend(Repo) { mModbusServer = new QTcpServer(); mDeviceID = DevID; mModbusPort = ModbusPort; connect(mModbusServer,SIGNAL(newConnection()),this,SLOT(NewModbusConnection())); mModbusMode = MODBUS_SLAVE_MODE; mZTWatchdogTimer = new QTimer; mZTWatchdogTimer->setSingleShot(false); mZTWatchdogTimer->setInterval(MODBUS_ZT_WATCHDOG_TIMEOUT); connect(mZTWatchdogTimer,SIGNAL(timeout()),this,SLOT(ModbusZTWatchdogTimeout())); mCCWatchdogTimer = new QTimer; mCCWatchdogTimer->setSingleShot(true); mCCWatchdogTimer->setInterval(MODBUS_CC_WATCHDOG_TIMEOUT); connect(mCCWatchdogTimer,SIGNAL(timeout()),this,SLOT(ModbusCCWatchdogTimeout())); mZTWatchdog = 0; mCCWatchdogState = 0; mCCLinkState = false; mLastDateTime = 0; } CModbusCCMgr::~CModbusCCMgr() { delete mModbusServer; delete mZTWatchdogTimer; delete mCCWatchdogTimer; } int CModbusCCMgr::StartModbusCCServer() { mModbusServer->listen(QHostAddress::Any,mModbusPort); CZTLog::instance()->AddLogString(QString("Serveur Modbus Commande Centralisée démarré sur le port %1").arg(mModbusPort),true); return 1; } void CModbusCCMgr::NewModbusConnection() { mModbusTCPSocketHandle = mModbusServer->nextPendingConnection(); if(mModbusTCPSocketHandle != 0) { mDataLinkValid = true; connect(mModbusTCPSocketHandle,SIGNAL(readyRead()),this,SLOT(ModbusDataReady())); connect(mModbusTCPSocketHandle,SIGNAL(disconnected()),this,SLOT(ConnectionLost())); //qDebug("ModbusCC: Connection with CC established"); CZTLog::instance()->AddLogString(QString("Connection Modbus avec la CC établie. IP[%1]").arg(mModbusTCPSocketHandle->peerAddress().toString()),true); mZTWatchdogTimer->start(); mCCWatchdogTimer->start(MODBUS_CC_WATCHDOG_TIMEOUT*2); //Allow twice the time for the first watchdog reset. mCCLinkState = true; emit ModbusCCConnected(); } } void CModbusCCMgr::ConnectionLost() { ModbusLinkDisconnected(); mZTWatchdogTimer->stop(); mCCWatchdogTimer->stop(); emit ModbusCCDisconnected(); CZTLog::instance()->AddLogString(QString("Connection Modbus (Ethernet) avec la CC rompue."),true); } bool CModbusCCMgr::IsModbusConnected() { return mDataLinkValid; } void CModbusCCMgr::RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length) { Q_UNUSED(StartAddress) Q_UNUSED(Length) qint16 WD = mModbusRepo->GetSingleReg(MODBUS_CC_WATCHDOG_BASE_REG_ADD); // qDebug("WD = %d",WD); if(WD != mCCWatchdogState) { mCCWatchdogTimer->start(MODBUS_CC_WATCHDOG_TIMEOUT); //The watchdog has toggled. Kick the timer. mCCWatchdogState = WD; if(mCCLinkState == false) { mCCLinkState = true; CZTLog::instance()->AddLogString("Lien de communication (Watchdog) avec la CC rétabli",true); } } qint16 NTPWrite = mModbusRepo->GetSingleReg(MODBUS_CC_CLK_UPDATE_BASE_REG_ADD); if(NTPWrite == 1) { //Update date & time... bool OK; QList DateTime = mModbusRepo->GetRegs(MODUBS_CC_CLK_SEC_BASE_REG_ADD,4,&OK); if(OK) { qint8 Secs, Minutes, Hours, Month, Day; Secs = (qint8)(DateTime.at(0) >> 8); Minutes = (qint8)(DateTime.at(1) & 0x00FF); Hours = (qint8)(DateTime.at(1) >> 8); Day = (qint8)(DateTime.at(2) & 0x00FF); Month = (qint8)(DateTime.at(2) >> 8); qint16 Year = DateTime.at(3); QDateTime NetworkTime; NetworkTime.setTimeSpec(Qt::UTC); NetworkTime.setDate(QDate(Year,Month,Day)); NetworkTime.setTime(QTime(Hours,Minutes,Secs)); // QDateTime MyTime = NetworkTime.toLocalTime(); if(mLastDateTime != 0) { delete mLastDateTime; } mLastDateTime = new QDateTime(NetworkTime.toLocalTime()); emit ModbusDateTimeReceived(mLastDateTime); qDebug("Date & Heure reçue du SACL: %s",mLastDateTime->toString("yyyy-MM-dd hh:mm:ss").toAscii().data()); mModbusRepo->WriteSingleReg(MODBUS_CC_CLK_UPDATE_BASE_REG_ADD,0); } } emit RepoHasChanged(); } void CModbusCCMgr::ModbusRequestException(quint8 ExceptionCode, quint8 FctCode) { //qDebug("Modbus CC: Request exception occured. ExceptCode: [%d], FctCode: [%d]",ExceptionCode,FctCode); CEngLog::instance()->AddLogString(QString("Modbus CC: Exception de requête. ExceptionCode[%1], FctCode[%2]").arg(ExceptionCode).arg(FctCode)); } void CModbusCCMgr::ModbusCCWatchdogTimeout() { CZTLog::instance()->AddLogString("Perte du lien de communication avec la CC: Watchdog CC Expiré",true); mCCLinkState = false; } void CModbusCCMgr::ModbusZTWatchdogTimeout() { qint16 WD = mZTWatchdog; mModbusRepo->WriteSingleReg(MODBUS_ZT_WATCHDOG_REG_ADD,WD); if(mZTWatchdog == 1) { mZTWatchdog = 0; } else { mZTWatchdog = 1; } }