Http Version - Added Alarm Button.

This commit is contained in:
unrealdragon 2026-08-12 18:22:15 +05:30
commit 07bd73bb33
6 changed files with 163 additions and 25 deletions

View file

@ -3,13 +3,15 @@ cmake_minimum_required(VERSION 3.16)
project(WaterLevelRewrite VERSION 0.1 LANGUAGES CXX) project(WaterLevelRewrite VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTORCC ON)
find_package(Qt6 REQUIRED COMPONENTS Quick) find_package(Qt6 REQUIRED COMPONENTS Quick Multimedia)
qt_standard_project_setup(REQUIRES 6.10) qt_standard_project_setup(REQUIRES 6.10)
qt_add_executable(appWaterLevelRewrite qt_add_executable(appWaterLevelRewrite
main.cpp main.cpp
media.qrc
) )
qt_add_qml_module(appWaterLevelRewrite qt_add_qml_module(appWaterLevelRewrite
@ -22,11 +24,9 @@ qt_add_qml_module(appWaterLevelRewrite
SOURCES configinterface.h configinterface.cpp SOURCES configinterface.h configinterface.cpp
QML_FILES ConnectButton.qml QML_FILES ConnectButton.qml
SOURCES requestworker.h requestworker.cpp SOURCES requestworker.h requestworker.cpp
RESOURCES media.qrc
) )
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
set_target_properties(appWaterLevelRewrite PROPERTIES set_target_properties(appWaterLevelRewrite PROPERTIES
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appWaterLevelRewrite # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appWaterLevelRewrite
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
@ -36,7 +36,7 @@ set_target_properties(appWaterLevelRewrite PROPERTIES
) )
target_link_libraries(appWaterLevelRewrite target_link_libraries(appWaterLevelRewrite
PRIVATE Qt6::Quick PRIVATE Qt6::Quick Qt6::Multimedia
) )
install(TARGETS appWaterLevelRewrite install(TARGETS appWaterLevelRewrite

View file

@ -21,7 +21,8 @@ Window {
property int distance_count_thres: 3 property int distance_count_thres: 3
property string mode: "http" property string mode: "http"
property string status: "Initializing" property string status: "Initializing"
property string alarm_status_text: ""
property var root_config: ({})
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
@ -91,11 +92,13 @@ Window {
max_thres_input: 0 max_thres_input: 0
} }
Text { Text {
id: status id: alarm_status
text: root.status text: root.alarm_status_text
visible: (root.alarm_status_text.length > 0 ) ? true : false
anchors { anchors {
bottom: connect_button.top bottom: status.top
bottomMargin: 20 bottomMargin: 20
horizontalCenter: parent.horizontalCenter horizontalCenter: parent.horizontalCenter
} }
@ -104,19 +107,43 @@ Window {
font.pointSize: root.font_normal_text_size font.pointSize: root.font_normal_text_size
} }
Text {
id: status
text: root.status
anchors {
bottom: button_base.top
bottomMargin: 20
horizontalCenter: parent.horizontalCenter
}
horizontalAlignment: Text.AlignHCenter
color: root.accent_color
font.pointSize: root.font_normal_text_size
}
Rectangle {
id: button_base
color: "#00000000"
width: parent.width / 1.5
height: parent.height / 20
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 50
}
ConnectButton { ConnectButton {
id: connect_button id: connect_button
height: parent.height / 20 width: parent.width / 2.1
width: parent.width / 4 height: parent.height
font_color: root.accent_color font_color: root.accent_color
font_enlarged_text_size: root.font_enlarged_text_size font_enlarged_text_size: root.font_enlarged_text_size
font_normal_text_size: root.font_normal_text_size font_normal_text_size: root.font_normal_text_size
color: root.background_color color: root.background_color
accent_color: root.accent_color accent_color: root.accent_color
anchors { anchors {
horizontalCenter: parent.horizontalCenter left: parent.left
leftMargin: 5
bottom: parent.bottom bottom: parent.bottom
bottomMargin: 50 bottomMargin: 5
} }
onConnect: { onConnect: {
if(connect_button.mode === 0) if(connect_button.mode === 0)
@ -130,6 +157,40 @@ Window {
} }
} }
} }
ConnectButton {
id: start_alarm
width: parent.width / 2.1
height: parent.height
font_color: root.accent_color
font_enlarged_text_size: root.font_enlarged_text_size
font_normal_text_size: root.font_normal_text_size
color: root.background_color
accent_color: root.accent_color
text: "Start Alarm"
text2: "Stop Alarm"
anchors {
left: connect_button.right
leftMargin: 10
bottom: parent.bottom
bottomMargin: 5
}
onConnect: {
if(start_alarm.mode === 0)
{
requester.startAlarm();
root.alarm_status_text = "Started Alarm; Waiting for Trigger: " + root.root_config.alert + "%"
}
else {
requester.stopAlarm();
root.alarm_status_text = "";
}
}
}
}
} }
RequestWorker { RequestWorker {
@ -162,6 +223,10 @@ Window {
function setConfig(config) { function setConfig(config) {
tank.setConfig(config); tank.setConfig(config);
requester.setConfig(config); requester.setConfig(config);
root.root_config = config;
} }
} }
onClosing: {
requester.stopAlarm();
}
} }

