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