using Common; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using Heisig.HMI.AdsManager; using InfineonHMI.Pages.Views; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System.Windows; using System.Windows.Controls; using InfineonHMI.Common; using TcEventLoggerAdsProxyLib; using TwinCAT.TypeSystem; namespace InfineonHMI; public sealed partial class MainWindowVM : ObservableObject, IRecipient, IDisposable { [ObservableProperty] private Page currentPage; [ObservableProperty] private Visibility statusBarVisible; [ObservableProperty] private string breadcrumb; [ObservableProperty] private string actualUser; [ObservableProperty] private string sCurrentPackMLMode; [ObservableProperty] private string sCurrentPackMLState; [ObservableProperty] private bool canUserChangePageProductionWindow; [ObservableProperty] private bool canUserChangePageReceipeWindow; private const string _actualUserPrefix = "Aktueller Benutzer: \n"; private readonly IAdsManager _adsManager; private readonly IConfiguration _config; private readonly TcEventLogger _eventlogger; private User currentUser; public User CurrentUser { get { return currentUser; } set { SetProperty(ref currentUser, value); ActualUser = _actualUserPrefix + currentUser.UserName + " lvl: " + currentUser.UserLevel; Users.setCurrentUser(value); CanUserChangePageProductionWindow = value.UserLevel == 100; CanUserChangePageReceipeWindow = value.UserLevel == 100; } } // Last active event [ObservableProperty] private string currentActiveEvent = ""; private readonly object _lock = new(); // Empty page private readonly Page _emptyPage; // Last navigate message private readonly Stack _messageStack = new(); NavigateMessage? _currentMessage; // Events page view model [ObservableProperty] EventsPageVM _eventsPageVM; // Settings page viem model SettingsPageVM? _settingsPageVM; private PackMLControlVM stMachinePackMLVM; ProductionOverviewPageVM? _productionOverviewPageVM; private MachineOverviewPageVM? _machineOverviewPageVM; // Hot Coolplate page view model HotCoolPlatePageVM? _hotCoolplatePageVM; // Kuka Robot page view model ReceipePageVM? _receipePageVM; public MainWindowVM(IAdsManager adsManager, IConfiguration config, TcEventLogger eventLogger) { _adsManager = adsManager; _config = config; SCurrentPackMLMode = "Aktueller Modus: "; SCurrentPackMLState = "Aktueller Status: "; ActualUser = _actualUserPrefix + "---------"; // Create empty page _emptyPage = new(); // Create events page viewmodel _eventlogger = eventLogger; _eventsPageVM = new(_eventlogger); CurrentPage = _emptyPage; _currentMessage = new NavigateMessage("", typeof(Page)); _messageStack.Push(_currentMessage); stMachinePackMLVM = new(_adsManager, "GVL_SCADA.stMachine.stMachineCmds"); WeakReferenceMessenger.Default.Register(this); breadcrumb = ""; _adsManager.Register("GVL_SCADA.stMachine.stMachineCmds.eCurrentState", StateChanged); _adsManager.Register("GVL_SCADA.stMachine.stMachineCmds.eCurrentMode", ModeChanged); } public MainWindowVM() { // Only used for design time SCurrentPackMLMode = "Aktueller Modus: "; SCurrentPackMLState = "Aktueller Status: "; } public void NavigateFromOuterPage(NavigateMessage message, NavigateMessage nextMessage) { _currentMessage = message; Navigate(message, nextMessage); } private void StateChanged(object? sender, ValueChangedEventArgs e) { var state = (int)e.Value; var curState = "Aktueller Status: "; switch (state) { case 0: curState += "Undefined"; break; case 1: curState += "Clearing"; break; case 2: curState += "Stopped"; break; case 3: curState += "Starting"; break; case 4: curState += "Idle"; break; case 5: curState += "Suspended"; break; case 6: curState += "Execute"; break; case 7: curState += "Stopping"; break; case 8: curState += "Aborting"; break; case 9: curState += "Aborted"; break; case 10: curState += "Holding"; break; case 11: curState += "Held"; break; case 12: curState += "Unholding"; break; case 13: curState += "Suspending"; break; case 14: curState += "Unsuspending"; break; case 15: curState += "Resetting"; break; case 16: curState += "Completing"; break; case 17: curState += "Completed"; break; default: curState += "Undefined"; break; } SCurrentPackMLState = curState; } private void ModeChanged(object? sender, ValueChangedEventArgs e) { var curMode = "Aktueller Modus: "; var mode = (int)e.Value; switch (mode) { case 0: curMode += "Invalid"; break; case 1: curMode += "Production"; break; case 2: curMode += "Maintenance"; break; case 3: curMode += "Manual"; break; case 4: curMode += "change_over"; break; case 5: curMode += "clean"; break; case 6: curMode += "set up"; break; case 7: curMode += "empty out"; break; default: curMode += "Invalid"; break; } sCurrentPackMLMode = curMode; } [RelayCommand] private void SettingsWindow() { StatusBarVisible = Visibility.Visible; _messageStack.Clear(); NavigateMessage message = new("", typeof(SettingsPage)); Receive(message); } [RelayCommand] public void ChangeUserClicked() { var userWindowVm = new UserManagementWindowVm(currentUser); CurrentUser = userWindowVm.GetCurrentUserLevel(); OverviewWindowClicked(); } [RelayCommand] private void OverviewWindowClicked() { _messageStack.Clear(); _currentMessage = new NavigateMessage("", typeof(Page)); NavigateMessage message = new(_config[""]!, typeof(MachineOverviewPage)); Receive(message); } [RelayCommand] private void ProductionWindowClicked() { StatusBarVisible = Visibility.Visible; _messageStack.Clear(); _currentMessage = new NavigateMessage("", typeof(Page)); NavigateMessage message = new(_config[""]!, typeof(ProductionOverviewPage)); Receive(message); } [RelayCommand] private void ProtocolWindowClicked() { } [RelayCommand] private void ReceipesWindowClicked() { StatusBarVisible = Visibility.Visible; _messageStack.Clear(); _currentMessage = new NavigateMessage("", typeof(Page)); NavigateMessage message = new(_config[""]!, typeof(ReceipePage)); Receive(message); } [RelayCommand] private void TrendWindowClicked() { } [RelayCommand] private void ComponentsWindowClicked() { } [RelayCommand] private void SettingsWindowClicked() { _messageStack.Clear(); NavigateMessage message = new("", typeof(SettingsPage)); Receive(message); } [RelayCommand] public void EventsListClicked() { StatusBarVisible = Visibility.Collapsed; _messageStack.Clear(); _currentMessage = new NavigateMessage("", typeof(Page)); NavigateMessage message = new("", typeof(EventsPage)); Receive(message); } // Only use for forward traversal! public void Receive(NavigateMessage message) { // Only change page if its a new page type if (CurrentPage.GetType() == message.type) //return; // Push current message if (_currentMessage != null) _messageStack.Push(_currentMessage); // Save current message for later push _currentMessage = message; Navigate(message); } private void Navigate(NavigateMessage message, NavigateMessage? nextMessage = null) { // Dispose current pages viewmodel if (CurrentPage.DataContext is IDisposable viewModel) { CurrentPage.DataContext = null; viewModel.Dispose(); } // Create new page switch (message.type.Name) { case nameof(ProductionOverviewPage): if (_productionOverviewPageVM == null || nextMessage != null) _productionOverviewPageVM = new ProductionOverviewPageVM(_adsManager, _config, _eventlogger, nextMessage); ProductionOverviewPage productionOverviewPage = new() { DataContext = _productionOverviewPageVM }; CurrentPage = productionOverviewPage; break; case nameof(MachineOverviewPage): _machineOverviewPageVM?.Dispose(); _machineOverviewPageVM = new MachineOverviewPageVM(_adsManager, _config,this, new ProductionOverviewPageVM(_adsManager, _config, _eventlogger), _eventlogger); MachineOverviewPage machineOverviewPage = new() { DataContext = _machineOverviewPageVM }; CurrentPage = machineOverviewPage; break; case nameof(EventsPage): #pragma warning disable MVVMTK0034 // Direct field reference to [ObservableProperty] backing field EventsPage eventsPage = new() { DataContext = _eventsPageVM }; #pragma warning restore MVVMTK0034 // Direct field reference to [ObservableProperty] backing field CurrentPage = eventsPage; Breadcrumb = " > Events"; break; case nameof(SettingsPage): // Create seetings page view model only once if (_settingsPageVM == null) _settingsPageVM = new(_adsManager, "GVL_CONFIG.stUnitConfig"); SettingsPage settingsPage = new() { DataContext = _settingsPageVM }; CurrentPage = settingsPage; Breadcrumb = " > Settings"; break; case nameof(ReceipePage): if (_receipePageVM == null) _receipePageVM = new(); ReceipePage receipePage = new() { DataContext = _receipePageVM }; CurrentPage = receipePage; Breadcrumb = " > Kuka Roboter"; break; case nameof(HotCoolPlatePage): if (_hotCoolplatePageVM == null) _hotCoolplatePageVM = new(_adsManager, "directlySetInViewModel"); HotCoolPlatePage hotCoolPlatePage = new() {DataContext = _hotCoolplatePageVM }; CurrentPage = hotCoolPlatePage; Breadcrumb = " > Heiz- /Kühlplatte"; break; default: CurrentPage = new Page(); break; } } private void AppendBreadcrumb(string path) { if (Breadcrumb[^1] != ' ') Breadcrumb += " > " + path; else Breadcrumb += "> " + path; } [RelayCommand] private void AckAlarms() { _adsManager.WriteValue("GVL_SCADA.stConfirmAlarmsBtn.xRequest", true); } public void Dispose() { // Dispose current pages viewmodel if (CurrentPage.DataContext is IDisposable viewModel) { CurrentPage.DataContext = null; viewModel.Dispose(); } } }