BIN
echo.mp3 Normal file

Binary file not shown.

5
media.qrc Normal file
View file

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/sounds">
<file>echo.mp3</file>
</qresource>
</RCC>

View file

@ -3,6 +3,7 @@
#include <QJsonValue> #include <QJsonValue>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonDocument> #include <QJsonDocument>
#include <QFile>
RequestWorker::RequestWorker(QObject *parent) RequestWorker::RequestWorker(QObject *parent)
: QObject{parent} : QObject{parent}
@ -16,11 +17,13 @@ void RequestWorker::setConfig(QJsonObject config)
this->interval = config["interval"].toInt(); this->interval = config["interval"].toInt();
this->max_height = config["max"].toInt(); this->max_height = config["max"].toInt();
this->min_height = config["min"].toInt(); this->min_height = config["min"].toInt();
this->alarm_thres = config["alert"].toInt();
qDebug() << "In cpp config values are: "; qDebug() << "In cpp config values are: ";
qDebug() << "Url: " << url; qDebug() << "Url: " << url;
qDebug() << "Interval: " << interval; qDebug() << "Interval: " << interval;
qDebug() << "Max Height: " << max_height; qDebug() << "Max Height: " << max_height;
qDebug() << "Min Height: " << min_height; qDebug() << "Min Height: " << min_height;
qDebug() << "Alert: " << alarm_thres;
} }
void RequestWorker::start() void RequestWorker::start()
@ -51,6 +54,34 @@ void RequestWorker::stop()
qDebug() << "Stopping" << timer->isActive(); qDebug() << "Stopping" << timer->isActive();
} }
void RequestWorker::playAlarm()
{
if(player_started)
return;
if(player) {
player->deleteLater();
player = nullptr;
}
if(audioOutput) {
audioOutput->deleteLater();
audioOutput->deleteLater();
}
qDebug() << "Loading player";
player = new QMediaPlayer(this);
audioOutput = new QAudioOutput(this);
player->setAudioOutput(audioOutput);
if (QFile::exists(":/sounds/echo.mp3")) {
qDebug() << "Resource found successfully!";
} else {
qDebug() << "Resource not found. Check CMakeLists.txt or .pro file!";
}
player->setSource(QUrl("qrc:/sounds/echo.mp3"));
audioOutput->setVolume(0.5);
connect(this, &RequestWorker::playMedia, player, &QMediaPlayer::play);
player_started = true;
emit playMedia();
}
void RequestWorker::makeRequest() void RequestWorker::makeRequest()
{ {
if(stop_timer) if(stop_timer)
@ -85,6 +116,13 @@ void RequestWorker::requestFinished(QNetworkReply *rep)
float rate_of_fill = ( float )(prev_distance - water_level) /(float) time_in_microseconds; float rate_of_fill = ( float )(prev_distance - water_level) /(float) time_in_microseconds;
rate_of_fill = rate_of_fill * 1'000'000; rate_of_fill = rate_of_fill * 1'000'000;
int expected_to_fill = (water_level - min_height) / rate_of_fill; int expected_to_fill = (water_level - min_height) / rate_of_fill;
int percentage_filled = (float (max_height - water_level) / float (max_height)) *100;
if(enable_alarm) {
qDebug() << "Alarm enabled";
if(percentage_filled >= alarm_thres) {
playAlarm();
}
}
if(reply_number == 0) { if(reply_number == 0) {
rate_of_fill = 0; rate_of_fill = 0;
expected_to_fill = 0; expected_to_fill = 0;
@ -93,6 +131,7 @@ void RequestWorker::requestFinished(QNetworkReply *rep)
qDebug() << "Got water level: " << water_level; qDebug() << "Got water level: " << water_level;
qDebug() << "Got rate of fill: " << rate_of_fill; qDebug() << "Got rate of fill: " << rate_of_fill;
qDebug() << "Got expected to fill: " << expected_to_fill; qDebug() << "Got expected to fill: " << expected_to_fill;
qDebug() << "Percentage filled: " << percentage_filled;
qDebug() << "Time difference: " << time_in_microseconds; qDebug() << "Time difference: " << time_in_microseconds;
prev_distance = water_level; prev_distance = water_level;
emit networkReply(data_water_level, rate_of_fill, expected_to_fill); emit networkReply(data_water_level, rate_of_fill, expected_to_fill);
@ -118,3 +157,23 @@ void RequestWorker::setStatus(const QString &newStatus)
m_status = newStatus; m_status = newStatus;
emit statusChanged(); emit statusChanged();
} }
void RequestWorker::startAlarm()
{
enable_alarm = true;
}
void RequestWorker::stopAlarm()
{
enable_alarm = false;
player_started = false;
if(player) {
player->stop();
player->deleteLater();
player = nullptr;
}
if(audioOutput) {
audioOutput->deleteLater();
audioOutput = nullptr;
}
}

View file

@ -6,6 +6,8 @@
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QNetworkReply> #include <QNetworkReply>
#include <QMediaPlayer>
#include <QAudioOutput>
#include <QTimer> #include <QTimer>
#include <QThread> #include <QThread>
#include <chrono> #include <chrono>
@ -24,10 +26,14 @@ class RequestWorker : public QObject
int min_height = 0; int min_height = 0;
bool stop_timer = false; bool stop_timer = false;
int reply_number = 0; int reply_number = 0;
int alarm_thres = 0;
bool enable_alarm = false;
bool player_started = false;
QMediaPlayer *player = nullptr;
QAudioOutput *audioOutput = nullptr;
std::chrono::time_point<std::chrono::high_resolution_clock> prev_time; std::chrono::time_point<std::chrono::high_resolution_clock> prev_time;
public: public:
explicit RequestWorker(QObject *parent = nullptr); explicit RequestWorker(QObject *parent = nullptr);
QString status() const; QString status() const;
void setStatus(const QString &newStatus); void setStatus(const QString &newStatus);
@ -35,12 +41,15 @@ signals:
void requestFailed(); void requestFailed();
void networkReply(int distance, float rate_of_fill, int expected_to_fill); void networkReply(int distance, float rate_of_fill, int expected_to_fill);
void statusChanged(); void statusChanged();
void playMedia();
public slots: public slots:
void startAlarm();
void stopAlarm();
void setConfig(QJsonObject config); void setConfig(QJsonObject config);
void start(); void start();
void stop(); void stop();
private slots: private slots:
void playAlarm();
void makeRequest(); void makeRequest();
void requestFinished(QNetworkReply *rep); void requestFinished(QNetworkReply *rep);
private: private: