From e82976b5212dde11bcdd50e6fbfcc63ac5229632 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Tue, 21 Sep 2021 15:42:44 +0200 Subject: [PATCH] added existing qt sources --- .gitignore | 73 ++++++++++++++++++++++ bobbycar-cloud.ini | 3 + bobbycar-cloud.pro | 9 +++ main.cpp | 149 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 234 insertions(+) create mode 100644 .gitignore create mode 100644 bobbycar-cloud.ini create mode 100644 bobbycar-cloud.pro create mode 100644 main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/bobbycar-cloud.ini b/bobbycar-cloud.ini new file mode 100644 index 0000000..fe3480a --- /dev/null +++ b/bobbycar-cloud.ini @@ -0,0 +1,3 @@ +port=11000 +url=http://localhost:8086/api/v2/write?org=test&bucket=bobbycar&precision=ms +token=SECRET diff --git a/bobbycar-cloud.pro b/bobbycar-cloud.pro new file mode 100644 index 0000000..ae62749 --- /dev/null +++ b/bobbycar-cloud.pro @@ -0,0 +1,9 @@ +QT = core network websockets + +CONFIG += c++latest + +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 + +SOURCES += main.cpp + +DISTFILES += bobbycar-cloud.ini diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..54f2c7c --- /dev/null +++ b/main.cpp @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + QSettings settings{"bobbycar-cloud.ini", QSettings::IniFormat}; + + QNetworkRequest request{QUrl{settings.value("url").toString()}}; + request.setRawHeader(QByteArray{"Authorization"}, QString{"Token %0"}.arg(settings.value("token").toString()).toUtf8()); + request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain; charset=utf-8"); + request.setRawHeader(QByteArray{"Accept"}, QByteArray{"application/json"}); + + QNetworkAccessManager manager; + + QWebSocketServer server{"bobbycar-cloud", QWebSocketServer::NonSecureMode}; + + QObject::connect(&server, &QWebSocketServer::newConnection, + [&](){ + QWebSocket *client = server.nextPendingConnection(); + if (!client) + return; + + auto clientId = client->requestUrl().path(); + if (clientId.startsWith('/')) + clientId.remove(0, 1); + + qDebug() << "new connection from" << client->peerAddress() << clientId; + + QObject::connect(client, &QWebSocket::textMessageReceived, [client, clientId, &manager, &request](const QString &message){ + qDebug() << "received" << client->peerAddress() << clientId /*<< message*/; + + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error); + if (error.error != QJsonParseError::NoError) + { + qWarning() << client->peerAddress() << client->requestUrl().path() << "could not parse json" << error.errorString(); + return; + } + + if (!doc.isArray()) + { + qWarning() << client->peerAddress() << client->requestUrl().path() << "json is not an array"; + return; + } + + auto docArr = doc.array(); + + const qint64 uptime = docArr[0].toDouble(); + const auto utc = QDateTime::fromMSecsSinceEpoch(docArr[1].toDouble()); + const auto freememory8 = docArr[2].toInt(); + + QString data; + data += QString{"system,host=%0 uptime=%1,freememory8=%2"} + .arg(clientId) + .arg(uptime) + .arg(freememory8); + + if (!docArr[3].isNull()) + data += QString{",rssi=%0"}.arg(docArr[3].toInt()); + + data += QString{" %0\n"}.arg(utc.toMSecsSinceEpoch()); + + if (!docArr[4].isNull() || !docArr[5].isNull()) + { + data += QString{"inputs,host=%0,type=potis,kind=raw %1%2%3 %4\n"} + .arg(clientId) + .arg(!docArr[4].isNull() ? QString{"gas=%0"}.arg(docArr[4].toInt()) : "") + .arg(!docArr[4].isNull() && !docArr[5].isNull() ? "," : "") + .arg(!docArr[5].isNull() ? QString{"brems=%0"}.arg(docArr[5].toInt()) : "") + .arg(utc.toMSecsSinceEpoch()); + } + + if (!docArr[6].isNull() || !docArr[7].isNull()) + { + data += QString{"inputs,host=%0,type=potis,kind=processed %1%2%3 %4\n"} + .arg(clientId) + .arg(!docArr[6].isNull() ? QString{"gas=%0"}.arg(docArr[6].toDouble()) : "") + .arg(!docArr[6].isNull() && !docArr[7].isNull() ? "," : "") + .arg(!docArr[7].isNull() ? QString{"brems=%0"}.arg(docArr[7].toDouble()) : "") + .arg(utc.toMSecsSinceEpoch()); + } + + const auto addController = [&](const QJsonArray &controller, const QString &board){ + data += QString{"measure,host=%0,board=%1 voltage=%2,temperature=%3 %4\n"} + .arg(clientId) + .arg(board) + .arg(controller[0].toDouble()) + .arg(controller[1].toDouble()) + .arg(utc.toMSecsSinceEpoch()); + + const auto addMotor = [&](const QJsonArray &motor, const QString &board, const QString &side){ + data += QString{"command,host=%0,board=%1,side=%2 inputTgt=%3 %4\n"} + .arg(clientId) + .arg(board) + .arg(side) + .arg(motor[0].toInt()) + .arg(utc.toMSecsSinceEpoch()); + data += QString{"measure,host=%0,board=%1,side=%2 speed=%3,current=%4,error=%5 %6\n"} + .arg(clientId) + .arg(board) + .arg(side) + .arg(motor[1].toDouble()) + .arg(motor[2].toDouble()) + .arg(motor[3].toInt()) + .arg(utc.toMSecsSinceEpoch()); + }; + + addMotor(controller[2].toArray(), board, "left"); + addMotor(controller[3].toArray(), board, "right"); + }; + + if (!docArr[8].isNull()) + addController(docArr[8].toArray(), "front"); + + if (!docArr[9].isNull()) + addController(docArr[9].toArray(), "back"); + + QNetworkReply *reply = manager.post(request, data.toUtf8()); + QObject::connect(reply, &QNetworkReply::finished, reply, [reply](){ + if (reply->error() != QNetworkReply::NoError) + qWarning() << "request finished" << reply->error() << reply->errorString(); + //qDebug() << reply->readAll(); + reply->deleteLater(); + }); + }); + + QObject::connect(client, &QWebSocket::disconnected, [](){ + qDebug() << "disconnected"; + }); + }); + + quint16 port = settings.value("port").toInt(); + if (!server.listen(QHostAddress::Any, port)) + qFatal("could not start listening %s", qPrintable(server.errorString())); + + qDebug() << "listening on port" << port; + + return app.exec(); +}