summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2026-01-16 21:49:22 +0100
committerxengineering <me@xengineering.eu>2026-01-17 20:56:45 +0100
commit1dc47d1991910d95b4472ed3e415adb0d46a6617 (patch)
treef7dba1ec72756d8460a770d3fe655872d32599dd
parente2a1b271e2cf417cd3104e6e0679cb54993e6d8f (diff)
downloadsia-app-1dc47d1991910d95b4472ed3e415adb0d46a6617.tar
sia-app-1dc47d1991910d95b4472ed3e415adb0d46a6617.tar.zst
sia-app-1dc47d1991910d95b4472ed3e415adb0d46a6617.zip
Display MQTT connection status
The user otherwise cannot trust the state of the contacts because the app could just be disconnected from the broker.
-rw-r--r--lib/data.dart12
-rw-r--r--lib/ui.dart30
2 files changed, 40 insertions, 2 deletions
diff --git a/lib/data.dart b/lib/data.dart
index 08f8881..f5a24e8 100644
--- a/lib/data.dart
+++ b/lib/data.dart
@@ -10,8 +10,9 @@ const String topicPrefix = 'sia';
class AppState with ChangeNotifier {
Map<String, bool> contacts = <String, bool>{};
-
late final MqttServerClient _client;
+ bool _brokerConnected = false;
+ bool get brokerConnected => _brokerConnected;
AppState() {
_initMqtt();
@@ -31,9 +32,11 @@ class AppState with ChangeNotifier {
_client.port = brokerPort;
_client.keepAlivePeriod = 2;
+ _client.disconnectOnNoResponsePeriod = 1;
_client.logging(on: false);
_client.onConnected = _onConnected;
+ _client.onDisconnected = _onDisconnected;
try {
await _client.connect();
@@ -47,6 +50,13 @@ class AppState with ChangeNotifier {
void _onConnected() {
_client.subscribe('$topicPrefix/contact/+/state', MqttQos.exactlyOnce);
+ _brokerConnected = true;
+ notifyListeners();
+ }
+
+ void _onDisconnected() {
+ _brokerConnected = false;
+ notifyListeners();
}
void _onMessage(List<MqttReceivedMessage<MqttMessage>> messages) {
diff --git a/lib/ui.dart b/lib/ui.dart
index ff8c3a8..38ace9a 100644
--- a/lib/ui.dart
+++ b/lib/ui.dart
@@ -11,7 +11,12 @@ class UI extends StatelessWidget {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Contacts")),
- body: const ContactList(),
+ body: const Column(
+ children: <Widget>[
+ Expanded(child: ContactList()),
+ ],
+ ),
+ bottomNavigationBar: const ConnectionStatus(),
),
);
}
@@ -43,3 +48,26 @@ class ContactList extends StatelessWidget {
);
}
}
+
+class ConnectionStatus extends StatelessWidget {
+ const ConnectionStatus({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Consumer<AppState>(
+ builder: (BuildContext context, AppState state, Widget? child) {
+ Icon icon;
+ Text text;
+ if (state.brokerConnected) {
+ icon = const Icon(Icons.cloud, color: Colors.green);
+ text = const Text('Connected');
+ } else {
+ icon = const Icon(Icons.cloud_off, color: Colors.red);
+ text = const Text('Disconnected');
+ }
+
+ return ListTile(leading: icon, title: text);
+ },
+ );
+ }
+}