DoorOpener.cpp, DoorOpener.h und 7 weitere dateien aktualisiert...

master
Tibor 1 year ago
parent dd5c8444af
commit 3510c85b82
  1. 69
      DoorOpener.cpp
  2. 11
      DoorOpener.h
  3. 9
      QmlMqttClient.cpp
  4. 4
      QmlMqttClient.h
  5. 1
      access_token
  6. 3
      heimdall-client.pro
  7. 1
      main.cpp
  8. 23
      main.qml
  9. 14
      variables.h

@ -1,32 +1,77 @@
#include "DoorOpener.h"
#include "log.h"
#include "variables.h"
#include <QFile>
#include <QDebug>
DoorOpener::DoorOpener(QObject* parent)
{
Q_UNUSED(parent);
LOG_DBG("Initializing DoorOpener:");
LOG_DBG("\t - Host: " + _hostname);
LOG_DBG("\t - Port: " + std::to_string(_port));
initializeWithMqtt();
}
void DoorOpener::initializeWithMqtt()
{
_client = new QMqttClient();
_client->setHostname(_hostname.c_str());
_client->setPort(_port);
_client->connectToHost();
_client->setHostname(hdvars::MQTT_HOSTNAME.c_str());
_client->setPort(hdvars::MQTT_PORT);
if (_client->state() == QMqttClient::Connected) {
LOG_INF("Connected to host " + _hostname + ".");
LOG_DBG("Initializing DoorOpener:");
LOG_DBG("\t - Host: " + _client->hostname().toStdString());
LOG_DBG("\t - Port: " + std::to_string(_client->port()));
// TODO this is bad architecture. it should be safe to know when the connection is established. (see main.qml)
if (_client->state() != QMqttClient::Connected) {
_client->connectToHost();
}
else {
LOG_ERR("Unable to connect to host " + _hostname + ".");
connect(_client, &QMqttClient::stateChanged, [](QMqttClient::ClientState state) {
LOG_INF("MQTT client state is now " + [&]() -> std::string {
switch (state) {
case QMqttClient::Disconnected:
return "\"Disconnected\"";
case QMqttClient::Connecting:
return "\"Connecting\"";
case QMqttClient::Connected:
return "\"Connected\"";
default:
return "";
}
}());
});
if (QFile atFile { "access_token" }; atFile.open(QIODevice::ReadOnly)) {
LOG_DBG("Reading access token.");
QString token { atFile.readAll() };
// we only care about the first line of the "access_token" file
_access_token = token.split("\n").first().toStdString();
if (_access_token.empty()) {
LOG_ERR("Unable to read access token.");
}
else {
LOG_INF("Access token read.");
}
}
}
bool DoorOpener::open()
{
LOG_DBG("Trying to send MQTT message to server with topic " + _topic + ".");
qint32 retval { _client->publish(QMqttTopicName(_topic.c_str()), QByteArray(MQTT_ACCESS_TOKEN)) };
if (_client->state() != QMqttClient::Connected) {
LOG_ERR("Connect to MQTT client before calling open() function.");
return false;
}
LOG_DBG("Trying to send MQTT message to server with topic " + hdvars::MQTT_TOPIC + ".");
if (_access_token.empty()) {
LOG_WRN("No access token provided.");
}
qint32 retval { _client->publish(QMqttTopicName(hdvars::MQTT_TOPIC.c_str()), QByteArray(_access_token.c_str())) };
LOG_DBG("publish() returned " + std::to_string(retval) + ".");

@ -5,8 +5,6 @@
#include <QByteArray>
#include <QMqttClient>
#define MQTT_ACCESS_TOKEN "SCJFMzEauiJvaHaQ0f50TM0safyZR0sq_taiOpenHeimDall"
class DoorOpener : public QObject
{
Q_OBJECT
@ -18,11 +16,10 @@ public slots:
bool open();
private:
QMqttClient* _client { nullptr };
// TODO
std::string _hostname { "localhost" };
std::uint32_t _port { 1883 };
std::string _topic { "taibsu_at_home/heimdall" };
QMqttClient* _client;
std::string _access_token {};
void initializeWithMqtt();
};
#endif // DOOROPENER_H

@ -1,16 +1,19 @@
#include "QmlMqttClient.h"
#include "log.h"
#include "variables.h"
QmlMqttClient::QmlMqttClient(QObject *parent)
: QMqttClient(parent)
{
setHostname(hdvars::MQTT_HOSTNAME.c_str());
setPort(hdvars::MQTT_PORT);
}
QmlMqttSubscription* QmlMqttClient::subscribe(const QString &topic)
QmlMqttSubscription* QmlMqttClient::subscribe()
{
LOG_INF("Initializing subscription with topic " + topic.toStdString() + ".");
LOG_INF("Initializing subscription with topic " + hdvars::MQTT_TOPIC + ".");
QMqttSubscription* sub { QMqttClient::subscribe(topic, 0) };
QMqttSubscription* sub { QMqttClient::subscribe(QMqttTopicFilter(hdvars::MQTT_TOPIC.c_str()), 0) };
QmlMqttSubscription* result { new QmlMqttSubscription(sub, this) };
return result;

@ -33,9 +33,9 @@ class QmlMqttClient : public QMqttClient
{
Q_OBJECT
public:
QmlMqttClient(QObject *parent = nullptr);
QmlMqttClient(QObject *parent = nullptr);
Q_INVOKABLE QmlMqttSubscription *subscribe(const QString &topic);
Q_INVOKABLE QmlMqttSubscription* subscribe();
private:
Q_DISABLE_COPY(QmlMqttClient)
};

@ -0,0 +1 @@
SCJFMzEauiJvaHaQ0f50TM0safyZR0sq_taiOpenHeimDall

@ -30,4 +30,5 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
HEADERS += \
DoorOpener.h \
QmlMqttClient.h \
log.h
log.h \
variables.h

@ -11,6 +11,7 @@ int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
// TODO put all these log lines in a static function in log.h: initialize(std::string filename)
// Logging configuration
std::string const& logfile { "heimdall-client.log" };

@ -20,28 +20,17 @@ Window {
opacity: .25
}
DoorOpener {
id: doorOpener
}
// mqtt client
MqttClient {
id: client
// TODO
property string _host: "localhost"
property string _port: "1883"
property string _topic: "taibsu_at_home/heimdall"
hostname: _host
port: _port
Component.onCompleted: {
// TODO this is bad architecture. it should be safe to know when the connection is established. (see DoorOpener.cpp)
connectToHost()
}
onConnected: {
subscribe(_topic)
subscribe()
}
onDisconnected: {
@ -50,7 +39,7 @@ Window {
onStateChanged: {
stateIndicator.color = getState()
stateIndicatorText.text = connected ? "✔" : "𐄂"
stateIndicatorText.text = color == "green" ? "✔" : "𐄂"
}
onMessageReceived: {
@ -75,6 +64,10 @@ Window {
}
}
DoorOpener {
id: doorOpener
}
// caption
Label {
id: caption
@ -216,8 +209,6 @@ Window {
}
bgrOpened.start()
console.log("color: " + bgColor)
}
Rectangle {

@ -0,0 +1,14 @@
#ifndef VARIABLES_H
#define VARIABLES_H
#include <string>
namespace hdvars
{
static const std::string MQTT_HOSTNAME { "localhost" };
static const std::string MQTT_TOPIC { "taibsu_at_home/heimdall" };
static const std::uint32_t MQTT_PORT { 1883 };
}
#endif // VARIABLES_H