mirror of https://github.com/nymea/nymea.git
add documentation and version check
parent
4589eb724b
commit
edb95e36fd
|
|
@ -72,7 +72,19 @@
|
|||
|
||||
DevicePluginKodi::DevicePluginKodi()
|
||||
{
|
||||
Q_INIT_RESOURCE(images);
|
||||
QFile file(":/images/guh-logo.png");
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qCWarning(dcKodi) << "could not open" << file.fileName();
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray guhLogoByteArray = file.readAll();
|
||||
if (guhLogoByteArray.isEmpty()) {
|
||||
qCWarning(dcKodi) << "could not read" << file.fileName();
|
||||
return;
|
||||
}
|
||||
m_logo = guhLogoByteArray;
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResources DevicePluginKodi::requiredHardware() const
|
||||
|
|
@ -82,11 +94,13 @@ DeviceManager::HardwareResources DevicePluginKodi::requiredHardware() const
|
|||
|
||||
DeviceManager::DeviceSetupStatus DevicePluginKodi::setupDevice(Device *device)
|
||||
{
|
||||
Kodi *kodi= new Kodi(QHostAddress(device->paramValue("ip").toString()), 9090, this);
|
||||
Kodi *kodi= new Kodi(m_logo, QHostAddress(device->paramValue("ip").toString()), 9090, this);
|
||||
|
||||
connect(kodi, &Kodi::connectionStatusChanged, this, &DevicePluginKodi::onConnectionChanged);
|
||||
connect(kodi, &Kodi::stateChanged, this, &DevicePluginKodi::onStateChanged);
|
||||
connect(kodi, &Kodi::actionExecuted, this, &DevicePluginKodi::onActionExecuted);
|
||||
connect(kodi, &Kodi::versionDataReceived, this, &DevicePluginKodi::versionDataReceived);
|
||||
connect(kodi, &Kodi::updateDataReceived, this, &DevicePluginKodi::onSetupFinished);
|
||||
connect(kodi, &Kodi::onPlayerPlay, this, &DevicePluginKodi::onPlayerPlay);
|
||||
connect(kodi, &Kodi::onPlayerPause, this, &DevicePluginKodi::onPlayerPause);
|
||||
connect(kodi, &Kodi::onPlayerStop, this, &DevicePluginKodi::onPlayerStop);
|
||||
|
|
@ -94,7 +108,8 @@ DeviceManager::DeviceSetupStatus DevicePluginKodi::setupDevice(Device *device)
|
|||
kodi->connectKodi();
|
||||
|
||||
m_kodis.insert(kodi, device);
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
m_asyncSetups.append(kodi);
|
||||
return DeviceManager::DeviceSetupStatusAsync;
|
||||
}
|
||||
|
||||
void DevicePluginKodi::deviceRemoved(Device *device)
|
||||
|
|
@ -169,7 +184,7 @@ DeviceManager::DeviceError DevicePluginKodi::executeAction(Device *device, const
|
|||
}
|
||||
|
||||
if (action.actionTypeId() == showNotificationActionTypeId) {
|
||||
kodi->showNotification(action.param("message").value().toString(), 8000, action.id());
|
||||
kodi->showNotification(action.param("message").value().toString(), 8000, action.param("type").value().toString(), action.id());
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
} else if (action.actionTypeId() == volumeActionTypeId) {
|
||||
kodi->setVolume(action.param("volume").value().toInt(), action.id());
|
||||
|
|
@ -201,8 +216,11 @@ void DevicePluginKodi::onConnectionChanged()
|
|||
Device *device = m_kodis.value(kodi);
|
||||
|
||||
if (kodi->connected()) {
|
||||
kodi->showNotification("Connected", 2000, ActionId());
|
||||
kodi->update();
|
||||
// if this is the first setup, check version
|
||||
if (m_asyncSetups.contains(kodi)) {
|
||||
m_asyncSetups.removeAll(kodi);
|
||||
kodi->checkVersion();
|
||||
}
|
||||
}
|
||||
|
||||
device->setStateValue(connectedStateTypeId, kodi->connected());
|
||||
|
|
@ -227,6 +245,37 @@ void DevicePluginKodi::onActionExecuted(const ActionId &actionId, const bool &su
|
|||
}
|
||||
}
|
||||
|
||||
void DevicePluginKodi::versionDataReceived(const QVariantMap &data)
|
||||
{
|
||||
Kodi *kodi = static_cast<Kodi *>(sender());
|
||||
Device *device = m_kodis.value(kodi);
|
||||
|
||||
QVariantMap version = data.value("version").toMap();
|
||||
QString apiVersion = QString("%1.%2.%3").arg(version.value("major").toString()).arg(version.value("minor").toString()).arg(version.value("patch").toString());
|
||||
qCDebug(dcKodi) << "API Version:" << apiVersion;
|
||||
|
||||
if (version.value("major").toInt() < 6) {
|
||||
qCWarning(dcKodi) << "incompatible api version:" << apiVersion;
|
||||
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
|
||||
return;
|
||||
}
|
||||
kodi->update();
|
||||
}
|
||||
|
||||
void DevicePluginKodi::onSetupFinished(const QVariantMap &data)
|
||||
{
|
||||
Kodi *kodi = static_cast<Kodi *>(sender());
|
||||
Device *device = m_kodis.value(kodi);
|
||||
|
||||
QVariantMap version = data.value("version").toMap();
|
||||
QString kodiVersion = QString("%1.%2 (%3)").arg(version.value("major").toString()).arg(version.value("minor").toString()).arg(version.value("tag").toString());
|
||||
qCDebug(dcKodi) << "Version:" << kodiVersion;
|
||||
|
||||
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess);
|
||||
|
||||
kodi->showNotification("Connected", 2000, "info", ActionId());
|
||||
}
|
||||
|
||||
void DevicePluginKodi::onPlayerPlay()
|
||||
{
|
||||
Kodi *kodi = static_cast<Kodi *>(sender());
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@
|
|||
#include <QHash>
|
||||
#include <QDebug>
|
||||
#include <QTcpSocket>
|
||||
#include <QPixmap>
|
||||
#include <QFile>
|
||||
#include <QImage>
|
||||
|
||||
class DevicePluginKodi : public DevicePlugin
|
||||
{
|
||||
|
|
@ -49,11 +52,16 @@ public:
|
|||
|
||||
private:
|
||||
QHash<Kodi *, Device *> m_kodis;
|
||||
QList<Kodi *> m_asyncSetups;
|
||||
QByteArray m_logo;
|
||||
|
||||
|
||||
private slots:
|
||||
void onConnectionChanged();
|
||||
void onStateChanged();
|
||||
void onActionExecuted(const ActionId &actionId, const bool &success);
|
||||
void versionDataReceived(const QVariantMap &data);
|
||||
void onSetupFinished(const QVariantMap &data);
|
||||
|
||||
void onPlayerPlay();
|
||||
void onPlayerPause();
|
||||
|
|
|
|||
|
|
@ -80,6 +80,16 @@
|
|||
"name": "message",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine"
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"type": "QString",
|
||||
"defaultValue": "info",
|
||||
"allowedValues": [
|
||||
"info",
|
||||
"warning",
|
||||
"error"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -112,7 +122,7 @@
|
|||
"playpause",
|
||||
"fastforward",
|
||||
"rewind",
|
||||
"togglefullscreen",
|
||||
"fullscreen",
|
||||
"mute",
|
||||
"volumeup",
|
||||
"volumedown",
|
||||
|
|
@ -134,6 +144,7 @@
|
|||
{
|
||||
"name": "command",
|
||||
"type": "QString",
|
||||
"defaultValue": "shutdown",
|
||||
"allowedValues": [
|
||||
"hibernate",
|
||||
"reboot",
|
||||
|
|
@ -151,6 +162,7 @@
|
|||
{
|
||||
"name": "command",
|
||||
"type": "QString",
|
||||
"defaultValue": "scan",
|
||||
"allowedValues": [
|
||||
"scan",
|
||||
"clean"
|
||||
|
|
@ -166,6 +178,7 @@
|
|||
{
|
||||
"name": "command",
|
||||
"type": "QString",
|
||||
"defaultValue": "scan",
|
||||
"allowedValues": [
|
||||
"scan",
|
||||
"clean"
|
||||
|
|
|
|||
|
|
@ -42,25 +42,23 @@ void JsonHandler::sendData(const QString &method, const QVariantMap ¶ms, con
|
|||
m_replys.insert(m_id, KodiReply(method, params, actionId));
|
||||
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(package);
|
||||
qCDebug(dcKodi) << "sending data" << jsonDoc.toJson();
|
||||
m_connection->sendData(jsonDoc.toJson());
|
||||
//qCDebug(dcKodi) << "sending data" << jsonDoc.toJson();
|
||||
m_id++;
|
||||
}
|
||||
|
||||
void JsonHandler::processNotification(const QString &method, const QVariantMap ¶ms)
|
||||
{
|
||||
qCDebug(dcKodi) << "got notification" << method;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +68,7 @@ void JsonHandler::processActionResponse(const KodiReply &reply, const QVariantMa
|
|||
{
|
||||
if (response.contains("error")) {
|
||||
qCDebug(dcKodi) << QJsonDocument::fromVariant(response).toJson();
|
||||
qCWarning(dcKodi) << "got action error response:" << response.value("error").toMap().value("message").toString();
|
||||
qCWarning(dcKodi) << "got error response for action" << reply.method() << ":" << response.value("error").toMap().value("message").toString();
|
||||
emit actionExecuted(reply.actionId(), false);
|
||||
} else {
|
||||
emit actionExecuted(reply.actionId(), true);
|
||||
|
|
@ -81,13 +79,18 @@ void JsonHandler::processRequestResponse(const KodiReply &reply, const QVariantM
|
|||
{
|
||||
if (response.contains("error")) {
|
||||
qCDebug(dcKodi) << QJsonDocument::fromVariant(response).toJson();
|
||||
qCWarning(dcKodi) << "got request error response:" << response.value("error").toMap().value("message").toString();
|
||||
qCWarning(dcKodi) << "got error response for request " << reply.method() << ":" << response.value("error").toMap().value("message").toString();
|
||||
}
|
||||
|
||||
if (reply.method() == "Application.GetProperties") {
|
||||
qCDebug(dcKodi) << "got update response" << response;
|
||||
qCDebug(dcKodi) << "got update response" << reply.method();
|
||||
emit updateDataReceived(response.value("result").toMap());
|
||||
}
|
||||
|
||||
if (reply.method() == "JSONRPC.Version") {
|
||||
qCDebug(dcKodi) << "got version response" << reply.method();
|
||||
emit versionDataReceived(response.value("result").toMap());
|
||||
}
|
||||
}
|
||||
|
||||
void JsonHandler::processResponse(const QByteArray &data)
|
||||
|
|
@ -99,7 +102,8 @@ void JsonHandler::processResponse(const QByteArray &data)
|
|||
qCWarning(dcKodi) << "failed to parse JSON data:" << data << ":" << error.errorString();
|
||||
return;
|
||||
}
|
||||
qCDebug(dcKodi) << "data received:" << jsonDoc.toJson();
|
||||
|
||||
//qCDebug(dcKodi) << "data received:" << jsonDoc.toJson();
|
||||
|
||||
QVariantMap message = jsonDoc.toVariant().toMap();
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ public:
|
|||
private:
|
||||
KodiConnection *m_connection;
|
||||
int m_id;
|
||||
|
||||
QHash<int, KodiReply> m_replys;
|
||||
|
||||
void processNotification(const QString &method, const QVariantMap ¶ms);
|
||||
|
|
@ -51,6 +50,7 @@ signals:
|
|||
void volumeChanged(const int &volume, const bool &muted);
|
||||
void actionExecuted(const ActionId &actionId, const bool &success);
|
||||
void updateDataReceived(const QVariantMap &data);
|
||||
void versionDataReceived(const QVariantMap &data);
|
||||
|
||||
void onPlayerPlay();
|
||||
void onPlayerPause();
|
||||
|
|
|
|||
|
|
@ -20,8 +20,11 @@
|
|||
|
||||
#include "kodi.h"
|
||||
|
||||
Kodi::Kodi(const QHostAddress &hostAddress, const int &port, QObject *parent) :
|
||||
QObject(parent)
|
||||
Kodi::Kodi(const QByteArray &logo, const QHostAddress &hostAddress, const int &port, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_logo(logo),
|
||||
m_muted(false),
|
||||
m_volume(-1)
|
||||
{
|
||||
m_connection = new KodiConnection(hostAddress, port, this);
|
||||
connect (m_connection, &KodiConnection::connectionStatusChanged, this, &Kodi::connectionStatusChanged);
|
||||
|
|
@ -29,6 +32,8 @@ Kodi::Kodi(const QHostAddress &hostAddress, const int &port, QObject *parent) :
|
|||
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::versionDataReceived, this, &Kodi::versionDataReceived);
|
||||
connect(m_jsonHandler, &JsonHandler::updateDataReceived, this, &Kodi::updateDataReceived);
|
||||
connect(m_jsonHandler, &JsonHandler::updateDataReceived, this, &Kodi::onUpdateFinished);
|
||||
connect(m_jsonHandler, &JsonHandler::onPlayerPlay, this, &Kodi::onPlayerPlay);
|
||||
connect(m_jsonHandler, &JsonHandler::onPlayerPause, this, &Kodi::onPlayerPause);
|
||||
|
|
@ -76,12 +81,14 @@ int Kodi::volume() const
|
|||
return m_volume;
|
||||
}
|
||||
|
||||
void Kodi::showNotification(const QString &message, const int &displayTime, const ActionId &actionId)
|
||||
void Kodi::showNotification(const QString &message, const int &displayTime, const QString ¬ificationType, const ActionId &actionId)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("title", "guh notification");
|
||||
params.insert("message", message);
|
||||
params.insert("displaytime", displayTime);
|
||||
params.insert("image", notificationType);
|
||||
|
||||
m_jsonHandler->sendData("GUI.ShowNotification", params, actionId);
|
||||
}
|
||||
|
||||
|
|
@ -151,6 +158,11 @@ void Kodi::update()
|
|||
m_jsonHandler->sendData("Application.GetProperties", params, ActionId());
|
||||
}
|
||||
|
||||
void Kodi::checkVersion()
|
||||
{
|
||||
m_jsonHandler->sendData("JSONRPC.Version", QVariantMap(), ActionId());
|
||||
}
|
||||
|
||||
void Kodi::connectKodi()
|
||||
{
|
||||
m_connection->connectKodi();
|
||||
|
|
@ -176,7 +188,7 @@ void Kodi::onUpdateFinished(const QVariantMap &data)
|
|||
m_volume = data.value("volume").toInt();
|
||||
}
|
||||
if (data.contains("muted")) {
|
||||
m_volume = data.value("muted").toBool();
|
||||
m_muted = data.value("muted").toBool();
|
||||
}
|
||||
emit stateChanged();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
|
||||
#include "kodiconnection.h"
|
||||
#include "jsonhandler.h"
|
||||
|
|
@ -32,7 +34,7 @@ class Kodi : public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit Kodi(const QHostAddress &hostAddress, const int &port = 9090, QObject *parent = 0);
|
||||
explicit Kodi(const QByteArray &logo, const QHostAddress &hostAddress, const int &port = 9090, QObject *parent = 0);
|
||||
|
||||
QHostAddress hostAddress() const;
|
||||
int port() const;
|
||||
|
|
@ -47,13 +49,14 @@ public:
|
|||
int volume() const;
|
||||
|
||||
// actions
|
||||
void showNotification(const QString &message, const int &displayTime, const ActionId &actionId);
|
||||
void showNotification(const QString &message, const int &displayTime, const QString ¬ificationType, 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 checkVersion();
|
||||
|
||||
void connectKodi();
|
||||
void disconnectKodi();
|
||||
|
|
@ -61,7 +64,7 @@ public:
|
|||
private:
|
||||
KodiConnection *m_connection;
|
||||
JsonHandler *m_jsonHandler;
|
||||
|
||||
QByteArray m_logo;
|
||||
bool m_muted;
|
||||
int m_volume;
|
||||
|
||||
|
|
@ -69,6 +72,9 @@ signals:
|
|||
void connectionStatusChanged();
|
||||
void stateChanged();
|
||||
void actionExecuted(const ActionId &actionId, const bool &success);
|
||||
void updateDataReceived(const QVariantMap &data);
|
||||
void versionDataReceived(const QVariantMap &data);
|
||||
|
||||
void onPlayerPlay();
|
||||
void onPlayerPause();
|
||||
void onPlayerStop();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ include(../../plugins.pri)
|
|||
|
||||
TARGET = $$qtLibraryTarget(guh_devicepluginkodi)
|
||||
|
||||
RESOURCES += images.qrc \
|
||||
RESOURCES += images.qrc
|
||||
|
||||
SOURCES += \
|
||||
devicepluginkodi.cpp \
|
||||
|
|
|
|||
Loading…
Reference in New Issue