Added a text to display wifi status.

This commit is contained in:
unrealdragon 2026-09-14 15:31:21 +05:30
commit b8201398e1
10 changed files with 267 additions and 18 deletions

View file

@ -5,38 +5,58 @@ project(WaterLevelRewrite VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
find_package(Qt6 REQUIRED COMPONENTS Quick Multimedia) find_package(Qt6 REQUIRED COMPONENTS Gui Core Quick Multimedia)
qt_standard_project_setup(REQUIRES 6.10) qt_standard_project_setup(REQUIRES 6.10)
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/importedcontent/CMakeLists.txt")
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/importedcontent)
endif()
qt_add_executable(appWaterLevelRewrite qt_add_executable(appWaterLevelRewrite
main.cpp main.cpp
media.qrc
) )
qt_add_qml_module(appWaterLevelRewrite qt_add_qml_module(appWaterLevelRewrite
URI WaterLevelRewrite URI WaterLevelRewrite
QML_FILES QML_FILES
Main.qml Main.qml
QML_FILES WaterTank.qml WaterTank.qml
QML_FILES SettingsBarIcon.qml SettingsBarIcon.qml
QML_FILES SettingsPopup.qml SettingsPopup.qml
SOURCES configinterface.h configinterface.cpp ConnectButton.qml
QML_FILES ConnectButton.qml SOURCES
SOURCES requestworker.h requestworker.cpp configinterface.h
RESOURCES media.qrc configinterface.cpp
requestworker.h
requestworker.cpp
wifihelper.h
wifihelper.cpp
RESOURCES
media.qrc
) )
set_target_properties(appWaterLevelRewrite PROPERTIES if(APPLE)
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appWaterLevelRewrite set_target_properties(appWaterLevelRewrite PROPERTIES
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appWaterLevelRewrite
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE MACOSX_BUNDLE TRUE
)
endif()
if(WIN32)
set_target_properties(appWaterLevelRewrite PROPERTIES
WIN32_EXECUTABLE TRUE WIN32_EXECUTABLE TRUE
)
endif()
set_target_properties(appWaterLevelRewrite PROPERTIES
QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android"
) )
target_link_libraries(appWaterLevelRewrite target_link_libraries(appWaterLevelRewrite
PRIVATE Qt6::Quick Qt6::Multimedia PRIVATE Qt6::Quick Qt6::Multimedia Qt6::Gui Qt6::Core
) )
install(TARGETS appWaterLevelRewrite install(TARGETS appWaterLevelRewrite

View file

@ -14,6 +14,7 @@ Window {
property color dark_accent_color: "#FF5F7F5F" property color dark_accent_color: "#FF5F7F5F"
property color danger_color: "#F0AF2F1F" property color danger_color: "#F0AF2F1F"
property color water_color: "#F00F7FAF" property color water_color: "#F00F7FAF"
property color water_color_above_alert: "#F00FAF0F"
property color background_color: "#1F1F1F" property color background_color: "#1F1F1F"
Material.accent: root.accent_color Material.accent: root.accent_color
property int font_enlarged_text_size: 20 property int font_enlarged_text_size: 20
@ -21,6 +22,7 @@ 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 connection_text_string: "Reading WiFi Status..."
property string alarm_status_text: "" property string alarm_status_text: ""
property var root_config: ({}) property var root_config: ({})
@ -73,6 +75,19 @@ Window {
} }
} }
Text {
id: connection_text
anchors {
top: top_bar.bottom
topMargin: 20
bottom: tank.top
horizontalCenter: parent.horizontalCenter
}
text: root.connection_text_string
color: root.accent_color
font.pointSize: root.font_normal_text_size
}
WaterTank { WaterTank {
id: tank id: tank
anchors { anchors {
@ -207,6 +222,16 @@ Window {
onRequestFailed: () => { onRequestFailed: () => {
status.color = root.danger_color; status.color = root.danger_color;
} }
onConnectionText: (text, error) => {
root.connection_text_string = text
if(!error) {
connection_text.color = root.accent_color
}
else {
connection_text.color = root.danger_color
}
}
} }
ConfigInterface { ConfigInterface {

View file

@ -107,7 +107,7 @@ Popup {
Text { Text {
id: alert_thres_label id: alert_thres_label
text: "Alert Percentage: " text: "Alert Threshold: "
anchors { anchors {
topMargin: 20 topMargin: 20
top: min_thres_label.bottom top: min_thres_label.bottom

View file

@ -9,6 +9,7 @@ Item {
property color tank_lid_color: "#F0121212" property color tank_lid_color: "#F0121212"
property color tank_base_color: "#00FFFFFF" property color tank_base_color: "#00FFFFFF"
property color water_level_color: "#F00F7FAF" property color water_level_color: "#F00F7FAF"
property color water_color_above_alert: "#F00FAF0F"
property color tank_base_border_color: "#F0121212" property color tank_base_border_color: "#F0121212"
property color text_color: "#F05FAF5F" property color text_color: "#F05FAF5F"
property double height_max: tank_base.height - 10 property double height_max: tank_base.height - 10
@ -19,6 +20,7 @@ Item {
property double max_thres_input: 0 property double max_thres_input: 0
property double rate_of_fill: 0 property double rate_of_fill: 0
property double expected_to_fill: 0 property double expected_to_fill: 0
property double alert_threshold: 0
Rectangle { Rectangle {
id: base id: base
@ -137,6 +139,7 @@ Item {
function setConfig(config: var) { function setConfig(config: var) {
min_thres_input = config.min; min_thres_input = config.min;
max_thres_input = config.max; max_thres_input = config.max;
alert_threshold = config.alert;
} }
function setDistance(distance) { function setDistance(distance) {
@ -156,8 +159,17 @@ Item {
console.log("Current reading is: " + current_reading) console.log("Current reading is: " + current_reading)
console.log("Normalized height is: " + normalized_height) console.log("Normalized height is: " + normalized_height)
console.log("Percentage filled is: " + percentage_filled) 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.current_level = normalized_height;
root.percentage_filled = percentage_filled; 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
}
} }
} }

View file

@ -0,0 +1,61 @@
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.qtproject.example.appWaterLevelRewrite"
android:installLocation="auto"
android:versionCode="1"
android:versionName="1.0">
<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.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"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true" />
<application
android:name="org.qtproject.qt.android.bindings.QtApplication"
android:hardwareAccelerated="true"
android:label="appWaterLevelRewrite"
android:requestLegacyExternalStorage="true"
android:enableOnBackInvokedCallback="false"
android:allowBackup="true"
android:fullBackupOnly="false">
<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="appWaterLevelRewrite"
android:launchMode="singleTop"
android:screenOrientation="unspecified"
android:exported="true">
<intent-filter>
<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="appWaterLevelRewrite" />
<meta-data
android:name="android.app.arguments"
android:value="" />
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.qtprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/qtprovider_paths"/>
</provider>
</application>
</manifest>

View file

@ -4,7 +4,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
qputenv("QT_SCALE_FACTOR", "1.0"); qputenv("QT_SCALE_FACTOR", "1.0");
qputenv("QT_SCALE_FACTOR_ROUNDING_POLICY", "Round");qputenv("QT_SCALE_FACTOR_ROUNDING_POLICY", "Round"); qputenv("QT_SCALE_FACTOR_ROUNDING_POLICY", "Round");
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);

View file

@ -8,7 +8,16 @@
RequestWorker::RequestWorker(QObject *parent) RequestWorker::RequestWorker(QObject *parent)
: QObject{parent} : QObject{parent}
{ {
#ifdef Q_OS_ANDROID
wifi = new WiFiHelper(this);
connect(wifi, &WiFiHelper::ssidRetrieved, this, &RequestWorker::gotWiFiSSID);
poll_wifi = new QTimer(this);
poll_wifi->setInterval(3000);
poll_wifi->setSingleShot(false);
connect(poll_wifi, &QTimer::timeout, this, &RequestWorker::pollWiFi);
wifi->requestPermissionsAndFetch();
poll_wifi->start();
#endif
} }
void RequestWorker::setConfig(QJsonObject config) void RequestWorker::setConfig(QJsonObject config)
@ -54,6 +63,31 @@ void RequestWorker::stop()
qDebug() << "Stopping" << timer->isActive(); qDebug() << "Stopping" << timer->isActive();
} }
void RequestWorker::pollWiFi()
{
#ifdef Q_OS_ANDROID
if(wifi) {
wifi->requestPermissionsAndFetch();
}
#endif
}
void RequestWorker::gotWiFiSSID(QString ssid)
{
if(ssid.length() > 0 && ssid != "Permission Denied" && ssid != "<unknown ssid>") {
emit connectionText("WiFi connected: " + ssid);
}
else if(ssid.length() == 0) {
emit connectionText("WiFi might not be connected", true);
}
else if(ssid != "<unknown ssid>") {
emit connectionText("Failed to query wifi info", true);
}
else {
emit connectionText("WiFi disconnected", true);
}
}
void RequestWorker::playAlarm() void RequestWorker::playAlarm()
{ {
if(player_started) if(player_started)

View file

@ -11,6 +11,9 @@
#include <QTimer> #include <QTimer>
#include <QThread> #include <QThread>
#include <chrono> #include <chrono>
#ifdef Q_OS_ANDROID
#include "wifihelper.h"
#endif
class RequestWorker : public QObject class RequestWorker : public QObject
{ {
@ -31,6 +34,10 @@ class RequestWorker : public QObject
bool player_started = false; bool player_started = false;
QMediaPlayer *player = nullptr; QMediaPlayer *player = nullptr;
QAudioOutput *audioOutput = nullptr; QAudioOutput *audioOutput = nullptr;
#ifdef Q_OS_ANDROID
WiFiHelper *wifi = nullptr;
QTimer *poll_wifi = nullptr;
#endif
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);
@ -42,6 +49,7 @@ signals:
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(); void playMedia();
void connectionText(QString text, bool errored = false);
public slots: public slots:
void startAlarm(); void startAlarm();
void stopAlarm(); void stopAlarm();
@ -49,6 +57,8 @@ public slots:
void start(); void start();
void stop(); void stop();
private slots: private slots:
void pollWiFi();
void gotWiFiSSID(QString ssid);
void playAlarm(); void playAlarm();
void makeRequest(); void makeRequest();
void requestFinished(QNetworkReply *rep); void requestFinished(QNetworkReply *rep);

70
wifihelper.cpp Normal file
View file

@ -0,0 +1,70 @@
#include "wifihelper.h"
#include <QCoreApplication>
#include <QGuiApplication>
#include <QJniObject>
#include <QPermissions>
WiFiHelper::WiFiHelper(QObject *parent)
: QObject{parent}
{
}
QString WiFiHelper::getWifiSsid() {
// Get Android application context in Qt 6
QJniObject context = QNativeInterface::QAndroidApplication::context();
if (!context.isValid()) return QString();
// Get WifiManager service
QJniObject wifiService = QJniObject::fromString("wifi");
QJniObject wifiManager = context.callObjectMethod(
"getSystemService",
"(Ljava/lang/String;)Ljava/lang/Object;",
wifiService.object()
);
if (!wifiManager.isValid()) return QString();
// Fetch WifiInfo
QJniObject wifiInfo = wifiManager.callObjectMethod(
"getConnectionInfo",
"()Landroid/net/wifi/WifiInfo;"
);
if (!wifiInfo.isValid()) return QString();
// Get SSID string
QJniObject ssidJni = wifiInfo.callObjectMethod(
"getSSID",
"()Ljava/lang/String;"
);
if (!ssidJni.isValid()) return QString();
QString ssid = ssidJni.toString();
// Android returns SSIDs wrapped in double quotes (e.g., "\"MyWiFi\"")
if (ssid.startsWith('"') && ssid.endsWith('"') && ssid.length() > 1) {
ssid = ssid.mid(1, ssid.length() - 2);
}
return ssid;
}
void WiFiHelper::requestPermissionsAndFetch() {
QLocationPermission locationPermission;
locationPermission.setAccuracy(QLocationPermission::Accuracy::Precise);
Qt::PermissionStatus status = qApp->checkPermission(locationPermission);
if (status == Qt::PermissionStatus::Granted) {
emit ssidRetrieved(getWifiSsid());
} else {
qDebug() << "Requesting permission.";
qApp->requestPermission(locationPermission, this, [this](const QPermission &permission) {
if (permission.status() == Qt::PermissionStatus::Granted) {
qDebug() << "Requested permission and got ssid";
emit ssidRetrieved(getWifiSsid());
} else {
qDebug() << "Failed to get WiFi SSID due to denied permission.";
emit ssidRetrieved("Permission Denied");
}
});
}
}

17
wifihelper.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef WIFIHELPER_H
#define WIFIHELPER_H
#include <QObject>
class WiFiHelper : public QObject
{
Q_OBJECT
public:
explicit WiFiHelper(QObject *parent = nullptr);
Q_INVOKABLE QString getWifiSsid();
Q_INVOKABLE void requestPermissionsAndFetch();
signals:
void ssidRetrieved(const QString &ssid);
};
#endif // WIFIHELPER_H