Files
2026-07-23 14:36:03 +02:00

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();
}
}