289 lines
8.0 KiB
C++
289 lines
8.0 KiB
C++
#include "ChaletLoraDevice.h"
|
|
#include "GlobalDefine.h"
|
|
|
|
|
|
CChaletLoraDevice::CChaletLoraDevice(int Address, CAbstractNetworkCommIF *NetworkInterface):
|
|
CNetworkDevice(ID_CHALET_DEVICE,Address,NetworkInterface)
|
|
{
|
|
NetworkInterface->mDevicePtr = this;
|
|
mDeviceAddress = Address;
|
|
mDeviceID = ID_CHALET_DEVICE;
|
|
|
|
|
|
mChaletStatusTimer = new QTimer();
|
|
mChaletStatusTimer->setInterval(1000);
|
|
mChaletStatusTimer->setSingleShot(true);
|
|
connect(mChaletStatusTimer,SIGNAL(timeout()),this,SLOT(CommTimerExpired()));
|
|
}
|
|
|
|
CChaletLoraDevice::~CChaletLoraDevice()
|
|
{
|
|
delete mChaletStatusTimer;
|
|
}
|
|
|
|
int CChaletLoraDevice::Start()
|
|
{
|
|
ScheduleChaletStatusRequest();
|
|
mChaletStatusTimer->start(1000);
|
|
return RET_OK;
|
|
}
|
|
|
|
int CChaletLoraDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data)
|
|
{
|
|
switch(MessageID)
|
|
{
|
|
case CHALET_ACK:
|
|
{
|
|
CmdResponseReceived(CHALET_ACK);
|
|
break;
|
|
}
|
|
case CHALET_GENERAL_STATUS_RESPONSE:
|
|
{
|
|
float temp;
|
|
qDebug("Chalet Status RX");
|
|
char VoltageArray[4];
|
|
|
|
mChaletMainStatus.mInverterRelayStatus = Data[0];
|
|
mChaletMainStatus.mWiFiModuleStatus = Data[1];
|
|
VoltageArray[0] = Data[2];
|
|
VoltageArray[1] = Data[3];
|
|
VoltageArray[2] = Data[4];
|
|
VoltageArray[3] = Data[5];
|
|
memcpy(&temp,VoltageArray,4);
|
|
mChaletMainStatus.mBatteryVoltage = temp;
|
|
CmdResponseReceived(CHALET_GENERAL_STATUS_REQUEST);
|
|
qDebug("voltage: %f",mChaletMainStatus.mBatteryVoltage);
|
|
break;
|
|
}
|
|
case CHALET_AC_POWER_STATE_STATUS_RESPONSE:
|
|
{
|
|
mChaletMainStatus.mInverterRelayStatus = Data[0];
|
|
CmdResponseReceived(CHALET_AC_POWER_SET_STATE_RESPONSE);
|
|
break;
|
|
}
|
|
case CHALET_AC_POWER_SET_STATE_RESPONSE:
|
|
{
|
|
qDebug("Lora set Inverter Power response : 0x%d",(int)Data[0]);
|
|
mChaletMainStatus.mInverterRelayStatus = Data[0];
|
|
CmdResponseReceived(CHALET_AC_POWER_SET_STATE_REQUEST);
|
|
break;
|
|
}
|
|
case CHALET_BATTERY_VOLTAGE_RESPONSE:
|
|
{
|
|
CmdResponseReceived(CHALET_BATTERY_VOLTAGE_REQUEST);
|
|
break;
|
|
}
|
|
case CHALET_BATTERY_CURRENT_RESPONSE:
|
|
{
|
|
CmdResponseReceived(CHALET_BATTERY_CURRENT_REQUEST);
|
|
break;
|
|
}
|
|
case CHALET_WIFI_STATUS_RESPONSE:
|
|
{
|
|
mChaletMainStatus.mWiFiModuleStatus = Data[0];
|
|
CmdResponseReceived(CHALET_WIFI_STATUS_REQUEST);
|
|
break;
|
|
}
|
|
case CHALET_WIFI_SET_STATE_RESPONSE:
|
|
{
|
|
qDebug("Lora set WiFi response : 0x%d",(int)Data[0]);
|
|
mChaletMainStatus.mWiFiModuleStatus = Data[0];
|
|
CmdResponseReceived(CHALET_WIFI_SET_STATE_REQUEST);
|
|
break;
|
|
}
|
|
case CHALET_DO_HARAKIRI_CONFIRMATION:
|
|
{
|
|
if(Data[0] == (char)1)
|
|
{
|
|
qDebug("ChaletDuino has commited suicide (HARAKIRI)");
|
|
mChaletMainStatus.mHarakiriDone = true;
|
|
}
|
|
else
|
|
{
|
|
qDebug("HARAKIRI magic word invalid.");
|
|
}
|
|
CmdResponseReceived(CHALET_DO_HARAKIRI_REQUEST);
|
|
break;
|
|
}
|
|
case CHALET_REBOOT_CPU_RESPONSE:
|
|
{
|
|
if(Data[0] == (char)1)
|
|
{
|
|
qDebug("ChaletDuino is rebooting");
|
|
}
|
|
else
|
|
{
|
|
qDebug("Reboot magic word invalid");
|
|
}
|
|
CmdResponseReceived(CHALET_DO_HARAKIRI_REQUEST);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
return RET_ERROR;
|
|
break;
|
|
}
|
|
|
|
}
|
|
return RET_OK;
|
|
}
|
|
|
|
void CChaletLoraDevice::CommTimerExpired()
|
|
{
|
|
if(mPendingNetworkMsgList.isEmpty())
|
|
{
|
|
qDebug("Empty command list in comm timer ");
|
|
ScheduleChaletStatusRequest();
|
|
mChaletStatusTimer->start(1000);
|
|
return;
|
|
}
|
|
if(mPendingNetworkMsgList.first().PendingResponse == true)
|
|
{
|
|
//The current command is still waiting for a response. Check how many times we tried to send it
|
|
qDebug("Cmd 0x%x timetout... retrying",mPendingNetworkMsgList.first().mMessageID);
|
|
if(mPendingNetworkMsgList.first().ResendCounter >= 5)
|
|
{
|
|
//TODO: manage this. Module offline?
|
|
}
|
|
else
|
|
{
|
|
mPendingNetworkMsgList[0].ResendCounter++;
|
|
}
|
|
}
|
|
|
|
qDebug("Sending chalet request 0x%x",mPendingNetworkMsgList.at(0).mMessageID);
|
|
|
|
mPendingNetworkMsgList[0].PendingResponse = true;
|
|
SendChaletCommand(mPendingNetworkMsgList.at(0).mMessageID,mPendingNetworkMsgList.at(0).mData.size(),mPendingNetworkMsgList.at(0).mData);
|
|
|
|
//Harakiri and Reboot commands should not stay in the queue...
|
|
if(mPendingNetworkMsgList.at(0).mMessageID == CHALET_DO_HARAKIRI_REQUEST ||
|
|
mPendingNetworkMsgList.at(0).mMessageID == CHALET_REBOOT_CPU_REQUEST)
|
|
{
|
|
mPendingNetworkMsgList.clear();
|
|
ScheduleChaletStatusRequest();
|
|
}
|
|
|
|
mChaletStatusTimer->start(5000); //we should get an answer within 5 seconds.
|
|
// SendChaletCommand(CHALET_GENERAL_STATUS_REQUEST,0,QByteArray());
|
|
}
|
|
|
|
int CChaletLoraDevice::SendWiFiModuleSetState(bool State)
|
|
{
|
|
QByteArray Data;
|
|
Data.resize(1);
|
|
if(State)
|
|
{
|
|
Data[0] = 1;
|
|
}
|
|
else
|
|
{
|
|
Data[0] = 0;
|
|
}
|
|
|
|
ScheduleChaletCommand(CHALET_WIFI_SET_STATE_REQUEST,1,Data);
|
|
return RET_OK;
|
|
}
|
|
|
|
int CChaletLoraDevice::SendInverterPowerRelayState(bool State)
|
|
{
|
|
QByteArray Data;
|
|
Data.resize(1);
|
|
if(State)
|
|
{
|
|
Data[0] = 1;
|
|
}
|
|
else
|
|
{
|
|
Data[0] = 0;
|
|
}
|
|
|
|
ScheduleChaletCommand(CHALET_AC_POWER_SET_STATE_REQUEST,Data);
|
|
// SendChaletCommand(CHALET_AC_POWER_SET_STATE_REQUEST,1,Data);
|
|
return RET_OK;
|
|
}
|
|
|
|
int CChaletLoraDevice::SendDOHarakiri()
|
|
{
|
|
QByteArray Data; //Magic word...
|
|
Data.clear();
|
|
Data.append(0xBA);
|
|
Data.append(0xAD);
|
|
Data.append(0xBE);
|
|
Data.append(0xEF);
|
|
|
|
ScheduleChaletCommand(CHALET_DO_HARAKIRI_REQUEST,Data);
|
|
}
|
|
|
|
int CChaletLoraDevice::SendRebootCmd()
|
|
{
|
|
QByteArray Data; //Magic word...
|
|
Data.clear();
|
|
Data.append(0xBA);
|
|
Data.append(0xAD);
|
|
Data.append(0xCA);
|
|
Data.append(0xFE);
|
|
|
|
ScheduleChaletCommand(CHALET_REBOOT_CPU_REQUEST,Data);
|
|
}
|
|
|
|
int CChaletLoraDevice::SendChaletCommand(int CmdID, int DataSize, QByteArray Data)
|
|
{
|
|
mNetworkInterfacePtr->SendNetworkMessage(ID_CHALET_DEVICE,mDeviceAddress,CmdID,DataSize,Data);
|
|
return RET_OK;
|
|
}
|
|
|
|
int CChaletLoraDevice::CmdResponseReceived(int CmdID)
|
|
{
|
|
Q_UNUSED(CmdID)
|
|
|
|
qDebug("Chalet response received from cmd: 0x%x",CmdID);
|
|
if(mPendingNetworkMsgList.size() == 0)
|
|
{
|
|
qDebug("Cmd ack received but list is empty!!!");
|
|
}
|
|
else
|
|
{
|
|
CChaletNetworkMessage Msg = mPendingNetworkMsgList.takeFirst();
|
|
if(Msg.mMessageID != CmdID)
|
|
{
|
|
qDebug("Inconsistency between active cmd and ack received [received 0x%x] != [cur 0x%x]!!!", Msg.mMessageID,CmdID);
|
|
}
|
|
}
|
|
|
|
if(mPendingNetworkMsgList.size() == 0) //If no message is left pending... schedule status request
|
|
{
|
|
ScheduleChaletStatusRequest();
|
|
mChaletStatusTimer->start(1000);//Next status request will be sent in 1000ms
|
|
}
|
|
else
|
|
{
|
|
mChaletStatusTimer->start(500); //wait a little and send the next cmd.
|
|
}
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
int CChaletLoraDevice::ScheduleChaletStatusRequest()
|
|
{
|
|
ScheduleChaletCommand(CHALET_GENERAL_STATUS_REQUEST,0,QByteArray());
|
|
}
|
|
|
|
int CChaletLoraDevice::ScheduleChaletCommand(int CmdID, int DataSize, QByteArray Data)
|
|
{
|
|
Q_UNUSED(DataSize)
|
|
CChaletNetworkMessage Command(CmdID,Data);
|
|
mPendingNetworkMsgList.append(Command);
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
int CChaletLoraDevice::ScheduleChaletCommand(int CmdID, QByteArray Data)
|
|
{
|
|
CChaletNetworkMessage Command(CmdID,Data);
|
|
mPendingNetworkMsgList.append(Command);
|
|
|
|
return RET_OK;
|
|
}
|
|
|