Files
Bus-Infotainment--IBus-/lib/backend/live_information.dart
2024-05-01 12:29:59 +01:00

190 lines
4.9 KiB
Dart

// Singleton
import 'dart:async';
import 'dart:convert';
import 'package:appwrite/appwrite.dart' as appwrite;
import 'package:appwrite/models.dart' as models;
import 'package:bus_infotainment/audio_cache.dart';
import 'package:bus_infotainment/auth/api_constants.dart';
import 'package:bus_infotainment/auth/auth_api.dart';
import 'package:bus_infotainment/backend/modules/announcement.dart';
import 'package:bus_infotainment/backend/modules/commands.dart';
import 'package:bus_infotainment/backend/modules/synced_time.dart';
import 'package:bus_infotainment/backend/modules/tracker.dart';
import 'package:bus_infotainment/tfl_datasets.dart';
import 'package:bus_infotainment/utils/audio%20wrapper.dart';
import 'package:bus_infotainment/utils/delegates.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:ntp/ntp.dart';
import 'package:permission_handler/permission_handler.dart';
class LiveInformation {
static final LiveInformation _singleton = LiveInformation._internal();
factory LiveInformation() {
return _singleton;
}
LiveInformation._internal();
Future<void> initialize() async {
{
// By default, load the bus sequences from the assets
print("Loading bus sequences from assets");
busSequences = BusSequences.fromCSV(
await rootBundle.loadString("assets/datasets/bus-blinds.csv"),
await rootBundle.loadString("assets/datasets/bus-sequences.csv")
);
print("Loaded bus sequences from assets");
try {
http.Response response = await http.get(Uri.parse('https://tfl.gov.uk/bus-sequences.csv'));
busSequences = BusSequences.fromCSV(
await rootBundle.loadString("assets/datasets/bus-blinds.csv"),
response.body
);
print("Loaded bus sequences from TFL");
} catch (e) {
print("Failed to load bus sequences from TFL. Using local copy.");
}
String sessionID = "test";
commandModule = CommandModule(sessionID);
}
// Initialise modules
syncedTimeModule = SyncedTimeModule();
announcementModule = AnnouncementModule();
initTrackerModule();
print("Initialised LiveInformation");
}
Future<void> initTrackerModule() async {
if (await Permission.location.isGranted) {
trackerModule = TrackerModule();
}
}
// Auth
AuthAPI auth = AuthAPI();
// Modules
late CommandModule commandModule;
late BusSequences busSequences;
late AnnouncementModule announcementModule;
late SyncedTimeModule syncedTimeModule;
late TrackerModule trackerModule;
// Important variables
BusRouteVariant? _currentRouteVariant;
// Events
EventDelegate<BusRouteVariant> routeVariantDelegate = EventDelegate();
// Internal methods
Future<void> setRouteVariant_Internal(BusRouteVariant routeVariant) async {
// Set the current route variant
_currentRouteVariant = routeVariant;
// Let everyone know that the route variant has been set/changed
routeVariantDelegate.trigger(routeVariant);
// Get all of the files that need to be cached
List<String> audioFiles = [];
for (BusRouteStop stop in routeVariant.busStops) {
audioFiles.add(stop.getAudioFileName());
}
// Cache/Load the audio files
await announcementModule
.announcementCache
.loadAnnouncementsFromBytes(await LiveInformation().announcementModule.getBundleBytes(), [
...audioFiles,
if (!routeVariant.busRoute.routeNumber.toLowerCase().startsWith("ul"))
"R_${routeVariant.busRoute.routeNumber}_001.mp3"
else
"R_RAIL_REPLACEMENT_SERVICE_001.mp3",
]
);
}
// Public methods
BusRouteVariant? getRouteVariant() {
return _currentRouteVariant;
}
Future<void> setRouteVariant(BusRouteVariant routeVariant) async {
await commandModule.executeCommand(
"setroute ${routeVariant.busRoute.routeNumber} ${routeVariant.busRoute.routeVariants.values.toList().indexOf(routeVariant)}"
);
}
/*
Everything under this will be considered legacy code
*/
}
class AnnouncementQueueEntry {
final String displayText;
final List<AudioWrapperSource> audioSources;
bool sendToServer = true;
DateTime? scheduledTime;
DateTime? timestamp;
AnnouncementQueueEntry({required this.displayText, required this.audioSources, this.sendToServer = true, this.scheduledTime, this.timestamp});
}
class NamedAnnouncementQueueEntry extends AnnouncementQueueEntry {
final String shortName;
NamedAnnouncementQueueEntry({
required this.shortName,
required String displayText,
required List<AudioWrapperSource> audioSources,
DateTime? scheduledTime,
DateTime? timestamp,
bool sendToServer = true,
}) : super(
displayText: displayText,
audioSources: audioSources,
sendToServer: sendToServer,
scheduledTime: scheduledTime,
timestamp: timestamp,
);
}
var abs = (int value) => value < 0 ? -value : value;