--- /dev/null
+# 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*
+CMakeLists.txt.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
+
--- /dev/null
+[submodule "paho.mqtt.c"]
+ path = paho.mqtt.c
+ url = https://github.com/eclipse/paho.mqtt.c
--- /dev/null
+cmake_minimum_required(VERSION 3.16)
+
+project(qthomecontrol VERSION 0.1 LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(Qt6 6.2 COMPONENTS Quick REQUIRED)
+
+if (UNIX)
+ add_subdirectory ("paho.mqtt.c")
+endif(UNIX)
+
+qt_add_executable(appqthomecontrol
+ main.cpp
+ mqttinterface.cpp
+ mqttinterface.h
+)
+
+qt_add_qml_module(appqthomecontrol
+ URI qthomecontrol
+ VERSION 1.0
+ QML_FILES main.qml
+ SOURCES
+ mqttinterface.h mqttinterface.cpp
+)
+
+set_target_properties(appqthomecontrol PROPERTIES
+ MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
+ MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
+ MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
+ MACOSX_BUNDLE TRUE
+ WIN32_EXECUTABLE TRUE
+)
+
+target_include_directories (appqthomecontrol PRIVATE paho.mqtt.c/src)
+
+target_link_libraries(appqthomecontrol
+ PRIVATE Qt6::Quick)
+
+if (WIN32)
+ target_link_libraries (appqthomecontrol PRIVATE ${CMAKE_SOURCE_DIR}/paho.mqtt.c/src/Release/paho-mqtt3a.lib ${CMAKE_SOURCE_DIR}/paho.mqtt.c/src/Release/paho-mqtt3c.lib)
+endif (WIN32)
+if (UNIX)
+ target_link_libraries (appqthomecontrol PRIVATE paho-mqtt3a paho-mqtt3c)
+endif(UNIX)
+
+install(TARGETS appqthomecontrol
+ BUNDLE DESTINATION .
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
--- /dev/null
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ const QUrl url(u"qrc:/qthomecontrol/main.qml"_qs);
+ QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
+ &app, [url](QObject *obj, const QUrl &objUrl) {
+ if (!obj && url == objUrl)
+ QCoreApplication::exit(-1);
+ }, Qt::QueuedConnection);
+ engine.load(url);
+
+ return app.exec();
+}
--- /dev/null
+import QtQuick
+import QtQuick.Controls 6.3
+import QtQuick.Layouts 6.3
+import qthomecontrol
+
+Window {
+ width: 720
+ height: 720
+ visible: true
+ color: "#000000"
+ title: qsTr("Hello World")
+
+ MQTTInterface {
+ id: mqttinterface
+ }
+
+ Slider {
+ id: slider
+ x: 13
+ y: 534
+ width: 695
+ height: 178
+ live: true
+ antialiasing: false
+ topPadding: 0
+ orientation: Qt.Horizontal
+ snapMode: RangeSlider.SnapOnRelease
+ stepSize: 1
+ to: 100
+ value: 0
+ }
+
+ Text {
+ id: text1
+ x: 206
+ y: 114
+ width: 309
+ height: 129
+ color: "#ffffff"
+ text: mqttinterface.bedroomTemperature.toFixed(1) + " °C"
+ font.pixelSize: 92
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ Text {
+ id: text2
+ x: 206
+ y: 285
+ width: 309
+ height: 129
+ color: "#ffffff"
+ text: mqttinterface.bedroomHumidity.toFixed(0) + " %"
+ font.pixelSize: 92
+ horizontalAlignment: Text.AlignHCenter
+ }
+}
--- /dev/null
+#include "mqttinterface.h"
+
+using namespace std;
+
+void delivered(void* context, MQTTClient_deliveryToken dt)
+{
+ MQTTInterface* thermostat = static_cast<MQTTInterface*>(context);
+ //thermostat->DeliverToken(dt);
+}
+
+int msgarrvd(void* context, char* topicName, int topicLen, MQTTClient_message* message)
+{
+ MQTTInterface* thermostat = static_cast<MQTTInterface*>(context);
+
+ if (string(topicName) == "bedroom/thermostat/temperature/raw") {
+ float temperature = stof(string((char*)message->payload));
+ thermostat->updateBedroomTemperature(temperature);
+ } else if (string(topicName) == "bedroom/thermostat/humidity/raw") {
+ float humidity = stof(string((char*)message->payload));
+ thermostat->updateBedroomHumidity(humidity);
+ }
+
+ MQTTClient_freeMessage(&message);
+ MQTTClient_free(topicName);
+
+
+ return 1;
+}
+
+void connlost(void* context, char* cause)
+{
+ MQTTInterface* thermostat = static_cast<MQTTInterface*>(context);
+
+ printf("\nConnection lost\n");
+ printf(" cause: %s\n", cause);
+
+ //thermostat->ShouldReconnect();
+}
+
+#define QOS 1
+
+MQTTInterface::MQTTInterface(QObject *parent)
+ : QObject{parent}
+{
+ MQTTClient_message pubmsg = MQTTClient_message_initializer;
+ MQTTClient_deliveryToken token;
+
+ int rc;
+ MQTTClient_create(&mClient, "tcp://10.0.1.213:1883", "bedroom-thermostat-fe",
+ MQTTCLIENT_PERSISTENCE_NONE, NULL);
+
+ if ((rc = MQTTClient_setCallbacks(mClient, this, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS)
+ {
+ printf("Failed to set callbacks, return code %d\n", rc);
+ return;
+ }
+
+ connectToServer();
+
+ char cbuf[256];
+ sprintf(cbuf, "%.1f", 15.3);
+ pubmsg.payload = (void*)cbuf;
+ pubmsg.payloadlen = strlen(cbuf);
+ pubmsg.qos = QOS;
+ pubmsg.retained = 0;
+ MQTTClient_publishMessage(mClient, "newtest/test", &pubmsg, &token);
+}
+
+void
+MQTTInterface::updateBedroomTemperature(float aTemperature)
+{
+ {
+ unique_lock<mutex> lk(mDataMutex);
+ mBedroomTemperature = aTemperature;
+ }
+
+ emit bedroomTemperatureChanged();
+}
+
+void
+MQTTInterface::updateBedroomHumidity(float aHumidity)
+{
+ {
+ unique_lock<mutex> lk(mDataMutex);
+ mBedroomHumidity = aHumidity;
+ }
+
+ emit bedroomHumidityChanged();
+}
+
+void
+MQTTInterface::connectToServer()
+{
+ int rc = 0;
+ MQTTClient_disconnect(mClient, 10000);
+
+ MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
+ conn_opts.keepAliveInterval = 20;
+ conn_opts.cleansession = 1;
+
+ if ((rc = MQTTClient_connect(mClient, &conn_opts)) != MQTTCLIENT_SUCCESS)
+ {
+ printf("Failed to connect, return code %d\n", rc);
+ return;
+ }
+
+ if ((rc = MQTTClient_subscribe(mClient, "bedroom/thermostat/temperature/raw", QOS)) != MQTTCLIENT_SUCCESS)
+ {
+ printf("Failed to subscribe, return code %d\n", rc);
+ }
+ if ((rc = MQTTClient_subscribe(mClient, "bedroom/thermostat/humidity/raw", QOS)) != MQTTCLIENT_SUCCESS)
+ {
+ printf("Failed to subscribe, return code %d\n", rc);
+ }
+}
--- /dev/null
+#ifndef MQTTINTERFACE_H
+#define MQTTINTERFACE_H
+
+#include <QObject>
+#include <QtQml/qqmlregistration.h>
+#include <mutex>
+
+#include "MQTTClient.h"
+
+class MQTTInterface : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal bedroomTemperature READ bedroomTemperature NOTIFY bedroomTemperatureChanged);
+ Q_PROPERTY(qreal bedroomHumidity READ bedroomHumidity NOTIFY bedroomHumidityChanged);
+ QML_ELEMENT
+
+public:
+ explicit MQTTInterface(QObject *parent = nullptr);
+
+ qreal bedroomTemperature() {
+ std::unique_lock<std::mutex> lk(mDataMutex);
+ return mBedroomTemperature;
+ }
+ qreal bedroomHumidity() {
+ std::unique_lock<std::mutex> lk(mDataMutex);
+ return mBedroomHumidity;
+ }
+
+ void updateBedroomTemperature(float aTemperature);
+ void updateBedroomHumidity(float aHumidity);
+
+signals:
+ void bedroomTemperatureChanged();
+ void bedroomHumidityChanged();
+
+private:
+ void connectToServer();
+
+ qreal mBedroomTemperature = 10;
+ qreal mBedroomHumidity = 50;
+ MQTTClient mClient;
+ std::mutex mDataMutex;
+};
+
+#endif // MQTTINTERFACE_H
--- /dev/null
+Subproject commit f7799da95e347bbc930b201b52a1173ebbad45a7