mirror of https://github.com/nymea/nymea.git
first working kodi version
parent
7836730b80
commit
5c05ac2bb6
Binary file not shown.
|
After Width: | Height: | Size: 215 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 372 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 268 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 215 KiB |
|
|
@ -20,13 +20,34 @@
|
|||
|
||||
/*!
|
||||
\page kodi.html
|
||||
\title Kodi
|
||||
\title Kodi - Media Center
|
||||
|
||||
\ingroup plugins
|
||||
\ingroup network
|
||||
|
||||
TODO: description
|
||||
This plugin allowes you to controll the media center \l{http://kodi.tv/}{Kodi}. If you want to discover
|
||||
and control Kodi with guh, you need to activate the remote access and the UPnP service.
|
||||
|
||||
\chapter "Activate UPnP"
|
||||
In order to discover Kodi in the network, you need to activate the UPnP serive in the Kodi settings:
|
||||
|
||||
\section2 Settings
|
||||
\image kodi_settings.png
|
||||
|
||||
\section2 Settings \unicode{0x2192} Services
|
||||
\image kodi_services.png
|
||||
|
||||
\section2 Settings \unicode{0x2192} Services \unicode{0x2192} UPnP
|
||||
Activate all options.
|
||||
\image kodi_upnp.png
|
||||
|
||||
|
||||
\chapter Activate "Remote Control"
|
||||
In order to control Kodi over the network with guh, you need to activate the remote control permissions:
|
||||
|
||||
\section2 Settings \unicode{0x2192} Services \unicode{0x2192} Remote Control
|
||||
Activate all options.
|
||||
\image kodi_remote.png
|
||||
|
||||
\chapter Plugin properties
|
||||
Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses}
|
||||
|
|
@ -41,7 +62,7 @@
|
|||
\note If a \l{StateType} has the parameter \tt{"writable": true}, an \l{ActionType} with the same uuid and \l{ParamType}{ParamTypes}
|
||||
will be created automatically.
|
||||
|
||||
\quotefile plugins/deviceplugins/udpcommander/devicepluginudpcommander.json
|
||||
\quotefile plugins/deviceplugins/kodi/devicepluginkodi.json
|
||||
*/
|
||||
|
||||
#include "devicepluginkodi.h"
|
||||
|
|
@ -61,32 +82,38 @@ DeviceManager::HardwareResources DevicePluginKodi::requiredHardware() const
|
|||
|
||||
DeviceManager::DeviceSetupStatus DevicePluginKodi::setupDevice(Device *device)
|
||||
{
|
||||
KodiConnection *kodiConnection = new KodiConnection(QHostAddress(device->paramValue("ip").toString()), 9090, this);
|
||||
Kodi *kodi= new Kodi(QHostAddress(device->paramValue("ip").toString()), 9090, this);
|
||||
|
||||
connect(kodiConnection, &KodiConnection::connectionStateChanged, this, &DevicePluginKodi::onConnectionChanged);
|
||||
connect(kodi, &Kodi::connectionStatusChanged, this, &DevicePluginKodi::onConnectionChanged);
|
||||
connect(kodi, &Kodi::stateChanged, this, &DevicePluginKodi::onStateChanged);
|
||||
connect(kodi, &Kodi::actionExecuted, this, &DevicePluginKodi::onActionExecuted);
|
||||
connect(kodi, &Kodi::onPlayerPlay, this, &DevicePluginKodi::onPlayerPlay);
|
||||
connect(kodi, &Kodi::onPlayerPause, this, &DevicePluginKodi::onPlayerPause);
|
||||
connect(kodi, &Kodi::onPlayerStop, this, &DevicePluginKodi::onPlayerStop);
|
||||
|
||||
kodiConnection->connectToKodi();
|
||||
kodi->connectKodi();
|
||||
|
||||
m_kodiConnections.insert(kodiConnection, device);
|
||||
m_kodis.insert(kodi, device);
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
|
||||
void DevicePluginKodi::deviceRemoved(Device *device)
|
||||
{
|
||||
KodiConnection *kodiConnection = m_kodiConnections.key(device);
|
||||
m_kodiConnections.remove(kodiConnection);
|
||||
qCDebug(dcKodi) << "delete Kodi" << device->paramValue("name");
|
||||
kodiConnection->deleteLater();
|
||||
Kodi *kodi = m_kodis.key(device);
|
||||
m_kodis.remove(kodi);
|
||||
qCDebug(dcKodi) << "delete " << device->paramValue("name");
|
||||
kodi->deleteLater();
|
||||
}
|
||||
|
||||
void DevicePluginKodi::guhTimer()
|
||||
{
|
||||
foreach (KodiConnection *kodi, m_kodiConnections.keys()) {
|
||||
foreach (Kodi *kodi, m_kodis.keys()) {
|
||||
if (!kodi->connected()) {
|
||||
kodi->connectToKodi();
|
||||
kodi->connectKodi();
|
||||
continue;
|
||||
} else {
|
||||
// update.. ?
|
||||
// no need for polling information, notifications do the job
|
||||
//kodi->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +123,7 @@ DeviceManager::DeviceError DevicePluginKodi::discoverDevices(const DeviceClassId
|
|||
{
|
||||
Q_UNUSED(params)
|
||||
Q_UNUSED(deviceClassId)
|
||||
qCDebug(dcKodi) << "start Kodi UPnP search";
|
||||
qCDebug(dcKodi) << "start UPnP search";
|
||||
upnpDiscover();
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
}
|
||||
|
|
@ -134,31 +161,90 @@ void DevicePluginKodi::upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &
|
|||
DeviceManager::DeviceError DevicePluginKodi::executeAction(Device *device, const Action &action)
|
||||
{
|
||||
if (device->deviceClassId() == kodiDeviceClassId) {
|
||||
if (action.actionTypeId() == sendNotificationActionTypeId) {
|
||||
Kodi *kodi = m_kodis.key(device);
|
||||
|
||||
// check connection state
|
||||
if (!kodi->connected()) {
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
}
|
||||
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
if (action.actionTypeId() == showNotificationActionTypeId) {
|
||||
kodi->showNotification(action.param("message").value().toString(), 8000, action.id());
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
} else if (action.actionTypeId() == volumeActionTypeId) {
|
||||
|
||||
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
kodi->setVolume(action.param("volume").value().toInt(), action.id());
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
} else if (action.actionTypeId() == muteActionTypeId) {
|
||||
kodi->setMuted(action.param("mute").value().toBool(), action.id());
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
} else if (action.actionTypeId() == pressButtonActionTypeId) {
|
||||
kodi->pressButton(action.param("button").value().toString(), action.id());
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
} else if (action.actionTypeId() == systemActionTypeId) {
|
||||
kodi->systemCommand(action.param("command").value().toString(), action.id());
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
} else if (action.actionTypeId() == videoLibraryActionTypeId) {
|
||||
kodi->videoLibrary(action.param("command").value().toString(), action.id());
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
} else if (action.actionTypeId() == audioLibraryActionTypeId) {
|
||||
kodi->audioLibrary(action.param("command").value().toString(), action.id());
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
}
|
||||
return DeviceManager::DeviceErrorActionTypeNotFound;
|
||||
}
|
||||
return DeviceManager::DeviceErrorDeviceClassNotFound;
|
||||
}
|
||||
|
||||
void DevicePluginKodi::onConnectionChanged(const bool &connected)
|
||||
void DevicePluginKodi::onConnectionChanged()
|
||||
{
|
||||
KodiConnection *kodiConnection = static_cast<KodiConnection *>(sender());
|
||||
Device *device = m_kodiConnections.value(kodiConnection);
|
||||
Kodi *kodi = static_cast<Kodi *>(sender());
|
||||
Device *device = m_kodis.value(kodi);
|
||||
|
||||
device->setStateValue(connectedStateTypeId, connected);
|
||||
if (kodi->connected()) {
|
||||
kodi->showNotification("Connected", 2000, ActionId());
|
||||
kodi->update();
|
||||
}
|
||||
|
||||
device->setStateValue(connectedStateTypeId, kodi->connected());
|
||||
}
|
||||
|
||||
void DevicePluginKodi::dataReceived(const QByteArray &data)
|
||||
void DevicePluginKodi::onStateChanged()
|
||||
{
|
||||
KodiConnection *kodiConnection = static_cast<KodiConnection *>(sender());
|
||||
emit dataReady(kodiConnection, data);
|
||||
Kodi *kodi = static_cast<Kodi *>(sender());
|
||||
Device *device = m_kodis.value(kodi);
|
||||
|
||||
// set device state values
|
||||
device->setStateValue(volumeStateTypeId, kodi->volume());
|
||||
device->setStateValue(muteStateTypeId, kodi->muted());
|
||||
}
|
||||
|
||||
void DevicePluginKodi::onActionExecuted(const ActionId &actionId, const bool &success)
|
||||
{
|
||||
if (success) {
|
||||
emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorNoError);
|
||||
} else {
|
||||
emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorInvalidParameter);
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginKodi::onPlayerPlay()
|
||||
{
|
||||
Kodi *kodi = static_cast<Kodi *>(sender());
|
||||
Device *device = m_kodis.value(kodi);
|
||||
emit emitEvent(Event(onPlayerPlayEventTypeId, device->id()));
|
||||
}
|
||||
|
||||
void DevicePluginKodi::onPlayerPause()
|
||||
{
|
||||
Kodi *kodi = static_cast<Kodi *>(sender());
|
||||
Device *device = m_kodis.value(kodi);
|
||||
emit emitEvent(Event(onPlayerPauseEventTypeId, device->id()));
|
||||
}
|
||||
|
||||
void DevicePluginKodi::onPlayerStop()
|
||||
{
|
||||
Kodi *kodi = static_cast<Kodi *>(sender());
|
||||
Device *device = m_kodis.value(kodi);
|
||||
emit emitEvent(Event(onPlayerStopEventTypeId, device->id()));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#define DEVICEPLUGINKODI_H
|
||||
|
||||
#include "plugin/deviceplugin.h"
|
||||
#include "kodiconnection.h"
|
||||
#include "kodi.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QDebug>
|
||||
|
|
@ -48,15 +48,16 @@ public:
|
|||
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
||||
|
||||
private:
|
||||
QHash<KodiConnection *, Device *> m_kodiConnections;
|
||||
|
||||
signals:
|
||||
void dataReady(KodiConnection *kodiConnection, const QByteArray &data);
|
||||
QHash<Kodi *, Device *> m_kodis;
|
||||
|
||||
private slots:
|
||||
void onConnectionChanged(const bool &connected);
|
||||
void dataReceived(const QByteArray &data);
|
||||
void onConnectionChanged();
|
||||
void onStateChanged();
|
||||
void onActionExecuted(const ActionId &actionId, const bool &success);
|
||||
|
||||
void onPlayerPlay();
|
||||
void onPlayerPause();
|
||||
void onPlayerStop();
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINKODI_H
|
||||
|
|
|
|||
|
|
@ -53,15 +53,123 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"eventTypes": [
|
||||
{
|
||||
"id": "2535a1eb-7643-4874-98f6-b027fdff6311",
|
||||
"idName": "onPlayerPlay",
|
||||
"name": "player play"
|
||||
},
|
||||
{
|
||||
"id": "99498b1c-e9c0-480a-9e91-662ee79ba976",
|
||||
"idName": "onPlayerPause",
|
||||
"name": "player pause"
|
||||
},
|
||||
{
|
||||
"id": "a02ce255-3abb-435d-a92e-7f99c952ecb2",
|
||||
"idName": "onPlayerStop",
|
||||
"name": "player stop"
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "dc0aa3b5-4eae-4e58-a4ac-d4c124da53f1",
|
||||
"idName": "sendNotification",
|
||||
"name": "send notification",
|
||||
"idName": "showNotification",
|
||||
"name": "show notification",
|
||||
"paramTypes": [
|
||||
{
|
||||
"name": "message",
|
||||
"type": "QString"
|
||||
"type": "QString",
|
||||
"inputType": "TextLine"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "28060803-aa85-44a4-9dec-ee669dfb629f",
|
||||
"idName": "pressButton",
|
||||
"name": "press button",
|
||||
"paramTypes": [
|
||||
{
|
||||
"name": "button",
|
||||
"type": "QString",
|
||||
"allowedValues": [
|
||||
"left",
|
||||
"right",
|
||||
"up",
|
||||
"down",
|
||||
"pageup",
|
||||
"pagedown",
|
||||
"select",
|
||||
"back",
|
||||
"info",
|
||||
"pause",
|
||||
"stop",
|
||||
"skipnext",
|
||||
"skipprevious",
|
||||
"stepforward",
|
||||
"stepback",
|
||||
"osd",
|
||||
"play",
|
||||
"playpause",
|
||||
"fastforward",
|
||||
"rewind",
|
||||
"togglefullscreen",
|
||||
"mute",
|
||||
"volumeup",
|
||||
"volumedown",
|
||||
"channelup",
|
||||
"channeldown",
|
||||
"red",
|
||||
"green",
|
||||
"yellow",
|
||||
"blue"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "8d51cd64-ecef-44f8-85b0-697bef252ce5",
|
||||
"idName": "system",
|
||||
"name": "system",
|
||||
"paramTypes": [
|
||||
{
|
||||
"name": "command",
|
||||
"type": "QString",
|
||||
"allowedValues": [
|
||||
"hibernate",
|
||||
"reboot",
|
||||
"shutdown",
|
||||
"suspend"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "59f7ad10-16eb-40b7-a88b-c8393ae8e413",
|
||||
"idName": "videoLibrary",
|
||||
"name": "video library",
|
||||
"paramTypes": [
|
||||
{
|
||||
"name": "command",
|
||||
"type": "QString",
|
||||
"allowedValues": [
|
||||
"scan",
|
||||
"clean"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "3d5120eb-1007-46c3-b76e-d9d4b105b9f2",
|
||||
"idName": "audioLibrary",
|
||||
"name": "audio library",
|
||||
"paramTypes": [
|
||||
{
|
||||
"name": "command",
|
||||
"type": "QString",
|
||||
"allowedValues": [
|
||||
"scan",
|
||||
"clean"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +1,133 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* Guh 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "jsonhandler.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QBuffer>
|
||||
#include <QJsonDocument>
|
||||
|
||||
JsonHandler::JsonHandler(QObject *parent) :
|
||||
QObject(parent)
|
||||
JsonHandler::JsonHandler(KodiConnection *connection, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_connection(connection),
|
||||
m_id(0)
|
||||
{
|
||||
connect(m_connection, &KodiConnection::dataReady, this, &JsonHandler::processResponse);
|
||||
}
|
||||
|
||||
//QByteArray JsonHandler::createHelloMessage(QString title, QString message)
|
||||
//{
|
||||
// QByteArray payload;
|
||||
void JsonHandler::sendData(const QString &method, const QVariantMap ¶ms, const ActionId &actionId)
|
||||
{
|
||||
QVariantMap package;
|
||||
package.insert("id", m_id);
|
||||
package.insert("method", method);
|
||||
package.insert("params", params);
|
||||
package.insert("jsonrpc", "2.0");
|
||||
|
||||
// QByteArray iconData;
|
||||
// QBuffer buffer(&iconData);
|
||||
// buffer.open(QIODevice::WriteOnly);
|
||||
// icon.save(&buffer, "PNG");
|
||||
// // payload.clear();
|
||||
m_replys.insert(m_id, KodiReply(method, params, actionId));
|
||||
|
||||
// // // titel
|
||||
// // payload.push_back(QByteArray::fromStdString(title.toStdString()));
|
||||
// // payload.push_back('\0');
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(package);
|
||||
qCDebug(dcKodi) << "sending data" << jsonDoc.toJson();
|
||||
m_connection->sendData(jsonDoc.toJson());
|
||||
m_id++;
|
||||
}
|
||||
|
||||
// // // message
|
||||
// // payload.push_back(QByteArray::fromStdString(message.toStdString()));
|
||||
// // payload.push_back('\0');
|
||||
void JsonHandler::processNotification(const QString &method, const QVariantMap ¶ms)
|
||||
{
|
||||
if (method == "Application.OnVolumeChanged") {
|
||||
QVariantMap data = params.value("data").toMap();
|
||||
qCDebug(dcKodi) << "got volume changed notification" << "volume:" << data.value("volume").toInt() << " muted:" << data.value("muted").toBool();
|
||||
emit volumeChanged(data.value("volume").toInt(), data.value("muted").toBool());
|
||||
} else if (method == "Player.onPlayerPlay") {
|
||||
qCDebug(dcKodi) << "got player play notification";
|
||||
emit onPlayerPlay();
|
||||
} else if (method == "Player.onPlayerPause") {
|
||||
qCDebug(dcKodi) << "got player pause notification";
|
||||
emit onPlayerPause();
|
||||
} else if (method == "Player.onPlayerStop") {
|
||||
qCDebug(dcKodi) << "got player stop notification";
|
||||
emit onPlayerPause();
|
||||
}
|
||||
|
||||
// // // icontype ( 0=>NOICON, 1=>JPEG , 2=>PNG , 3=>GIF )
|
||||
// // payload.push_back(2);
|
||||
}
|
||||
|
||||
// // payload.push_back("0000");
|
||||
void JsonHandler::processActionResponse(const KodiReply &reply, const QVariantMap &response)
|
||||
{
|
||||
if (response.contains("error")) {
|
||||
qCDebug(dcKodi) << QJsonDocument::fromVariant(response).toJson();
|
||||
qCWarning(dcKodi) << "got action error response:" << response.value("error").toMap().value("message").toString();
|
||||
emit actionExecuted(reply.actionId(), false);
|
||||
} else {
|
||||
emit actionExecuted(reply.actionId(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// // // image data
|
||||
// // payload.push_back(iconData);
|
||||
// // payload.push_back('\0');
|
||||
void JsonHandler::processRequestResponse(const KodiReply &reply, const QVariantMap &response)
|
||||
{
|
||||
if (response.contains("error")) {
|
||||
qCDebug(dcKodi) << QJsonDocument::fromVariant(response).toJson();
|
||||
qCWarning(dcKodi) << "got request error response:" << response.value("error").toMap().value("message").toString();
|
||||
}
|
||||
|
||||
// // qCDebug(dcKodi) << payload;
|
||||
if (reply.method() == "Application.GetProperties") {
|
||||
qCDebug(dcKodi) << "got update response" << response;
|
||||
emit updateDataReceived(response.value("result").toMap());
|
||||
}
|
||||
}
|
||||
|
||||
// return payload;
|
||||
//}
|
||||
void JsonHandler::processResponse(const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
if(error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcKodi) << "failed to parse JSON data:" << data << ":" << error.errorString();
|
||||
return;
|
||||
}
|
||||
qCDebug(dcKodi) << "data received:" << jsonDoc.toJson();
|
||||
|
||||
QVariantMap message = jsonDoc.toVariant().toMap();
|
||||
|
||||
// check jsonrpc value
|
||||
if (!message.contains("jsonrpc") || message.value("jsonrpc").toString() != "2.0") {
|
||||
qCWarning(dcKodi) << "jsonrpc 2.0 value missing in message" << data;
|
||||
}
|
||||
|
||||
// check id (if there is no id, it's an notification from kodi)
|
||||
if (!message.contains("id")) {
|
||||
|
||||
// check method
|
||||
if (!message.contains("method")) {
|
||||
qCWarning(dcKodi) << "method missing in message" << data;
|
||||
}
|
||||
|
||||
processNotification(message.value("method").toString(), message.value("params").toMap());
|
||||
return;
|
||||
}
|
||||
|
||||
int id = message.value("id").toInt();
|
||||
KodiReply reply = m_replys.take(id);
|
||||
|
||||
// check if this message is a response to an action call
|
||||
if (reply.actionId() != ActionId()) {
|
||||
processActionResponse(reply, message);
|
||||
return;
|
||||
}
|
||||
|
||||
processRequestResponse(reply, message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,63 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* Guh 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef JSONHANDLER_H
|
||||
#define JSONHANDLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
#include <QHash>
|
||||
|
||||
#include "kodiconnection.h"
|
||||
#include "kodireply.h"
|
||||
#include "typeutils.h"
|
||||
|
||||
class JsonHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit JsonHandler(QObject *parent = 0);
|
||||
explicit JsonHandler(KodiConnection *connection = 0, QObject *parent = 0);
|
||||
|
||||
//static QByteArray createHelloMessage(QString title, QString message);
|
||||
void sendData(const QString &method, const QVariantMap ¶ms, const ActionId &actionId);
|
||||
|
||||
private:
|
||||
KodiConnection *m_connection;
|
||||
int m_id;
|
||||
|
||||
QHash<int, KodiReply> m_replys;
|
||||
|
||||
void processNotification(const QString &method, const QVariantMap ¶ms);
|
||||
void processActionResponse(const KodiReply &reply, const QVariantMap &response);
|
||||
void processRequestResponse(const KodiReply &reply, const QVariantMap &response);
|
||||
|
||||
signals:
|
||||
void volumeChanged(const int &volume, const bool &muted);
|
||||
void actionExecuted(const ActionId &actionId, const bool &success);
|
||||
void updateDataReceived(const QVariantMap &data);
|
||||
|
||||
public slots:
|
||||
void onPlayerPlay();
|
||||
void onPlayerPause();
|
||||
void onPlayerStop();
|
||||
|
||||
private slots:
|
||||
void processResponse(const QByteArray &data);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,182 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* Guh 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "kodi.h"
|
||||
|
||||
Kodi::Kodi(const QHostAddress &hostAddress, const int &port, QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
m_connection = new KodiConnection(hostAddress, port, this);
|
||||
connect (m_connection, &KodiConnection::connectionStatusChanged, this, &Kodi::connectionStatusChanged);
|
||||
|
||||
m_jsonHandler = new JsonHandler(m_connection, this);
|
||||
connect(m_jsonHandler, &JsonHandler::volumeChanged, this, &Kodi::onVolumeChanged);
|
||||
connect(m_jsonHandler, &JsonHandler::actionExecuted, this, &Kodi::actionExecuted);
|
||||
connect(m_jsonHandler, &JsonHandler::updateDataReceived, this, &Kodi::onUpdateFinished);
|
||||
connect(m_jsonHandler, &JsonHandler::onPlayerPlay, this, &Kodi::onPlayerPlay);
|
||||
connect(m_jsonHandler, &JsonHandler::onPlayerPause, this, &Kodi::onPlayerPause);
|
||||
connect(m_jsonHandler, &JsonHandler::onPlayerStop, this, &Kodi::onPlayerStop);
|
||||
}
|
||||
|
||||
QHostAddress Kodi::hostAddress() const
|
||||
{
|
||||
return m_connection->hostAddress();
|
||||
}
|
||||
|
||||
int Kodi::port() const
|
||||
{
|
||||
return m_connection->port();
|
||||
}
|
||||
|
||||
bool Kodi::connected() const
|
||||
{
|
||||
return m_connection->connected();
|
||||
}
|
||||
|
||||
void Kodi::setMuted(const bool &muted, const ActionId &actionId)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("mute", muted);
|
||||
|
||||
m_jsonHandler->sendData("Application.SetMute", params, actionId);
|
||||
}
|
||||
|
||||
bool Kodi::muted() const
|
||||
{
|
||||
return m_muted;
|
||||
}
|
||||
|
||||
void Kodi::setVolume(const int &volume, const ActionId &actionId)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("volume", volume);
|
||||
|
||||
m_jsonHandler->sendData("Application.SetVolume", params, actionId);
|
||||
}
|
||||
|
||||
int Kodi::volume() const
|
||||
{
|
||||
return m_volume;
|
||||
}
|
||||
|
||||
void Kodi::showNotification(const QString &message, const int &displayTime, const ActionId &actionId)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("title", "guh notification");
|
||||
params.insert("message", message);
|
||||
params.insert("displaytime", displayTime);
|
||||
m_jsonHandler->sendData("GUI.ShowNotification", params, actionId);
|
||||
}
|
||||
|
||||
void Kodi::pressButton(const QString &button, const ActionId &actionId)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("action", button);
|
||||
m_jsonHandler->sendData("Input.ExecuteAction", params, actionId);
|
||||
}
|
||||
|
||||
void Kodi::systemCommand(const QString &command, const ActionId &actionId)
|
||||
{
|
||||
QString method;
|
||||
if (command == "hibernate") {
|
||||
method = "Hibernate";
|
||||
} else if (command == "reboot") {
|
||||
method = "Reboot";
|
||||
} else if (command == "shutdown") {
|
||||
method = "Shutdown";
|
||||
} else if (command == "suspend") {
|
||||
method = "Suspend";
|
||||
} else {
|
||||
// already checkt with allowed values
|
||||
}
|
||||
|
||||
m_jsonHandler->sendData("System." + method, QVariantMap(), actionId);
|
||||
}
|
||||
|
||||
void Kodi::videoLibrary(const QString &command, const ActionId &actionId)
|
||||
{
|
||||
QString method;
|
||||
if (command == "scan") {
|
||||
method = "Scan";
|
||||
} else if (command == "clean") {
|
||||
method = "Clean";
|
||||
} else {
|
||||
// already checkt with allowed values
|
||||
}
|
||||
|
||||
m_jsonHandler->sendData("VideoLibrary." + method, QVariantMap(), actionId);
|
||||
}
|
||||
|
||||
void Kodi::audioLibrary(const QString &command, const ActionId &actionId)
|
||||
{
|
||||
QString method;
|
||||
if (command == "scan") {
|
||||
method = "Scan";
|
||||
} else if (command == "clean") {
|
||||
method = "Clean";
|
||||
} else {
|
||||
// already checkt with allowed values
|
||||
}
|
||||
|
||||
m_jsonHandler->sendData("AudioLibrary." + method, QVariantMap(), actionId);
|
||||
}
|
||||
|
||||
void Kodi::update()
|
||||
{
|
||||
QVariantMap params;
|
||||
QVariantList properties;
|
||||
properties.append("volume");
|
||||
properties.append("muted");
|
||||
properties.append("name");
|
||||
properties.append("version");
|
||||
params.insert("properties", properties);
|
||||
|
||||
m_jsonHandler->sendData("Application.GetProperties", params, ActionId());
|
||||
}
|
||||
|
||||
void Kodi::connectKodi()
|
||||
{
|
||||
m_connection->connectKodi();
|
||||
}
|
||||
|
||||
void Kodi::disconnectKodi()
|
||||
{
|
||||
m_connection->disconnectKodi();
|
||||
}
|
||||
|
||||
void Kodi::onVolumeChanged(const int &volume, const bool &muted)
|
||||
{
|
||||
if (m_volume != volume || m_muted != muted) {
|
||||
m_volume = volume;
|
||||
m_muted = muted;
|
||||
emit stateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void Kodi::onUpdateFinished(const QVariantMap &data)
|
||||
{
|
||||
if (data.contains("volume")) {
|
||||
m_volume = data.value("volume").toInt();
|
||||
}
|
||||
if (data.contains("muted")) {
|
||||
m_volume = data.value("muted").toBool();
|
||||
}
|
||||
emit stateChanged();
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* Guh 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef KODI_H
|
||||
#define KODI_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "kodiconnection.h"
|
||||
#include "jsonhandler.h"
|
||||
|
||||
class Kodi : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit Kodi(const QHostAddress &hostAddress, const int &port = 9090, QObject *parent = 0);
|
||||
|
||||
QHostAddress hostAddress() const;
|
||||
int port() const;
|
||||
|
||||
bool connected() const;
|
||||
|
||||
// propertys
|
||||
void setMuted(const bool &muted, const ActionId &actionId);
|
||||
bool muted() const;
|
||||
|
||||
void setVolume(const int &volume, const ActionId &actionId);
|
||||
int volume() const;
|
||||
|
||||
// actions
|
||||
void showNotification(const QString &message, const int &displayTime, const ActionId &actionId);
|
||||
void pressButton(const QString &button, const ActionId &actionId);
|
||||
void systemCommand(const QString &command, const ActionId &actionId);
|
||||
void videoLibrary(const QString &command, const ActionId &actionId);
|
||||
void audioLibrary(const QString &command, const ActionId &actionId);
|
||||
|
||||
void update();
|
||||
|
||||
void connectKodi();
|
||||
void disconnectKodi();
|
||||
|
||||
private:
|
||||
KodiConnection *m_connection;
|
||||
JsonHandler *m_jsonHandler;
|
||||
|
||||
bool m_muted;
|
||||
int m_volume;
|
||||
|
||||
signals:
|
||||
void connectionStatusChanged();
|
||||
void stateChanged();
|
||||
void actionExecuted(const ActionId &actionId, const bool &success);
|
||||
void onPlayerPlay();
|
||||
void onPlayerPause();
|
||||
void onPlayerStop();
|
||||
|
||||
private slots:
|
||||
void onVolumeChanged(const int &volume, const bool &muted);
|
||||
void onUpdateFinished(const QVariantMap &data);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // KODI_H
|
||||
|
|
@ -7,10 +7,14 @@ RESOURCES += images.qrc \
|
|||
SOURCES += \
|
||||
devicepluginkodi.cpp \
|
||||
kodiconnection.cpp \
|
||||
jsonhandler.cpp
|
||||
jsonhandler.cpp \
|
||||
kodi.cpp \
|
||||
kodireply.cpp
|
||||
|
||||
HEADERS += \
|
||||
devicepluginkodi.h \
|
||||
kodiconnection.h \
|
||||
jsonhandler.h
|
||||
jsonhandler.h \
|
||||
kodi.h \
|
||||
kodireply.h
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* Guh 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "kodiconnection.h"
|
||||
#include "loggingcategories.h"
|
||||
#include "jsonhandler.h"
|
||||
|
|
@ -18,7 +38,7 @@ KodiConnection::KodiConnection(const QHostAddress &hostAddress, const int &port,
|
|||
connect(m_socket, &QTcpSocket::readyRead, this, &KodiConnection::readData);
|
||||
}
|
||||
|
||||
void KodiConnection::connectToKodi()
|
||||
void KodiConnection::connectKodi()
|
||||
{
|
||||
if (m_socket->state() == QAbstractSocket::ConnectingState) {
|
||||
return;
|
||||
|
|
@ -26,7 +46,7 @@ void KodiConnection::connectToKodi()
|
|||
m_socket->connectToHost(m_hostAddress, m_port);
|
||||
}
|
||||
|
||||
void KodiConnection::disconnectFromKodi()
|
||||
void KodiConnection::disconnectKodi()
|
||||
{
|
||||
m_socket->close();
|
||||
}
|
||||
|
|
@ -50,51 +70,31 @@ void KodiConnection::onConnected()
|
|||
{
|
||||
qCDebug(dcKodi) << "connected successfully to" << hostAddress().toString() << port();
|
||||
m_connected = true;
|
||||
// QPixmap logo = QPixmap(":/images/guh-logo.png");
|
||||
// qCDebug(dcKodi) << "image size" << logo.size();
|
||||
emit connectionStateChanged(true);
|
||||
emit connectionStatusChanged();
|
||||
}
|
||||
|
||||
void KodiConnection::onDisconnected()
|
||||
{
|
||||
qCDebug(dcKodi) << "disconnected from" << hostAddress().toString() << port();
|
||||
m_connected = false;
|
||||
emit connectionStateChanged(false);
|
||||
emit connectionStatusChanged();
|
||||
}
|
||||
|
||||
void KodiConnection::onError(QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
qCWarning(dcKodi) << "socket error:" << socketError << m_socket->errorString();
|
||||
if (connected()) {
|
||||
qCWarning(dcKodi) << "socket error:" << socketError << m_socket->errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void KodiConnection::readData()
|
||||
{
|
||||
QByteArray data = m_socket->readAll();
|
||||
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
if(error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcKodi) << "failed to parse JSON data:" << data << ":" << error.errorString();
|
||||
return;
|
||||
}
|
||||
qCDebug(dcKodi) << "data received:" << jsonDoc.toJson();
|
||||
|
||||
emit dataReady(data);
|
||||
}
|
||||
|
||||
void KodiConnection::sendData(const QString &method, const QVariantMap ¶ms)
|
||||
void KodiConnection::sendData(const QByteArray &message)
|
||||
{
|
||||
QVariantMap package;
|
||||
package.insert("id", m_id);
|
||||
package.insert("method", method);
|
||||
package.insert("params", params);
|
||||
package.insert("jsonrpc", "2.0");
|
||||
m_id++;
|
||||
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(package);
|
||||
qCDebug(dcKodi) << "sending data" << jsonDoc.toJson();
|
||||
|
||||
m_socket->write(jsonDoc.toJson());
|
||||
m_socket->write(message);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* Guh 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef KODICONNECTION_H
|
||||
#define KODICONNECTION_H
|
||||
|
||||
|
|
@ -12,8 +32,8 @@ class KodiConnection : public QObject
|
|||
public:
|
||||
explicit KodiConnection(const QHostAddress &hostAddress, const int &port = 9090, QObject *parent = 0);
|
||||
|
||||
void connectToKodi();
|
||||
void disconnectFromKodi();
|
||||
void connectKodi();
|
||||
void disconnectKodi();
|
||||
|
||||
QHostAddress hostAddress() const;
|
||||
int port() const;
|
||||
|
|
@ -21,14 +41,13 @@ public:
|
|||
bool connected();
|
||||
|
||||
private:
|
||||
QTcpSocket *m_socket;
|
||||
|
||||
QHostAddress m_hostAddress;
|
||||
int m_port;
|
||||
int m_id;
|
||||
bool m_connected;
|
||||
|
||||
|
||||
QTcpSocket *m_socket;
|
||||
|
||||
private slots:
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
|
|
@ -36,11 +55,11 @@ private slots:
|
|||
void readData();
|
||||
|
||||
signals:
|
||||
void connectionStateChanged(const bool &connected);
|
||||
void connectionStatusChanged();
|
||||
void dataReady(const QByteArray &data);
|
||||
|
||||
public slots:
|
||||
void sendData(const QString &method, const QVariantMap ¶ms = QVariantMap());
|
||||
void sendData(const QByteArray &message);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* Guh 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "kodireply.h"
|
||||
|
||||
KodiReply::KodiReply()
|
||||
{
|
||||
}
|
||||
|
||||
KodiReply::KodiReply(const QString &method, const QVariantMap ¶ms, const ActionId &actionId) :
|
||||
m_method(method),
|
||||
m_params(params),
|
||||
m_actionId(actionId)
|
||||
{
|
||||
}
|
||||
|
||||
void KodiReply::setActionId(const ActionId &actionId)
|
||||
{
|
||||
m_actionId = actionId;
|
||||
}
|
||||
|
||||
ActionId KodiReply::actionId() const
|
||||
{
|
||||
return m_actionId;
|
||||
}
|
||||
|
||||
void KodiReply::setMethod(const QString &method)
|
||||
{
|
||||
m_method = method;
|
||||
}
|
||||
|
||||
QString KodiReply::method() const
|
||||
{
|
||||
return m_method;
|
||||
}
|
||||
|
||||
void KodiReply::setParams(const QVariantMap ¶ms)
|
||||
{
|
||||
m_params = params;
|
||||
}
|
||||
|
||||
QVariantMap KodiReply::params() const
|
||||
{
|
||||
return m_params;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* Guh 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef KODIREPLY_H
|
||||
#define KODIREPLY_H
|
||||
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
|
||||
#include "typeutils.h"
|
||||
|
||||
class KodiReply
|
||||
{
|
||||
public:
|
||||
KodiReply();
|
||||
KodiReply(const QString &method, const QVariantMap ¶ms, const ActionId &actionId = ActionId());
|
||||
|
||||
void setActionId(const ActionId &actionId);
|
||||
ActionId actionId() const;
|
||||
|
||||
void setMethod(const QString &method);
|
||||
QString method() const;
|
||||
|
||||
void setParams(const QVariantMap ¶ms);
|
||||
QVariantMap params() const;
|
||||
|
||||
private:
|
||||
QString m_method;
|
||||
QVariantMap m_params;
|
||||
ActionId m_actionId;
|
||||
|
||||
};
|
||||
|
||||
#endif // KODIREPLY_H
|
||||
Loading…
Reference in New Issue