diff --git a/CMakeLists.txt b/CMakeLists.txt
index 103c3b1..eff65b6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,13 +3,15 @@ cmake_minimum_required(VERSION 3.16)
project(WaterLevelRewrite VERSION 0.1 LANGUAGES CXX)
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_add_executable(appWaterLevelRewrite
main.cpp
+ media.qrc
)
qt_add_qml_module(appWaterLevelRewrite
@@ -22,11 +24,9 @@ qt_add_qml_module(appWaterLevelRewrite
SOURCES configinterface.h configinterface.cpp
QML_FILES ConnectButton.qml
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
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appWaterLevelRewrite
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
@@ -36,7 +36,7 @@ set_target_properties(appWaterLevelRewrite PROPERTIES
)
target_link_libraries(appWaterLevelRewrite
- PRIVATE Qt6::Quick
+ PRIVATE Qt6::Quick Qt6::Multimedia
)
install(TARGETS appWaterLevelRewrite
diff --git a/Main.qml b/Main.qml
index 950a2b9..1b6c5fc 100644
--- a/Main.qml
+++ b/Main.qml
@@ -21,7 +21,8 @@ Window {
property int distance_count_thres: 3
property string mode: "http"
property string status: "Initializing"
-
+ property string alarm_status_text: ""
+ property var root_config: ({})
Rectangle {
anchors.fill: parent
@@ -91,11 +92,13 @@ Window {
max_thres_input: 0
}
+
Text {
- id: status
- text: root.status
+ id: alarm_status
+ text: root.alarm_status_text
+ visible: (root.alarm_status_text.length > 0 ) ? true : false
anchors {
- bottom: connect_button.top
+ bottom: status.top
bottomMargin: 20
horizontalCenter: parent.horizontalCenter
}
@@ -104,32 +107,90 @@ Window {
font.pointSize: root.font_normal_text_size
}
- ConnectButton {
- id: connect_button
+ 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
- width: parent.width / 4
- 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
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 50
}
- onConnect: {
- if(connect_button.mode === 0)
- {
- requester.start();
- root.status = "Waiting to Send.";
+ ConnectButton {
+ id: connect_button
+ 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
+ anchors {
+ left: parent.left
+ leftMargin: 5
+ bottom: parent.bottom
+ bottomMargin: 5
}
- else {
- root.status = "Stopped.";
- requester.stop();
+ onConnect: {
+ if(connect_button.mode === 0)
+ {
+ requester.start();
+ root.status = "Waiting to Send.";
+ }
+ else {
+ root.status = "Stopped.";
+ requester.stop();
+ }
}
}
+
+ 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 {
@@ -162,6 +223,10 @@ Window {
function setConfig(config) {
tank.setConfig(config);
requester.setConfig(config);
+ root.root_config = config;
}
}
+ onClosing: {
+ requester.stopAlarm();
+ }
}
diff --git a/echo.mp3 b/echo.mp3
new file mode 100644
index 0000000..4373d95
Binary files /dev/null and b/echo.mp3 differ
diff --git a/media.qrc b/media.qrc
new file mode 100644
index 0000000..2af454f
--- /dev/null
+++ b/media.qrc
@@ -0,0 +1,5 @@
+
+
+ echo.mp3
+
+
diff --git a/requestworker.cpp b/requestworker.cpp
index 649d515..c02ea40 100644
--- a/requestworker.cpp
+++ b/requestworker.cpp
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
RequestWorker::RequestWorker(QObject *parent)
: QObject{parent}
@@ -16,11 +17,13 @@ void RequestWorker::setConfig(QJsonObject config)
this->interval = config["interval"].toInt();
this->max_height = config["max"].toInt();
this->min_height = config["min"].toInt();
+ this->alarm_thres = config["alert"].toInt();
qDebug() << "In cpp config values are: ";
qDebug() << "Url: " << url;
qDebug() << "Interval: " << interval;
qDebug() << "Max Height: " << max_height;
qDebug() << "Min Height: " << min_height;
+ qDebug() << "Alert: " << alarm_thres;
}
void RequestWorker::start()
@@ -51,6 +54,34 @@ void RequestWorker::stop()
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()
{
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;
rate_of_fill = rate_of_fill * 1'000'000;
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) {
rate_of_fill = 0;
expected_to_fill = 0;
@@ -93,6 +131,7 @@ void RequestWorker::requestFinished(QNetworkReply *rep)
qDebug() << "Got water level: " << water_level;
qDebug() << "Got rate of fill: " << rate_of_fill;
qDebug() << "Got expected to fill: " << expected_to_fill;
+ qDebug() << "Percentage filled: " << percentage_filled;
qDebug() << "Time difference: " << time_in_microseconds;
prev_distance = water_level;
emit networkReply(data_water_level, rate_of_fill, expected_to_fill);
@@ -118,3 +157,23 @@ void RequestWorker::setStatus(const QString &newStatus)
m_status = newStatus;
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;
+ }
+}
diff --git a/requestworker.h b/requestworker.h
index 37d0888..f78e3a6 100644
--- a/requestworker.h
+++ b/requestworker.h
@@ -6,6 +6,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -24,10 +26,14 @@ class RequestWorker : public QObject
int min_height = 0;
bool stop_timer = false;
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 prev_time;
public:
explicit RequestWorker(QObject *parent = nullptr);
-
QString status() const;
void setStatus(const QString &newStatus);
@@ -35,12 +41,15 @@ signals:
void requestFailed();
void networkReply(int distance, float rate_of_fill, int expected_to_fill);
void statusChanged();
-
+ void playMedia();
public slots:
+ void startAlarm();
+ void stopAlarm();
void setConfig(QJsonObject config);
void start();
void stop();
private slots:
+ void playAlarm();
void makeRequest();
void requestFinished(QNetworkReply *rep);
private: