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 contacts = {}; late final MqttServerClient _client; bool _brokerConnected = false; bool get brokerConnected => _brokerConnected; AppState() { _initMqtt(); } @override void dispose() { _client.disconnect(); super.dispose(); } Future _initMqtt() async { _client = MqttServerClient( brokerHostname, 'sia_app_${DateTime.now().millisecondsSinceEpoch}', ); _client.port = brokerPort; _client.keepAlivePeriod = 2; _client.disconnectOnNoResponsePeriod = 1; _client.logging(on: false); _client.onConnected = _onConnected; _client.onDisconnected = _onDisconnected; 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 _onMessage(List> messages) { for (final MqttReceivedMessage message in messages) { final String topic = message.topic; // format /contacts/
/state final List 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; } } }