Implemented cmdline interface
This commit is contained in:
18
autocomplete.sh
Normal file
18
autocomplete.sh
Normal file
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
function _r3ctl_autocomplete()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
|
||||
if [[ "$COMP_CWORD" -eq 1 ]]
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "log script sendYmhButton" "$cur") )
|
||||
elif [[ "$COMP_CWORD" -eq 2 ]]
|
||||
then
|
||||
if [[ "${COMP_WORDS[1]}" = "sendYmhButton" ]]
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "ymhpower ymhcd ymhtuner ymhtape ymhwdtv ymhsattv ymhvcr ymh7 ymhaux ymhextdec ymhtest ymhtunabcde ymheffect ymhtvlolup ymhtvvoldown ymhvoldown ymhvolup ymhmute ymhsleep ymhp5 ymhtunminus ymhtunplus ymhprgup ymhprgdown ymhminus ymhplus ymhtimelevel ymhmenu" "$cur") )
|
||||
fi
|
||||
fi
|
||||
}
|
||||
complete -F _r3ctl_autocomplete r3ctl
|
125
main.cpp
125
main.cpp
@ -1,53 +1,102 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QWebSocket>
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonDocument>
|
||||
#include <QTimer>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "r3client.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
|
||||
QWebSocket webSocket;
|
||||
QObject::connect(&webSocket, &QWebSocket::connected, [&](){ qDebug() << "connected()"; });
|
||||
QObject::connect(&webSocket, &QWebSocket::disconnected, [&](){ qDebug() << "disconnected()"; });
|
||||
// QObject::connect(&webSocket, &QWebSocket::textFrameReceived, [&](const QString &frame, bool isLastFrame){
|
||||
// qDebug() << "textFrameReceived()";
|
||||
// });
|
||||
// QObject::connect(&webSocket, &QWebSocket::binaryFrameReceived, [&](const QByteArray &frame, bool isLastFrame){
|
||||
// qDebug() << "binaryFrameReceived()";
|
||||
// });
|
||||
QObject::connect(&webSocket, &QWebSocket::textMessageReceived, [&](const QString &message){
|
||||
qDebug() << "textMessageReceived()" << message;
|
||||
});
|
||||
QObject::connect(&webSocket, &QWebSocket::binaryMessageReceived, [&](const QByteArray &message){
|
||||
qDebug() << "binaryMessageReceived()" << message;
|
||||
});
|
||||
QObject::connect(&webSocket, qOverload<QAbstractSocket::SocketError>(&QWebSocket::error), [&](QAbstractSocket::SocketError error){
|
||||
qDebug() << "error()" << error;
|
||||
});
|
||||
webSocket.open(QUrl{"ws://licht.realraum.at/sock"});
|
||||
const auto arguments = [&](){
|
||||
auto arguments = a.arguments();
|
||||
arguments.removeFirst();
|
||||
return arguments;
|
||||
}();
|
||||
|
||||
const auto sendMQTT = [&](const QString &ctx, const QJsonValue &data){
|
||||
const QJsonObject m{{"ctx", ctx}, {"data", data}};
|
||||
const auto text = QJsonDocument{m}.toJson();
|
||||
qDebug() << "sendTextMessage()" << text;
|
||||
webSocket.sendTextMessage(text);
|
||||
};
|
||||
if (arguments.isEmpty())
|
||||
{
|
||||
puts("No cmd given!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const auto mqtttopic_golightctrl = [](const QString &lightname){
|
||||
return QString{"action/GoLightCtrl/%0"}.arg(lightname);
|
||||
};
|
||||
R3Client client;
|
||||
|
||||
const auto sendYmhButton = [&](const QString &btn){
|
||||
sendMQTT(mqtttopic_golightctrl(btn), QJsonObject{{"Action", "send"}});
|
||||
};
|
||||
QObject::connect(&client, &R3Client::disconnected, [](){ qDebug() << "disconnected()"; });
|
||||
QObject::connect(&client, &R3Client::error, [](QAbstractSocket::SocketError error){ qDebug() << "error()" << error; });
|
||||
|
||||
QTimer::singleShot(1000, [&](){
|
||||
sendYmhButton("ymhvolup");
|
||||
});
|
||||
if (arguments.first() == "log")
|
||||
{
|
||||
QObject::connect(&client, &R3Client::connected, [](){ qDebug() << "connected()"; });
|
||||
QObject::connect(&client, &R3Client::statusReceived, [](const QString &ctx, const QJsonValue &jsonValue){ qDebug() << "statusReceived()" << ctx << jsonValue; });
|
||||
}
|
||||
else if (arguments.first() == "script")
|
||||
{
|
||||
QObject::connect(&client, &R3Client::connected, [&](){
|
||||
client.sendMQTT("action/ceilingscripts/activatescript", QJsonObject{
|
||||
{"colourlist", QJsonArray{
|
||||
QJsonObject{{"b", 0}, {"cw", 0}, {"g", 0}, {"r", 1000}, {"ww", 0}},
|
||||
QJsonObject{{"b", 100}, {"cw", 0}, {"g", 0}, {"r", 800}, {"ww", 0}},
|
||||
QJsonObject{{"b", 300}, {"cw", 0}, {"g", 0}, {"r", 0}, {"ww", 0}},
|
||||
QJsonObject{{"b", 100}, {"cw", 0}, {"g", 500}, {"r", 0}, {"ww", 0}},
|
||||
QJsonObject{{"b", 0}, {"cw", 0}, {"g", 800}, {"r", 0}, {"ww", 0}},
|
||||
QJsonObject{{"b", 0}, {"cw", 0}, {"g", 200}, {"r", 800}, {"ww", 0}}
|
||||
}},
|
||||
{"fadeduration", 500},
|
||||
{"script", "wave"}
|
||||
});
|
||||
});
|
||||
}
|
||||
else if (arguments.first() == "sendYmhButton")
|
||||
{
|
||||
if (arguments.size() < 2)
|
||||
{
|
||||
puts("No button given for sendYmhButton");
|
||||
return -3;
|
||||
}
|
||||
|
||||
const auto btn = arguments.at(1);
|
||||
|
||||
QObject::connect(&client, &R3Client::connected, [&client,btn](){
|
||||
client.sendYmhButton(btn);
|
||||
});
|
||||
QObject::connect(&client, &R3Client::statusReceived, [btn](const QString &ctx, const QJsonValue &jsonValue){
|
||||
if (ctx != "action/yamahastereo/ircmd")
|
||||
return;
|
||||
if (!jsonValue.isObject())
|
||||
{
|
||||
qWarning() << "json data is not an object";
|
||||
qWarning() << jsonValue;
|
||||
return;
|
||||
}
|
||||
const auto object = jsonValue.toObject();
|
||||
if (!object.contains("Cmd"))
|
||||
{
|
||||
qWarning() << "json data does not contain Cmd";
|
||||
qWarning() << object;
|
||||
return;
|
||||
}
|
||||
const auto cmdValue = object.value("Cmd");
|
||||
if (!cmdValue.isString())
|
||||
{
|
||||
qWarning() << "json data Cmd is not a string";
|
||||
qWarning() << object;
|
||||
return;
|
||||
}
|
||||
const auto cmd = cmdValue.toString();
|
||||
if (cmd == btn)
|
||||
QCoreApplication::quit();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
puts("Invalid cmd. Valid are log, script, sendYmhButton");
|
||||
return -2;
|
||||
}
|
||||
|
||||
client.open();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
|
101
r3client.cpp
Normal file
101
r3client.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
#include "r3client.h"
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
R3Client::R3Client(QObject *parent) :
|
||||
QObject{parent}
|
||||
{
|
||||
connect(&m_webSocket, &QWebSocket::connected, this, &R3Client::connected);
|
||||
connect(&m_webSocket, &QWebSocket::disconnected, this, &R3Client::disconnected);
|
||||
connect(&m_webSocket, qOverload<QAbstractSocket::SocketError>(&QWebSocket::error), this, &R3Client::error);
|
||||
connect(&m_webSocket, &QWebSocket::textMessageReceived, this, &R3Client::textMessageReceived);
|
||||
connect(&m_webSocket, &QWebSocket::binaryMessageReceived, this, &R3Client::binaryMessageReceived);
|
||||
}
|
||||
|
||||
void R3Client::open()
|
||||
{
|
||||
m_webSocket.open(QUrl{"ws://licht.realraum.at/sock"});
|
||||
}
|
||||
|
||||
void R3Client::close(QWebSocketProtocol::CloseCode closeCode, const QString &reason)
|
||||
{
|
||||
m_webSocket.close(closeCode, reason);
|
||||
}
|
||||
|
||||
void R3Client::sendMQTT(const QString &ctx, const QJsonValue &data)
|
||||
{
|
||||
const QJsonObject m{{"ctx", ctx}, {"data", data}};
|
||||
//qDebug() << m;
|
||||
const auto text = QJsonDocument{m}.toJson(QJsonDocument::Compact);
|
||||
//qDebug() << "sendTextMessage()" << text;
|
||||
m_webSocket.sendTextMessage(text);
|
||||
}
|
||||
|
||||
void R3Client::sendYmhButton(const QString &btn)
|
||||
{
|
||||
sendMQTT(mqtttopic_golightctrl(btn), QJsonObject{{"Action", "send"}});
|
||||
}
|
||||
|
||||
QString R3Client::mqtttopic_golightctrl(const QString &lightname)
|
||||
{
|
||||
return QString{"action/GoLightCtrl/%0"}.arg(lightname);
|
||||
}
|
||||
|
||||
void R3Client::textMessageReceived(const QString &message)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument document = QJsonDocument::fromJson(message.toUtf8(), &error);
|
||||
if (error.error != QJsonParseError::NoError)
|
||||
{
|
||||
qWarning() << "could not parse JSON" << error.errorString();
|
||||
qDebug() << "textMessageReceived()" << message;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!document.isObject())
|
||||
{
|
||||
qWarning() << "json is not an object";
|
||||
qDebug() << "textMessageReceived()" << message;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto obj = document.object();
|
||||
|
||||
if (!obj.contains("ctx"))
|
||||
{
|
||||
qWarning() << "json does not contain ctx";
|
||||
qDebug() << "textMessageReceived()" << message;
|
||||
return;
|
||||
}
|
||||
|
||||
QString ctx;
|
||||
|
||||
{
|
||||
const auto ctxValue = obj.value("ctx");
|
||||
if (!ctxValue.isString())
|
||||
{
|
||||
qWarning() << "ctx is not a string!";
|
||||
qDebug() << "textMessageReceived()" << message;
|
||||
return;
|
||||
}
|
||||
|
||||
ctx = ctxValue.toString();
|
||||
}
|
||||
|
||||
if (!obj.contains("data"))
|
||||
{
|
||||
qWarning() << "json does not contain data";
|
||||
qDebug() << "textMessageReceived()" << message;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto data = obj.value("data");
|
||||
|
||||
emit statusReceived(ctx, data);
|
||||
}
|
||||
|
||||
void R3Client::binaryMessageReceived(const QByteArray &message)
|
||||
{
|
||||
qWarning() << "binaryMessageReceived()" << message;
|
||||
}
|
32
r3client.h
Normal file
32
r3client.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QWebSocket>
|
||||
|
||||
class R3Client : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
R3Client(QObject *parent = nullptr);
|
||||
|
||||
void open();
|
||||
void close(QWebSocketProtocol::CloseCode closeCode = QWebSocketProtocol::CloseCodeNormal, const QString &reason = QString{});
|
||||
|
||||
void sendMQTT(const QString &ctx, const QJsonValue &data);
|
||||
void sendYmhButton(const QString &btn);
|
||||
static QString mqtttopic_golightctrl(const QString &lightname);
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void error(QAbstractSocket::SocketError error);
|
||||
void statusReceived(const QString &ctx, const QJsonValue &jsonValue);
|
||||
|
||||
private slots:
|
||||
void textMessageReceived(const QString &message);
|
||||
void binaryMessageReceived(const QByteArray &message);
|
||||
|
||||
private:
|
||||
QWebSocket m_webSocket;
|
||||
};
|
Reference in New Issue
Block a user