added kodi connection and jsonhandler

This commit is contained in:
Simon Stürz 2015-06-22 10:35:39 +02:00 committed by Michael Zanetti
parent ceaad7c7fd
commit 1f35f78238
12 changed files with 278 additions and 26 deletions

View File

@ -17,3 +17,5 @@ usr/lib/guh/plugins/libguh_devicepluginunitec.so
usr/lib/guh/plugins/libguh_devicepluginleynew.so
usr/lib/guh/plugins/libguh_deviceplugintune.so
usr/lib/guh/plugins/libguh_devicepluginudpcommander.so
usr/lib/guh/plugins/libguh_devicepluginkodi.so

View File

@ -48,3 +48,4 @@ Q_LOGGING_CATEGORY(dcUdpCommander, "UdpCommander")
Q_LOGGING_CATEGORY(dcWakeOnLan, "WakeOnLan")
Q_LOGGING_CATEGORY(dcWemo, "Wemo")
Q_LOGGING_CATEGORY(dcWifiDetector, "WifiDetector")
Q_LOGGING_CATEGORY(dcKodi, "Kodi")

View File

@ -53,6 +53,7 @@ Q_DECLARE_LOGGING_CATEGORY(dcUdpCommander)
Q_DECLARE_LOGGING_CATEGORY(dcWakeOnLan)
Q_DECLARE_LOGGING_CATEGORY(dcWemo)
Q_DECLARE_LOGGING_CATEGORY(dcWifiDetector)
Q_DECLARE_LOGGING_CATEGORY(dcKodi)

View File

@ -25,6 +25,8 @@
\ingroup plugins
\ingroup network
TODO: description
\chapter Plugin properties
Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses}
@ -45,6 +47,7 @@
#include "devicepluginkodi.h"
#include "plugin/device.h"
#include "plugininfo.h"
#include "loggingcategories.h"
DevicePluginKodi::DevicePluginKodi()
{
@ -53,52 +56,85 @@ DevicePluginKodi::DevicePluginKodi()
DeviceManager::HardwareResources DevicePluginKodi::requiredHardware() const
{
return DeviceManager::HardwareResourceNone;
return DeviceManager::HardwareResourceTimer | DeviceManager::HardwareResourceUpnpDisovery;
}
DeviceManager::DeviceSetupStatus DevicePluginKodi::setupDevice(Device *device)
{
Q_UNUSED(device)
KodiConnection *kodiConnection = new KodiConnection(QHostAddress(device->paramValue("ip").toString()), 9090, this);
connect(kodiConnection, &KodiConnection::connectionStateChanged, this, &DevicePluginKodi::onConnectionChanged);
kodiConnection->connectToKodi();
m_kodiConnections.insert(kodiConnection, device);
return DeviceManager::DeviceSetupStatusSuccess;
}
void DevicePluginKodi::deviceRemoved(Device *device)
{
Q_UNUSED(device)
KodiConnection *kodiConnection = m_kodiConnections.key(device);
m_kodiConnections.remove(kodiConnection);
qCDebug(dcKodi) << "delete Kodi" << device->paramValue("name");
kodiConnection->deleteLater();
}
DeviceManager::DeviceSetupStatus DevicePluginKodi::confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(pairingTransactionId)
Q_UNUSED(deviceClassId)
Q_UNUSED(params)
return DeviceManager::DeviceSetupStatusSuccess;
}
DeviceManager::DeviceError DevicePluginKodi::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(params)
Q_UNUSED(deviceClassId)
qCDebug(dcKodi) << "start Kodi UPnP search";
upnpDiscover();
return DeviceManager::DeviceErrorNoError;
return DeviceManager::DeviceErrorAsync;
}
void DevicePluginKodi::upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList)
{
Q_UNUSED(upnpDeviceDescriptorList)
QList<DeviceDescriptor> deviceDescriptors;
foreach (const UpnpDeviceDescriptor &upnpDescriptor, upnpDeviceDescriptorList) {
if (upnpDescriptor.modelName().contains("Kodi")) {
qCDebug(dcKodi) << upnpDescriptor;
DeviceDescriptor deviceDescriptor(kodiDeviceClassId, "Kodi - Media Center", upnpDescriptor.hostAddress().toString());
ParamList params;
params.append(Param("name", upnpDescriptor.friendlyName()));
params.append(Param("ip", upnpDescriptor.hostAddress().toString()));
params.append(Param("port", 9090));
deviceDescriptor.setParams(params);
deviceDescriptors.append(deviceDescriptor);
}
}
emit devicesDiscovered(kodiDeviceClassId, deviceDescriptors);
}
void DevicePluginKodi::networkManagerReplyReady(QNetworkReply *reply)
DeviceManager::DeviceError DevicePluginKodi::executeAction(Device *device, const Action &action)
{
Q_UNUSED(reply)
if (device->deviceClassId() == kodiDeviceClassId) {
if (action.actionTypeId() == sendNotificationActionTypeId) {
return DeviceManager::DeviceErrorNoError;
} else if (action.actionTypeId() == volumeActionTypeId) {
return DeviceManager::DeviceErrorNoError;
}
return DeviceManager::DeviceErrorActionTypeNotFound;
}
return DeviceManager::DeviceErrorDeviceClassNotFound;
}
void DevicePluginKodi::guhTimer()
void DevicePluginKodi::onConnectionChanged(const bool &connected)
{
KodiConnection *kodiConnection = static_cast<KodiConnection *>(sender());
Device *device = m_kodiConnections.value(kodiConnection);
device->setStateValue(connectedStateTypeId, connected);
}
void DevicePluginKodi::dataReceived(const QByteArray &data)
{
KodiConnection *kodiConnection = static_cast<KodiConnection *>(sender());
emit dataReady(kodiConnection, data);
}

