Implemented cmdline interface

This commit is contained in:
2020-05-03 03:31:09 +02:00
parent 874f3797a9
commit 3dc8321055
5 changed files with 243 additions and 39 deletions

18
autocomplete.sh Normal file
View 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
View File

@ -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
View 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
View 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;
};

View File

@ -5,4 +5,8 @@ CONFIG += c++14
DEFINES += QT_DEPRECATED_WARNINGS QT_DISABLE_DEPRECATED_BEFORE=0x060000
SOURCES += \
main.cpp
main.cpp \
r3client.cpp
HEADERS += \
r3client.h