190 lines
5.8 KiB
C++
190 lines
5.8 KiB
C++
#include "ModbusSEIMgr.h"
|
|
#include <QTcpSocket>
|
|
#include "ModbusCCDefs.h"
|
|
#include "ModbusSEIDefs.h"
|
|
#include "GlobalDefine.h"
|
|
#include <ZTLog.h>
|
|
|
|
CModbusSEIMgr::CModbusSEIMgr(CModbusRepository *SEIRepo, CModbusRepository *CCRepo, QHostAddress ServerIP, int ModbusPort, int DevID):
|
|
CModbusBackend(SEIRepo)
|
|
{
|
|
// connect(mModbusTCPSocketHandle,SIGNAL(readyRead()),this,SLOT(ModbusDataReady()));
|
|
mModbusMode = MODBUS_MASTER_MODE;
|
|
mModbusPort = ModbusPort;
|
|
mDeviceID = DevID;
|
|
mSEIIPAddress = ServerIP;
|
|
|
|
mCCRepoHandle = CCRepo;
|
|
|
|
mZTWatchdog = false;
|
|
|
|
mConnectionTimer = new QTimer();
|
|
mConnectionTimer->setInterval(SEI_CLIENT_RECONNECT_TIMEOUT);
|
|
mConnectionTimer->setSingleShot(false);
|
|
mConnectionTimer->stop();
|
|
|
|
mSEIModbusUpdateTimer = new QTimer();
|
|
mSEIModbusUpdateTimer->setInterval(1000);
|
|
mSEIModbusUpdateTimer->setSingleShot(false);
|
|
mSEIModbusUpdateTimer->stop();
|
|
|
|
|
|
mModbusTCPSocketHandle = new QTcpSocket();
|
|
connect(mModbusTCPSocketHandle,SIGNAL(readyRead()),this,SLOT(ModbusDataReady()));
|
|
connect(mModbusTCPSocketHandle,SIGNAL(disconnected()),this,SLOT(SocketDisconnected()));
|
|
connect(mModbusTCPSocketHandle,SIGNAL(connected()),this,SLOT(SocketConnected()));
|
|
connect(mConnectionTimer,SIGNAL(timeout()),this,SLOT(ConnectionTimerExpired()));
|
|
connect(mSEIModbusUpdateTimer,SIGNAL(timeout()),this,SLOT(SEIModbusUpdateTimerExpired()));
|
|
}
|
|
|
|
CModbusSEIMgr::~CModbusSEIMgr()
|
|
{
|
|
if(mModbusTCPSocketHandle->state() != QAbstractSocket::UnconnectedState)
|
|
{
|
|
mModbusTCPSocketHandle->disconnectFromHost();
|
|
mModbusTCPSocketHandle->waitForDisconnected(1000);
|
|
}
|
|
delete mModbusTCPSocketHandle;
|
|
|
|
if(mConnectionTimer)
|
|
delete mConnectionTimer;
|
|
if(mSEIModbusUpdateTimer)
|
|
delete mSEIModbusUpdateTimer;
|
|
}
|
|
|
|
int CModbusSEIMgr::StartSEICommunication()
|
|
{
|
|
mConnectionTimer->start();
|
|
return RET_OK;
|
|
}
|
|
|
|
int CModbusSEIMgr::ConnectToSlave(QHostAddress SlaveIP, int SlavePort)
|
|
{
|
|
if(mModbusTCPSocketHandle->state() != QAbstractSocket::UnconnectedState)
|
|
{
|
|
return RET_ERROR;
|
|
}
|
|
|
|
mModbusTCPSocketHandle->connectToHost(SlaveIP,SlavePort);
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
int CModbusSEIMgr::DisconnectFromSlave()
|
|
{
|
|
mModbusTCPSocketHandle->disconnectFromHost();
|
|
mConnectionTimer->start();
|
|
|
|
return 1;
|
|
}
|
|
|
|
void CModbusSEIMgr::SocketConnected()
|
|
{
|
|
emit ModbusMasterConnected(mModbusTCPSocketHandle->localAddress().toIPv4Address(),mModbusTCPSocketHandle->peerAddress().toIPv4Address());
|
|
// qDebug("Master: Connection established with NetTrac");
|
|
CZTLog::instance()->AddLogString("Connection Modbus (Ethernet) avec NetTrac établi",true);
|
|
mConnectionTimer->stop();
|
|
mSEIModbusUpdateTimer->start();
|
|
}
|
|
|
|
void CModbusSEIMgr::SocketDisconnected()
|
|
{
|
|
ModbusLinkDisconnected();
|
|
emit ModbusMasterDisconnected();
|
|
mConnectionTimer->start();
|
|
mSEIModbusUpdateTimer->stop();
|
|
// qDebug("Disconnected from NetTrac");
|
|
// CZTLog::instance()->AddLogString("Connexion avec NetTrac établi",true);
|
|
CZTLog::instance()->AddLogString("Connection Modbus (Ethernet) avec NetTrac rompue",true);
|
|
}
|
|
|
|
int CModbusSEIMgr::ReadModbusRegisters()
|
|
{
|
|
//return SendReadHoldingRegistersRequest(ZT_DATA_BASE_REGISTER_ADDRESS,4); //Read all 3 registers from ZT (2000 - 2003)
|
|
return RET_OK;
|
|
}
|
|
|
|
void CModbusSEIMgr::ConnectionTimerExpired()
|
|
{
|
|
//Establish connection only if not connected
|
|
if(mModbusTCPSocketHandle->state() == QAbstractSocket::UnconnectedState)
|
|
{
|
|
ConnectToSlave(mSEIIPAddress,mModbusPort);
|
|
}
|
|
}
|
|
|
|
int CModbusSEIMgr::SEISettingsChanged(QHostAddress ServerIP, int ModbusPort, int DevID)
|
|
{
|
|
if(DevID > 255)
|
|
{
|
|
return RET_ERROR;
|
|
}
|
|
|
|
|
|
mSEIIPAddress = ServerIP;
|
|
mModbusPort = ModbusPort;
|
|
mDeviceID = DevID;
|
|
|
|
//Make shure we are disconnected. Connection timer will do the reconnection.
|
|
DisconnectFromSlave();
|
|
|
|
return RET_OK;
|
|
|
|
}
|
|
|
|
void CModbusSEIMgr::SEIModbusUpdateTimerExpired()
|
|
{
|
|
//The SEI Modbus table is updated on event, triggered by the TKTransport object (see ZTTKUpdated()).
|
|
//Just update the watchdog and send the current table.
|
|
mZTWatchdog = !mZTWatchdog;
|
|
|
|
if(mZTWatchdog)
|
|
{
|
|
mModbusRepo->WriteSingleReg(SEI_MODBUS_ZT_WATCHDOG_REG,0x01);
|
|
}
|
|
else
|
|
{
|
|
mModbusRepo->WriteSingleReg(SEI_MODBUS_ZT_WATCHDOG_REG,0);
|
|
}
|
|
|
|
SendWriteHoldingRegistersRequest(SEI_MODBUS_ZT_DATA_BASE_REG,SEI_MODBUS_ZT_TABLE_DATA_SIZE);
|
|
|
|
}
|
|
|
|
|
|
//This signal is emitted by TKTransport when a changed happened in the TK after the CC modbus table has been updated.
|
|
//We just need to copy the relevant info from the CC repo...
|
|
//As per specification, we must also send an update on change to the SEI
|
|
void CModbusSEIMgr::ZTTKUpdated()
|
|
{
|
|
//Copy data from CC modbus table to SEI modbus table.
|
|
mModbusRepo->WriteHRData(SEI_MODBUS_ZT_DATA_BASE_REG,SEI_MODBUS_ZT_TABLE_DATA_SIZE,mCCRepoHandle->GetHRData(MODBUS_ZT_DATA_BASE_REG,SEI_MODBUS_ZT_TABLE_DATA_SIZE));
|
|
|
|
//Keep our actual watchdog value..
|
|
if(mZTWatchdog)
|
|
{
|
|
mModbusRepo->WriteSingleReg(SEI_MODBUS_ZT_WATCHDOG_REG,0x01);
|
|
}
|
|
else
|
|
{
|
|
mModbusRepo->WriteSingleReg(SEI_MODBUS_ZT_WATCHDOG_REG,0);
|
|
}
|
|
|
|
//Send the data now to NetTrac
|
|
SendWriteHoldingRegistersRequest(SEI_MODBUS_ZT_WATCHDOG_REG,SEI_MODBUS_ZT_TABLE_DATA_SIZE);
|
|
|
|
}
|
|
|
|
void CModbusSEIMgr::RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length)
|
|
{
|
|
Q_UNUSED(StartAddress)
|
|
Q_UNUSED(Length)
|
|
|
|
emit ModbusMasterRepositoryUpdated();
|
|
}
|
|
|
|
void CModbusSEIMgr::ModbusResponseException(quint8 ExceptionCode, quint8 FctCode)
|
|
{
|
|
qDebug("Modbus MASTER exception: code:%d Fct:%d",ExceptionCode,FctCode);
|
|
}
|