import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:manager_api/api.dart'; //import 'package:mqtt_client/mqtt_browser_client.dart'; import 'package:mqtt_client/mqtt_client.dart'; import 'package:mqtt_client/mqtt_server_client.dart'; import 'package:tablet_app/Helpers/DeviceInfoHelper.dart'; import 'package:tablet_app/Models/tabletContext.dart'; import 'package:tablet_app/app_context.dart'; import 'DatabaseHelper.dart'; class MQTTHelper { MQTTHelper._privateConstructor(); bool isInstantiated = false; static final MQTTHelper instance = MQTTHelper._privateConstructor(); void onConnected(dynamic appContext) { print('Connected !!!!!!!!!!!! ----------------------------------'); TabletAppContext tabletAppContext = appContext.getContext(); if(kIsWeb) { /*tabletAppContext.clientBrowserMQTT!.updates!.listen((List> c) async { handleMessage(appContext, c); });*/ } else { tabletAppContext.clientMQTT!.updates!.listen((List> c) async { handleMessage(appContext, c); }); } } Future handleMessage(AppContext appContext, List> c) async { TabletAppContext tabletAppContext = appContext.getContext(); final MqttPublishMessage message = c[0].payload as MqttPublishMessage; final payload = MqttPublishPayload.bytesToStringAsString(message.payload.message); print('Received message:$payload from topic: ${c[0].topic}'); var topic = c[0].topic.split('/')[0]; switch(topic) { case "config": print('Get message in topic config = $payload'); var configId = c[0].topic.split('/')[1]; if (configId != null) { // Check if tablet config print("Check if tablet config"); print(tabletAppContext.configuration); if (tabletAppContext.configuration != null) { if (tabletAppContext.configuration!.id == configId) { // refresh config try { PlayerMessageDTO playerMessage = PlayerMessageDTO.fromJson(jsonDecode(payload))!; var isConfigChanged = playerMessage.configChanged != null ? playerMessage.configChanged : false; var isDeleted = playerMessage.isDeleted != null ? playerMessage.isDeleted : false; print(isDeleted); if (isDeleted!) { // Clear all print("isDeleted"); tabletAppContext.configuration = null; appContext.setContext(tabletAppContext); // UPDATE IT LOCALLY (SQLite) await DatabaseHelper.instance.update(tabletAppContext); } else { if (isConfigChanged!) { updateConfig(appContext); } } } catch(e) { print('Error = $e'); } } } } break; case "player": print('Get message in topic player = $payload'); // refresh device info try { PlayerMessageDTO playerMessage = PlayerMessageDTO.fromJson(jsonDecode(payload))!; var isConfigChanged = playerMessage.configChanged != null ? playerMessage.configChanged : false; if (isConfigChanged!) { updateDevice(appContext); } } catch(e) { print('Error = $e'); } break; } } // unconnected void onDisconnected() { print('Disconnected'); } // subscribe to topic succeeded void onSubscribed(String topic) { print('Subscribed topic: $topic'); } // subscribe to topic failed void onSubscribeFail(String topic) { print('Failed to subscribe $topic'); } // unsubscribe succeeded void onUnsubscribed(String topic) { print('Unsubscribed topic: $topic'); } Future connect(dynamic appContext) async { TabletAppContext tabletAppContext = appContext.getContext(); var identifier = kIsWeb ? "Demo Web" : await DeviceInfoHelper.getDeviceDetails(); var hostToTake = tabletAppContext.host; if(tabletAppContext.host!.lastIndexOf(":") > 5) { hostToTake = tabletAppContext.host!.substring(0,tabletAppContext.host!.lastIndexOf(":")); } var message = { "deviceId": tabletAppContext.deviceId != null ? tabletAppContext.deviceId : identifier, "connected": false }; final connMessage = MqttConnectMessage().authenticateAs("user1", "MyMuseum2023!") // TODO ONLINE // 'admin', 'mdlf2021!' .keepAliveFor(60) .withWillTopic('player/status') .withWillMessage(jsonEncode(message)) .withClientIdentifier('tablet_app_'+identifier!) .startClean() .withWillQos(MqttQos.atLeastOnce); if(kIsWeb) { /*tabletAppContext.clientBrowserMQTT = MqttBrowserClient.withPort(hostToTake!.replaceAll('https://api.', ''), 'tablet_app_'+identifier!, 1883); tabletAppContext.clientBrowserMQTT!.logging(on: false); tabletAppContext.clientBrowserMQTT!.keepAlivePeriod = 20; tabletAppContext.clientBrowserMQTT!.onDisconnected = onDisconnected; tabletAppContext.clientBrowserMQTT!.onConnected = () => onConnected(appContext); tabletAppContext.clientBrowserMQTT!.onSubscribed = onSubscribed; tabletAppContext.clientBrowserMQTT!.connectionMessage = connMessage; tabletAppContext.clientBrowserMQTT!.autoReconnect = true; try { await tabletAppContext.clientBrowserMQTT!.connect(); // For get config changed request if(tabletAppContext.configuration != null) { tabletAppContext.clientBrowserMQTT!.subscribe('config/#', MqttQos.atLeastOnce); } // For get device assignation config request if(tabletAppContext.deviceId != null) { tabletAppContext.clientBrowserMQTT!.subscribe('player/${tabletAppContext.deviceId}', MqttQos.atLeastOnce); var message = { "deviceId": tabletAppContext.deviceId, "connected": true }; const pubTopic = 'player/status'; final builder = MqttClientPayloadBuilder(); builder.addString(jsonEncode(message)); tabletAppContext.clientBrowserMQTT!.publishMessage(pubTopic, MqttQos.atLeastOnce, builder.payload!); } } catch (e) { print('Exception clientBrowserMQTT: $e'); tabletAppContext.clientBrowserMQTT!.disconnect(); }*/ } else { tabletAppContext.clientMQTT = MqttServerClient.withPort(hostToTake!.replaceAll('https://api.', ''), 'tablet_app_'+identifier!, 1883); tabletAppContext.clientMQTT!.logging(on: true); tabletAppContext.clientMQTT!.keepAlivePeriod = 20; tabletAppContext.clientMQTT!.onDisconnected = onDisconnected; tabletAppContext.clientMQTT!.onConnected = () => onConnected(appContext); tabletAppContext.clientMQTT!.onSubscribed = onSubscribed; tabletAppContext.clientMQTT!.connectionMessage = connMessage; tabletAppContext.clientMQTT!.autoReconnect = true; try { await tabletAppContext.clientMQTT!.connect(); // For get config changed request if(tabletAppContext.configuration != null) { tabletAppContext.clientMQTT!.subscribe('config/#', MqttQos.atLeastOnce); } // For get device assignation config request if(tabletAppContext.deviceId != null) { tabletAppContext.clientMQTT!.subscribe('player/${tabletAppContext.deviceId}', MqttQos.atLeastOnce); var message = { "deviceId": tabletAppContext.deviceId, "connected": true }; const pubTopic = 'player/status'; final builder = MqttClientPayloadBuilder(); builder.addString(jsonEncode(message)); tabletAppContext.clientMQTT!.publishMessage(pubTopic, MqttQos.atLeastOnce, builder.payload!); } } catch (e) { print('Exception clientMQTT: $e'); tabletAppContext.clientMQTT!.disconnect(); } } isInstantiated = true; //return kIsWeb ? tabletAppContext.clientBrowserMQTT : tabletAppContext.clientMQTT!; return tabletAppContext.clientMQTT!; } Future updateDevice(dynamic appContext) async { print("updateDevice"); TabletAppContext tabletAppContext = appContext.getContext(); DeviceDetailDTO? device = await tabletAppContext.clientAPI!.deviceApi!.deviceGetDetail(tabletAppContext.deviceId!); print(device); if (device != null) { // STORE IT LOCALLY !! TabletAppContext tabletAppContext = appContext.getContext(); tabletAppContext.deviceId = device.id; tabletAppContext.configuration!.id = device.configurationId; print(tabletAppContext); print(tabletAppContext.instanceId); appContext.setContext(tabletAppContext); // STORE IT LOCALLY (SQLite) await DatabaseHelper.instance.update(tabletAppContext); Fluttertoast.showToast( msg: "La tablette a bien été mise à jour", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.lightGreen, textColor: Colors.white, fontSize: 16.0 ); } else { Fluttertoast.showToast( msg: "Une erreur est survenue lors de la mise à jour de la tablette", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.deepOrangeAccent, textColor: Colors.white, fontSize: 16.0 ); } } void updateConfig(appContext) async { print("update config"); TabletAppContext tabletAppContext = appContext.getContext(); ConfigurationDTO? configuration = await tabletAppContext.clientAPI!.configurationApi!.configurationGetDetail(tabletAppContext.configuration!.id!); if (configuration != null) { // STORE IT LOCALLY !! TabletAppContext tabletAppContext = appContext.getContext(); tabletAppContext.configuration = configuration; if(!configuration.languages!.contains(tabletAppContext.language)) { tabletAppContext.language = configuration.languages![0]; } appContext.setContext(tabletAppContext); // STORE IT LOCALLY (SQLite) await DatabaseHelper.instance.update(tabletAppContext); Fluttertoast.showToast( msg: "La configuration a bien été mise à jour", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.lightGreen, textColor: Colors.white, fontSize: 16.0 ); } else { Fluttertoast.showToast( msg: "Une erreur est survenue lors de la mise à jour de la configuration", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.deepOrangeAccent, textColor: Colors.white, fontSize: 16.0 ); } } }