minor fixes

This commit is contained in:
Michael Zanetti 2022-05-08 14:45:16 +02:00
parent 767baba7e4
commit 8eeeeb12f6
4 changed files with 109 additions and 38 deletions

View File

@ -44,6 +44,7 @@
#include <QColor>
#include <QTimer>
#include <QDataStream>
#include <QJsonDocument>
IntegrationPluginOwlet::IntegrationPluginOwlet()
{
@ -852,7 +853,55 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info)
params.insert("ledCount", thing->paramValue(ws2812ThingLedCountParamTypeId).toUInt());
params.insert("ledMode", "WS2812Mode" + thing->paramValue(ws2812ThingLedModeParamTypeId).toString());
params.insert("ledClock", "WS2812Clock" + thing->paramValue(ws2812ThingLedClockParamTypeId).toString());
client->sendCommand("GPIO.ConfigurePin", params);
int id = client->sendCommand("GPIO.ConfigurePin", params);
connect(client, &OwletClient::replyReceived, thing, [id, client, thing](int commandId, const QVariantMap &/*params*/){
if (id != commandId)
return;
qCDebug(dcOwlet()) << "Configuration sent...";
QVariantMap params;
params.insert("id", thing->paramValue(ws2812ThingPinParamTypeId).toUInt());
params.insert("power", thing->stateValue(ws2812PowerStateTypeId).toBool());
params.insert("brightness", thing->stateValue(ws2812BrightnessStateTypeId).toInt());
QColor color = thing->stateValue(ws2812ColorStateTypeId).value<QColor>();
params.insert("color", (color.rgb() & 0xFFFFFF));
int effect = thing->stateValue(ws2812EffectStateTypeId).toInt();
params.insert("effect", effect);
qCDebug(dcOwlet()) << "Initializing" << QJsonDocument::fromVariant(params).toJson();
client->sendCommand("GPIO.ControlPin", params);
connect(client, &OwletClient::notificationReceived, thing, [=](const QString &name, const QVariantMap &params){
qCDebug(dcOwlet()) << "***Notif" << name << params;
if (thing->thingClassId() == digitalInputThingClassId) {
if (params.value("id").toInt() == thing->paramValue(digitalInputThingPinParamTypeId)) {
thing->setStateValue(digitalInputPowerStateTypeId, params.value("power").toBool());
}
}
if (thing->thingClassId() == digitalOutputThingClassId) {
if (params.value("id").toInt() == thing->paramValue(digitalOutputThingPinParamTypeId)) {
thing->setStateValue(digitalOutputPowerStateTypeId, params.value("power").toBool());
}
}
if (thing->thingClassId() == ws2812ThingClassId) {
if (name == "GPIO.PinChanged") {
if (params.contains("power")) {
thing->setStateValue(ws2812PowerStateTypeId, params.value("power").toBool());
}
if (params.contains("brightness")) {
thing->setStateValue(ws2812BrightnessStateTypeId, params.value("brightness").toInt());
}
if (params.contains("color")) {
thing->setStateValue(ws2812ColorStateTypeId, params.value("color").value<QColor>());
}
if (params.contains("effect")) {
thing->setStateValue(ws2812EffectStateTypeId, params.value("effect").toInt());
}
}
}
});
});
}
@ -870,36 +919,6 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info)
thing->setStateValue("connected", false);
});
connect(client, &OwletClient::notificationReceived, this, [=](const QString &name, const QVariantMap &params){
qCDebug(dcOwlet()) << "***Notif" << name << params;
if (thing->thingClassId() == digitalInputThingClassId) {
if (params.value("id").toInt() == thing->paramValue(digitalInputThingPinParamTypeId)) {
thing->setStateValue(digitalInputPowerStateTypeId, params.value("power").toBool());
}
}
if (thing->thingClassId() == digitalOutputThingClassId) {
if (params.value("id").toInt() == thing->paramValue(digitalOutputThingPinParamTypeId)) {
thing->setStateValue(digitalOutputPowerStateTypeId, params.value("power").toBool());
}
}
if (thing->thingClassId() == ws2812ThingClassId) {
if (name == "GPIO.PinChanged") {
if (params.contains("power")) {
thing->setStateValue(ws2812PowerStateTypeId, params.value("power").toBool());
}
if (params.contains("brightness")) {
thing->setStateValue(ws2812BrightnessStateTypeId, params.value("brightness").toInt());
}
if (params.contains("color")) {
thing->setStateValue(ws2812ColorStateTypeId, params.value("color").value<QColor>());
}
if (params.contains("effect")) {
thing->setStateValue(ws2812EffectStateTypeId, params.value("effect").toInt());
}
}
}
});
client->transport()->connectTransport();
}

View File

