From ce06fed6182268e662dd72ae48d7d1966c59a2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 4 Mar 2019 16:25:43 +0100 Subject: [PATCH 1/3] Fix netatmo plugin timer interval and initialization --- netatmo/devicepluginnetatmo.cpp | 14 ++++++++++++-- netatmo/devicepluginnetatmo.h | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/netatmo/devicepluginnetatmo.cpp b/netatmo/devicepluginnetatmo.cpp index 9300a70f..6f20a476 100644 --- a/netatmo/devicepluginnetatmo.cpp +++ b/netatmo/devicepluginnetatmo.cpp @@ -60,8 +60,7 @@ DevicePluginNetatmo::~DevicePluginNetatmo() void DevicePluginNetatmo::init() { - m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(30); - connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginNetatmo::onPluginTimer); + } DeviceManager::DeviceSetupStatus DevicePluginNetatmo::setupDevice(Device *device) @@ -69,6 +68,11 @@ DeviceManager::DeviceSetupStatus DevicePluginNetatmo::setupDevice(Device *device if (device->deviceClassId() == netatmoConnectionDeviceClassId) { qCDebug(dcNetatmo) << "Setup netatmo connection" << device->name() << device->params(); + if (!m_pluginTimer) { + m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(300); + connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginNetatmo::onPluginTimer); + } + OAuth2 *authentication = new OAuth2("561c015d49c75f0d1cce6e13", "GuvKkdtu7JQlPD47qTTepRR9hQ0CUPAj4Tae3Ohcq", this); authentication->setUrl(QUrl("https://api.netatmo.net/oauth2/token")); authentication->setUsername(device->paramValue(netatmoConnectionDeviceUsernameParamTypeId).toString()); @@ -113,6 +117,12 @@ void DevicePluginNetatmo::deviceRemoved(Device *device) OAuth2 * authentication = m_authentications.key(device); m_authentications.remove(authentication); authentication->deleteLater(); + + if (m_pluginTimer) { + m_pluginTimer->deleteLater(); + m_pluginTimer = nullptr; + } + } else if (device->deviceClassId() == indoorDeviceClassId) { NetatmoBaseStation *indoor = m_indoorDevices.key(device); m_indoorDevices.remove(indoor); diff --git a/netatmo/devicepluginnetatmo.h b/netatmo/devicepluginnetatmo.h index e7236071..3cd1763d 100644 --- a/netatmo/devicepluginnetatmo.h +++ b/netatmo/devicepluginnetatmo.h @@ -50,7 +50,7 @@ public slots: DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; private: - PluginTimer *m_pluginTimer; + PluginTimer *m_pluginTimer = nullptr; QList m_asyncSetups; QHash m_authentications; From 7bb0829718d994b02c129b7b1b98b831c8a44e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 4 Mar 2019 17:50:09 +0100 Subject: [PATCH 2/3] Disable netatmo timer only if there is no device left --- netatmo/devicepluginnetatmo.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/netatmo/devicepluginnetatmo.cpp b/netatmo/devicepluginnetatmo.cpp index 6f20a476..d8ace1be 100644 --- a/netatmo/devicepluginnetatmo.cpp +++ b/netatmo/devicepluginnetatmo.cpp @@ -117,12 +117,6 @@ void DevicePluginNetatmo::deviceRemoved(Device *device) OAuth2 * authentication = m_authentications.key(device); m_authentications.remove(authentication); authentication->deleteLater(); - - if (m_pluginTimer) { - m_pluginTimer->deleteLater(); - m_pluginTimer = nullptr; - } - } else if (device->deviceClassId() == indoorDeviceClassId) { NetatmoBaseStation *indoor = m_indoorDevices.key(device); m_indoorDevices.remove(indoor); @@ -132,6 +126,11 @@ void DevicePluginNetatmo::deviceRemoved(Device *device) m_outdoorDevices.remove(outdoor); outdoor->deleteLater(); } + + if (myDevices().isEmpty() && m_pluginTimer) { + m_pluginTimer->deleteLater(); + m_pluginTimer = nullptr; + } } DeviceManager::DeviceError DevicePluginNetatmo::executeAction(Device *device, const Action &action) From 2d7a21c926429fa9d88a26551a5a4e73a7c0b66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 5 Mar 2019 16:01:53 +0100 Subject: [PATCH 3/3] Fix netatmo API changes and improve overall behaviour --- netatmo/devicepluginnetatmo.cpp | 92 +++++++++++++++++++-------------- netatmo/devicepluginnetatmo.h | 6 ++- 2 files changed, 58 insertions(+), 40 deletions(-) diff --git a/netatmo/devicepluginnetatmo.cpp b/netatmo/devicepluginnetatmo.cpp index d8ace1be..8136e493 100644 --- a/netatmo/devicepluginnetatmo.cpp +++ b/netatmo/devicepluginnetatmo.cpp @@ -55,7 +55,7 @@ DevicePluginNetatmo::DevicePluginNetatmo() DevicePluginNetatmo::~DevicePluginNetatmo() { - hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer); + } void DevicePluginNetatmo::init() @@ -69,7 +69,7 @@ DeviceManager::DeviceSetupStatus DevicePluginNetatmo::setupDevice(Device *device qCDebug(dcNetatmo) << "Setup netatmo connection" << device->name() << device->params(); if (!m_pluginTimer) { - m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(300); + m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(600); connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginNetatmo::onPluginTimer); } @@ -133,6 +133,21 @@ void DevicePluginNetatmo::deviceRemoved(Device *device) } } +void DevicePluginNetatmo::postSetupDevice(Device *device) +{ + if (device->deviceClassId() == indoorDeviceClassId) { + QString stationId = device->paramValue(indoorDeviceMacParamTypeId).toString(); + if (m_indoorStationInitData.contains(stationId) && m_indoorDevices.values().contains(device)) { + m_indoorDevices.key(device)->updateStates(m_indoorStationInitData.take(stationId)); + } + } else if (device->deviceClassId() == outdoorDeviceClassId) { + QString stationId = device->paramValue(outdoorDeviceMacParamTypeId).toString(); + if (m_outdoorStationInitData.contains(stationId) && m_outdoorDevices.values().contains(device)) { + m_outdoorDevices.key(device)->updateStates(m_outdoorStationInitData.take(stationId)); + } + } +} + DeviceManager::DeviceError DevicePluginNetatmo::executeAction(Device *device, const Action &action) { Q_UNUSED(device) @@ -155,10 +170,10 @@ void DevicePluginNetatmo::refreshData(Device *device, const QString &token) m_refreshRequest.insert(reply, device); } -void DevicePluginNetatmo::processRefreshData(const QVariantMap &data, const QString &connectionId) +void DevicePluginNetatmo::processRefreshData(const QVariantMap &data, Device *connectionDevice) { + // Process the data if (data.contains("body")) { - // check devices if (data.value("body").toMap().contains("devices")) { QVariantList deviceList = data.value("body").toMap().value("devices").toList(); @@ -170,11 +185,12 @@ void DevicePluginNetatmo::processRefreshData(const QVariantMap &data, const QStr Device *indoorDevice = findIndoorDevice(deviceMap.value("_id").toString()); // check if we have to create the device (auto) if (!indoorDevice) { - DeviceDescriptor descriptor(indoorDeviceClassId, "Indoor Station", deviceMap.value("station_name").toString(), connectionId); + DeviceDescriptor descriptor(indoorDeviceClassId, deviceMap.value("module_name").toString(), deviceMap.value("station_name").toString(), connectionDevice->id()); ParamList params; params.append(Param(indoorDeviceNameParamTypeId, deviceMap.value("station_name").toString())); params.append(Param(indoorDeviceMacParamTypeId, deviceMap.value("_id").toString())); descriptor.setParams(params); + m_indoorStationInitData.insert(deviceMap.value("_id").toString(), deviceMap); emit autoDevicesAppeared(indoorDeviceClassId, QList() << descriptor); } else { if (m_indoorDevices.values().contains(indoorDevice)) { @@ -182,30 +198,31 @@ void DevicePluginNetatmo::processRefreshData(const QVariantMap &data, const QStr } } } - } - } - // check modules - if (data.value("body").toMap().contains("modules")) { - QVariantList modulesList = data.value("body").toMap().value("modules").toList(); - // check devices - foreach (QVariant moduleVariant, modulesList) { - QVariantMap moduleMap = moduleVariant.toMap(); - // we support currently only NAModule1 - if (moduleMap.value("type").toString() == "NAModule1") { - Device *outdoorDevice = findOutdoorDevice(moduleMap.value("_id").toString()); - // check if we have to create the device (auto) - if (!outdoorDevice) { - DeviceDescriptor descriptor(outdoorDeviceClassId, "Outdoor Module", moduleMap.value("module_name").toString(), connectionId); - ParamList params; - params.append(Param(outdoorDeviceNameParamTypeId, moduleMap.value("module_name").toString())); - params.append(Param(outdoorDeviceMacParamTypeId, moduleMap.value("_id").toString())); - params.append(Param(outdoorDeviceBaseStationParamTypeId, moduleMap.value("main_device").toString())); - descriptor.setParams(params); - emit autoDevicesAppeared(outdoorDeviceClassId, QList() << descriptor); - } else { - if (m_outdoorDevices.values().contains(outdoorDevice)) { - m_outdoorDevices.key(outdoorDevice)->updateStates(moduleMap); + // check modules + if (deviceMap.contains("modules")) { + QVariantList modulesList = deviceMap.value("modules").toList(); + foreach (QVariant moduleVariant, modulesList) { + QVariantMap moduleMap = moduleVariant.toMap(); + // we support currently only NAModule1 + if (moduleMap.value("type").toString() == "NAModule1") { + Device *outdoorDevice = findOutdoorDevice(moduleMap.value("_id").toString()); + + // check if we have to create the device (auto) + if (!outdoorDevice) { + DeviceDescriptor descriptor(outdoorDeviceClassId, "Outdoor Module", moduleMap.value("module_name").toString(), connectionDevice->id()); + ParamList params; + params.append(Param(outdoorDeviceNameParamTypeId, moduleMap.value("module_name").toString())); + params.append(Param(outdoorDeviceMacParamTypeId, moduleMap.value("_id").toString())); + params.append(Param(outdoorDeviceBaseStationParamTypeId, deviceMap.value("_id").toString())); + descriptor.setParams(params); + m_outdoorStationInitData.insert(moduleMap.value("_id").toString(), moduleMap); + emit autoDevicesAppeared(outdoorDeviceClassId, QList() << descriptor); + } else { + if (m_outdoorDevices.values().contains(outdoorDevice)) { + m_outdoorDevices.key(outdoorDevice)->updateStates(moduleMap); + } + } } } } @@ -235,7 +252,7 @@ Device *DevicePluginNetatmo::findOutdoorDevice(const QString &macAddress) } } } - return 0; + return nullptr; } void DevicePluginNetatmo::onPluginTimer() @@ -252,8 +269,9 @@ void DevicePluginNetatmo::onPluginTimer() void DevicePluginNetatmo::onNetworkReplyFinished() { QNetworkReply *reply = static_cast(sender()); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + reply->deleteLater(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); // update values request if (m_refreshRequest.keys().contains(reply)) { Device *device = m_refreshRequest.take(reply); @@ -262,7 +280,6 @@ void DevicePluginNetatmo::onNetworkReplyFinished() if (status != 200) { qCWarning(dcNetatmo) << "Device list reply HTTP error:" << status << reply->errorString(); device->setStateValue(netatmoConnectionConnectedStateTypeId, false); - reply->deleteLater(); return; } @@ -271,35 +288,32 @@ void DevicePluginNetatmo::onNetworkReplyFinished() QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error); if (error.error != QJsonParseError::NoError) { qCWarning(dcNetatmo) << "Device list reply JSON error:" << error.errorString(); - reply->deleteLater(); return; } - //qCDebug(dcNetatmo) << jsonDoc.toJson(); - processRefreshData(jsonDoc.toVariant().toMap(), device->id().toString()); + qCDebug(dcNetatmo) << qUtf8Printable(jsonDoc.toJson()); + processRefreshData(jsonDoc.toVariant().toMap(), device); } - - reply->deleteLater(); } void DevicePluginNetatmo::onAuthenticationChanged() { OAuth2 *authentication = static_cast(sender()); Device *device = m_authentications.value(authentication); - if (!device) return; - // set the available state + // Set the available state device->setStateValue(netatmoConnectionConnectedStateTypeId, authentication->authenticated()); // check if this is was a setup athentication if (m_asyncSetups.contains(device)) { + m_asyncSetups.removeAll(device); if (authentication->authenticated()) { - m_asyncSetups.removeAll(device); emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess); refreshData(device, authentication->token()); } else { + authentication->deleteLater(); emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure); } } diff --git a/netatmo/devicepluginnetatmo.h b/netatmo/devicepluginnetatmo.h index 3cd1763d..de045840 100644 --- a/netatmo/devicepluginnetatmo.h +++ b/netatmo/devicepluginnetatmo.h @@ -45,6 +45,7 @@ public: void init() override; DeviceManager::DeviceSetupStatus setupDevice(Device *device) override; void deviceRemoved(Device *device) override; + void postSetupDevice(Device *device) override; public slots: DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; @@ -53,6 +54,9 @@ private: PluginTimer *m_pluginTimer = nullptr; QList m_asyncSetups; + QHash m_indoorStationInitData; + QHash m_outdoorStationInitData; + QHash m_authentications; QHash m_indoorDevices; QHash m_outdoorDevices; @@ -60,7 +64,7 @@ private: QHash m_refreshRequest; void refreshData(Device *device, const QString &token); - void processRefreshData(const QVariantMap &data, const QString &connectionId); + void processRefreshData(const QVariantMap &data, Device *connectionDevice); Device *findIndoorDevice(const QString &macAddress); Device *findOutdoorDevice(const QString &macAddress);