View File

@ -22,9 +22,11 @@
#define DEVICEPLUGINKODI_H
#include "plugin/deviceplugin.h"
#include "kodiconnection.h"
#include <QHash>
#include <QDebug>
#include <QTcpSocket>
class DevicePluginKodi : public DevicePlugin
{
@ -39,16 +41,20 @@ public:
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
DeviceManager::DeviceSetupStatus confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
void upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
void guhTimer() override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private:
QHash<KodiConnection *, Device *> m_kodiConnections;
signals:
void dataReady(KodiConnection *kodiConnection, const QByteArray &data);
private slots:
void onConnectionChanged(const bool &connected);
void dataReceived(const QByteArray &data);
};

View File

@ -8,13 +8,60 @@
"deviceClasses": [
{
"deviceClassId": "d09953e3-c5bd-415b-973b-0d0bf2be3f69",
"idName": "kodi",
"name": "Kodi",
"createMethods": ["discovery"],
"createMethods": ["user", "discovery"],
"paramTypes": [
{
"name": "name",
"type": "QString",
"inputType": "TextLine"
},
{
"name": "ip",
"type" : "QString",
"inputType": "IPv4Address"
},
{
"name": "port",
"type" : "int"
}
],
"stateTypes": [
{
"id": "09dfbd40-c97c-4a20-9ecd-f80e389a4864",
"idName": "connected",
"name": "connected",
"type": "bool"
},
{
"id": "bc98cdb0-4d0e-48ca-afc7-922e49bb7813",
"idName": "mute",
"name": "mute",
"type": "bool"
},
{
"id": "9dfe5d78-4c3f-497c-bab1-bb9fdf7e93a9",
"idName": "volume",
"name": "volume",
"unit": "Percentage",
"type": "int",
"writable": true,
"minValue": 0,
"maxValue": 100
}
],
"actionTypes": [
{
"id": "dc0aa3b5-4eae-4e58-a4ac-d4c124da53f1",
"idName": "sendNotification",
"name": "send notification",
"paramTypes": [
{
"name": "message",
"type": "QString"
}
]
}
]
}

View File

@ -0,0 +1,6 @@
#include "jsonhandler.h"
JsonHandler::JsonHandler(QObject *parent) :
QObject(parent)
{
}

View File

@ -0,0 +1,18 @@
#ifndef JSONHANDLER_H
#define JSONHANDLER_H
#include <QObject>
class JsonHandler : public QObject
{
Q_OBJECT
public:
explicit JsonHandler(QObject *parent = 0);
signals:
public slots:
};
#endif // JSONHANDLER_H

View File

@ -3,8 +3,12 @@ include(../../plugins.pri)
TARGET = $$qtLibraryTarget(guh_devicepluginkodi)
SOURCES += \
devicepluginkodi.cpp
devicepluginkodi.cpp \
kodiconnection.cpp \
jsonhandler.cpp
HEADERS += \
devicepluginkodi.h
devicepluginkodi.h \
kodiconnection.h \
jsonhandler.h

View File

@ -0,0 +1,85 @@
#include "kodiconnection.h"
#include "loggingcategories.h"
KodiConnection::KodiConnection(const QHostAddress &hostAddress, const int &port, QObject *parent) :
QObject(parent),
m_hostAddress(hostAddress),
m_port(port)
{
m_socket = new QTcpSocket(this);
connect(m_socket, &QTcpSocket::connected, this, &KodiConnection::onConnected);
connect(m_socket, &QTcpSocket::disconnected, this, &KodiConnection::onDisconnected);
connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)));
connect(m_socket, &QTcpSocket::readyRead, this, &KodiConnection::readData);
}
void KodiConnection::connectToKodi()
{
m_socket->connectToHost(m_hostAddress, m_port);
}
void KodiConnection::disconnectFromKodi()
{
m_socket->close();
}
QHostAddress KodiConnection::hostAddress() const
{
return m_hostAddress;
}
int KodiConnection::port() const
{
return m_port;
}
void KodiConnection::onConnected()
{
qCDebug(dcKodi) << "connected successfully to" << hostAddress().toString() << port();
emit connectionStateChanged(true);
}
void KodiConnection::onDisconnected()
{
qCDebug(dcKodi) << "disconnected from" << hostAddress().toString() << port();
emit connectionStateChanged(false);
}
void KodiConnection::onError(QAbstractSocket::SocketError socketError)
{
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();
unsigned short m_IconSize;
emit dataReady(data);
}
void KodiConnection::sendData(const QString &method, const QVariantMap &params)
{
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());
}

