/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2019 Bernhard Trinnes . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /*! \page coinmarketcap.html \title coin market cap \brief Plugin to get the latest crypto prices. \ingroup plugins The coin market cap plugin gets the latest crypto prices from coin market cap and displays it in your favourite fiat currency. \chapter Plugin properties Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses} and \l{Vendor}{Vendors} of this \l{DevicePlugin}. For more details how to read this JSON file please check out the documentation for \l{The plugin JSON File}. \quotefile plugins/deviceplugins/coinmarketcap/deviceplugincoinmarketcap.json */ #include "deviceplugincoinmarketcap.h" #include "network/networkaccessmanager.h" #include "plugininfo.h" #include DevicePluginCoinMarketCap::DevicePluginCoinMarketCap() { } DeviceManager::DeviceSetupStatus DevicePluginCoinMarketCap::setupDevice(Device *device) { if(!m_pluginTimer) { m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10); connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginCoinMarketCap::onPluginTimer); } if (device->deviceClassId() == currentPricesDeviceClassId) { getPriceCall(device); return DeviceManager::DeviceSetupStatusSuccess; } return DeviceManager::DeviceSetupStatusFailure; } void DevicePluginCoinMarketCap::deviceRemoved(Device *device) { while (m_httpRequests.values().contains(device)) { QNetworkReply *reply = m_httpRequests.key(device); m_httpRequests.remove(reply); reply->deleteLater(); } if (myDevices().empty()) { hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer); } } void DevicePluginCoinMarketCap::onPluginTimer() { foreach (Device *device, myDevices()) { if (device->deviceClassId() == currentPricesDeviceClassId) { getPriceCall(device); } } } void DevicePluginCoinMarketCap::onPriceCallFinished() { QNetworkReply *reply = static_cast(sender()); qCDebug(dcCoinMarketCap()) << "GET reply finished"; int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (!m_httpRequests.contains(reply)) { reply->deleteLater(); return; } Device *device = m_httpRequests.take(reply); // Check HTTP status code if (status != 200 || reply->error() != QNetworkReply::NoError) { qCWarning(dcCoinMarketCap()) << "Request error:" << status << reply->errorString(); device->setStateValue(currentPricesConnectedStateTypeId, false); } // check JSON file QJsonParseError error; QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll(), &error); reply->deleteLater(); if (error.error != QJsonParseError::NoError) { qCWarning(dcCoinMarketCap()) << "Update reply JSON error:" << error.errorString(); reply->deleteLater(); return; } QVariantList list = jsonResponse.toVariant().toList(); foreach (QVariant element, list) { QVariantMap elementMap = element.toMap(); device->setStateValue(currentPricesConnectedStateTypeId, true); double price; if (elementMap.value("id").toString() == "bitcoin") { price = elementMap.value(QString("price_%1").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())).toDouble(); qDebug(dcCoinMarketCap()) << "Bitcoin Price in" << QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower() << price; device->setStateValue(currentPricesBtcStateTypeId, price); } else if (elementMap.value("id").toString() == "ethereum") { price = elementMap.value(QString("price_%1").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())).toDouble(); qDebug(dcCoinMarketCap()) << "Etherium Price in" << QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower() << price; device->setStateValue(currentPricesEthStateTypeId, price); } else if (elementMap.value("id").toString() == "ripple") { price = elementMap.value(QString("price_%1").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())).toDouble(); qDebug(dcCoinMarketCap()) << "Ripple Price in" << QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower() << price; device->setStateValue(currentPricesXrpStateTypeId, price); } else if (elementMap.value("id").toString() == "bitcoin-cash") { price = elementMap.value(QString("price_%1").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())).toDouble(); qDebug(dcCoinMarketCap()) << "Bitcoin-cash Price in" << QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower() << price; device->setStateValue(currentPricesBchStateTypeId, price); } else if (elementMap.value("id").toString() == "litecoin") { price = elementMap.value(QString("price_%1").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())).toDouble(); qDebug(dcCoinMarketCap()) << "Litecoin Price in" << QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower() << price; device->setStateValue(currentPricesLtcStateTypeId, price); } else if (elementMap.value("id").toString() == "nem") { price = elementMap.value(QString("price_%1").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())).toDouble(); qDebug(dcCoinMarketCap()) << "Nem Price in" << QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower() << price; device->setStateValue(currentPricesXemStateTypeId, price); } else if (elementMap.value("id").toString() == "ethereum-classic") { price = elementMap.value(QString("price_%1").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())).toDouble(); qDebug(dcCoinMarketCap()) << "Ethereum Classic Price in" << QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower() << price; device->setStateValue(currentPricesEtcStateTypeId, price); } else if (elementMap.value("id").toString() == "dash") { price = elementMap.value(QString("price_%1").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())).toDouble(); device->setStateValue(currentPricesDashStateTypeId, price); } else if (elementMap.value("id").toString() == "iota") { price = elementMap.value(QString("price_%1").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())).toDouble(); device->setStateValue(currentPricesMiotaStateTypeId, price); } else if (elementMap.value("id").toString() == "neo") { price = elementMap.value(QString("price_%1").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())).toDouble(); device->setStateValue(currentPricesAnsStateTypeId, price); } } } void DevicePluginCoinMarketCap::getPriceCall(Device *device) { QUrl url; url.setUrl(QString("https://api.coinmarketcap.com/v1/ticker/?convert=%1&limit=30").arg(QString(device->paramValue(currentPricesDeviceFiatParamTypeId).toString()).toLower())); QNetworkRequest request; request.setUrl(url); request.setRawHeader("User-Agent", "nymea 1.0"); QNetworkReply *reply = hardwareManager()->networkManager()->get(request); connect(reply, &QNetworkReply::finished, this, &DevicePluginCoinMarketCap::onPriceCallFinished); m_httpRequests.insert(reply, device); }