diff --git a/MasterCtrl.pro b/MasterCtrl.pro index c6dbba7..d3308aa 100644 --- a/MasterCtrl.pro +++ b/MasterCtrl.pro @@ -1,6 +1,7 @@ #QT += Network #QT += gui declarative network QT += gui network serialport + greaterThan(QT_MAJOR_VERSION, 4): QT += widgets #CONFIG += console @@ -37,7 +38,10 @@ HEADERS += \ Sources/Sprinkler/SprinklerMgr.h \ Sources/AvReceiver/AvReceiverInterface.h \ Sources/AvReceiver/AvReceiverData.h \ - Sources/Chalet/ChaletNetworkMessage.h + Sources/Chalet/ChaletNetworkMessage.h \ + Sources/HttpServer/HttpServer.h \ + Sources/BlynkCloudClient.h \ + Sources/Chalet/ChaletDataLogger.h SOURCES += \ Sources/Chalet/ChaletData.cpp \ @@ -70,7 +74,10 @@ SOURCES += \ Sources/Sprinkler/SprinklerMgr.cpp \ Sources/AvReceiver/AvReceiverInterface.cpp \ Sources/AvReceiver/AvReceiverData.cpp \ - Sources/Chalet/ChaletNetworkMessage.cpp + Sources/Chalet/ChaletNetworkMessage.cpp \ + Sources/HttpServer/HttpServer.cpp \ + Sources/BlynkCloudClient.cpp \ + Sources/Chalet/ChaletDataLogger.cpp DEFINES -= Q_OS_UNIX @@ -87,7 +94,10 @@ INCLUDEPATH += $$PWD/ \ $$PWD/Sources/Sprinkler \ $$PWD/Sources/AvReceiver \ $$PWD/Sources/Chalet \ + $$PWD/Sources/HttpServer \ + $$PWD/blynk-library-master/src/ \ FORMS += -DISTFILES += +DISTFILES += \ + ../../../../Dev/qthttpserver/mkspecs/modules/qt_lib_httpserver.pri diff --git a/Sources/BlynkCloudClient.cpp b/Sources/BlynkCloudClient.cpp new file mode 100644 index 0000000..a4297c1 --- /dev/null +++ b/Sources/BlynkCloudClient.cpp @@ -0,0 +1,109 @@ +#include "BlynkCloudClient.h" +#include +#include +#include + +CBlynkCloudClient::CBlynkCloudClient() +{ + mBlynkSocket = new QNetworkAccessManager; + connect(mBlynkSocket,SIGNAL(finished(QNetworkReply*)),this,SLOT(BlynkServerFinished(QNetworkReply*))); + connect(mBlynkSocket,SIGNAL(sslErrors(QNetworkReply*,QList)),this,SLOT(sslErrors(QNetworkReply*,QList))); + + mDummy = 0; +} + +void CBlynkCloudClient::TestBlynk() +{ + //QString URL = QString("http://blynk-cloud.com/NzI2kH0L0sLOO8NWyPyoZPS7IFJ3Gtho/update/V0?value=%1").arg(mDummy++); + QString URL = QString("http://blynk-cloud.com/NzI2kH0L0sLOO8NWyPyoZPS7IFJ3Gtho/get/V10"); + mBlynkSocket->get(QNetworkRequest(URL)); + +} + +void CBlynkCloudClient::UpdateChaletCurrent(int Current) +{ + QString URL = QString("http://blynk-cloud.com/NzI2kH0L0sLOO8NWyPyoZPS7IFJ3Gtho/update/V1?value=%1").arg(Current); + + mBlynkSocket->get(QNetworkRequest(URL)); + +} + +void CBlynkCloudClient::UpdateChaletVoltage(float Voltage) +{ + QString URL = QString("http://blynk-cloud.com/NzI2kH0L0sLOO8NWyPyoZPS7IFJ3Gtho/update/V0?value=%1").arg(Voltage); + + mBlynkSocket->get(QNetworkRequest(URL)); + +} + +void CBlynkCloudClient::UpdateChaletWifiStatus(int Status) +{ + QString URL = QString("http://blynk-cloud.com/NzI2kH0L0sLOO8NWyPyoZPS7IFJ3Gtho/update/V10?value=%1").arg(Status); + + mBlynkSocket->get(QNetworkRequest(URL)); + +} + +void CBlynkCloudClient::UpdateChaletInverterStatus(int Status) +{ + QString URL = QString("http://blynk-cloud.com/NzI2kH0L0sLOO8NWyPyoZPS7IFJ3Gtho/update/V10?value=%1").arg(Status); + + mBlynkSocket->get(QNetworkRequest(URL)); + +} + +void CBlynkCloudClient::UpdateChaletStatusLed(int Status) +{ + QString URL = QString("http://blynk-cloud.com/NzI2kH0L0sLOO8NWyPyoZPS7IFJ3Gtho/update/V12?value=%1").arg(Status); + + mBlynkSocket->get(QNetworkRequest(URL)); +} + +int CBlynkCloudClient::GetChaletWifiToggleSwitchStatus() +{ +// http://blynk-cloud.com/NzI2kH0L0sLOO8NWyPyoZPS7IFJ3Gtho/get/V10 + QString URL = QString("http://blynk-cloud.com/NzI2kH0L0sLOO8NWyPyoZPS7IFJ3Gtho/get/V10"); + + mBlynkSocket->get(QNetworkRequest(URL)); +} + +void CBlynkCloudClient::BlynkServerFinished(QNetworkReply *NetworkReply) +{ + if(NetworkReply->isFinished() == false) + return; + + if(NetworkReply->error() != QNetworkReply::NoError) + { + qDebug("Network error... %d", NetworkReply->error()); + return; + } + + + QByteArray Reply = NetworkReply->readAll(); + if(Reply.isEmpty()) + return; + + NetworkReply->deleteLater(); + + QString ReplyString(Reply); + ReplyString.remove("[\""); + ReplyString.remove("\"]"); + QJsonValue Result(ReplyString); +// QJsonParseError error; +// QJsonDocument JsonReply = QJsonDocument::fromJson(Reply,&error); +// QJsonObject JsonObject = JsonReply.object(); +// QStringList Keys = JsonObject.keys(); + + int toto = ReplyString.toInt(); + qDebug("Switch = %d",toto); + + + +} + +void CBlynkCloudClient::sslErrors(QNetworkReply *reply, QList error) +{ + + qDebug("Ssl errors..."); + reply->ignoreSslErrors(); +} diff --git a/Sources/BlynkCloudClient.h b/Sources/BlynkCloudClient.h new file mode 100644 index 0000000..63baa1c --- /dev/null +++ b/Sources/BlynkCloudClient.h @@ -0,0 +1,32 @@ +#ifndef BLYNKCLOUDCLIENT_H +#define BLYNKCLOUDCLIENT_H + +#include +#include + +class CBlynkCloudClient : public QObject +{ + Q_OBJECT + +public: + CBlynkCloudClient(); + + void TestBlynk(); + void UpdateChaletVoltage(float Voltage); + void UpdateChaletCurrent(int Current); + void UpdateChaletWifiStatus(int Status); + void UpdateChaletInverterStatus(int Status); + void UpdateChaletStatusLed(int Status); + + int GetChaletWifiToggleSwitchStatus(); + + int mDummy; +private: + QNetworkAccessManager *mBlynkSocket; + +public slots: + void BlynkServerFinished(QNetworkReply*); + void sslErrors(QNetworkReply*,QList); +}; + +#endif // BLYNKCLOUDCLIENT_H diff --git a/Sources/Chalet/ChaletData.cpp b/Sources/Chalet/ChaletData.cpp index cb9319d..821f9ec 100644 --- a/Sources/Chalet/ChaletData.cpp +++ b/Sources/Chalet/ChaletData.cpp @@ -5,10 +5,12 @@ CChaletMainStatus::CChaletMainStatus() { mInverterRelayStatus = UNKNOWN_STATE; mWiFiModuleStatus = UNKNOWN_STATE; + mCurrentSensorStatus = UNKNOWN_STATE; mBatteryCurrent = 0; mBatteryVoltage = 0; mIsOnline = false; mHarakiriDone = false; + mStatusToggleBit = 0; } @@ -48,6 +50,8 @@ QByteArray CChaletMainStatus::ToByteArray() Strm << mBatteryVoltage; Strm << mBatteryCurrent; Strm << mBatterySOC; + Strm << mIsOnline; + Strm << mCurrentSensorStatus; return Data; } diff --git a/Sources/Chalet/ChaletData.h b/Sources/Chalet/ChaletData.h index a358819..20860e4 100644 --- a/Sources/Chalet/ChaletData.h +++ b/Sources/Chalet/ChaletData.h @@ -18,14 +18,17 @@ public: quint8 mInverterRelayStatus; quint8 mWiFiModuleStatus; + qint8 mCurrentSensorStatus; float mBatteryVoltage; - float mBatteryCurrent; - float mBatterySOC; + qint16 mBatteryCurrent; + qint16 mBatterySOC; bool mHarakiriDone; bool mIsOnline; + bool mStatusToggleBit; + QDateTime mLastLoraStatus; }; diff --git a/Sources/Chalet/ChaletDataLogger.cpp b/Sources/Chalet/ChaletDataLogger.cpp new file mode 100644 index 0000000..aa661c1 --- /dev/null +++ b/Sources/Chalet/ChaletDataLogger.cpp @@ -0,0 +1,6 @@ +#include "ChaletDataLogger.h" + +CChaletDataLogger::CChaletDataLogger(QObject *parent) : QObject(parent) +{ + +} diff --git a/Sources/Chalet/ChaletDataLogger.h b/Sources/Chalet/ChaletDataLogger.h new file mode 100644 index 0000000..16c12dd --- /dev/null +++ b/Sources/Chalet/ChaletDataLogger.h @@ -0,0 +1,17 @@ +#ifndef CHALETDATALOGGER_H +#define CHALETDATALOGGER_H + +#include + +class CChaletDataLogger : public QObject +{ + Q_OBJECT +public: + explicit CChaletDataLogger(QObject *parent = 0); + +signals: + +public slots: +}; + +#endif // CHALETDATALOGGER_H \ No newline at end of file diff --git a/Sources/Chalet/ChaletLoraDevice.cpp b/Sources/Chalet/ChaletLoraDevice.cpp index b93f98d..040cdf8 100644 --- a/Sources/Chalet/ChaletLoraDevice.cpp +++ b/Sources/Chalet/ChaletLoraDevice.cpp @@ -2,6 +2,7 @@ #include "GlobalDefine.h" + CChaletLoraDevice::CChaletLoraDevice(int Address, CAbstractNetworkCommIF *NetworkInterface): CNetworkDevice(ID_CHALET_DEVICE,Address,NetworkInterface) { @@ -40,10 +41,15 @@ int CChaletLoraDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, i case CHALET_GENERAL_STATUS_RESPONSE: { float temp; + qint16 temp2; qDebug("Chalet Status RX"); char VoltageArray[4]; + char SolarPanelCurrentArray[2]; + char BatterySOCArray[2]; + + mChaletMainStatus.mInverterRelayStatus = ((Data[0] & LORA_CHALET_STATUS_POWER_RELAY_MASK) != 0); + mChaletMainStatus.mCurrentSensorStatus = ((Data[0] & LORA_CHALET_STATUS_CUR_SENSOR_MASK) != 0); - mChaletMainStatus.mInverterRelayStatus = Data[0]; mChaletMainStatus.mWiFiModuleStatus = Data[1]; VoltageArray[0] = Data[2]; VoltageArray[1] = Data[3]; @@ -51,8 +57,30 @@ int CChaletLoraDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, i VoltageArray[3] = Data[5]; memcpy(&temp,VoltageArray,4); mChaletMainStatus.mBatteryVoltage = temp; + + SolarPanelCurrentArray[0] = Data[6]; + SolarPanelCurrentArray[1] = Data[7]; + memcpy(&temp2,SolarPanelCurrentArray,2); + mChaletMainStatus.mBatteryCurrent = temp2; + + BatterySOCArray[0] = Data[8]; + BatterySOCArray[1] = Data[9]; + memcpy(&temp2,BatterySOCArray,2); + mChaletMainStatus.mBatterySOC = temp2; + + mChaletMainStatus.mStatusToggleBit = !mChaletMainStatus.mStatusToggleBit; + CmdResponseReceived(CHALET_GENERAL_STATUS_REQUEST); qDebug("voltage: %f",mChaletMainStatus.mBatteryVoltage); + qDebug("Current: %d",mChaletMainStatus.mBatteryCurrent); + qDebug("SOC: %d",mChaletMainStatus.mBatterySOC); + + mBlynkInterface.UpdateChaletCurrent(mChaletMainStatus.mBatteryCurrent); + mBlynkInterface.UpdateChaletVoltage(mChaletMainStatus.mBatteryVoltage); +// mBlynkInterface.UpdateChaletWifiStatus((int)mChaletMainStatus.mInverterRelayStatus); + mBlynkInterface.UpdateChaletInverterStatus((int)mChaletMainStatus.mInverterRelayStatus); + mBlynkInterface.UpdateChaletStatusLed(((int)mChaletMainStatus.mStatusToggleBit)*255); + break; } case CHALET_AC_POWER_STATE_STATUS_RESPONSE: @@ -134,21 +162,27 @@ void CChaletLoraDevice::CommTimerExpired() { qDebug("Empty command list in comm timer "); ScheduleChaletStatusRequest(); - mChaletStatusTimer->start(1000); + mChaletStatusTimer->start(LORA_NORMAL_REQUEST_TIMEOUT); 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) + if(mPendingNetworkMsgList.first().ResendCounter >= 2) { - //TODO: manage this. Module offline? - } - else - { - mPendingNetworkMsgList[0].ResendCounter++; + //After 2 retries, declare module offline, clear the send buffer and start sending status requests... + if(mChaletMainStatus.mIsOnline == true) + { + mChaletMainStatus.mIsOnline = false; + qDebug("Chalet LORA interface Offline. Switching to status requests..."); + + mPendingNetworkMsgList.clear(); + ScheduleChaletStatusRequest(); + mPendingNetworkMsgList.first().ResendCounter = 2; + } } + mPendingNetworkMsgList[0].ResendCounter++; } qDebug("Sending chalet request 0x%x",mPendingNetworkMsgList.at(0).mMessageID); @@ -164,7 +198,7 @@ void CChaletLoraDevice::CommTimerExpired() ScheduleChaletStatusRequest(); } - mChaletStatusTimer->start(5000); //we should get an answer within 5 seconds. + mChaletStatusTimer->start(LORA_RESPONSE_TIME_TIMEOUT); //we should get an answer within 5 seconds. // SendChaletCommand(CHALET_GENERAL_STATUS_REQUEST,0,QByteArray()); } @@ -181,8 +215,7 @@ int CChaletLoraDevice::SendWiFiModuleSetState(bool State) Data[0] = 0; } - ScheduleChaletCommand(CHALET_WIFI_SET_STATE_REQUEST,1,Data); - return RET_OK; + return ScheduleChaletCommand(CHALET_WIFI_SET_STATE_REQUEST,1,Data); } int CChaletLoraDevice::SendInverterPowerRelayState(bool State) @@ -198,9 +231,7 @@ int CChaletLoraDevice::SendInverterPowerRelayState(bool State) Data[0] = 0; } - ScheduleChaletCommand(CHALET_AC_POWER_SET_STATE_REQUEST,Data); - // SendChaletCommand(CHALET_AC_POWER_SET_STATE_REQUEST,1,Data); - return RET_OK; + return ScheduleChaletCommand(CHALET_AC_POWER_SET_STATE_REQUEST,Data); } int CChaletLoraDevice::SendDOHarakiri() @@ -212,7 +243,7 @@ int CChaletLoraDevice::SendDOHarakiri() Data.append(0xBE); Data.append(0xEF); - ScheduleChaletCommand(CHALET_DO_HARAKIRI_REQUEST,Data); + return ScheduleChaletCommand(CHALET_DO_HARAKIRI_REQUEST,Data); } int CChaletLoraDevice::SendRebootCmd() @@ -224,7 +255,7 @@ int CChaletLoraDevice::SendRebootCmd() Data.append(0xCA); Data.append(0xFE); - ScheduleChaletCommand(CHALET_REBOOT_CPU_REQUEST,Data); + return ScheduleChaletCommand(CHALET_REBOOT_CPU_REQUEST,Data); } int CChaletLoraDevice::SendChaletCommand(int CmdID, int DataSize, QByteArray Data) @@ -237,6 +268,12 @@ int CChaletLoraDevice::CmdResponseReceived(int CmdID) { Q_UNUSED(CmdID) + if(mChaletMainStatus.mIsOnline == false) + { + mChaletMainStatus.mIsOnline = true; + qDebug("Chalet is ONLINE!"); + } + qDebug("Chalet response received from cmd: 0x%x",CmdID); if(mPendingNetworkMsgList.size() == 0) { @@ -266,20 +303,46 @@ int CChaletLoraDevice::CmdResponseReceived(int CmdID) int CChaletLoraDevice::ScheduleChaletStatusRequest() { - ScheduleChaletCommand(CHALET_GENERAL_STATUS_REQUEST,0,QByteArray()); + return 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); + +// if(mChaletMainStatus.mIsOnline == false) +// { +// return RET_ERROR; +// } + +// CChaletNetworkMessage Command(CmdID,Data); +// mPendingNetworkMsgList.append(Command); + + ScheduleChaletCommand(CmdID,Data); return RET_OK; } int CChaletLoraDevice::ScheduleChaletCommand(int CmdID, QByteArray Data) { +// if(mChaletMainStatus.mIsOnline == false) +// { +// return RET_ERROR; +// } + + if(mChaletMainStatus.mIsOnline == true && CmdID != CHALET_GENERAL_STATUS_REQUEST) //When chalet is online, send command right away if we are not waiting for an answer. + { + //if we are in nominal conditions (waiting to send a status request). Cancel the status request and send the command right away. + if((mPendingNetworkMsgList.size() == 1) && + (mPendingNetworkMsgList.at(0).mMessageID == CHALET_GENERAL_STATUS_REQUEST) && + mPendingNetworkMsgList.at(0).PendingResponse == false) + { + mPendingNetworkMsgList.clear(); + mChaletStatusTimer->start(10); //Allow some time to breathe + } + + } + CChaletNetworkMessage Command(CmdID,Data); mPendingNetworkMsgList.append(Command); diff --git a/Sources/Chalet/ChaletLoraDevice.h b/Sources/Chalet/ChaletLoraDevice.h index 2671d9f..34d8202 100644 --- a/Sources/Chalet/ChaletLoraDevice.h +++ b/Sources/Chalet/ChaletLoraDevice.h @@ -9,8 +9,16 @@ #include "ChaletData.h" #include "ChaletNetworkMessage.h" #include +#include "BlynkCloudClient.h" #define LORA_MAGIC_WORD 0xBAADCAFE +#define LORA_NORMAL_REQUEST_TIMEOUT 1000 +#define LORA_IMMEDIATE_REQUEST_TIMEOUT 300 +#define LORA_RETRY_REQUEST_TIMEOUT 1000 +#define LORA_RESPONSE_TIME_TIMEOUT 5000 + +#define LORA_CHALET_STATUS_POWER_RELAY_MASK 0x01 +#define LORA_CHALET_STATUS_CUR_SENSOR_MASK 0x02 class CChaletLoraDevice : public QObject, public CNetworkDevice @@ -27,6 +35,7 @@ public: int Start(); CChaletMainStatus GetChaletMainStatus() {return mChaletMainStatus;} + CBlynkCloudClient mBlynkInterface; CChaletMainStatus mChaletMainStatus; QList mPendingNetworkMsgList; diff --git a/Sources/GlobalDefine.h b/Sources/GlobalDefine.h index 90bb81e..492e439 100644 --- a/Sources/GlobalDefine.h +++ b/Sources/GlobalDefine.h @@ -11,5 +11,7 @@ #define ON_STATE 1 #define OFF_STATE 0 #define UNKNOWN_STATE -1 +#define OK_STATE 1 +#define DEFECT_STATE 0 #endif // GLOBALDEFINE_H diff --git a/Sources/HttpServer/HttpServer.cpp b/Sources/HttpServer/HttpServer.cpp new file mode 100644 index 0000000..4f5ea6f --- /dev/null +++ b/Sources/HttpServer/HttpServer.cpp @@ -0,0 +1,5 @@ +#include "HttpServer.h" + +CHttpServer::CHttpServer() +{ +} diff --git a/Sources/HttpServer/HttpServer.h b/Sources/HttpServer/HttpServer.h new file mode 100644 index 0000000..7e7448b --- /dev/null +++ b/Sources/HttpServer/HttpServer.h @@ -0,0 +1,11 @@ +#ifndef HTTPSERVER_H +#define HTTPSERVER_H + + +class CHttpServer +{ +public: + CHttpServer(); +}; + +#endif // HTTPSERVER_H \ No newline at end of file diff --git a/Sources/MasterCtrl.cpp b/Sources/MasterCtrl.cpp index f6de6da..64e1394 100644 --- a/Sources/MasterCtrl.cpp +++ b/Sources/MasterCtrl.cpp @@ -1,7 +1,6 @@ #include "MasterCtrl.h" #include - // #include //#include @@ -98,6 +97,7 @@ void CMasterCtrl::Start() + // mAppWidget.show(); diff --git a/Sources/MasterCtrl.h b/Sources/MasterCtrl.h index 7931d6f..eeb4a6a 100644 --- a/Sources/MasterCtrl.h +++ b/Sources/MasterCtrl.h @@ -15,6 +15,7 @@ #include "ChaletLoraDevice.h" //#include "ChaletLoraInterface.h" #include "LoraNetworkCommIF.h" +#include "HttpServer.h" //#include "AppIconWidget.h" @@ -43,6 +44,8 @@ public: CLoraNetworkCommIF *mChaletLoraNetworkCommInterface; // CAppIconWidget mAppWidget; + CHttpServer mHttpServer; +