first commit
This commit is contained in:
commit
9bfa1e11fe
1 changed files with 1751 additions and 0 deletions
532
Main.qml
Normal file
532
Main.qml
Normal file
|
|
@ -0,0 +1,532 @@
|
|||
import QtQuick
|
||||
import waterLevelSensor
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
|
||||
Window {
|
||||
width: 640
|
||||
height: 480
|
||||
visible: true
|
||||
title: qsTr("Hello World")
|
||||
id: root
|
||||
property color accent_color: "#F05FAF5F"
|
||||
property color danger_color: "#F0AF2F1F"
|
||||
property color water_color: "#F00F7FAF"
|
||||
Material.accent: root.accent_color
|
||||
property int font_enlarged_text_size: 20
|
||||
property int font_normal_text_size: 18
|
||||
property double distance: 0
|
||||
property int distance_count: 0
|
||||
// visibility: Window.FullScreen
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
id: background
|
||||
color: "#DF0F0F0F"
|
||||
Rectangle {
|
||||
id: top_bar
|
||||
height: Math.min(root.height / 12, 100)
|
||||
width: root.width
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
topMargin: 25
|
||||
}
|
||||
color: "#0A0F0F0F"
|
||||
|
||||
Rectangle {
|
||||
id: settings_rect
|
||||
height: top_bar.height - 20
|
||||
width: top_bar.width / 12
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
bottomMargin: 5
|
||||
topMargin: 5
|
||||
leftMargin: 5
|
||||
}
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
color: "#0A0F0F0F"
|
||||
border.color: "#AF121212"
|
||||
border.width: 0.5
|
||||
radius: 2
|
||||
Text {
|
||||
id: settings_text
|
||||
text: "⚙"
|
||||
anchors.centerIn: parent
|
||||
color: root.accent_color
|
||||
font.pointSize: root.font_enlarged_text_size
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: settings_button_area
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
property color settings_rect_pressed_prev: "#00000000"
|
||||
property color settings_rect_entered_prev: "#00000000"
|
||||
onEntered: {
|
||||
settings_rect_entered_prev = settings_rect.color
|
||||
settings_rect.color = "#5A1F1F1F"
|
||||
}
|
||||
onExited: {
|
||||
settings_rect.color = settings_rect_entered_prev
|
||||
}
|
||||
onPressed: {
|
||||
settings_rect_pressed_prev = settings_rect.color
|
||||
settings_rect.color = "#5A1F4F1F"
|
||||
settings_popup.open()
|
||||
}
|
||||
onReleased: {
|
||||
settings_rect.color = settings_rect_pressed_prev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Rectangle {
|
||||
property color old_color: "#0F0F0F0F"
|
||||
id: status_indicator
|
||||
width: 20
|
||||
height: 20
|
||||
radius: 20
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
topMargin: 20
|
||||
bottomMargin: 5
|
||||
leftMargin: 5
|
||||
rightMargin: 20
|
||||
}
|
||||
color: "#F0AF2F1F"
|
||||
layer.enabled: true
|
||||
layer.effect: MultiEffect {
|
||||
shadowEnabled: true
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: status_label
|
||||
anchors {
|
||||
top: parent.top
|
||||
topMargin: 20
|
||||
right: status_indicator.left
|
||||
rightMargin: 10
|
||||
}
|
||||
horizontalAlignment: Text.AlignRight
|
||||
width: parent.width - status_indicator.width
|
||||
height: parent.height
|
||||
color: root.accent_color
|
||||
font.pointSize: root.font_normal_text_size
|
||||
text: "Disconnected"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: base
|
||||
color: "#0A0F0F0F"
|
||||
width: parent.width
|
||||
height: parent.height - top_bar.height
|
||||
anchors {
|
||||
top: top_bar.bottom
|
||||
bottom: parent.bottom
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: settings_popup
|
||||
background: Rectangle {
|
||||
color: "#F0121212"
|
||||
radius: 5
|
||||
border.color: root.accent_color
|
||||
border.width: 1
|
||||
}
|
||||
height: parent.height / 1.5
|
||||
width: parent.width / 1.5
|
||||
anchors.centerIn: Overlay.overlay
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: settings_base
|
||||
anchors.fill: parent
|
||||
color: "#F0121212"
|
||||
|
||||
Text {
|
||||
id: settings_label
|
||||
text: "Settings"
|
||||
width: parent.width
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: root.accent_color
|
||||
font.pointSize: root.font_enlarged_text_size
|
||||
}
|
||||
|
||||
|
||||
Text {
|
||||
id: max_thres_label
|
||||
text: "Max Threshold: "
|
||||
anchors {
|
||||
topMargin: 20
|
||||
top: settings_label.bottom
|
||||
left: parent.left
|
||||
}
|
||||
height: max_thres_input.height
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: root.accent_color
|
||||
font.pixelSize: root.font_normal_text_size
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: max_thres_input
|
||||
text: config.max
|
||||
anchors {
|
||||
left: max_thres_label.right
|
||||
leftMargin: 5
|
||||
top: settings_label.bottom
|
||||
topMargin: 20
|
||||
}
|
||||
color: root.accent_color
|
||||
font.pixelSize: root.font_normal_text_size
|
||||
}
|
||||
|
||||
|
||||
Text {
|
||||
id: min_thres_label
|
||||
text: "Min Threshold: "
|
||||
anchors {
|
||||
topMargin: 20
|
||||
top: max_thres_label.bottom
|
||||
left: parent.left
|
||||
}
|
||||
height: min_thres_input.height
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: root.accent_color
|
||||
font.pixelSize: root.font_normal_text_size
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: min_thres_input
|
||||
text: config.min
|
||||
anchors {
|
||||
left: min_thres_label.right
|
||||
leftMargin: 5
|
||||
top: max_thres_label.bottom
|
||||
topMargin: 20
|
||||
}
|
||||
color: root.accent_color
|
||||
font.pixelSize: root.font_normal_text_size
|
||||
}
|
||||
|
||||
|
||||
Text {
|
||||
id: alert_thres_label
|
||||
text: "Alert Percentage: "
|
||||
anchors {
|
||||
topMargin: 20
|
||||
top: min_thres_label.bottom
|
||||
left: parent.left
|
||||
}
|
||||
height: alert_thres_input.height
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: root.accent_color
|
||||
font.pixelSize: root.font_normal_text_size
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: alert_thres_input
|
||||
text: config.alert
|
||||
anchors {
|
||||
left: alert_thres_label.right
|
||||
leftMargin: 5
|
||||
top: min_thres_label.bottom
|
||||
topMargin: 20
|
||||
}
|
||||
color: root.accent_color
|
||||
font.pixelSize: root.font_normal_text_size
|
||||
}
|
||||
|
||||
Text {
|
||||
id: settings_error_label
|
||||
property string settings_error_text: ""
|
||||
text: "Error: " + settings_error_text
|
||||
visible: settings_error_text === "" ? false : true
|
||||
anchors {
|
||||
topMargin: 20
|
||||
top: alert_thres_label.bottom
|
||||
left: parent.left
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: root.danger_color
|
||||
font.pixelSize: root.font_normal_text_size
|
||||
}
|
||||
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: save_config
|
||||
anchors {
|
||||
topMargin: 10
|
||||
bottom: parent.bottom
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
color: "#F0121212"
|
||||
width: parent.width / 2.5
|
||||
height: 60
|
||||
border {
|
||||
width: 1
|
||||
color: root.accent_color
|
||||
}
|
||||
radius: 3
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "Save"
|
||||
color: root.accent_color
|
||||
font.pointSize: root.font_enlarged_text_size
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
property color settings_rect_pressed_prev: "#00000000"
|
||||
property color settings_rect_entered_prev: "#00000000"
|
||||
onEntered: {
|
||||
settings_rect_entered_prev = save_config.color
|
||||
save_config.color = "#5A1F1F1F"
|
||||
}
|
||||
onExited: {
|
||||
save_config.color = settings_rect_entered_prev
|
||||
}
|
||||
onPressed: {
|
||||
settings_rect_pressed_prev = save_config.color
|
||||
save_config.color = "#5A1F4F1F"
|
||||
let max = parseFloat(min_thres_input.text);
|
||||
let min = parseFloat(min_thres_input.text);
|
||||
let alert = parseFloat(alert_thres_input.text);
|
||||
console.log("Parsed values:", max, min, alert);
|
||||
if(max < min) {
|
||||
settings_error_label.settings_error_text = "Max cannot be less than min";
|
||||
return;
|
||||
}
|
||||
if (alert > 100 || alert < 0) {
|
||||
settings_error_label.settings_error_text = "Alert must be between 0 to 100";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let current_min_reading = Math.max(0, (parseFloat(min_thres_input.text)));
|
||||
let effective_max_reading = Math.max(0, (parseFloat(max_thres_input.text)) - current_min_reading);
|
||||
let alert_effective_reading = (effective_max_reading * (100 - alert) / 100) + current_min_reading;
|
||||
console.log("Alert effective reading is: " + alert_effective_reading + " for value: " + alert);
|
||||
listener.setAlert(alert_effective_reading);
|
||||
config.saveConfig(max_thres_input.text, min_thres_input.text, alert_thres_input.text);
|
||||
settings_popup.close();
|
||||
}
|
||||
onReleased: {
|
||||
save_config.color = settings_rect_pressed_prev
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: tank_lid
|
||||
color: "#F0121212"
|
||||
anchors {
|
||||
bottom: tank_base.top
|
||||
horizontalCenter: tank_base.horizontalCenter
|
||||
bottomMargin: -5
|
||||
}
|
||||
radius: 10
|
||||
width: parent.width / 4
|
||||
height: parent.height / 15
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: tank_base
|
||||
color: "#0FFFFFFF"
|
||||
anchors.centerIn: parent
|
||||
width: parent.width / 2.5
|
||||
height: parent.height / 2
|
||||
border.color: "#F0121212"
|
||||
border.width: 5
|
||||
radius: 4
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: water_level
|
||||
color: root.water_color
|
||||
property double height_max: tank_base.height - 10
|
||||
property double current_level: 0
|
||||
property double percentage_filled: 0
|
||||
height: water_level.current_level
|
||||
width: tank_base.width - 10
|
||||
anchors {
|
||||
bottom: tank_base.bottom
|
||||
horizontalCenter: tank_base.horizontalCenter
|
||||
bottomMargin: 5
|
||||
}
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
Behavior on height {
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: info_text
|
||||
text: "Current Reading: " + root.distance.toFixed(2) + " cm"
|
||||
anchors {
|
||||
top: tank_base.bottom
|
||||
topMargin: 20
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: root.accent_color
|
||||
font.pixelSize: root.font_normal_text_size
|
||||
}
|
||||
|
||||
Text {
|
||||
id: info_percent_text
|
||||
text: "Percentage filled: " + water_level.percentage_filled.toFixed(2) + " %"
|
||||
anchors {
|
||||
top: info_text.bottom
|
||||
topMargin: 10
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: root.accent_color
|
||||
font.pixelSize: root.font_normal_text_size
|
||||
}
|
||||
|
||||
Text {
|
||||
id: error_text
|
||||
property string error_string: ""
|
||||
text: "Error: " + error_string
|
||||
visible: error_string === "" ? false : true;
|
||||
anchors {
|
||||
top: info_percent_text.bottom
|
||||
topMargin: 10
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: root.danger_color
|
||||
font.pixelSize: root.font_normal_text_size
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Timer {
|
||||
id: status_indicator_timer
|
||||
running: false
|
||||
repeat: false
|
||||
triggeredOnStart: false
|
||||
interval: 300
|
||||
onTriggered: {
|
||||
status_indicator.color = status_indicator.old_color;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigInterface {
|
||||
id: config
|
||||
onConfigData: (max, min, alert) => {
|
||||
console.log("Got config data as: ", max, min, alert);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UDPListener {
|
||||
id: listener
|
||||
|
||||
onShowError: (err) => {
|
||||
error_text.error_string = err;
|
||||
}
|
||||
|
||||
onDistanceChanged: {
|
||||
console.log("Distance changed");
|
||||
root.distance = listener.distance;
|
||||
error_text.error_string = "";
|
||||
console.log("Distance count: ", root.distance_count);
|
||||
if(root.distance_count >= 5) {
|
||||
status_label.text = "Recieving values";
|
||||
let current_min_reading = Math.max(0, (parseFloat(min_thres_input.text)));
|
||||
let effective_max_reading = Math.max(0, (parseFloat(max_thres_input.text)) - current_min_reading);
|
||||
let current_reading = Math.max(0, root.distance - current_min_reading);
|
||||
let height_max_possible = water_level.height_max;
|
||||
let percentage_filled = Math.max(0, ((effective_max_reading - current_reading) / effective_max_reading * 100))
|
||||
let normalized_height = percentage_filled * height_max_possible / 100;
|
||||
let alert = parseFloat(alert_thres_input.text);
|
||||
if(percentage_filled <= alert) {
|
||||
console.log("Water Level is lower than alert");
|
||||
water_level.color = root.danger_color;
|
||||
}
|
||||
else {
|
||||
water_level.color = root.water_color;
|
||||
}
|
||||
|
||||
console.log("Current reading is: " + current_reading)
|
||||
console.log("Normalized height is: " + normalized_height)
|
||||
water_level.current_level = normalized_height;
|
||||
water_level.percentage_filled = percentage_filled;
|
||||
}
|
||||
}
|
||||
onConnected: {
|
||||
error_text.error_string = "";
|
||||
console.log("Connected");
|
||||
status_indicator.color = "#F05F5F0F"
|
||||
status_label.text = "Waiting for more values";
|
||||
|
||||
}
|
||||
onDisconnected: {
|
||||
error_text.error_string = "Disconnected";
|
||||
console.log("Disconnected");
|
||||
status_indicator.color = "#F05F5F0F"
|
||||
status_label.text = "Disconnected";
|
||||
}
|
||||
onDistanceReceived: (distance, time) => {
|
||||
if(root.distance_count >= 1)
|
||||
dataBlink();
|
||||
if(root.distance_count == 0) {
|
||||
let current_min_reading = Math.max(0, (parseFloat(min_thres_input.text)));
|
||||
let effective_max_reading = Math.max(0, (parseFloat(max_thres_input.text)) - current_min_reading);
|
||||
let alert = parseFloat(alert_thres_input.text);
|
||||
let alert_effective_reading = (effective_max_reading * (100 - alert) / 100) + current_min_reading;
|
||||
console.log("Alert effective reading is: " + alert_effective_reading + " for value: " + alert);
|
||||
listener.setAlert(alert_effective_reading);
|
||||
}
|
||||
|
||||
distance_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
onClosing:(close)=> {
|
||||
if(Qt.platform.os === "android"){
|
||||
close.accepted = false
|
||||
} else {
|
||||
close.accepted = true
|
||||
}
|
||||
}
|
||||
|
||||
function dataBlink() {
|
||||
let old_color = status_indicator.color;
|
||||
let new_color = "#F04FAF5F";
|
||||
status_indicator.color = new_color;
|
||||
status_indicator.old_color = old_color;
|
||||
status_indicator_timer.start();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue