/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see
") + 11;
int delta = data.indexOf("/128",index);
QHostAddress nodeAddress(QString(data.mid(index, delta - index)));
// check if we already have found this node
foreach (Device *device, myDevices()) {
if (device->paramValue(merkurNodeDeviceHostParamTypeId).toString() == nodeAddress.toString()) {
return;
}
}
QUrl url;
url.setScheme("coap");
url.setHost(nodeAddress.toString());
url.setPath("/.well-known/core");
qCDebug(dcOsdomotics) << "Discover node on" << url.toString();
CoapReply *reply = m_coap->get(CoapRequest(url));
if (reply->isFinished()) {
if (reply->error() != CoapReply::NoError) {
qCWarning(dcOsdomotics) << "Reply finished with error" << reply->errorString();
} else {
qCDebug(dcOsdomotics) << "Reply finished" << reply;
}
// Note: please don't forget to delete the reply
reply->deleteLater();
return;
}
m_discoveryRequests.insert(reply, device);
}
void DevicePluginOsdomotics::updateNode(Device *device)
{
qCDebug(dcOsdomotics) << "Update node" << device->paramValue(merkurNodeDeviceHostParamTypeId).toString() << "battery value";
QUrl url;
url.setScheme("coap");
url.setHost(device->paramValue(merkurNodeDeviceHostParamTypeId).toString());
url.setPath("/sensors/battery");
CoapReply *reply = m_coap->get(CoapRequest(url));
if (reply->isFinished()) {
if (reply->error() != CoapReply::NoError) {
qCWarning(dcOsdomotics) << "CoAP reply finished with error" << reply->errorString();
reply->deleteLater();
}
}
m_updateRequests.insert(reply, device);
}
Device *DevicePluginOsdomotics::findDevice(const QHostAddress &address)
{
foreach (Device *device, myDevices()) {
if (device->paramValue(merkurNodeDeviceHostParamTypeId).toString() == address.toString()) {
return device;
}
}
return nullptr;
}
void DevicePluginOsdomotics::onPluginTimer()
{
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == merkurNodeDeviceClassId) {
updateNode(device);
} else if(device->deviceClassId() == rplRouterDeviceClassId) {
scanNodes(device);
}
}
}
void DevicePluginOsdomotics::onNetworkReplyFinished()
{
QNetworkReply *reply = static_cast(sender());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (m_asyncNodeRescans.contains(reply)) {
Device *device = m_asyncSetup.take(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcOsdomotics) << "Setup reply HTTP error:" << reply->errorString();
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
parseNodes(device, data);
}
reply->deleteLater();
}
void DevicePluginOsdomotics::coapReplyFinished(CoapReply *reply)
{
qCDebug(dcOsdomotics) << "coap reply finished" << reply;
if (m_discoveryRequests.contains(reply)) {
Device *device = m_discoveryRequests.take(reply);
if (reply->error() != CoapReply::NoError) {
qCWarning(dcOsdomotics) << "CoAP discover reply finished with error" << reply->errorString();
reply->deleteLater();
return;
}
// TODO: parse CoRE links and get the type of the node
DeviceDescriptor descriptor(merkurNodeDeviceClassId, "Merkur Node", reply->request().url().host());
ParamList params;
params.append(Param(merkurNodeDeviceNameParamTypeId, "Merkur Node"));
params.append(Param(merkurNodeDeviceHostParamTypeId, reply->request().url().host()));
params.append(Param(merkurNodeDeviceRouterParamTypeId, device->id()));
descriptor.setParams(params);
emit autoDevicesAppeared({descriptor});
} else if (m_updateRequests.contains(reply)) {
Device *device = m_updateRequests.take(reply);
if (reply->error() != CoapReply::NoError) {
qCWarning(dcOsdomotics) << "CoAP update reply finished with error" << reply->errorString();
reply->deleteLater();
return;
}
int batteryValue = reply->payload().toInt();
qCDebug(dcOsdomotics) << "Node updated" << batteryValue;
device->setStateValue(merkurNodeBatteryStateTypeId, batteryValue);
}
reply->deleteLater();
}