void DevicePluginNetworkInfo::actionDataReady(const ActionId &actionId, const QByteArray &data)
{
    // Convert the rawdata to a json document
    QJsonParseError error;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);

    // Check if we got a valid JSON document
    if(error.error != QJsonParseError::NoError) {
        qCWarning(dcNetworkInfo) << "Failed to parse JSON data" << data << ":" << error.errorString();

        // the action execution is finished, and was not successfully
        emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorHardwareFailure);
        return;
    }

    // print the fetched data in json format to stdout
    qCDebug(dcNetworkInfo) << jsonDoc.toJson();

    // Get the device for this action
    Device *device = m_asyncActions.take(actionId);

    // Parse the data and update the states of our device
    QVariantMap dataMap = jsonDoc.toVariant().toMap();

    // Set the city state
    if (dataMap.contains("city")) {
        device->setStateValue(cityStateTypeId, dataMap.value("city").toString());
    }

    // Set the country state
    if (dataMap.contains("countryCode")) {
        device->setStateValue(countryStateTypeId, dataMap.value("countryCode").toString());
    }

    // Set the wan ip
    if (dataMap.contains("query")) {
        device->setStateValue(addressStateTypeId, dataMap.value("query").toString());
    }

    // Set the time zone state
    if (dataMap.contains("timezone")) {
        device->setStateValue(timeZoneStateTypeId, dataMap.value("timezone").toString());
    }

    // Set the longitude state
    if (dataMap.contains("lon")) {
        device->setStateValue(lonStateTypeId, dataMap.value("lon").toDouble());
    }

    // Set the latitude state
    if (dataMap.contains("lat")) {
        device->setStateValue(latStateTypeId, dataMap.value("lat").toDouble());
    }

    qCDebug(dcNetworkInfo) << "Action" << actionId << "execution finished successfully.";

    // Emit the successfull action execution result to the device manager
    emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorNoError);
}
void DevicePluginMailNotification::sendMailFinished(const bool &success, const ActionId &actionId)
{
    if(success) {
        emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorNoError);
    } else {
        emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorDeviceNotFound);
    }
}
// This method will be called whenever the reply from a NetworkManager call is ready.
void DevicePluginNetworkInfo::networkManagerReplyReady(QNetworkReply *reply)
{
    // Make shore this is our reply
    if (!m_asyncActionReplies.keys().contains(reply))
        return;

    // This is one of our action replies!!

    // Take the corresponding action from our hash
    ActionId actionId = m_asyncActionReplies.take(reply);

    // Check the status code of the reply
    if (reply->error()) {

        // Print the warning message
        qCWarning(dcNetworkInfo) << "Reply error" << reply->errorString();

        // The action execution is finished and was not successfully
        emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorHardwareNotAvailable);

        // Important -> delete the reply to prevent a memory leak!
        reply->deleteLater();
        return;
    }

    // The request was successfull, lets read the payload
    QByteArray data = reply->readAll();

    // Important -> delete the reply to prevent a memory leak!
    reply->deleteLater();

    // Process the data from the reply
    actionDataReady(actionId, data);
}