Skip to content
Snippets Groups Projects
Commit 3a968541 authored by Maximilian Betz's avatar Maximilian Betz
Browse files

storing configuration in shared preferences

parent 6c9ec194
No related branches found
No related tags found
No related merge requests found
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'datamodel.dart';
import 'sensorconnector.dart';
import 'databaseconnector.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Configuration extends StatefulWidget {
const Configuration({Key? key}) : super(key: key);
......@@ -23,7 +23,67 @@ class _MyHomePageState extends State<Configuration> {
SensorConnector connector = SensorConnector();
final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
@override
Future<void> updateConfiguration() async {
final EventStoreInstance event = EventStoreInstance();
futureAuthToken.then((value){ //NOTE: Counterintuitive async callback function
debugPrint("Login credentials correct! Auth Token: " + value);
futureDevices.then((value) {
debugPrint("Device List complete");
configuration.devices = value;
futureEventTypes.then((value) async {
debugPrint("Event Types List complete");
configuration.eventTypes = value;
debugPrint("EventType Json: " + jsonEncode(
configuration.eventTypes[0]));
debugPrint("Device Json: " + jsonEncode(
configuration.devices[0]));
debugPrint("Current Collection Json: " + jsonEncode(
configuration.currentCollection));
debugPrint("Sensor Login Json: " + jsonEncode(
configuration.loginInformation));
try {
//Update id and urn for the add event widget with some initial data
event.currentEvent.id = 0;
event.currentEvent.urnId = configuration.devices[0]
.id; //TODO: fix if devices are an empty list.
event.currentEvent.urn = configuration.devices[0].urn;
event.currentEvent.description = '';
event.currentEvent.label = '';
event.currentEvent.type = configuration.eventTypes[0]
.name;
var date = DateTime.now().toUtc();
var isoDate = date.toIso8601String();
event.currentEvent.startDate = isoDate;
event.currentEvent.endDate = isoDate;
configuration.initialized = true;
//debugPrint (configuration.toMap().toString(), wrapWidth: 512);
HapticFeedback.vibrate();
//TODO: display success user feedback
//TODO: store complete "configuration"
} catch (e) {
throw Exception('Something went wrong try again');
}
final prefs = await SharedPreferences.getInstance();
prefs.setString('configuration', jsonEncode(configuration.toMap()));
prefs.setString('currentEvent', jsonEncode(event.toMap()));
debugPrint('Configuration stored!');
});
});
});
//TODO: display failed as user feedback somehow
}
@override
void initState() {
super.initState();
......@@ -147,6 +207,9 @@ class _MyHomePageState extends State<Configuration> {
label: const Text('Reset all'),
onPressed: () {
//events.reset(); //TODO: remove before release!
var db = DatabaseInstance();
db.delete();
configuration.reset(); //TODO: remove before release this is not a real use case!
},
),
......@@ -157,52 +220,7 @@ class _MyHomePageState extends State<Configuration> {
icon: const Icon(Icons.save),
label: const Text('Store'),
onPressed: () {
futureAuthToken.then((value){ //NOTE: Counterintuitive async callback function
debugPrint("Login credentials correct! Auth Token: " + value);
futureDevices.then((value) {
debugPrint("Device List complete");
configuration.devices = value;
futureEventTypes.then((value) {
debugPrint("Event Types List complete");
configuration.eventTypes = value;
debugPrint("EventType Json: " + jsonEncode(
configuration.eventTypes[0]));
debugPrint("Device Json: " + jsonEncode(
configuration.devices[0]));
debugPrint("Current Collection Json: " + jsonEncode(
configuration.currentCollection));
debugPrint("Sensor Login Json: " + jsonEncode(
configuration.loginInformation));
try {
//Update id and urn for the add event widget with some initial data
events.currentEvent.id = 0;
events.currentEvent.urnId = configuration.devices[0]
.id; //TODO: fix if devices are an empty list.
events.currentEvent.urn = configuration.devices[0].urn;
events.currentEvent.description = '';
events.currentEvent.label = '';
events.currentEvent.type = configuration.eventTypes[0]
.name;
var date = DateTime.now().toUtc();
var isoDate = date.toIso8601String();
events.currentEvent.startDate = isoDate;
events.currentEvent.endDate = isoDate;
configuration.initialized = true;
HapticFeedback.vibrate();
//TODO: display success user feedback
//TODO: store complete "configuration"
} catch (e) {
throw Exception('Something went wrong try again');
}
});
});
});
updateConfiguration();
//TODO: display failed as user feedback somehow
},
),
......
......@@ -12,9 +12,7 @@ class DatabaseInstance extends DatabaseConnector {
return _instance;
}
DatabaseInstance._internal() {
//connect();
}
DatabaseInstance._internal();
}
......@@ -36,11 +34,16 @@ abstract class DatabaseConnector{
);
},
// Set the version. This executes the onCreate function and provides a
// path to perform database upgrades and downgrades.
// path to perform database upgrades and downgrades
version: 1,
);
}
Future<void> delete() async{
deleteDatabase(join(await getDatabasesPath(), eventDatabase)); //NOTE: deletes everything. Just use for debug!
await connect(); //Create a new and empty database
}
Future<int> addEvent(Event event) async {
int rowId = 0;
rowId = await database.insert(
......
import 'dart:convert';
import 'package:flutter/cupertino.dart';
......@@ -31,7 +30,7 @@ class Collection {
@override
String toString(){
return collectionName;
return collectionName + ' ' + id.toString() + ' ' + description;
}
}
......@@ -256,6 +255,42 @@ abstract class ConfigurationStoreBase {
SensorLogin loginInformation = SensorLogin('', '');
bool initialized = false;
Map<String, dynamic> toMap() {
return {
'collections' : jsonEncode(collections),
'currentCollection': currentCollection.toJson(),
'devices': jsonEncode(devices),
'eventTypes': jsonEncode(eventTypes),
'loginInformation' : loginInformation.toJson(),
'initialized' : initialized,
};
}
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));
}
loginInformation = SensorLogin.fromJson(map['loginInformation']);
initialized = map['initialized'];
}
Collection getCollectionFromName(String name) {
for (var collection in collections) {
if (collection.collectionName == name) {
......@@ -283,6 +318,8 @@ abstract class ConfigurationStoreBase {
throw Exception('Event with name :' + name + ' was not found.');
}
void reset(){
collections = [];
devices = [];
......@@ -311,7 +348,6 @@ class ConfigurationStoreInstance extends ConfigurationStoreBase {
abstract class EventStoreBase{
//List<Event> events = [];
Event currentEvent = Event(
id: 0,
urnId:-1,
......@@ -328,35 +364,35 @@ abstract class EventStoreBase{
elevation: ''
);
/*
int getPendingEventCount(List<Event> events){
int count = 0;
for (var event in events) {
if (event.status == 'PENDING') {
count++;
}
}
return count;
Map<String, dynamic> toMap() {
return {
'currentEvent' : currentEvent.toJson()
};
}
*/
//String getEventDump(List<Event> events){
// String ev = '[';
// for (var event in events) {
// ev += jsonEncode(event);
// ev += ',';
// }
// ev += ']';
// return ev;
//}
//fromEventDump(dump){
// events = [];
// for (var entry in dump) {
// debugPrint('Added Event from Storage: ' + entry.toString());
// events.add(Event.fromJson(entry));
// }
//}
void fromMap(Map<String, dynamic> map) {
currentEvent = Event.fromJson(map['currentEvent']);
}
//String getEventDump(List<Event> events){
// String ev = '[';
// for (var event in events) {
// ev += jsonEncode(event);
// ev += ',';
// }
// ev += ']';
// return ev;
//}
//fromEventDump(dump){
// events = [];
// for (var entry in dump) {
// debugPrint('Added Event from Storage: ' + entry.toString());
// events.add(Event.fromJson(entry));
// }
//}
}
......@@ -368,7 +404,6 @@ class EventStoreInstance extends EventStoreBase {
}
EventStoreInstance._internal() {
//events = [];
currentEvent = Event(
id:0,
urnId:-1,
......@@ -387,7 +422,6 @@ class EventStoreInstance extends EventStoreBase {
}
void reset(){
//events = [];
currentEvent = Event(
id:0,
urnId:-1,
......
import 'dart:io';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'datamodel.dart';
......@@ -11,64 +9,42 @@ import 'overview.dart';
import 'configuration.dart';
import 'databaseconnector.dart';
Future<void> pathStuff() async {
//Directory downloadsDirectory = await DownloadsPathProvider.downloadsDirectory;
//Directory appDocDir = await getApplicationDocumentsDirectory();
//debugPrint(appDocDir.path.toString());
Future<void> loadConfiguration() async {
final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
final EventStoreInstance event = EventStoreInstance();
WidgetsFlutterBinding.ensureInitialized();
final prefs = await SharedPreferences.getInstance();
//prefs.setString('events', 'blabla');
final String? events = prefs.getString('events');
print('Shared Preferences: ' + events!);
final String? storedConfiguration = prefs.getString('configuration');
if (storedConfiguration != null){
debugPrint('Configuration String: ' + storedConfiguration);
configuration.fromMap(jsonDecode(storedConfiguration));
debugPrint('Configuration loaded from shared preferences');
}else{
debugPrint('Failed to load configuration from shared preferences.');
}
//const storage = FlutterSecureStorage();
final String? currentEvent = prefs.getString('currentEvent');
if (currentEvent != null){
debugPrint('Configuration Current Event String: ' + currentEvent);
event.fromMap(jsonDecode(currentEvent));
debugPrint('Configuration Current Event loaded from shared preferences');
}else{
debugPrint('Failed to load Current Event configuration from shared preferences.');
}
//const storage = FlutterSecureStorage(); //TODO: move login information to secure storage
//Map<String, String> allValues = await storage.readAll();
//print('Secure Storage: ' + allValues.toString());
var database = DatabaseInstance();
await database.connect(); //Do once at start of APP!
Event event = Event.fromJson({"id":0,"urnId":102,"urn":"mooring:f9-12","label":"hggg","type":"Calibration",
"typeId":15,"description":"ggggg","status":"PENDING",
"startDate":"2022-03-28T07:00:02.712112Z",
"endDate":"2022-03-28T07:00:02.712112Z","latitude":"53.5440109",
"longitude":"8.58033187","elevation":"48.7139892578125"});
List<Event> tempEvents = [];
//Update second event in sql database
event.id = 2;
event.description = 'updated description1';
//database.updateEvent(event);
//debugPrint("Add Event to database: " + event.toString());
//int rowId = await database.addEvent(event);
//debugPrint("Events row Id: " + rowId.toString());
tempEvents = await database.getEvents();
debugPrint("Events in SQL Database: ");
for (var event in tempEvents){
debugPrint(event.toString());
}
}
void main() {
pathStuff();
loadConfiguration();
EventStoreInstance events = EventStoreInstance();
final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
......@@ -78,32 +54,6 @@ void main() {
configuration.loginInformation = SensorLogin.fromJson({"mail":"admin","password":"adminadmin"}); //TODO: replace for productive version.
//Load data from storage:
//events.currentEvent = Event.fromJson({"id":102,"urn":"mooring:f9-12","label":"gg","type":"Calibration","typeId":15,"description":"gvg","status":"EXPORTED","startDate":"2022-03-25T09:24:48.856120Z","endDate":"2022-03-25T09:24:48.856120Z","latitude":"53.54388522","longitude":"8.58144825","elevation":"1.9925537109375"});
//events.events.add(Event.fromJson({"id":102,"urn":"mooring:f9-12","label":"gg","type":"Calibration","typeId":15,"description":"gvg","status":"EXPORTED","startDate":"2022-03-25T09:24:48.856120Z","endDate":"2022-03-25T09:24:48.856120Z","latitude":"53.54388522","longitude":"8.58144825","elevation":"1.9925537109375"}));
//configuration.devices.add(Device.fromJson({"id":102,"urn":"mooring:f9-12"}));
//configuration.eventTypes.add(EventType.fromJson({"id":15,"name":"Calibration"}));
//configuration.currentCollection = Collection.fromJson({"id":1,"description":"","collectionName":"FRAM"});
//configuration.initialized = true;
/*
events.fromEventDump(
[
{"id":1,"urnId":102,"urn":"mooring:f9-12","label":"hggg","type":"Calibration",
"typeId":15,"description":"ggggg","status":"PENDING",
"startDate":"2022-03-28T07:00:02.712112Z",
"endDate":"2022-03-28T07:00:02.712112Z","latitude":"53.5440109",
"longitude":"8.58033187","elevation":"48.7139892578125"},
{"id":2,"urnId":102,"urn":"mooring:f9-12","label":"hggg","type":"Calibration",
"typeId":15,"description":"ggggg","status":"PENDING",
"startDate":"2022-03-28T07:00:03.828190Z",
"endDate":"2022-03-28T07:00:03.828190Z","latitude":"53.54401033",
"longitude":"8.58032778","elevation":"48.720947265625"},
]);
//events.fromEventDump([{"id":102,"urn":"mooring:f9-12","label":"cf","type":"Calibration","typeId":15,"description":"fd","status":"PENDING","startDate":"2022-03-25T12:47:30.659436Z","endDate":"2022-03-25T12:47:30.659436Z","latitude":"","longitude":"","elevation":""},{"id":102,"urn":"mooring:f9-12","label":"cf","type":"Calibration","typeId":15,"description":"fd","status":"PENDING","startDate":"2022-03-25T12:47:32.136009Z","endDate":"2022-03-25T12:47:32.136009Z","latitude":"","longitude":"","elevation":""}]);
*/
runApp(MaterialApp(
title: 'Mobile Event Log',
theme: ThemeData(
......
......@@ -39,7 +39,6 @@ class _ViewEvents extends State<ViewEvents> {
void initState() {
_syncStatus = '';
super.initState();
fetchEventsFromDb();
}
......@@ -48,42 +47,36 @@ class _ViewEvents extends State<ViewEvents> {
SensorConnector connection = SensorConnector();
List<Event> events = await database.getPendingEvents();
int syncCounter = events.length;
debugPrint('Pending Events');
for (var event in events){
debugPrint(event.toString());
}
int syncCounter = events.length;
if(syncCounter > 0) {
try {
String? token = await connection.getAuthToken(
configuration.loginInformation.mail,
configuration.loginInformation.password);
if (token != null) {
debugPrint('Number of Events: ' + events.length.toString());
debugPrint('Number of Pending Events: ' + syncCounter.toString());
var index = 0;
for (var event in events) {
debugPrint('Idx: ' + index.toString() + ' ' +
event.toSensorJson().toString());
index++;
if (await connection.putEvent(event, token) == true) {
//Event has been posted to Sensor.
syncCounter--;
debugPrint(
'put success, remaining events: ' + syncCounter.toString());
event.status = 'EXPORTED'; //Update event to export only once
database.updateEvent(event); //Update Event in SQL Database
fetchEventsFromDb(); //update view list //TODO: this is bad performance
setState(() {});
} else {
throw Exception('Sync for ' + event.urn + 'failed');
}
var index = 0;
for (var event in events) {
debugPrint('Idx: ' + index.toString() + ' ' +
event.toSensorJson().toString());
index++;
if (await connection.putEvent(event, token) == true) {
//Event has been posted to Sensor.
syncCounter--;
debugPrint(
'put success, remaining events: ' + syncCounter.toString());
event.status = 'EXPORTED'; //Update event to export only once
database.updateEvent(event); //Update Event as exported in SQL Database
fetchEventsFromDb(); //update view list //TODO: this is bad for the sync performance! Consider working with localevent list for the UI!
setState(() {});
} else {
throw Exception('Sync for ' + event.urn + 'failed');
}
_syncStatus = 'export success';
}
_syncStatus = 'export success';
} on SocketException catch (e) {
debugPrint('Exception: $e');
_syncStatus = 'No connection';
......@@ -94,13 +87,12 @@ class _ViewEvents extends State<ViewEvents> {
setState(() {});
}
}else{
debugPrint('Nothing to export');
debugPrint('No PENDING event(s)');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("View & Sync"),
......@@ -269,9 +261,6 @@ class _ViewEvents extends State<ViewEvents> {
icon: null,
label: const Text('Sync'),
onPressed: () {
//debugPrint(_events.getEventDump());
syncEvents();
},
),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment