ZT/sources/Modbus/ModbusSEIMgr.cpp
2019-09-25 13:45:03 -04:00

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);
}