tablet-app/lib/Helpers/MQTTHelper.dart

307 lines
11 KiB
Dart

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<MqttReceivedMessage<MqttMessage>> c) async {
handleMessage(appContext, c);
});*/
} else {
tabletAppContext.clientMQTT!.updates!.listen((List<MqttReceivedMessage<MqttMessage>> c) async {
handleMessage(appContext, c);
});
}
}
Future<void> handleMessage(AppContext appContext, List<MqttReceivedMessage<MqttMessage>> 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<dynamic> 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('admin', 'mdlf2021!') // TODO ONLINE
.keepAliveFor(60)
.withWillTopic('player/status')
.withWillMessage(jsonEncode(message))
.withClientIdentifier('tablet_app_'+identifier!)
.startClean()
.withWillQos(MqttQos.atLeastOnce);
if(kIsWeb) {
/*tabletAppContext.clientBrowserMQTT = MqttBrowserClient.withPort(hostToTake!.replaceAll('http://', ''), '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('http://', ''), 'tablet_app_'+identifier!, 1883);
tabletAppContext.clientMQTT!.logging(on: false);
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<void> 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
);
}
}
}