blob: 38fd56491cb95c5758516ae58ad4b9d2861be908 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
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';
class AppState with ChangeNotifier {
Map<String, bool> contacts = <String, bool>{};
late final MqttServerClient _client;
bool _brokerConnected = false;
bool get brokerConnected => _brokerConnected;
AppState() {
_initMqtt();
}
@override
void dispose() {
_client.disconnect();
super.dispose();
}
Future<void> _initMqtt() async {
_client = MqttServerClient(
brokerHostname,
'sia_app_${DateTime.now().millisecondsSinceEpoch}',
);
_client.port = brokerPort;
_client.keepAlivePeriod = 2;
_client.autoReconnect = true;
_client.disconnectOnNoResponsePeriod = 1;
_client.logging(on: false);
_client.onConnected = _onConnected;
_client.onDisconnected = _onDisconnected;
_client.onAutoReconnect = _onAutoReconnect;
_client.onAutoReconnected = _onAutoReconnected;
try {
await _client.connect();
} catch (e) {
_client.disconnect();
return;
}
_client.updates?.listen(_onMessage);
}
void _onConnected() {
_client.subscribe('$topicPrefix/contact/+/state', MqttQos.exactlyOnce);
_brokerConnected = true;
notifyListeners();
}
void _onDisconnected() {
_brokerConnected = false;
notifyListeners();
}
void _onAutoReconnect() {
_brokerConnected = false;
notifyListeners();
}
void _onAutoReconnected() {
_brokerConnected = true;
notifyListeners();
}
void _onMessage(List<MqttReceivedMessage<MqttMessage>> messages) {
for (final MqttReceivedMessage<MqttMessage> message in messages) {
final String topic = message.topic;
// format <prefix>/contacts/<address>/state
final List<String> parts = topic.split('/');
if (parts.length != 4 || parts[1] != 'contact' || parts[3] != 'state') {
continue;
}
final String address = parts[2];
final MqttPublishMessage payloadMessage =
message.payload as MqttPublishMessage;
final String payload =
MqttPublishPayload.bytesToStringAsString(payloadMessage.payload.message);
final bool? parsedState = _parseBool(payload);
if (parsedState != null) {
contacts[address] = parsedState;
notifyListeners();
}
}
}
bool? _parseBool(String payload) {
switch (payload.toLowerCase()) {
case 'open':
return true;
case 'closed':
return false;
default:
return null;
}
}
}
|