323 lines
9.9 KiB
Dart
323 lines
9.9 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get_storage/get_storage.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:device_info_plus/device_info_plus.dart';
|
|
|
|
import '../models/response_output.dart';
|
|
import '../helper/constants.dart';
|
|
|
|
enum MainView { dashboard, traun, sarleinsbach, lannach, settings }
|
|
|
|
class HomeController extends GetxController {
|
|
// Der Key, mit dem wir das Scaffold von hier aus steuern
|
|
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
|
|
|
final boxSettings = GetStorage();
|
|
final currentView = MainView.dashboard.obs;
|
|
|
|
//--------------Settings View---------------------------
|
|
final userWebMethodesController = TextEditingController().obs;
|
|
final passwordWebMethodesController = TextEditingController().obs;
|
|
|
|
final powerUrlController = TextEditingController().obs;
|
|
|
|
void saveSettings() {
|
|
String wbUser = userWebMethodesController.value.text;
|
|
String wbPassword = passwordWebMethodesController.value.text;
|
|
String wbPowerUrl = powerUrlController.value.text;
|
|
|
|
boxSettings.write('wbUser', wbUser);
|
|
boxSettings.write('wbPassword', wbPassword);
|
|
boxSettings.write('wbPowerUrl', wbPowerUrl);
|
|
|
|
kDisplaySnackBarGreen("Settings saved successfully!");
|
|
|
|
print('Einstellungen gespeichert:');
|
|
print('Admin User: $wbUser');
|
|
print('Admin Password: $wbPassword');
|
|
print('Web Methodes Power URL: $wbPowerUrl');
|
|
}
|
|
//------------------------------------------------------
|
|
// http get request to fetch data from the provided URL
|
|
//------------------------------------------------------
|
|
|
|
final dateFromToIsoController = TextEditingController().obs;
|
|
final dateToIsoController = TextEditingController().obs;
|
|
final inputSwitchBranches = RxnString('TraunPV');
|
|
final responseOutputTraunPV = ResponseOutput().obs;
|
|
final responseOutputTraunImport = ResponseOutput().obs;
|
|
final responseOutputSarleinsbachPV = ResponseOutput().obs;
|
|
final responseOutputSarleinsbachImport = ResponseOutput().obs;
|
|
final responseOutputLannachPV = ResponseOutput().obs;
|
|
final responseOutputLannachImport = ResponseOutput().obs;
|
|
|
|
/// Map: Branch → (PV Observable, Import Observable)
|
|
Map<String, Map<String, dynamic>> get _branchConfig => {
|
|
'TraunPV': {
|
|
'pv': responseOutputTraunPV,
|
|
'import': responseOutputTraunImport,
|
|
'pvSuffix': 'TraunPV',
|
|
'importSuffix': 'TraunImport',
|
|
},
|
|
'TraunImport': {
|
|
'pv': responseOutputTraunPV,
|
|
'import': responseOutputTraunImport,
|
|
'pvSuffix': 'TraunPV',
|
|
'importSuffix': 'TraunImport',
|
|
},
|
|
'SarleinsbachPV': {
|
|
'pv': responseOutputSarleinsbachPV,
|
|
'import': responseOutputSarleinsbachImport,
|
|
'pvSuffix': 'SarleinsbachPV',
|
|
'importSuffix': 'SarleinsbachImport',
|
|
},
|
|
'SarleinsbachImport': {
|
|
'pv': responseOutputSarleinsbachPV,
|
|
'import': responseOutputSarleinsbachImport,
|
|
'pvSuffix': 'SarleinsbachPV',
|
|
'importSuffix': 'SarleinsbachImport',
|
|
},
|
|
'LannachPV': {
|
|
'pv': responseOutputLannachPV,
|
|
'import': responseOutputLannachImport,
|
|
'pvSuffix': 'LannachPV',
|
|
'importSuffix': 'LannachImport',
|
|
},
|
|
'LannachImport': {
|
|
'pv': responseOutputLannachPV,
|
|
'import': responseOutputLannachImport,
|
|
'pvSuffix': 'LannachPV',
|
|
'importSuffix': 'LannachImport',
|
|
},
|
|
};
|
|
|
|
//Device Info data
|
|
Future<bool> isAndroidSimulator() async {
|
|
// Prüfen, ob es überhaupt Android ist
|
|
if (!Platform.isAndroid) return false;
|
|
|
|
final deviceInfo = DeviceInfoPlugin();
|
|
final androidInfo = await deviceInfo.androidInfo;
|
|
|
|
// Wenn es KEIN physisches Gerät ist, ist es ein Simulator/Emulator
|
|
return !androidInfo.isPhysicalDevice;
|
|
}
|
|
|
|
void fetchData() async {
|
|
final inputFromIso = dateFromToIsoController.value.text;
|
|
final inputToIso = dateToIsoController.value.text;
|
|
final branch = inputSwitchBranches.value;
|
|
|
|
if (branch == null || branch.isEmpty) {
|
|
kDisplaySnackBarRed('Ungültiger Standort ausgewählt.');
|
|
return;
|
|
}
|
|
|
|
final baseUrl = getBaseUrl;
|
|
if (baseUrl.isEmpty) {
|
|
kDisplaySnackBarRed('Bitte zuerst die Server-URL eintragen.');
|
|
return;
|
|
}
|
|
|
|
final config = _branchConfig[branch];
|
|
if (config == null) {
|
|
kDisplaySnackBarRed('Unbekannte Branche: $branch');
|
|
return;
|
|
}
|
|
|
|
final credentials =
|
|
'${userWebMethodesController.value.text}:${passwordWebMethodesController.value.text}';
|
|
final basicAuth = 'Basic ${base64Encode(utf8.encode(credentials))}';
|
|
final baseUri = Uri.parse(baseUrl);
|
|
|
|
try {
|
|
// Fetch PV Daten
|
|
await _fetchAndStore(
|
|
baseUri,
|
|
inputFromIso,
|
|
inputToIso,
|
|
config['pvSuffix'],
|
|
config['pv'],
|
|
basicAuth,
|
|
);
|
|
|
|
// Fetch Import Daten
|
|
await _fetchAndStore(
|
|
baseUri,
|
|
inputFromIso,
|
|
inputToIso,
|
|
config['importSuffix'],
|
|
config['import'],
|
|
basicAuth,
|
|
);
|
|
} catch (e) {
|
|
print('Error: $e');
|
|
kDisplaySnackBarRed('Netzwerkfehler: $e');
|
|
}
|
|
}
|
|
|
|
/// Hilfsfunktion - reduziert Codeverdoppelung
|
|
Future<void> _fetchAndStore(
|
|
Uri baseUri,
|
|
String inputFromIso,
|
|
String inputToIso,
|
|
String switchBranch,
|
|
dynamic responseObservable,
|
|
String basicAuth,
|
|
) async {
|
|
final uri = baseUri.replace(
|
|
queryParameters: {
|
|
...baseUri.queryParameters,
|
|
'InputFromIso': inputFromIso,
|
|
'InputToIso': inputToIso,
|
|
'InputSwitchBranches': switchBranch,
|
|
},
|
|
);
|
|
|
|
try {
|
|
final response = await http.get(
|
|
uri,
|
|
headers: {'Authorization': basicAuth, 'Accept': 'application/json'},
|
|
);
|
|
|
|
final statusGroup = response.statusCode ~/ 100;
|
|
|
|
if (statusGroup == 2) {
|
|
print('✓ $switchBranch erfolgreich geladen');
|
|
responseObservable.value = ResponseOutput.fromJson(
|
|
jsonDecode(response.body),
|
|
);
|
|
} else if (statusGroup == 4) {
|
|
kDisplaySnackBarRed('Fehler 4xx: ${response.statusCode}');
|
|
} else if (statusGroup == 5) {
|
|
kDisplaySnackBarRed('Fehler 5xx: ${response.statusCode}');
|
|
} else {
|
|
kDisplaySnackBarRed('Fehler: ${response.statusCode}');
|
|
}
|
|
} catch (e) {
|
|
print('Error fetching $switchBranch: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
final isEmulator = false.obs;
|
|
|
|
// Synchroner Getter
|
|
String get getBaseUrl {
|
|
if (kIsWeb) {
|
|
if (kDebugMode) {
|
|
// Lokale Entwicklung mit lokalem Proxy
|
|
return 'http://localhost:3000/invoke/IFN_ASKI_Service.flows/getAskiData?';
|
|
} else {
|
|
// Produktion: Direkt an den Server oder über den Produktions-Proxy
|
|
return 'http://localhost:3000/invoke/IFN_ASKI_Service.flows/getAskiData?';
|
|
// ODER bei Nginx-Proxy: '/api/IFN_ASKI_Service.flows/getAskiData?'
|
|
}
|
|
}
|
|
|
|
if (isEmulator.value) {
|
|
return 'http://10.12.101.27:5556/invoke/IFN_ASKI_Service.flows/getAskiData?';
|
|
}
|
|
|
|
return powerUrlController.value.text.trim();
|
|
}
|
|
|
|
/// Wählt die richtige Base-URL:
|
|
/// Web: localhost:3000 (Reverse Proxy)
|
|
/// Desktop: Direkt von Settings
|
|
// Future<String> _getBaseUrl() async {
|
|
// final settingsUrl = powerUrlController.value.text.trim();
|
|
|
|
// // Auf Web: verwende Reverse Proxy auf localhost:3000
|
|
// if (kIsWeb) {
|
|
// return 'http://localhost:3000/invoke/IFN_ASKI_Service.flows/getAskiData?';
|
|
// }
|
|
// if (await isAndroidSimulator()) {
|
|
// return 'http://10.12.101.27:5556/invoke/IFN_ASKI_Service.flows/getAskiData?';
|
|
// }
|
|
|
|
// // Auf Desktop (Windows, Linux, macOS): direkt von Settings
|
|
// return settingsUrl;
|
|
// }
|
|
|
|
void changeView(MainView view) {
|
|
currentView.value = view;
|
|
if (currentView.value == MainView.dashboard) {
|
|
inputSwitchBranches.value = 'TraunPV';
|
|
} else if (currentView.value == MainView.traun) {
|
|
inputSwitchBranches.value = 'TraunPV';
|
|
} else if (currentView.value == MainView.sarleinsbach) {
|
|
inputSwitchBranches.value = 'SarleinsbachPV';
|
|
} else if (currentView.value == MainView.lannach) {
|
|
inputSwitchBranches.value = 'LannachPV';
|
|
}
|
|
if (currentView.value != MainView.dashboard) {
|
|
fetchData(); // Fetch data whenever the view changes
|
|
}
|
|
}
|
|
|
|
void toggleDrawer() {
|
|
final ScaffoldState? state = scaffoldKey.currentState;
|
|
|
|
if (state != null) {
|
|
if (state.isDrawerOpen) {
|
|
print("Schließe Drawer...");
|
|
state.closeDrawer(); // Wartet auf das Ende der Schließ-Animation
|
|
print("Drawer geschlossen.");
|
|
} else {
|
|
print("Öffne Drawer...");
|
|
state.openDrawer(); // Wartet auf das Ende der Öffnen-Animation
|
|
print("Drawer geöffnet.");
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
void onInit() async {
|
|
super.onInit();
|
|
if (!kIsWeb && Platform.isAndroid) {
|
|
final deviceInfo = DeviceInfoPlugin();
|
|
final androidInfo = await deviceInfo.androidInfo;
|
|
isEmulator(!androidInfo.isPhysicalDevice);
|
|
}
|
|
_readStorageData();
|
|
}
|
|
|
|
void _readStorageData() {
|
|
bool hasWbUser = boxSettings.hasData('wbUser');
|
|
if (hasWbUser) {
|
|
userWebMethodesController.value.text = boxSettings.read('wbUser');
|
|
}
|
|
bool hasWbPassword = boxSettings.hasData('wbPassword');
|
|
if (hasWbPassword) {
|
|
passwordWebMethodesController.value.text = boxSettings.read('wbPassword');
|
|
}
|
|
bool hasWbPowerUrl = boxSettings.hasData('wbPowerUrl');
|
|
if (hasWbPowerUrl) {
|
|
powerUrlController.value.text = boxSettings.read('wbPowerUrl');
|
|
}
|
|
//fromDateTimeIso and toDateTimeIso
|
|
dateFromToIsoController.value.text = DateTime(
|
|
DateTime.now().year,
|
|
DateTime.now().month,
|
|
DateTime.now().day,
|
|
).toIso8601String();
|
|
dateToIsoController.value.text = DateTime.now().toIso8601String();
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
userWebMethodesController.close();
|
|
powerUrlController.close();
|
|
passwordWebMethodesController.close();
|
|
dateFromToIsoController.close();
|
|
dateToIsoController.close();
|
|
super.onClose();
|
|
}
|
|
}
|