import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:managerapi/api.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 '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(); tabletAppContext.clientMQTT.updates.listen((List> c) async { final MqttPublishMessage message = c[0].payload; 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 = await DeviceInfoHelper.getDeviceDetails(); tabletAppContext.clientMQTT = MqttServerClient.withPort(tabletAppContext.host.replaceAll('http://', ''), 'tablet_app_'+identifier, 1883); isInstantiated = true; tabletAppContext.clientMQTT.logging(on: false); tabletAppContext.clientMQTT.keepAlivePeriod = 20; tabletAppContext.clientMQTT.onDisconnected = onDisconnected; tabletAppContext.clientMQTT.onConnected = () => onConnected(appContext); tabletAppContext.clientMQTT.onSubscribed = onSubscribed; var message = { "deviceId": tabletAppContext.deviceId != null ? tabletAppContext.deviceId : identifier, "connected": false }; final connMessage = MqttConnectMessage().authenticateAs('admin', 'mdlf2021!') // TODO ONLINE .keepAliveFor(60) .withWillTopic('player/status') .withWillMessage(jsonEncode(message)) .withClientIdentifier('tablet_app_'+identifier) .startClean() .withWillQos(MqttQos.atLeastOnce); 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: $e'); tabletAppContext.clientMQTT.disconnect(); } 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; 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 ); } } }