Philips Hue APIv2 support (#1637)

* Support Philips Hue APIv2 and refactoring

* Fix MDNSBrower - if timeout during host resolvment occurs

* Hue API v2 - Migrate database

* Fix macOS build

* Handle network timeout before any other error

* Address CodeQL findings

* Clean-up and Fixes

* Only getProperties, if username is available

* Option to layout by entertainment area center

* Fix Wizard

---------

Co-authored-by: Paulchen-Panther <16664240+Paulchen-Panther@users.noreply.github.com>
This commit is contained in:
LordGrey
2023-10-03 20:33:11 +02:00
committed by GitHub
parent 33722c9a09
commit cd22d4454d
13 changed files with 2541 additions and 898 deletions

View File

@@ -10,12 +10,13 @@
#include <QUrlQuery>
#include <QJsonDocument>
#include <QFile>
#include <QBasicTimer>
#include <QTimerEvent>
#include <chrono>
constexpr std::chrono::milliseconds DEFAULT_REST_TIMEOUT{ 1000 };
constexpr std::chrono::milliseconds DEFAULT_REST_TIMEOUT{ 2000 };
//Set QNetworkReply timeout without external timer
//https://stackoverflow.com/questions/37444539/how-to-set-qnetworkreply-timeout-without-external-timer
@@ -28,7 +29,7 @@ public:
enum HandleMethod { Abort, Close };
ReplyTimeout(QNetworkReply* reply, const int timeout, HandleMethod method = Abort) :
QObject(reply), m_method(method), m_timedout(false)
QObject(reply), m_method(method), m_timedout(false)
{
Q_ASSERT(reply);
if (reply && reply->isRunning()) {
@@ -87,6 +88,10 @@ public:
QJsonDocument getBody() const { return _responseBody; }
void setBody(const QJsonDocument& body) { _responseBody = body; }
QByteArray getHeader(const QByteArray header) const;
void setHeaders(const QList<QNetworkReply::RawHeaderPair>& pairs);
QString getErrorReason() const { return _errorReason; }
void setErrorReason(const QString& errorReason) { _errorReason = errorReason; }
@@ -99,6 +104,8 @@ public:
private:
QJsonDocument _responseBody {};
QHash<QByteArray, QByteArray> _responseHeaders;
bool _hasError = false;
QString _errorReason;
@@ -131,6 +138,7 @@ class ProviderRestApi : public QObject
public:
///
/// @brief Constructor of the REST-API wrapper
///
ProviderRestApi();
@@ -176,6 +184,20 @@ public:
///
virtual ~ProviderRestApi() override;
///
/// @brief Set the API's scheme
///
/// @param[in] scheme
///
void setScheme(const QString& scheme);
///
/// @brief Get the API's scheme
///
/// return schme
///
QString getScheme() { return _apiUrl.scheme(); }
///
/// @brief Set an API's host
///
@@ -190,6 +212,13 @@ public:
///
void setPort(const int port) { _apiUrl.setPort(port); }
///
/// @brief Get the API's port
///
/// return port
///
int getPort() { return _apiUrl.port(); }
///
/// @brief Set an API's url
///
@@ -204,6 +233,13 @@ public:
///
QUrl getUrl() const;
///
/// @brief Set an API's base path (the stable path element before addressing resources)
///
/// @param[in] pathElements to form a path, e.g. (clip,v2,resource) results in "/clip/v2/resource"
///
void setBasePath(const QStringList& pathElements);
///
/// @brief Set an API's base path (the stable path element before addressing resources)
///
@@ -211,6 +247,11 @@ public:
///
void setBasePath(const QString& basePath);
///
/// @brief Clear an API's base path (the stable path element before addressing resources)
///
void clearBasePath();
///
/// @brief Set an API's path to address resources
///
@@ -218,12 +259,18 @@ public:
///
void setPath(const QString& path);
///
/// @brief Set an API's path to address resources
///
/// @param[in] pathElements to form a path, e.g. (lights,1,state) results in "/lights/1/state/"
///
void setPath(const QStringList& pathElements);
///
/// @brief Clear an API's path
///
void clearPath();
///
/// @brief Append an API's path element to path set before
///
@@ -252,6 +299,10 @@ public:
///
void setQuery(const QUrlQuery& query);
QString getBasePath() {return _basePath;}
QString getPath() {return _path;}
///
/// @brief Execute GET request
///
@@ -359,6 +410,14 @@ public:
/// @param[in] timeout in milliseconds.
void setTransferTimeout(std::chrono::milliseconds timeout = DEFAULT_REST_TIMEOUT) { _requestTimeout = timeout; }
bool setCaCertificate(const QString& caFileName);
void acceptSelfSignedCertificates(bool accept);
void setAlternateServerIdentity(const QString& serverIdentity);
QString getAlternateServerIdentity() const;
///
/// @brief Set the common logger for LED-devices.
///
@@ -366,6 +425,10 @@ public:
///
void setLogger(Logger* log) { _log = log; }
protected slots:
/// Handle the SSLErrors
void onSslErrors(QNetworkReply* reply, const QList<QSslError>& errors);
private:
///
@@ -379,9 +442,11 @@ private:
httpResponse executeOperation(QNetworkAccessManager::Operation op, const QUrl& url, const QByteArray& body = {});
bool checkServerIdentity(const QSslConfiguration& sslConfig) const;
Logger* _log;
// QNetworkAccessManager object for sending REST-requests.
/// QNetworkAccessManager object for sending REST-requests.
QNetworkAccessManager* _networkManager;
std::chrono::milliseconds _requestTimeout;
@@ -394,6 +459,9 @@ private:
QUrlQuery _query;
QNetworkRequest _networkRequestHeaders;
QString _serverIdentity;
bool _isSeflSignedCertificateAccpeted;
};
#endif // PROVIDERRESTKAPI_H