@ -55,6 +55,9 @@ public:
void executeAction(ThingActionInfo *info) override;
void thingRemoved(Thing *thing) override;
private:
void processActionQueue(Thing *thing);
private:
ZeroConfServiceBrowser *m_zeroConfBrowser = nullptr;
@ -76,6 +79,9 @@ private:
void setupArduinoChildThing(OwletSerialClient *client, quint8 pinId, OwletSerialClient::PinMode pinMode);
void configurePin(OwletSerialClient *client, quint8 pinId, OwletSerialClient::PinMode pinMode);
QString getPinName(Thing *parent, quint8 pinId);
QHash<Thing*, QList<ThingActionInfo*>> m_actionQueue;
QHash<Thing*, ThingActionInfo*> m_pendingActions;
};
#endif // INTEGRATIONPLUGINOWLET_H

View File

@ -11,6 +11,17 @@ OwletClient::OwletClient(OwletTransport *transport, QObject *parent) :
{
transport->setParent(this);
m_commandTimeoutTimer.setInterval(5000);
connect(&m_commandTimeoutTimer, &QTimer::timeout, this, [=](){
if (m_pendingCommandId != -1) {
QVariantMap params;
params.insert("error", "TimeoutError");
emit replyReceived(m_pendingCommandId, params);
m_pendingCommandId = -1;
sendNextRequest();
}
});
connect(m_transport, &OwletTransport::dataReceived, this, &OwletClient::dataReceived);
connect(m_transport, &OwletTransport::error, this, &OwletClient::error);
connect(m_transport, &OwletTransport::connectedChanged, this, [=](bool isConnected){
@ -39,13 +50,18 @@ int OwletClient::sendCommand(const QString &method, const QVariantMap &params)
return -1;
}
int id = ++m_commandId;
quint16 id = ++m_commandId;
QVariantMap packet;
packet.insert("id", id);
packet.insert("method", method);
packet.insert("params", params);
m_transport->sendData(QJsonDocument::fromVariant(packet).toJson(QJsonDocument::Compact));
qCDebug(dcOwlet) << "Sending command" << qUtf8Printable(QJsonDocument::fromVariant(packet).toJson());
Command cmd;
cmd.id = id;
cmd.payload = packet;
m_commandQueue.append(cmd);
sendNextRequest();
return id;
}
@ -60,10 +76,9 @@ void OwletClient::dataReceived(const QByteArray &data)
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(m_receiveBuffer.left(splitIndex), &error);
if (error.error != QJsonParseError::NoError) {
// qWarning() << "Could not parse json data from nymea" << m_receiveBuffer.left(splitIndex) << error.errorString();
qCWarning(dcOwlet) << "Could not parse json data from nymea" << m_receiveBuffer.left(splitIndex) << error.errorString();
return;
}
// qDebug() << "received response" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented));
m_receiveBuffer = m_receiveBuffer.right(m_receiveBuffer.length() - splitIndex - 1);
if (!m_receiveBuffer.isEmpty()) {
staticMetaObject.invokeMethod(this, "dataReceived", Qt::QueuedConnection, Q_ARG(QByteArray, QByteArray()));
@ -72,11 +87,31 @@ void OwletClient::dataReceived(const QByteArray &data)
QVariantMap packet = jsonDoc.toVariant().toMap();
if (packet.contains("notification")) {
qCDebug(dcOwlet()) << "Notification received:" << packet;
qCDebug(dcOwlet()) << "Notification received:" << qUtf8Printable(QJsonDocument::fromVariant(packet).toJson());
emit notificationReceived(packet.value("notification").toString(), packet.value("params").toMap());
} else if (packet.contains("id")) {
qCDebug(dcOwlet()) << "reply received:" << packet;
qCDebug(dcOwlet()) << "Reply received:" << qUtf8Printable(QJsonDocument::fromVariant(packet).toJson());
int id = packet.value("id").toInt();
if (id == m_pendingCommandId) {
m_pendingCommandId = -1;
sendNextRequest();
}
emit replyReceived(id, packet.value("params").toMap());
} else {
qCWarning(dcOwlet) << "Unhandled data from owlet" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented));
}
}
void OwletClient::sendNextRequest()
{
if (m_commandQueue.isEmpty()) {
return;
}
if (m_pendingCommandId != -1) {
return;
}
Command cmd = m_commandQueue.takeFirst();
m_pendingCommandId = cmd.id;
m_transport->sendData(QJsonDocument::fromVariant(cmd.payload).toJson(QJsonDocument::Compact));
m_commandTimeoutTimer.start();
}

View File

@ -4,6 +4,7 @@
#include <QObject>
#include <QHostAddress>
#include <QTcpSocket>
#include <QTimer>
class OwletTransport;
@ -30,12 +31,22 @@ signals:
private slots:
void dataReceived(const QByteArray &data);
void sendNextRequest();
private:
struct Command {
int id;
QVariantMap payload;
};
OwletTransport *m_transport = nullptr;
int m_commandId = 0;
quint16 m_commandId = 0;
QByteArray m_receiveBuffer;
QList<Command> m_commandQueue;
qint32 m_pendingCommandId = -1;
QTimer m_commandTimeoutTimer;
};
#endif // OWLETCLIENT_H