View File

@ -0,0 +1,45 @@
#ifndef KODICONNECTION_H
#define KODICONNECTION_H
#include <QObject>
#include <QTcpSocket>
#include <QHostAddress>
#include <QJsonDocument>
class KodiConnection : public QObject
{
Q_OBJECT
public:
explicit KodiConnection(const QHostAddress &hostAddress, const int &port = 9090, QObject *parent = 0);
void connectToKodi();
void disconnectFromKodi();
QHostAddress hostAddress() const;
int port() const;
private:
QHostAddress m_hostAddress;
int m_port;
int m_id;
QTcpSocket *m_socket;
private slots:
void onConnected();
void onDisconnected();
void onError(QAbstractSocket::SocketError socketError);
void readData();
signals:
void connectionStateChanged(const bool &connected);
void dataReady(const QByteArray &data);
public slots:
void sendData(const QString &method, const QVariantMap &params = QVariantMap());
};
#endif // KODICONNECTION_H

View File

@ -81,6 +81,7 @@ int main(int argc, char *argv[])
s_loggingFilters.insert("WakeOnLan", false);
s_loggingFilters.insert("Wemo", false);
s_loggingFilters.insert("WifiDetector", false);
s_loggingFilters.insert("Kodi", true);
QCommandLineParser parser;