diff options
Diffstat (limited to 'lib/data.dart')
| -rw-r--r-- | lib/data.dart | 108 |
1 files changed, 83 insertions, 25 deletions
diff --git a/lib/data.dart b/lib/data.dart index 2583d1a..365f5bc 100644 --- a/lib/data.dart +++ b/lib/data.dart @@ -1,23 +1,82 @@ -import 'dart:async'; - import 'package:flutter/foundation.dart'; import 'package:mqtt_client/mqtt_client.dart'; import 'package:mqtt_client/mqtt_server_client.dart'; -const String brokerHostname = 'sia.xengineering.eu'; const int brokerPort = 1883; const String topicPrefix = 'sia'; +enum MachineState { + init, // user does not want connection MQTT not connected + disconnected, // user wants connection but MQTT not (yet) connected + unreachable, // connected to MQTT broker but Sia server not reachable + reachable, // connected to MQTT and Sia server reachable +} + +enum MachineEvent { + connect, // user wants to connect + disconnect, // user does not want an connection anymore + connected, // connection to MQTT broker established + disconnected, // connection to MQTT broker lost + reachable, // Sia server is reachable via MQTT + unreachable, // Sia server not reachable via MQTT +} + class AppState with ChangeNotifier { + static const Map<MachineState, Map<MachineEvent, MachineState>> machine = <MachineState, Map<MachineEvent, MachineState>> { + MachineState.init: <MachineEvent, MachineState> { + MachineEvent.connect: MachineState.disconnected, + }, + MachineState.disconnected: <MachineEvent, MachineState> { + MachineEvent.disconnect: MachineState.init, + MachineEvent.connected: MachineState.unreachable, + }, + MachineState.unreachable: <MachineEvent, MachineState> { + MachineEvent.disconnect: MachineState.init, + MachineEvent.disconnected: MachineState.disconnected, + MachineEvent.reachable: MachineState.reachable, + }, + MachineState.reachable: <MachineEvent, MachineState> { + MachineEvent.disconnect: MachineState.init, + MachineEvent.disconnected: MachineState.disconnected, + MachineEvent.unreachable: MachineState.unreachable, + }, + }; + MachineState state = MachineState.init; + Map<String, bool> contacts = <String, bool>{}; - late final MqttServerClient _client; - bool _brokerConnected = false; - bool get brokerConnected => _brokerConnected; - bool _serverConnected = false; - bool get serverConnected => _serverConnected; + late MqttServerClient _client; + + String fqdn = ''; + + AppState(); - AppState() { - _initMqtt(); + void process(MachineEvent event) { + MachineState lastState = state; + + Map<MachineEvent, MachineState>? transitions = machine[lastState]; + if (transitions == null) { + return; + } + + MachineState? nextState = transitions[event]; + if (nextState == null) { + return; + } + + if (nextState == lastState) { + return; + } + + if (lastState == MachineState.init) { + _initMqtt(); + } + + if (nextState == MachineState.init) { + _deinitMqtt(); + } + + state = nextState; + notifyListeners(); } @override @@ -26,9 +85,9 @@ class AppState with ChangeNotifier { super.dispose(); } - Future<void> _initMqtt() async { + void _initMqtt() { _client = MqttServerClient( - brokerHostname, + fqdn, 'sia_app_${DateTime.now().millisecondsSinceEpoch}', ); @@ -44,7 +103,7 @@ class AppState with ChangeNotifier { _client.onAutoReconnected = _onAutoReconnected; try { - await _client.connect(); + _client.connect(); } catch (e) { _client.disconnect(); return; @@ -53,26 +112,27 @@ class AppState with ChangeNotifier { _client.updates?.listen(_onMessage); } + void _deinitMqtt() { + _client.disconnect(); + } + void _onConnected() { _client.subscribe('$topicPrefix/contact/+/state', MqttQos.exactlyOnce); _client.subscribe('$topicPrefix/server/health', MqttQos.exactlyOnce); - _brokerConnected = true; - notifyListeners(); + + process(MachineEvent.connected); } void _onDisconnected() { - _brokerConnected = false; - notifyListeners(); + process(MachineEvent.disconnected); } void _onAutoReconnect() { - _brokerConnected = false; - notifyListeners(); + process(MachineEvent.disconnected); } void _onAutoReconnected() { - _brokerConnected = true; - notifyListeners(); + process(MachineEvent.connected); } void _onMessage(List<MqttReceivedMessage<MqttMessage>> messages) { @@ -86,13 +146,11 @@ class AppState with ChangeNotifier { if (topic == '$topicPrefix/server/health') { if (payload == 'good') { - _serverConnected = true; - notifyListeners(); + process(MachineEvent.reachable); } if (payload == 'bad') { - _serverConnected = false; - notifyListeners(); + process(MachineEvent.unreachable); } } |
