Skip to content
Snippets Groups Projects
datamodel.dart 13.8 KiB
Newer Older
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
Maximilian Betz's avatar
Maximilian Betz committed
import 'package:shared_preferences/shared_preferences.dart';
import 'package:package_info_plus/package_info_plus.dart';
class Collection {
  int id;
  String description;
  String collectionName;

  Collection({
    required this.id,
    required this.description,
    required this.collectionName,
  });

  factory Collection.fromJson(Map<String, dynamic> json) {
    return Collection(
      id: json['id'],
      description: json['description'],
      collectionName: json['collectionName'],
  Map<String, dynamic> toJson() => {
    'id': id,
    'description': description,
    'collectionName' : collectionName
  };

Maximilian Betz's avatar
Maximilian Betz committed
    return '$collectionName $id $description';
class Device{
  int id;
  String urn;

  Device(this.id, this.urn);

  factory Device.fromJson(Map<String, dynamic> json){
    return Device( json['id'] as int,
        json['urn'] as String);
  Map<String, dynamic> toJson() => {
    'id': id,
    'urn': urn
  };

  @override
  String toString(){
Maximilian Betz's avatar
Maximilian Betz committed
    return urn;
  int id;  //This shall be the mysql primary key database id
  int urnId;
  String urn;
  String label;
Maximilian Betz's avatar
Maximilian Betz committed
  String type; // Event type name  TODO: this should be an EventType variable
  int typeId;
  String description;
  String status;
  String startDate;
  String endDate;
Maximilian Betz's avatar
Maximilian Betz committed
  String latitude;
  String longitude;
  String elevation;
  Event({
    required this.id,
    required this.urn,
    required this.label,
    required this.type,
    required this.typeId,
    required this.description,
    required this.status,
    required this.startDate,
    required this.endDate,
    required this.latitude,
    required this.longitude,
    required this.elevation,
  factory Event.fromEvent(Event event){
    return Event(
      id: event.id,
      urnId: event.urnId,
      urn: event.urn,
      label: event.label,
      type: event.type,
      typeId: event.typeId,
      description: event.description,
      status: event.status,
      startDate: event.startDate,
      endDate: event.endDate,
      latitude: event.latitude,
      longitude: event.longitude,
      elevation: event.elevation,
  factory Event.fromJson(Map<String, dynamic> json){
    if (false == json.containsKey('data')){
      //Update from old version.
      json['data'] = '';
    }

    return Event(
      id: json['id'],
      urn: json['urn'],
      label: json['label'],
      type: json['type'],
      typeId: json['typeId'],
      description: json['description'],
      status: json['status'],
      startDate: json['startDate'],
      endDate: json['endDate'],
      latitude: json['latitude'],
      longitude: json['longitude'],
      elevation: json['elevation'],
Maximilian Betz's avatar
Maximilian Betz committed
    );
  Map<String, dynamic> toMap() {
    return {
      'id' : id,
      'urnId': urnId,
      'urn': urn,
      'label': label,
      'type' : type,
      'typeId' : typeId,
      'description' : description,
      'status' : status,
      'startDate' : startDate,
      'endDate' : endDate,
      'latitude' : latitude,
      'longitude' : longitude,
      'elevation' : elevation,
      'data' : data
  Map<String, dynamic> toMapNoId() {
    return {
      'urnId': urnId,
      'urn': urn,
      'label': label,
      'type' : type,
      'typeId' : typeId,
      'description' : description,
      'status' : status,
      'startDate' : startDate,
      'endDate' : endDate,
      'latitude' : latitude,
      'longitude' : longitude,
      'elevation' : elevation,
      'data' : data
  Map<String, dynamic> toJson() => {
    'urn': urn,
    'label': label,
    'type' : type,
    'typeId' : typeId,
    'description' : description,
    'status' : status,
    'startDate' : startDate,
    'endDate' : endDate,
    'latitude' : latitude,
    'longitude' : longitude,
    'data' : data,
Maximilian Betz's avatar
Maximilian Betz committed
  Map<String, dynamic> toSensorJson() {
    return {
      "\"inheritToAllChildren\"":"\"false\"",
      "\"inheritToChildren\"":[],
      "\"event\"":{
        "\"startDate\"":"\"$startDate\"",
        "\"endDate\"":"\"$endDate\"",
        "\"label\"":"\"$label\"",
        "\"description\"":"\"$description\"",
        "\"eventType\"":"\"$typeId\"",
        "\"latitude\"":"\"$latitude\"",
        "\"longitude\"":"\"$longitude\"",
        "\"elevationInMeter\"":"\"$elevation\"",
        "\"id\"":"\"0\""
      }
  @override
  String toString(){
    return '{ '
        '${this.id}, '
        '${this.urnId}, '
Maximilian Betz's avatar
Maximilian Betz committed
        '${this.urn}, '
        '${this.label}, '
        '${this.type}, '
        '${this.description}, '
        '${this.startDate}, '
        '${this.endDate}, '
Maximilian Betz's avatar
Maximilian Betz committed
        '${this.latitude},'
        '${this.longitude},'
        '${this.elevation},'
        '${this.status},'
        '${this.data} }';
Maximilian Betz's avatar
Maximilian Betz committed
  EventType({
    required this.id,
    required this.name
  });
Maximilian Betz's avatar
Maximilian Betz committed
  EventType.fromSensorJson(Map<String, dynamic> json)
      :   id = json['id'],
        name = json['generalName'];

  EventType.fromJson(Map<String, dynamic> json)
      : id = json['id'],
        name = json['name'];

  Map<String, dynamic> toJson() => {
    'id': id,
    'name': name,
  };
Maximilian Betz's avatar
Maximilian Betz committed

  @override
  String toString(){
    return name;
  }
    "cntUp" : cntUp,
    "cnt": cnt,
    "prefix": prefix
  };

  LabelConfiguration.fromJson(Map<String, dynamic> json)
      : cntUp = json['cntUp'],
        cnt = json['cnt'],
        prefix = json['prefix'];
class SensorLogin{
  String mail;
  String password;

  SensorLogin(
      this.mail,
      this.password,
      );

  Map<String, dynamic> toJson() => {
Maximilian Betz's avatar
Maximilian Betz committed
    "mail": mail,
    "password": password
Maximilian Betz's avatar
Maximilian Betz committed

  SensorLogin.fromJson(Map<String, dynamic> json)
      : mail = json['mail'],
        password = json['password'];
// Storage classes
// ConfigurationStoreBase for Collection, devices, event types, login information
// EventStoreBase for created event information.
abstract class ConfigurationStoreBase {
  List<Collection> collections = [];
  Collection currentCollection = Collection(id: -1, description: '', collectionName: '');
  List<Device> devices = [];
  List<EventType> eventTypes = [];
Maximilian Betz's avatar
Maximilian Betz committed
  SensorLogin loginInformation = SensorLogin('', '');
  LabelConfiguration labelConfig = LabelConfiguration(0, true, '');
  Map<String, dynamic> toMap() {
    return {
      'collections' : jsonEncode(collections),
      'currentCollection': currentCollection.toJson(),
      'devices': jsonEncode(devices),
      'eventTypes': jsonEncode(eventTypes),
      'initialized' : initialized,
      'labelConfiguration' : jsonEncode(labelConfig),
      'restRequestUrl' : restRequestUrl,
  Map<String, dynamic> loginDataToMap() {
    return {
      'loginInformation' : loginInformation.toJson(),
    };
  }

  void loginDataFromMap(Map<String, dynamic> map){
    loginInformation = SensorLogin.fromJson(map['loginInformation']);
  }

  void fromMap(Map<String, dynamic> map) {
    List<dynamic> dynList = jsonDecode(map['collections']);
    collections = [];
    for (var element in dynList){
      collections.add(Collection.fromJson(element));
    }
    currentCollection = Collection.fromJson(map['currentCollection']);

    dynList = jsonDecode(map['devices']);
    devices = [];
    for (var element in dynList){
      devices.add(Device.fromJson(element));
    }

    dynList = jsonDecode(map['eventTypes']);
    eventTypes = [];
    for (var element in dynList){
      eventTypes.add(EventType.fromJson(element));
    }
    labelConfig = LabelConfiguration.fromJson(json.decode(map['labelConfiguration']));
    initialized = map['initialized'];
  }


  Collection getCollectionFromName(String name) {
    for (var collection in collections) {
      if (collection.collectionName == name) {
        return collection;
      }
    }
Maximilian Betz's avatar
Maximilian Betz committed
    throw Exception('Event with name :$name was not found.');
  int getDeviceIdFromUrn(String urn) {
    for (var device in devices) {
      if (device.urn == urn) {
        return device.id;
      }
    }
Maximilian Betz's avatar
Maximilian Betz committed
    throw Exception('Device with urn:$urn was not found.');
  int getEventIdFromName(String name) {
    for (var eventType in eventTypes) {
      if (eventType.name == name) {
        return eventType.id;
      }
    }
Maximilian Betz's avatar
Maximilian Betz committed
    throw Exception('Event with name :$name was not found.');
  void reset(){
    collections = [];
    devices = [];
    eventTypes = [];
    currentCollection = Collection(id: -1, description: '', collectionName: '');
    collections.add(currentCollection); //Add a dummy collection. Dropdown menu does not like empty lists
    loginInformation = SensorLogin('', '');
class ConfigurationStoreInstance extends ConfigurationStoreBase {
  static final ConfigurationStoreInstance _instance = ConfigurationStoreInstance
      ._internal();
  @override
  void reset(){
    super.reset();
    deleteSharedPrefs();
  }

Maximilian Betz's avatar
Maximilian Betz committed
  Future<void> storeToSharedPrefs() async {

    const secureStorage = FlutterSecureStorage();
    var writeData = await secureStorage.write(key: 'login', value: jsonEncode(loginDataToMap()));

Maximilian Betz's avatar
Maximilian Betz committed
    final prefs = await SharedPreferences.getInstance();
    prefs.setString('configuration', jsonEncode(toMap()));
Maximilian Betz's avatar
Maximilian Betz committed
  }

  Future<void> loadFromSharedPrefs() async {

    const secureStorage = FlutterSecureStorage();
    final String? readData = await secureStorage.read(key: 'login');
    if (readData != null) {
      loginDataFromMap(jsonDecode(readData));
      debugPrint('Login loaded from secure storage');
    }else{
      debugPrint('Failed to load login details from secure storage');
    }

Maximilian Betz's avatar
Maximilian Betz committed
    final prefs = await SharedPreferences.getInstance();
    final String? configuration = prefs.getString('configuration');
    if (configuration != null){
      debugPrint('Configuration String: $configuration');
Maximilian Betz's avatar
Maximilian Betz committed
      fromMap(jsonDecode(configuration));
      debugPrint('Configuration loaded from shared preferences');
Maximilian Betz's avatar
Maximilian Betz committed
    }else{
      debugPrint('Failed to load configuration from shared preferences.');
Maximilian Betz's avatar
Maximilian Betz committed
    }
  }

  Future<void> deleteSharedPrefs() async {
    final prefs = await SharedPreferences.getInstance();
    prefs.clear();
    await prefs.remove('configuration');

    const secureStorage = FlutterSecureStorage();
    secureStorage.delete(key: 'login');
  }

  factory ConfigurationStoreInstance() {
  ConfigurationStoreInstance._internal() {
    collections = [];
    collections.add(currentCollection);
    devices = [];
    eventTypes = [];
abstract class EventStoreBase{
Maximilian Betz's avatar
Maximilian Betz committed
  bool gnssSync = true;
  Event currentEvent = Event(
      urn:'urn0',
      label:'',
      type:'',
      typeId:-1,
      description:'',
      status:'PENDING',
      startDate:'',
      endDate: '',
      latitude: '',
      longitude: '',
Maximilian Betz's avatar
Maximilian Betz committed

  Map<String, dynamic> toMap() {
    return {
Maximilian Betz's avatar
Maximilian Betz committed
      'currentEvent' : currentEvent.toJson(),
Maximilian Betz's avatar
Maximilian Betz committed
  }

  void fromMap(Map<String, dynamic> map) {
    currentEvent = Event.fromJson(map['currentEvent']);
Maximilian Betz's avatar
Maximilian Betz committed
    gnssSync = map['gnssSync'];
class EventStoreInstance extends EventStoreBase {
  static final EventStoreInstance _instance = EventStoreInstance._internal();
Maximilian Betz's avatar
Maximilian Betz committed
  Future<void> storeToSharedPrefs() async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setString('currentEvent', jsonEncode(toMap()));
    debugPrint('Stored current event to shared prefs');
  }

  Future<void> loadFromSharedPrefs() async {
    final prefs = await SharedPreferences.getInstance();
    final String? currentEvent = prefs.getString('currentEvent');
    if (currentEvent != null){
      debugPrint('Configuration Current Event String: $currentEvent');
Maximilian Betz's avatar
Maximilian Betz committed
      fromMap(jsonDecode(currentEvent));
      debugPrint('Configuration Current Event loaded from shared preferences');
    }else{
      debugPrint('Failed to load Current Event configuration from shared preferences.');
    }
  }

  Future<void> deleteSharedPrefs() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove('currentEvent');
  }

  factory EventStoreInstance() {
  EventStoreInstance._internal() {
    currentEvent = Event(
        urn:'urn0',
        label:'',
        type:'',
        typeId:-1,
        description:'',
        status:'PENDING',
        startDate:'',
        endDate: '',
        latitude: '',
        longitude: '',

  void reset(){
    gnssSync = true;
    showAllEvents = false;
    currentEvent = Event(
        urn:'urn0',
        label:'',
        type:'',
        typeId:-1,
        description:'',
        status:'PENDING',
        startDate:'',
        endDate: '',
        latitude: '',
        longitude: '',
    deleteSharedPrefs();
String versionNumber = '';
String buildNumber = '';
Future<void> loadVersionInfo() async {
  PackageInfo packageInfo = await PackageInfo.fromPlatform();
  versionNumber = packageInfo.version;
  buildNumber = packageInfo.buildNumber;
}