Compare commits

..
40 changed files with 1851 additions and 2728 deletions

84
.gitignore vendored
View file

@ -1,82 +1,2 @@
# 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*
*.qbs.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
# Directories with generated files
.moc/
.obj/
.pch/
.rcc/
.uic/
/build*/
build/*
.qtcreator/*

View file

@ -1,111 +1,69 @@
cmake_minimum_required(VERSION 3.16)
project(waterLevelSensor VERSION 0.1 LANGUAGES CXX)
project(WaterLevelRewrite VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTORCC ON)
find_package(Qt6 REQUIRED COMPONENTS Quick Network CorePrivate)
find_package(Qt6 REQUIRED COMPONENTS Gui Core Quick Multimedia)
qt_standard_project_setup(REQUIRES 6.11)
qt_add_executable(appwaterLevelSensor
main.cpp
images.qrc
)
if(ANDROID)
include(FetchContent)
FetchContent_Declare(
android_openssl
DOWNLOAD_EXTRACT_TIMESTAMP true
URL https://github.com/KDAB/android_openssl/archive/refs/heads/master.zip
)
FetchContent_MakeAvailable(android_openssl)
include(${android_openssl_SOURCE_DIR}/android_openssl.cmake)
qt_add_library(service SHARED
servicemain.cpp
service.h service.cpp
)
set_property(TARGET appwaterLevelSensor APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/android)
set_property(TARGET service APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/android)
target_link_libraries(service
PRIVATE
Qt::Core
Qt::Network
Qt::CorePrivate
Qt::Quick
)
qt_add_qml_module(appwaterLevelSensor
URI waterLevelSensor
QML_FILES
Main.qml
RESOURCES
RESOURCES images.qrc
SOURCES moving_container.h
SOURCES configinterface.h configinterface.cpp
SOURCES udplistener.h udplistener.cpp
SOURCES service.h
RESOURCES README.md
)
add_android_openssl_libraries(service appwaterLevelSensor)
target_link_libraries(appwaterLevelSensor
PRIVATE Qt6::Quick Qt6::Network service
)
qt_finalize_executable(appwaterLevelSensor)
add_dependencies(appwaterLevelSensor service)
qt_generate_deploy_app_script(
TARGET appwaterLevelSensor
OUTPUT_SCRIPT deploy_script
NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})
qt_standard_project_setup(REQUIRES 6.10)
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/importedcontent/CMakeLists.txt")
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/importedcontent)
endif()
if(NOT ANDROID)
qt_add_qml_module(appwaterLevelSensor
URI waterLevelSensor
qt_add_executable(appWaterLevelRewrite
main.cpp
)
qt_add_qml_module(appWaterLevelRewrite
URI WaterLevelRewrite
QML_FILES
Main.qml
RESOURCES
RESOURCES images.qrc
SOURCES udplistener.h udplistener.cpp
SOURCES moving_container.h
SOURCES configinterface.h configinterface.cpp
WaterTank.qml
SettingsBarIcon.qml
SettingsPopup.qml
ConnectButton.qml
SOURCES
configinterface.h
configinterface.cpp
requestworker.h
requestworker.cpp
wifihelper.h
wifihelper.cpp
RESOURCES
media.qrc
QML_FILES CustomCheckBox.qml
QML_FILES RequestResponsePopup.qml
QML_FILES ColorInput.qml
)
# 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 manu ally though.
set_target_properties(appwaterLevelSensor PROPERTIES
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appwaterLevelSensor
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
if(APPLE)
set_target_properties(appWaterLevelRewrite PROPERTIES
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appWaterLevelRewrite
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
)
endif()
if(WIN32)
set_target_properties(appWaterLevelRewrite PROPERTIES
WIN32_EXECUTABLE TRUE
)
endif()
set_target_properties(appWaterLevelRewrite PROPERTIES
QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android"
)
target_link_libraries(appwaterLevelSensor
PRIVATE Qt6::Quick Qt6::Network
target_link_libraries(appWaterLevelRewrite
PRIVATE Qt6::Quick Qt6::Multimedia Qt6::Gui Qt6::Core
)
qt_finalize_executable(appwaterLevelSensor)
include(GNUInstallDirs)
install(TARGETS appwaterLevelSensor
install(TARGETS appWaterLevelRewrite
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif()

21
ColorInput.qml Normal file
View file

@ -0,0 +1,21 @@
import QtQuick
import QtQuick.Effects
import QtQuick.Controls
import QtQuick.Controls.Material
TextField {
id: color_text
text: "F05FAF5F"
property alias color_text: base.color
Rectangle {
id: base
anchors {
right: parent.right
rightMargin: 10
verticalCenter: parent.verticalCenter
}
width: 10
height: parent.height / 2
color: "#" + color_text.text
}
}

63
ConnectButton.qml Normal file
View file

@ -0,0 +1,63 @@
import QtQuick
import QtQuick.Effects
import QtQuick.Controls
import QtQuick.Controls.Material
Rectangle {
id: root
property color accent_color: "#00000000"
property color font_color: "#00000000"
property int font_enlarged_text_size: 20
property int font_normal_text_size: 16
property string text: "Connect"
property string text2: "Stop"
property int mode: 0
signal connect;
layer.enabled: true
layer.effect: MultiEffect {
shadowEnabled: true
}
Text {
anchors.centerIn: parent
font.pointSize: root.font_enlarged_text_size
color: root.font_color
text: mode ? root.text2 : root.text
horizontalAlignment: Text.AlignHCenter
}
radius: 5
border {
color: root.accent_color
width: 0.5
}
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 = root.color
root.color = "#5A1F1F1F"
}
onExited: {
root.color = settings_rect_entered_prev
}
onPressed: {
settings_rect_pressed_prev = root.color
root.color = "#5A1F4F1F"
root.connect();
switchMode();
}
onReleased: {
root.color = settings_rect_pressed_prev
}
}
function switchMode() {
if(root.mode === 0)
root.mode = 1
else
root.mode = 0;
}
}

17
CustomCheckBox.qml Normal file
View file

@ -0,0 +1,17 @@
import QtQuick
import QtQuick.Controls.Basic
CheckBox {
id: control
property color font_color: "#0000FF00"
property int font_point_size: 22
font.pointSize: font_point_size
checked: true
contentItem: Text {
text: control.text
font: control.font
color: control.font_color
verticalAlignment: Text.AlignVCenter
leftPadding: control.indicator.width + control.spacing
}
}

1022
Main.qml

File diff suppressed because it is too large Load diff

View file

@ -1,14 +0,0 @@
package org.qtproject.example.androidnotifier;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.BitmapFactory;
import android.app.NotificationChannel;
public class NotificationManager {
}

View file

@ -1,17 +0,0 @@
# Water Level Sensor
Builds using QtCreator, use Qt Version 6.9.<br>
Builds for android and desktop.<br>
On Android Creates a service from service.cpp and android/src/org/qtproject/example/appwaterLevelSensor/WaterLevelService.java.<br>
Changes in AndroidManifest.xml are important.<br>
On Desktop just waits for values from a UDP Broadcast on local network with port 8176 and shows those values.<br>
On Android the service does that, and creates an alert notification if the value in broadcast is less than alert threshold.<br>
<br>
Create a new socket in Worker that will instantly start listening.<br>
In the service launch the threads and immediately send client hello to the worker socket.<br>
On client hello send command data to the android service.<br>
On quit send server bye to android service.<br>
On server bye deinit the sockets that send data to cpp server.<br>
On next launch, the command and client threads can be reinitialized from the StartService java class.<br>

30
RequestResponsePopup.qml Normal file
View file

@ -0,0 +1,30 @@
import QtQuick
import QtQuick.Effects
import QtQuick.Controls
import QtQuick.Controls.Material
Popup {
id: request_response_popup
property color accent_color: "#00000000"
property int font_enlarged_text_size: 20
property int font_normal_text_size: 16
property string request_response_string: ""
background: Rectangle {
color: "#F0121212"
radius: 5
border.color: request_response_popup.accent_color
border.width: 1
}
height: Math.max(parent.height / 1.6, contentHeight)
width: parent.width / 1.2
anchors.centerIn: Overlay.overlay
ScrollView {
id: view
anchors.fill: parent
TextArea {
text: request_response_string
font.pointSize: font_normal_text_size
color: request_response_popup.accent_color
}
}
}

49
SettingsBarIcon.qml Normal file
View file

@ -0,0 +1,49 @@
import QtQuick
import QtQuick.Effects
import QtQuick.Controls
import QtQuick.Controls.Material
Rectangle {
id: settings_rect
signal open;
property color accent_color: "#00000000"
property int font_enlarged_text_size: 20
property string text: "⚙"
Behavior on color {
ColorAnimation {
duration: 200
}
}
Text {
id: settings_text
text: settings_rect.text
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: settings_rect.accent_color
font.pointSize: settings_rect.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_rect.open();
}
onReleased: {
settings_rect.color = settings_rect_pressed_prev
}
}
}

594
SettingsPopup.qml Normal file
View file

@ -0,0 +1,594 @@
import QtQuick
import QtQuick.Effects
import QtQuick.Controls
import QtQuick.Controls.Material
Popup {
id: settings_popup
signal saveConfig(config: var)
signal deleteConfig()
property color accent_color: "#00000000"
property int font_enlarged_text_size: 20
property int font_normal_text_size: 16
property color background_color: "#00000000"
property var config: {
"max": 0,
"min": 0,
"alert": 0,
"interval": 0,
"url": "none",
"water_tank_width": 2,
"water_tank_height": 1.3,
"rate_of_fill_enable": true,
"current_reading_enable": true,
"percentage_enable": true,
"filling_status_enable": true,
"expected_to_fill_enable": true,
"accent_color": "F05FAF5F",
"dark_accent_color": "FF5F7F5F",
"danger_color": "F0AF2F1F",
"water_color": "F00F7FAF",
"water_color_above_alert": "F00FAF0F",
"background_color": "1F1F1F",
"font_normal_text_size": 16,
"font_enlarged_text_size": 20
}
background: Rectangle {
color: "#F0121212"
radius: 5
border.color: settings_popup.accent_color
border.width: 1
}
height: Math.max(parent.height / 1.6, contentHeight)
width: parent.width / 1.2
anchors.centerIn: Overlay.overlay
Rectangle {
id: settings_base
anchors.fill: parent
color: "#F0121212"
ScrollView {
id: rect_base_scroll_view
anchors {
top: parent.top
horizontalCenter: parent.horizontalCenter
bottom: save_config.top
bottomMargin: 10
}
width: parent.width
clip: true
// Use contentWidth and contentHeight to define the scrollable area
contentWidth: availableWidth
contentHeight: settings_column.height
Column {
id: settings_column
width: rect_base_scroll_view.width
spacing: 20
Text {
id: settings_label
text: "Settings"
width: parent.width
horizontalAlignment: Text.AlignHCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_enlarged_text_size
}
// Max Threshold
Row {
width: parent.width
spacing: 10
Text {
text: "Max Threshold: "
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: max_thres_input.verticalCenter
}
}
TextField {
id: max_thres_input
text: config.max
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
}
}
// Min Threshold
Row {
width: parent.width
spacing: 10
Text {
text: "Min Threshold: "
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: min_thres_input.verticalCenter
}
}
TextField {
id: min_thres_input
text: config.min
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
}
}
// Alert Threshold
Row {
width: parent.width
spacing: 10
Text {
text: "Alert Threshold: "
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: alert_thres_input.verticalCenter
}
}
TextField {
id: alert_thres_input
text: config.alert
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
}
}
// Update Interval
Row {
width: parent.width
spacing: 10
Text {
text: "Update Interval: "
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: interval_input.verticalCenter
}
}
TextField {
id: interval_input
text: config.interval
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
}
}
// URL
Row {
width: parent.width
spacing: 10
Text {
text: "Url: "
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: http_url_input.verticalCenter
}
}
TextField {
id: http_url_input
text: config.url
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
cursorPosition: 0
}
}
// Tank Image Width
Row {
width: parent.width
spacing: 10
Text {
text: "Tank Image Width"
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: water_tank_width_input.verticalCenter
}
}
TextField {
id: water_tank_width_input
text: String(config.water_tank_width)
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
cursorPosition: 0
}
}
// Tank Image Height
Row {
width: parent.width
spacing: 10
Text {
text: "Tank Image Height"
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: water_tank_height_input.verticalCenter
}
}
TextField {
id: water_tank_height_input
text: String(config.water_tank_height)
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
cursorPosition: 0
}
}
// Accent Color
Row {
width: parent.width
spacing: 10
Text {
text: "Accent Color"
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: accent_color_input.verticalCenter
}
}
ColorInput {
id: accent_color_input
text: config.accent_color
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
}
}
// Dark Accent Color
Row {
width: parent.width
spacing: 10
Text {
text: "Dark Accent Color"
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: dark_accent_color_input.verticalCenter
}
}
ColorInput {
id: dark_accent_color_input
text: config.dark_accent_color
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
}
}
// Danger Color
Row {
width: parent.width
spacing: 10
Text {
text: "Danger Text Color"
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: danger_color_input.verticalCenter
}
}
ColorInput {
id: danger_color_input
text: config.danger_color
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
}
}
// Water Color
Row {
width: parent.width
spacing: 10
Text {
text: "Water Color"
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: water_color_input.verticalCenter
}
}
ColorInput {
id: water_color_input
text: config.water_color
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
}
}
// Alert Water Color
Row {
width: parent.width
spacing: 10
Text {
text: "Alert Water Color"
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: water_color_above_alert_input.verticalCenter
}
}
ColorInput {
id: water_color_above_alert_input
text: config.water_color_above_alert
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
}
}
// Background Color
Row {
width: parent.width
spacing: 10
Text {
text: "Backgound Color"
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: background_color_input.verticalCenter
}
}
ColorInput {
id: background_color_input
text: config.background_color
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
}
}
// Normal Font Size
Row {
width: parent.width
spacing: 10
Text {
text: "Font Size"
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: font_normal_text_size_input.verticalCenter
}
}
TextField {
id: font_normal_text_size_input
text: String(config.font_normal_text_size)
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
cursorPosition: 0
}
}
// Header Font Size
Row {
width: parent.width
spacing: 10
Text {
text: "Header Font Size"
width: parent.width * 0.4
verticalAlignment: Text.AlignVCenter
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
anchors {
verticalCenter: font_enlarged_text_size_input.verticalCenter
}
}
TextField {
id: font_enlarged_text_size_input
text: String(config.font_enlarged_text_size)
width: parent.width * 0.55
color: settings_popup.accent_color
font.pointSize: settings_popup.font_normal_text_size
cursorPosition: 0
}
}
// CheckBox
CustomCheckBox {
id: current_reading_enable
checked: config.current_reading_enable
font_color: settings_popup.accent_color
font_point_size: settings_popup.font_normal_text_size
text: "Enable Current Reading"
leftPadding: 0
}
// CheckBox
CustomCheckBox {
id: percentage_enable
checked: config.percentage_enable
font_color: settings_popup.accent_color
font_point_size: settings_popup.font_normal_text_size
text: "Enable Percentage Reading"
leftPadding: 0
}
// CheckBox
CustomCheckBox {
id: filling_status_enable
checked: config.filling_status_enable
font_color: settings_popup.accent_color
font_point_size: settings_popup.font_normal_text_size
text: "Enable Filling Status"
leftPadding: 0
}
// CheckBox
CustomCheckBox {
id: rate_of_fill_enable
checked: config.rate_of_fill_enable
font_color: settings_popup.accent_color
font_point_size: settings_popup.font_normal_text_size
text: "Enable Text Rate of Fill"
leftPadding: 0
}
// CheckBox
CustomCheckBox {
id: expected_to_fill_enable
checked: config.expected_to_fill_enable
font_color: settings_popup.accent_color
font_point_size: settings_popup.font_normal_text_size
text: "Enable Expected to fill"
leftPadding: 0
}
ConnectButton {
id: delete_config_button
width: parent.width / 1.5
height: 80
anchors {
horizontalCenter: parent.horizontalCenter
}
font_color: settings_popup.accent_color
font_enlarged_text_size: settings_popup.font_enlarged_text_size
font_normal_text_size: settings_popup.font_normal_text_size
color: settings_popup.background_color
accent_color: settings_popup.accent_color
text: "Delete/Reset Config"
text2: text
onConnect: {
settings_popup.deleteConfig();
}
}
}
}
Rectangle {
id: save_config
anchors {
topMargin: 10
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
}
color: "#F0121212"
width: parent.width / 1.3
height: 60
border {
width: 1
color: settings_popup.accent_color
}
radius: 3
Text {
anchors.centerIn: parent
text: "Save"
color: settings_popup.accent_color
font.pointSize: settings_popup.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(max_thres_input.text);
let min = parseFloat(min_thres_input.text);
let alert = parseFloat(alert_thres_input.text);
let url = http_url_input.text;
let interval = parseInt(interval_input.text);
let image_width = parseFloat(water_tank_width_input.text);
let image_height = parseFloat(water_tank_height_input.text);
let current_reading = current_reading_enable.checked;
let percentage_reading = percentage_enable.checked
let filling_status = filling_status_enable.checked;
let rate_of_fill = rate_of_fill_enable.checked;
let expected_to_fill = expected_to_fill_enable.checked;
let normal_font_size = parseInt(font_normal_text_size_input.text);
let enlarged_font_size = parseInt(font_enlarged_text_size_input.text);
let accent_color = accent_color_input.text;
let dark_accent_color = dark_accent_color_input.text;
let danger_color = danger_color_input.text;
let water_color = water_color_input.text;
let water_color_above_alert = water_color_above_alert_input.text;
let background_color = background_color_input.text;
var new_config = {"max": max, "min": min, "alert": alert, "url": url,
"interval": interval,
"water_tank_height": image_height,
"water_tank_width": image_width,
"current_reading_enable": current_reading,
"percentage_enable": percentage_reading,
"filling_status_enable": filling_status,
"rate_of_fill_enable": rate_of_fill,
"expected_to_fill_enable": expected_to_fill,
"font_normal_text_size": normal_font_size,
"font_enlarged_text_size": enlarged_font_size,
"accent_color": accent_color,
"dark_accent_color": dark_accent_color,
"danger_color": danger_color,
"water_color": water_color,
"water_color_above_alert": water_color_above_alert,
"background_color": background_color
}
settings_popup.saveConfig(new_config)
settings_popup.close();
}
onReleased: {
save_config.color = settings_rect_pressed_prev
}
}
}
}
}

204
WaterTank.qml Normal file
View file

@ -0,0 +1,204 @@
import QtQuick
import QtQuick.Effects
import QtQuick.Controls
import QtQuick.Controls.Material
Item {
id: root
property color base_color: "#000F0F0F"
property color tank_lid_color: "#F0121212"
property color tank_base_color: "#00FFFFFF"
property color water_level_color: "#F00F7FAF"
property color water_color_above_alert: "#F00FAF0F"
property color tank_base_border_color: "#F0121212"
property color text_color: "#F05FAF5F"
property double height_max: tank_base.height - 10
property int font_normal_text_size: 0
property int font_enlarged_text_size: 0
property double current_level: 0
property double percentage_filled: 0
property int distance: 0
property double min_thres_input: 0
property double max_thres_input: 0
property double rate_of_fill: 0
property double expected_to_fill: 0
property double alert_threshold: 0
property bool enable_current_reading: true
property bool enable_percentage_reading: true
property bool enable_filling_status: true
property bool enable_rate_of_fill: true
property bool enable_expected_to_fill: true
Rectangle {
id: base
color: root.base_color
anchors.fill: parent
Rectangle {
id: tank_lid
color: root.tank_lid_color
anchors {
top: parent.top
horizontalCenter: tank_base.horizontalCenter
bottomMargin: -5
}
radius: 10
width: tank_base.width / 3
height: tank_base.height / 15
}
Rectangle {
id: tank_base
color: root.tank_base_color
anchors {
top: tank_lid.bottom
horizontalCenter: parent.horizontalCenter
}
width: parent.width
height: parent.height * 0.55
border.color: root.tank_base_border_color
border.width: 5
radius: 4
}
Rectangle {
id: water_level
color: root.water_level_color
height: root.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
}
}
}
ScrollView {
id: rect_base_scroll_view
anchors {
margins: 5
top: tank_base.bottom
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
}
width: parent.width
contentWidth: parent.width
contentHeight: settings_column.implicitHeight
Column {
id: settings_column
spacing: 10
width: rect_base_scroll_view.width
Text {
id: water_level_reading
text: "Current Reading: " + (root.distance / 10)+ " cm"
font.pointSize: root.font_normal_text_size
color: root.text_color
visible: enable_current_reading
anchors {
horizontalCenter: parent.horizontalCenter
}
horizontalAlignment: Text.AlignHCenter
}
Text {
id: water_level_percentage
text: "Percentage: " + root.percentage_filled.toFixed(2) + " %"
font.pointSize: root.font_normal_text_size
visible: enable_percentage_reading
color: root.text_color
anchors {
horizontalCenter: parent.horizontalCenter
}
horizontalAlignment: Text.AlignHCenter
}
Text {
id: fill_status
text: "Filling status: " + (( root.rate_of_fill > 0)? "Filling" : "Discharging")
font.pointSize: root.font_normal_text_size
color: root.text_color
visible: enable_filling_status
anchors {
horizontalCenter: parent.horizontalCenter
}
horizontalAlignment: Text.AlignHCenter
}
Text {
id: rate_of_fill_label
text: "Rate of fill: " + root.rate_of_fill + " cm/s"
font.pointSize: root.font_normal_text_size
color: root.text_color
visible: enable_rate_of_fill
anchors {
horizontalCenter: parent.horizontalCenter
}
horizontalAlignment: Text.AlignHCenter
}
Text {
id: expected_to_fill_label
text: "Expected to fill in: " + root.expected_to_fill + " s"
font.pointSize: root.font_normal_text_size
color: root.text_color
visible: (root.rate_of_fill > 0 && enable_expected_to_fill === true) ? true : false
anchors {
horizontalCenter: parent.horizontalCenter
}
horizontalAlignment: Text.AlignHCenter
}
}
}
}
function setConfig(config: var) {
min_thres_input = config.min;
max_thres_input = config.max;
alert_threshold = config.alert;
enable_current_reading = config.current_reading_enable;
enable_percentage_reading = config.percentage_enable;
enable_filling_status = config.filling_status_enable;
enable_rate_of_fill = config.rate_of_fill_enable;
enable_expected_to_fill = config.expected_to_fill_enable;
}
function setDistance(distance) {
root.distance = distance;
let distance_f = distance / 10;
console.log("Distance changed to: ", distance_f);
let current_min_reading = Math.max(0, min_thres_input);
let effective_max_reading = Math.max(0, max_thres_input) - current_min_reading;
let current_reading = Math.max(0, distance_f - current_min_reading);
console.log("Current reading is: " + current_reading)
console.log("Current min reading is: " + current_min_reading)
console.log("Effective max reading is: " + effective_max_reading)
let height_max_possible = root.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;
console.log("Current reading is: " + current_reading)
console.log("Normalized height is: " + normalized_height)
console.log("Percentage filled is: " + percentage_filled)
console.log("Alert threshold is: " + root.alert_threshold)
console.log("Is level above alert threshold: " + (distance_f <= root.alert_threshold))
root.current_level = normalized_height;
root.percentage_filled = percentage_filled;
if(distance_f <= root.alert_threshold) {
water_level.color = water_color_above_alert
}
else {
water_level.color = water_level_color
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 KiB

View file

@ -1,18 +1,18 @@
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.qtproject.example.appwaterLevelSensor"
package="org.qtproject.example.appWaterLevelRewrite"
android:installLocation="auto"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" />
<supports-screens
android:anyDensity="true"
@ -22,26 +22,15 @@
<application
android:name="org.qtproject.qt.android.bindings.QtApplication"
android:hardwareAccelerated="true"
android:label="appwaterLevelSensor"
android:label="appWaterLevelRewrite"
android:requestLegacyExternalStorage="true"
android:enableOnBackInvokedCallback="false"
android:allowBackup="true"
android:fullBackupOnly="false">
<service android:name=".WaterLevelService"
android:foregroundServiceType="connectedDevice"
android:exported="true"
android:process=":water_service"
android:stopWithTask="false">
<!-- <property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="Monitoring water levels via local network UDP packets for real-time sensor alerts." />-->
<meta-data android:name="android.app.lib_name" android:value="service"/>
<meta-data android:name="android.app.background_running" android:value="true"/>
</service>
<activity
android:name="org.qtproject.qt.android.bindings.QtActivity"
android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
android:label="appwaterLevelSensor"
android:label="appWaterLevelRewrite"
android:launchMode="singleTop"
android:screenOrientation="unspecified"
android:exported="true">
@ -49,9 +38,11 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="appwaterLevelSensor" />
android:value="appWaterLevelRewrite" />
<meta-data
android:name="android.app.arguments"
android:value="" />

View file

@ -1,83 +0,0 @@
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
//noinspection AndroidGradlePluginVersion
classpath 'com.android.tools.build:gradle:8.8.0'
}
}
repositories {
google()
mavenCentral()
}
apply plugin: qtGradlePluginType
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
//noinspection GradleDependency
implementation 'androidx.core:core:1.16.0'
}
android {
/*******************************************************
* The following variables:
* - androidBuildToolsVersion,
* - androidCompileSdkVersion
* - qtAndroidDir - holds the path to qt android files
* needed to build any Qt application
* on Android.
* - qtGradlePluginType - whether to build an app or a library
*
* are defined in gradle.properties file. This file is
* updated by QtCreator and androiddeployqt tools.
* Changing them manually might break the compilation!
*******************************************************/
namespace = androidPackageName
compileSdkVersion androidCompileSdkVersion
buildToolsVersion androidBuildToolsVersion
ndkVersion = androidNdkVersion
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = [qtAndroidDir + '/src', 'src', 'java']
aidl.srcDirs = [qtAndroidDir + '/src', 'src', 'aidl']
res.srcDirs = [qtAndroidDir + '/res', 'res']
resources.srcDirs = ['resources']
renderscript.srcDirs = ['src']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}
tasks.withType(JavaCompile) {
options.incremental = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
abortOnError = false
}
aaptOptions {
// Do not compress Qt binary resources file
noCompress 'rcc'
}
defaultConfig {
resConfig "en"
minSdkVersion qtMinSdkVersion
targetSdkVersion qtTargetSdkVersion
ndk.abiFilters = qtTargetAbiList.split(",")
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Some files were not shown because too many files have changed in this diff Show more