using Ionic.Zip; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL; using Tango.BL.Builders; using Tango.BL.Entities; using Tango.Core; using Tango.Core.Commands; using Tango.Explorer; using Tango.Integration.Operation; using Tango.Logging; using Tango.PMR.Diagnostics; using Tango.PMR.IFS; using Tango.PMR.MachineStatus; using Tango.PMR.ThreadLoading; using Tango.PPC.Common; using Tango.PPC.Maintenance.Commands; using Tango.PPC.Maintenance.Dialogs; using Tango.PPC.Maintenance.Helpers; using Tango.PPC.Maintenance.Models; using Tango.PPC.Maintenance.Views; using Tango.PPC.Storage; using Tango.Settings; namespace Tango.PPC.Maintenance.ViewModels { public class MaintenanceViewVM : PPCViewModel { public enum Boards { //[Description("Main")] //Main = 1, [Description("Heads")] Heads = 1, [Description("Dryer")] Dryer = 2, [Description("Mid tanks")] Midtanks = 3, [Description("Lubricant")] Lubricant = 4, [Description("Dispenser 1")] Dispenser_1 = 5, [Description("Dispenser 2")] Dispenser_2 = 6, [Description("Dispenser 3")] Dispenser_3 = 7, [Description("Dispenser 4")] Dispenser_4 = 8, //[Description("Dispenser 5")] //Dispenser_5 = 9, //[Description("Dispenser 6")] //Dispenser_6 = 10, [Description("Winder 1")] Winder_1 = 11, [Description("Winder 2")] Winder_2 = 12, [Description("Winder 3")] Winder_3 = 13, [Description("Winder 4")] Winder_4 = 14, } public class WasteStateModel : ExtendedObject { public class RMLDisplayModel { public String Name { get; set; } public String Guid { get; set; } public String FinalName { get; set; } } private CartridgeState _state; public CartridgeState State { get { return _state; } set { _state = value; RaisePropertyChangedAuto(); } } public CartridgeSlot Slot { get; set; } } public ObservableCollection Guides { get; set; } public RelayCommand OpenGuideCommand { get; set; } private List _midTankLevels; public List MidTankLevels { get { return _midTankLevels; } set { _midTankLevels = value; RaisePropertyChangedAuto(); } } private OverallTemperatureModel _overallTemperature; public OverallTemperatureModel OverallTemperature { get { return _overallTemperature; } set { _overallTemperature = value; RaisePropertyChangedAuto(); } } private String _totalDyeTime; public String TotalDyeTime { get { return _totalDyeTime; } set { _totalDyeTime = value; RaisePropertyChangedAuto(); } } private String _totalDyeMeters; public String TotalDyeMeters { get { return _totalDyeMeters; } set { _totalDyeMeters = value; RaisePropertyChangedAuto(); } } private SpoolState _spoolState; public SpoolState SpoolState { get { return _spoolState; } set { if (_spoolState != value) { _spoolState = value; RaisePropertyChangedAuto(); } } } private List _wasteStates; public List WasteStates { get { return _wasteStates; } set { _wasteStates = value; RaisePropertyChangedAuto(); } } private bool _isInkAutoFillingEnabled; public bool IsInkAutoFillingEnabled { get { return _isInkAutoFillingEnabled; } set { _isInkAutoFillingEnabled = value; RaisePropertyChangedAuto(); OnInkAutoFillingChanged(); } } public List ListBoards { get { return typeof(Boards).GetEnumValues().Cast().ToList(); } } private Boards _selectedBoard; public Boards SelecteadBoard { get { return _selectedBoard; } set { _selectedBoard = value; RaisePropertyChangedAuto(); } } public List Rmls { get; set; } private ObservableCollection _RMLDisplayList; public ObservableCollection RMLDisplayList { get { return _RMLDisplayList; } set { _RMLDisplayList = value; RaisePropertyChangedAuto(); } } private WasteStateModel.RMLDisplayModel _selectedRML; public WasteStateModel.RMLDisplayModel SelectedRML { get { return _selectedRML; } set { if (_selectedRML != value) { _selectedRML = value; RaisePropertyChangedAuto(); } } } private String _threadLoadingStatus; public String ThreadLoadingStatus { get { return _threadLoadingStatus; } set { _threadLoadingStatus = value; RaisePropertyChangedAuto(); } } private bool _readyForLoading; public bool ReadyForLoading { get { return _readyForLoading; } set { _readyForLoading = value; RaisePropertyChangedAuto(); } } private bool _startedDryerWinding; public bool StartedDryerWinding { get { return _startedDryerWinding; } set { _startedDryerWinding = value; RaisePropertyChangedAuto(); } } private bool _enableHeaters; public bool EnableHeaters { get { return _enableHeaters; } set { if (_enableHeaters != value) { _enableHeaters = value; OnHeatersStateChanged(); RaisePropertyChangedAuto(); } } } public RelayCommand ExportLogsCommand { get; set; } public OpenCloseDyeingHeadCommand OpenCloseDyeingHeadCommand { get; set; } public OpenCloseLeftLeadingWheelsCommand OpenCloseLeftLeadingWheelsCommand { get; set; } public OpenCloseRightLeadingWheelsCommand OpenCloseRightLeadingWheelsCommand { get; set; } public ResetThreadLoadingCommand ResetThreadLoadingCommand { get; set; } public RelayCommand HeadCleaningCommand { get; set; } public RelayCommand StartThreadLoadingCommand { get; set; } public RelayCommand StartThreadBreakCommand { get; set; } public RelayCommand DispenseCleanerLiquidCommand { get; set; } public RelayCommand ViewBitResultsCommand { get; set; } public RelayCommand ResetBoardCommand { get; set; } public RelayCommand MoveToLoadPositionCommand { get; set; } public RelayCommand StartDryerWindingCommand { get; set; } public RelayCommand AbortThreadLoadingCommand { get; set; } private bool _canAbortThreadLoading; public bool CanAbortThreadLoading { get { return _canAbortThreadLoading; } set { _canAbortThreadLoading = value; RaisePropertyChangedAuto(); } } public MaintenanceViewVM() { Guides = new ObservableCollection(GuideHelper.CreateAllGuides()); OverallTemperature = new OverallTemperatureModel(); OpenGuideCommand = new RelayCommand(OpenGuide); ExportLogsCommand = new RelayCommand(ExportLogsToStorage); OpenCloseDyeingHeadCommand = new OpenCloseDyeingHeadCommand(); OpenCloseLeftLeadingWheelsCommand = new OpenCloseLeftLeadingWheelsCommand(); OpenCloseRightLeadingWheelsCommand = new OpenCloseRightLeadingWheelsCommand(); ResetThreadLoadingCommand = new ResetThreadLoadingCommand(); HeadCleaningCommand = new RelayCommand(PerformHeadCleaning, () => MachineProvider.MachineOperator.CanPrint); StartThreadLoadingCommand = new RelayCommand(StartThreadLoadingWizard, () => MachineProvider.MachineOperator.CanPrint); StartThreadBreakCommand = new RelayCommand(StartThreadBreakWizard, () => MachineProvider.MachineOperator.CanPrint); ViewBitResultsCommand = new RelayCommand(ViewBitResult, () => MachineProvider.MachineOperator.IsConnected); ResetBoardCommand = new RelayCommand(RunReset, () => MachineProvider.MachineOperator.IsConnected); MoveToLoadPositionCommand = new RelayCommand(MoveToLoadPosition, () => { return MachineProvider.MachineOperator.IsConnected && MachineProvider.MachineOperator.CanPrint && false == StartedDryerWinding; }); StartDryerWindingCommand = new RelayCommand(StartDryerWinding, () => ReadyForLoading); WasteStates = new List() { new WasteStateModel() { Slot = CartridgeSlot.WasteMiddle, State = CartridgeState.Absent }, new WasteStateModel() { Slot = CartridgeSlot.WasteLower, State = CartridgeState.Absent } }; SelecteadBoard = Boards.Dryer; ReadyForLoading = false; AbortThreadLoadingCommand = new RelayCommand(AbortThreadLoading); } public override void OnApplicationStarted() { MachineProvider.MachineOperator.InkFillingStatusChanged += MachineOperator_InkFillingStatusChanged; MachineProvider.MachineOperator.MachineStatusChanged += MachineOperator_MachineStatusChanged; MachineProvider.MachineOperator.MachineEventsStateProvider.EventsChanged += MachineEventsStateProvider_EventsChanged; MachineProvider.MachineOperator.ThreadLoadingStatusChanged += MachineOperator_ThreadLoadingStatusChanged; DispenseCleanerLiquidCommand = new RelayCommand(DispenseCleanerLiquid, () => { if (MachineProvider.Machine.MachineHeadType == BL.Enumerations.HeadTypes.Arc) { return MachineProvider.MachineOperator.MachineEventsStateProvider.Events.Any(x => x.Type == BL.Enumerations.EventTypes.DYEING_HEAD_ARC_LID_IS_OPEN); } else { return MachineProvider.MachineOperator.MachineEventsStateProvider.Events.Any(x => x.Type == BL.Enumerations.EventTypes.DYEING_HEAD_COVER_IS_OPEN); } }); RaisePropertyChanged(nameof(DispenseCleanerLiquidCommand)); _enableHeaters = true; RaisePropertyChanged(nameof(EnableHeaters)); } public async void CresteRMLS() { using (ObservablesContext db = ObservablesContext.CreateDefault()) { LogManager.Log("Loading RMLS..."); Rmls = (await new RmlsCollectionBuilder(db).SetAll().WithActiveParametersGroup().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).BuildAsync()).OrderBy(x => x.FinalName).ToList(); //Rmls = (await new RmlsCollectionBuilder(db).SetAll().WithActiveParametersGroup().BuildAsync()).OrderBy(x => x.FinalName).ToList(); RMLDisplayList = Rmls.Select(p => new WasteStateModel.RMLDisplayModel { Guid = p.Guid, Name = p.Name, FinalName = p.FinalName }).OrderBy(x => x.FinalName).ToObservableCollection(); SelectedRML = RMLDisplayList.FirstOrDefault(); } } public override void OnApplicationReady() { base.OnApplicationReady(); MidTankLevels = MachineProvider.Machine.Configuration.NoneEmptyIdsPacks.Where(x => x.MidTankType.HasLevelMeasure).OrderBy(x => x.PackIndex).Select(x => new MidTankLevelModel() { Max = MachineOperator.MAX_MIDTANK_LITERS, IDSPack = x, }).OrderBy(y => y.IDSPack.LiquidType.Code).ToList(); if (Rmls == null) CresteRMLS(); } private void MachineEventsStateProvider_EventsChanged(object sender, IEnumerable e) { OpenCloseDyeingHeadCommand.IsEnabled = !e.Any(x => x.Type == BL.Enumerations.EventTypes.DRYER_DOOR_OPEN); InvokeUI(() => { DispenseCleanerLiquidCommand.RaiseCanExecuteChanged(); }); } private void MachineOperator_MachineStatusChanged(object sender, MachineStatus status) { UpdateMidTankLevels(status); OverallTemperature.Temperature = status.OverallTemperature; SpoolState = status.SpoolState; _isInkAutoFillingEnabled = status.AutoInkFillingEnabled; RaisePropertyChanged(nameof(IsInkAutoFillingEnabled)); InvalidateRelayCommands(); } private void MachineOperator_InkFillingStatusChanged(object sender, InkFillingStatusChangedEventArgs e) { foreach (var cartridge in e.Status.CartridgesStatuses.Where(x => x.Cartridge.Slot != CartridgeSlot.Ink)) { var wasteState = WasteStates.SingleOrDefault(x => x.Slot == cartridge.Cartridge.Slot); if (wasteState != null) { wasteState.State = cartridge.State; } } } private void MachineOperator_ThreadLoadingStatusChanged(object sender, StartThreadLoadingResponse e) { if (e != null) { var State = e.State; switch (e.State) { case ThreadLoadingState.Preparing: { ThreadLoadingStatus = "Moving to load position"; break; } case ThreadLoadingState.ReadyForLoading: { ReadyForLoading = true; ThreadLoadingStatus = "Ready for thread loading."; break; } case ThreadLoadingState.PreparationError: { ThreadLoadingStatus = "Failed to move. Please inspect and try again."; break; } case ThreadLoadingState.Finalizing: { ThreadLoadingStatus = "Thread loading is running."; ReadyForLoading = false; break; } case ThreadLoadingState.FinalizationError: { ThreadLoadingStatus = $"Thread loading failed.{e.ErrorReason}"; ReadyForLoading = false; StartedDryerWinding = false; break; } case ThreadLoadingState.Completed: { ReadyForLoading = false; StartedDryerWinding = false; ThreadLoadingStatus = "Thread loading completed successfully."; break; } default: { ThreadLoadingStatus = ""; StartedDryerWinding = false; return; } }; if (e.State != ThreadLoadingState.None && e.State != ThreadLoadingState.Completed) { CanAbortThreadLoading = true; } } } public async void OpenGuide(GuideBase guide) { await NavigationManager.NavigateWithObject(guide); } private void UpdateMidTankLevels(MachineStatus status) { if (IsVisible) { foreach (var item in status.IDSPacksLevels) { var model = MidTankLevels.SingleOrDefault(x => x.IDSPack.PackIndex == item.Index); if (model != null) { model.Level = item.MidTankLevel; } } } } private async void ExportLogsToStorage() { var result = await NavigationManager. NavigateForResult( new Storage.Models.StorageNavigationRequest() { Intent = Storage.Models.StorageNavigationIntent.SaveFile, DefaultFileName = $"Tango-Logs-{DateTime.Now.ToFileName()}", Filter = "do not display anything", Title = "Export System Logs", }); if (result != null) { String file = result.Path + ".zip"; IsFree = false; try { NotificationProvider.SetGlobalBusyMessage("Exporting system logs..."); var appFileLogger = LogManager.RegisteredLoggers.FirstOrDefault(x => x is FileLogger) as FileLogger; await Task.Factory.StartNew(() => { using (ZipFile zip = new ZipFile(file)) { zip.Password = "1Creativity"; if (appFileLogger != null) { zip.AddDirectory(appFileLogger.Folder); } zip.ParallelDeflateThreshold = -1; zip.Save(); } }); NotificationProvider.ReleaseGlobalBusyMessage(); await NotificationProvider.ShowSuccess("System logs exported successfully."); } catch (Exception ex) { NotificationProvider.ReleaseGlobalBusyMessage(); LogManager.Log(ex, "Error exporting system logs."); await NotificationProvider.ShowError($"An error occurred while trying to export the system logs.\n{ex.FlattenMessage()}"); } finally { NotificationProvider.ReleaseGlobalBusyMessage(); IsFree = true; } } } public async override void OnNavigatedTo() { base.OnNavigatedTo(); try { using (ObservablesContext db = ObservablesContext.CreateDefault()) { var jobRuns = await db.JobRuns.Select(x => new { x.StartDate, x.EndDate, x.EndPosition }).ToListAsync(); TotalDyeTime = TimeSpan.FromHours(jobRuns.Select(x => x.EndDate - x.StartDate).Sum(x => x.TotalHours)).ToStringUnlimitedHours(); int meters = (int)jobRuns.Select(x => x.EndPosition).Sum(); TotalDyeMeters = $"{meters.ToString("N0")} meters"; } } catch (Exception ex) { LogManager.Log(ex, "Error loading machine counters."); TotalDyeTime = "error!"; TotalDyeMeters = "error!"; } } private async void PerformHeadCleaning() { await NotificationProvider.ShowDialog(); } private void StartThreadLoadingWizard() { ThreadLoadingService.StartThreadLoadingWizard(); } private void StartThreadBreakWizard() { ThreadLoadingService.StartThreadBreakWizard(); } private async void DispenseCleanerLiquid() { await NotificationProvider.ShowDialog(); } private async void OnInkAutoFillingChanged() { if (IsInkAutoFillingEnabled) { try { NotificationProvider.SetGlobalBusyMessage("Enabling auto ink filling..."); await MachineProvider.MachineOperator.SendRequest(new SetInkAutoFillingModeRequest() { Enable = true }); } catch (Exception ex) { LogManager.Log(ex, "Error enabling auto ink filling."); _isInkAutoFillingEnabled = false; RaisePropertyChanged(nameof(IsInkAutoFillingEnabled)); await NotificationProvider.ShowError($"Error enabling auto ink filling.\n{ex.Message}"); } finally { NotificationProvider.ReleaseGlobalBusyMessage(); } } else { try { NotificationProvider.SetGlobalBusyMessage("Disabling auto ink filling..."); await MachineProvider.MachineOperator.SendRequest(new SetInkAutoFillingModeRequest() { Enable = false }); } catch (Exception ex) { LogManager.Log(ex, "Error disabling auto ink filling."); _isInkAutoFillingEnabled = true; RaisePropertyChanged(nameof(IsInkAutoFillingEnabled)); await NotificationProvider.ShowError($"Error disabling auto ink filling.\n{ex.Message}"); } finally { NotificationProvider.ReleaseGlobalBusyMessage(); } } } private async void ViewBitResult() { await BitManager.ShowBitResultsDialog(); } private async void RunReset() { try { await MachineProvider.MachineOperator.ResetCard(SelecteadBoard.ToInt32()); await NotificationProvider.ShowInfo($"The {SelecteadBoard.ToDescription()} was reset successfully!"); } catch (Exception ex) { await NotificationProvider.ShowError($"We could not reset the {SelecteadBoard.ToDescription()}.\n{ex.FlattenMessage()}"); } } private void MoveToLoadPosition() { MachineProvider.MachineOperator.StartThreadLoading(); } private async void AbortThreadLoading() { if (CanAbortThreadLoading) { try { CanAbortThreadLoading = false; ThreadLoadingStatus = "Aborting thread loading..."; await MachineProvider.MachineOperator.AbortThreadLoading(); await Task.Delay(1000); ThreadLoadingStatus = "Thread loading aborted"; } catch (Exception ex) { LogManager.Log(ex, "Error aborting thread loading."); CanAbortThreadLoading = true; } } } private void StartDryerWinding() { try { var rml = Rmls.Where(x => x.Guid == SelectedRML.Guid).FirstOrDefault(); if (rml != null && rml.GetActiveProcessGroup() != null) { var processParametersTable = rml.GetActiveProcessGroup().ProcessParametersTables.FirstOrDefault(); if (processParametersTable != null) { StartedDryerWinding = true; MachineProvider.MachineOperator.ContinueThreadLoading(processParametersTable.Clone()); } } } catch (Exception) { StartedDryerWinding = false; } } private async void OnHeatersStateChanged() { if (EnableHeaters == false)//turn off heaters { try { await MachineProvider.MachineOperator.UploadProcessParameters(new ProcessParametersTable()); } catch (Exception ex) { LogManager.Log(ex, "Error resetting process parameters."); } } else { try { var currentProcessParameters = MachineProvider.MachineOperator.CurrentProcessParameters; if (currentProcessParameters == null || currentProcessParameters.Guid == null) { var settings = SettingsManager.Default.GetOrCreate(); var defRmlGuid = Settings.DefaultRmlGuid ?? Rmls.First().Guid; var rml = Rmls.Where(x => x.Guid == defRmlGuid).FirstOrDefault(); if (rml != null && rml.GetActiveProcessGroup() != null) { currentProcessParameters = rml.GetActiveProcessGroup().ProcessParametersTables.FirstOrDefault(); } } if (currentProcessParameters != null) { await MachineProvider.MachineOperator.UploadProcessParameters(currentProcessParameters); } } catch (Exception ex) { LogManager.Log(ex, "Error upload process parameters."); } } } } }