/// <summary> /// Инициализируем устройства приема наличных, включаем питание на шине MDB /// </summary> /// <returns></returns> public static async Task Init_MDB() { try { while (MDB.MDBSerialPort == null) { await Task.Delay(100); } MDB.MDBStarted += CashDevices_MDBStarted; MDB.MDBCCTubesStatus += CashDevices_MDBCCTubesStatus; MDB.MDBChangeDispensed += CashDevices_MDBChangeDispensed; MDB.MDBInsertedBill += CashDevices_MDBInsertedBill; MDB.MDBInsertedCoinRoutedToCashBox += CashDevices_MDBInsertedCoinRoutedToCashBox; MDB.MDBInsertedCoinRoutedToCCTube += CashDevices_MDBInsertedCoinRoutedToCCTube; MDB.MDBDataProcessingError += CashDevices_MDBDataProcessingError; MDB.MDBError += CashDevices_MDBError; MDB.MDBCCReseted += CashDevices_MDBCCReseted; MDB.MDBBAReseted += CashDevices_MDBBAReseted; MDB.MDBCCPayOutBusy += CashDevices_MDBCCPayOutBusy; MDB.MDBInformationMessageReceived += CashDevices_MDBInformationMessageReceived; #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Run(MDB.DispensedCoinsInfoTask, StartPage.GlobalCancellationTokenSource.Token); Task.Run(MDB.SendCommandTask, StartPage.GlobalCancellationTokenSource.Token); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBLED, Colors.Yellow); StartPage.AddItemToLogBox("Включаем питание шины MDB..."); StartPage.MDBPin.Write(GpioPinValue.Low); } catch { StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBLED, Colors.Red); } }
/// <summary> /// Подключаем обработчики событий от устройств, включаем питание на шине MDB /// </summary> /// <returns></returns> public static void StartMDB() { try { MDB.MDBAdapterStarted += CashDevices_MDBStarted; MDB.MDBCoinChangerTubesStatus += CashDevices_MDBCCTubesStatus; MDB.MDBChangeDispensed += CashDevices_MDBChangeDispensed; MDB.MDBInsertedBill += CashDevices_MDBInsertedBill; MDB.MDBInsertedCoinRoutedToCashBox += CashDevices_MDBInsertedCoinRoutedToCashBox; MDB.MDBInsertedCoinRoutedToCoinChangerTube += CashDevices_MDBInsertedCoinRoutedToCCTube; MDB.MDBDataProcessingError += CashDevices_MDBDataProcessingError; MDB.MDBError += CashDevices_MDBError; MDB.MDBCoinChangerReseted += CashDevices_MDBCCReseted; MDB.MDBBillValidatorReseted += CashDevices_MDBBAReseted; MDB.MDBCoinChangerPayoutStarted += CashDevices_MDBCCPayOutStarted; MDB.MDBInformationMessageReceived += CashDevices_MDBInformationMessageReceived; StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBLED, Colors.Yellow); StartPage.AddItemToLogBox("Включаем питание шины MDB..."); StartPage.MDBPin.Write(GpioPinValue.Low); } catch { StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBLED, Colors.Red); } }
public static Task DispensedCoinsInfoTask() { Task.Delay(1000).Wait(); StartPage.AddItemToLogBox("Старт отслеживания выданной сдачи..."); while (true) { try { if (CheckDispenseResult) { GetDispensedInfo(); StartPage.AddItemToLogBox("Ожидаем данные о выданной сдаче..."); int RetryCount = 0; while (CheckDispenseResult && RetryCount < 51) //ждать ответа от монетоприемника будем 5 секунд, потом забъем хуй и продолжим работать { Task.Delay(100).Wait(); //пауза на 0.1сек RetryCount++; } CheckDispenseResult = false; } } catch (Exception ex) { StartPage.AddItemToLogBox(ex.Message); } Task.Delay(1000).Wait(); } }
private static void CashDesk_AllTasksCancelled() { if (StartPage.CurrentState == StartPage.States.Init) { StartPage.AddItemToLogBox("Успешная отмена заданий ККТ"); } }
/// <summary> /// информация о состоянии смены /// </summary> /// <param name="StageStateString"></param> private static void CashDesk_StageStateReceived(StageProperties StageState) { try { //SystemState.KKTStageOpened = (StageState.CurrentStageState == StageProperties.StageState.Opened); StartPage.SystemState.KKTStageOver24h = (StageState.CurrentStageState == StageProperties.StageState.Over24h); StartPage.SystemState.LastStageClosedDateTime = Convert.ToInt64(StageState.StageClosedDateTime.ToString("yyyyMMddHHmmss")); StartPage.SystemState.LastStageClosedDateTimeStr = StageState.StageClosedDateTime.ToString("dd.MM.yyyy HH:mm:ss"); if (StartPage.CurrentState != StartPage.States.Init && StartPage.CurrentState != StartPage.States.OutOfService && StartPage.CurrentState != StartPage.States.ServiceMode && StartPage.SystemState.KKTStageOver24h) { StartPage.CurrentState = StartPage.States.OutOfService; #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed MDB.DisableCashDevicesAsync(); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { var frame = Window.Current.Content as Frame; frame.Navigate(typeof(OutOfServicePage)); }); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed StartPage.AddItemToLogBox("Длительность смены превысила 24ч, устройство переведено в режим \"Не обслуживает\""); } } catch { } }
/// <summary> /// Обрабатыввем сведения о выданной сдаче /// </summary> /// <param name="DispensedSum"></param> private static void CashDevices_MDBChangeDispensed(List <MDB.CoinsRecord> CoinsRecords) { double tmpdispvalue = CoinsRecords.Sum(x => x.CoinValue * x.CoinsDispensed); StartPage.AddItemToLogBox("Выдана сдача, руб: " + tmpdispvalue.ToString("N2")); StartPage.UserDeposit -= tmpdispvalue; StartPage.CurrentSaleSession.ActualChangeDispensed += (int)tmpdispvalue; }
/// <summary> /// Монета помещена в кэшбокс /// </summary> /// <param name="CoinValue"></param> private static void CashDevices_MDBInsertedCoinRoutedToCashBox(double CoinValue) { StartPage.AddItemToLogBox("Монета помещена в кэшбокс ₽" + CoinValue.ToString("N2")); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed ServiceTasks.UpdateCashCounter(1, CoinValue, 0, 0); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed if ((StartPage.CurrentState == StartPage.States.ReadyToServe) || (StartPage.CurrentState == StartPage.States.ReadyToDispenseWater)) { StartPage.UserDeposit += CoinValue; } }
/// <summary> /// Вставлена купюра /// </summary> /// <param name="BillValue"></param> private static void CashDevices_MDBInsertedBill(double BillValue) { StartPage.AddItemToLogBox("Прием купюры ₽" + BillValue.ToString("N2")); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed ServiceTasks.UpdateCashCounter(0, 0, 1, (int)BillValue); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed if ((StartPage.CurrentState == StartPage.States.ReadyToServe) || (StartPage.CurrentState == StartPage.States.ReadyToDispenseWater)) { StartPage.UserDeposit += BillValue; } }
/// <summary> /// MDB устройства включены /// </summary> private static void CashDevices_MDBStarted() { Task.Run(() => { StartPage.UpdateProgress(10); StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBLED, Colors.Green); StartPage.AddItemToLogBox("Найден адаптер MDB-RS232"); int count = 0; while (count < 10) { Task.Delay(100).Wait(); count++; } MDB.MDBInitStep = 1; MDB.ResetCashDevices(); }); }
/// <summary> /// Критическая ошибка устройств приема наличных /// </summary> /// <param name="ErrorMessage"></param> private static void CashDevices_MDBError(string ErrorMessage) { if ((StartPage.CurrentState == StartPage.States.ReadyToServe) || (StartPage.CurrentState == StartPage.States.ReadyToDispenseWater) || (StartPage.CurrentState == StartPage.States.DispenseChange)) { StartPage.CurrentState = StartPage.States.OutOfService; MDB.MDBInitStep = 6; MDB.DisableCashDevices(); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { var frame = Window.Current.Content as Frame; frame.Navigate(typeof(OutOfServicePage)); }); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed StartPage.AddItemToLogBox("Устройства приема наличных принудительно отключены из-за ошибки."); } }
/// <summary> /// Берем MAC сетевой карты, вычисляем MD5 хеш, надеемся, что полученное значение уникально /// </summary> /// <returns></returns> private static string GetHardwareID() { string result = ""; var networkProfiles = Windows.Networking.Connectivity.NetworkInformation.GetConnectionProfiles().ToList(); foreach (var net in networkProfiles) { result += net.NetworkAdapter.NetworkAdapterId.ToString(); } string strAlgName = HashAlgorithmNames.Md5; IBuffer buffUtf8Msg = CryptographicBuffer.ConvertStringToBinary(result, BinaryStringEncoding.Utf8); HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName); IBuffer buffHash = objAlgProv.HashData(buffUtf8Msg); string hex = CryptographicBuffer.EncodeToHexString(buffHash); StartPage.AddItemToLogBox("Hardware ID: " + hex); return(hex); }
/// <summary> /// MDB устройства включены /// </summary> private static void CashDevices_MDBStarted() { Task.Run(() => { StartPage.UpdateProgress(15); StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBLED, Colors.Green); StartPage.UpdateStartLEDs(StartPage.StartPageInstance.UART0LED, Colors.Green); StartPage.AddItemToLogBox("Найден адаптер MDB-RS232"); int count = 0; while (count < 10) { Task.Delay(100).Wait(); count++; } MDBInitStep = 1; #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed MDB.ResetCashDevicesAsync(); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed }); }
/// <summary> /// Инициализирует последовательный порт шины MDB /// </summary> /// <param name="cashdeskseroalportid">Исключить конкретный порт из поиска</param> public static async void ConnectMDBSerialPort(string cashdeskseroalportid) { try { MDBCommandsListSemaphore.Release(); StartPage.UpdateStartLEDs(StartPage.StartPageInstance.UART0LED, Colors.Yellow); StartPage.UpdateProgress(5); StartPage.AddItemToLogBox("Поиск последовательного порта шины MDB..."); string aqs = SerialDevice.GetDeviceSelector(); var dis = await DeviceInformation.FindAllAsync(aqs); foreach (var item in dis) { if (item.Id != cashdeskseroalportid) { MDBSerialPort = await SerialDevice.FromIdAsync(item.Id); } } if (MDBSerialPort == null) { return; } MDBSerialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000); MDBSerialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000); MDBSerialPort.BaudRate = 9600; MDBSerialPort.Parity = SerialParity.None; MDBSerialPort.StopBits = SerialStopBitCount.One; MDBSerialPort.DataBits = 8; string a = "Порт шины MDB успешно настроен: "; a += MDBSerialPort.BaudRate + "-"; a += MDBSerialPort.DataBits + "-"; a += MDBSerialPort.Parity.ToString() + "-"; a += MDBSerialPort.StopBits; StartPage.AddItemToLogBox(a); ListenMDBSerialPort(); } catch (Exception ex) { StartPage.AddItemToLogBox(ex.Message); } }
/// <summary> /// Критическая ошибка устройств приема наличных /// </summary> /// <param name="ErrorMessage"></param> private static void CashDevices_MDBError(string ErrorMessage) { if ((StartPage.CurrentState == StartPage.States.ReadyToServe) || (StartPage.CurrentState == StartPage.States.ReadyToDispenseWater) || (StartPage.CurrentState == StartPage.States.DispenseChange)) { ChangePage.ChangeModeSemaphore.Wait(); //надо убедиться, что выдача сдачи так или иначе завершена и сессия продажи закрыта ChangePage.ChangeModeSemaphore.Release(); //удерживать флаг эксклюзивного доступа ни к чему, освобождаем StartPage.CurrentState = StartPage.States.OutOfService; MDBInitStep = 6; #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed MDB.DisableCashDevicesAsync(); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { var frame = Window.Current.Content as Frame; frame.Navigate(typeof(OutOfServicePage)); }); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed StartPage.AddItemToLogBox("Устройства приема наличных принудительно отключены из-за ошибки."); } }
/// <summary> /// произведен сброс купюроприемника /// </summary> private static void CashDevices_MDBBAReseted() { Task.Run(() => { Mutex m2 = new Mutex(true, "MDBDeviceResetHandlerMutex", out bool mutexWasCreated); if (!mutexWasCreated) { try { m2.WaitOne(); } catch (AbandonedMutexException) { } } try { if ((!StartPage.bareset) && (MDB.MDBInitStep == 3 || MDB.MDBInitStep == 4)) { MDB.MDBInitStep++; StartPage.UpdateProgress(5); StartPage.bareset = true; StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBBALED, Colors.Green); StartPage.AddItemToLogBox("Купюроприемник готов к работе"); if (StartPage.ccreset) { string oosfilename = ApplicationData.Current.LocalFolder.Path + "\\" + GlobalVars.HardWareID + ".031"; StartPage.CurrentState = StartPage.States.OutOfService; #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { var frame = Window.Current.Content as Frame; frame.Navigate(typeof(OutOfServicePage)); }); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed StartPage.AddItemToLogBox("Ожидание полной инициализации..."); int count = 0; while (count < 100) { Task.Delay(100).Wait(); count++; } MDB.MDBInitStep = 5; StartPage.AddItemToLogBox("Устройства приема наличных обнаружены и настроены"); } } if ((!StartPage.bainit) && (MDB.MDBInitStep == 1 || MDB.MDBInitStep == 2)) { MDB.MDBInitStep++; StartPage.UpdateProgress(5); StartPage.bainit = true; StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBBALED, Colors.Yellow); StartPage.AddItemToLogBox("Купюроприемник инициализирован"); StartPage.UpdateProgress(5); int count = 0; while (count < 20) { Task.Delay(100).Wait(); count++; } MDB.ResetBA(); } } catch (Exception ex) { StartPage.AddItemToLogBox("Ошибка: " + ex.Message); } finally { } m2.ReleaseMutex(); m2.Dispose(); }); }
/// <summary> /// Обрабатыввем сведения о выданной сдаче /// </summary> /// <param name="DispensedSum"></param> private static void CashDevices_MDBChangeDispensed(int DispensedSum) { StartPage.AddItemToLogBox("Выдана сдача, руб: " + DispensedSum.ToString("N2")); }
/// <summary> /// Считывает данные с ппоследовательного порта шины MDB /// </summary> private static async void ListenMDBSerialPort() { StartPage.UpdateProgress(5); while (true) { try { while (MDBSerialPort == null) { await Task.Delay(100); } StartPage.UpdateStartLEDs(StartPage.StartPageInstance.UART0LED, Colors.Green); StartPage.AddItemToLogBox("Порт MDB открыт, ожидание данных..."); MDBSerialDataReaderObject = new DataReader(MDBSerialPort.InputStream) { InputStreamOptions = InputStreamOptions.Partial }; List <byte> tmpres = new List <byte> { }; while (true) { Task <UInt32> loadAsyncTask = MDBSerialDataReaderObject.LoadAsync(64).AsTask(StartPage.GlobalCancellationTokenSource.Token); UInt32 bytesRead = 0; bytesRead = await loadAsyncTask; if (bytesRead > 0) { byte[] tmpbyte = new byte[bytesRead]; MDBSerialDataReaderObject.ReadBytes(tmpbyte); for (int i = 0; i < tmpbyte.Length; i++) { if ((tmpbyte[i] == '\n') /* || (tmpbyte[tmpbyte.Length - 1] == 10)*/) { byte[] b = tmpres.ToArray(); //Task.Factory.StartNew(() => { ProcessIncomingMDB(b); }); //ProcessIncomingMDB(b); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Run(() => { Mutex mut = new Mutex(true, "DataProcessMutex", out bool created); if (!created) { try { mut.WaitOne(); } catch { } } string tmpstr = Encoding.UTF8.GetString(b).Trim(); if (tmpstr == "00 00 00") { return; } tmpstr = tmpstr.Replace("\r", ""); CurrenzaC2Green_ICTA7V7_DataProcess(tmpstr); mut.ReleaseMutex(); mut.Dispose(); }); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed tmpres = new List <byte> { }; } else { tmpres.Add(tmpbyte[i]); } } //CollectMDBData(tmpbyte); //Task.Factory.StartNew(() => { CollectMDBData(tmpbyte); }); } } } catch (TaskCanceledException) { CloseMDBSerialDevice(); } catch (Exception ex) { StartPage.AddItemToLogBox(ex.Message); } finally { if (MDBSerialDataReaderObject != null) { MDBSerialDataReaderObject.DetachStream(); MDBSerialDataReaderObject = null; } } } }
/// <summary> /// Ошибка при обработке данных от устройств приема наличных /// </summary> /// <param name="DataProcessingErrorMessage"></param> private static void CashDevices_MDBDataProcessingError(string DataProcessingErrorMessage) { StartPage.AddItemToLogBox(DataProcessingErrorMessage); }
/// <summary> /// Обрабатываем текстовую информацию от устройств приема наличных /// </summary> /// <param name="MDBInformationMessage"></param> private static void CashDevices_MDBInformationMessageReceived(string MDBInformationMessage) { StartPage.AddItemToLogBox(MDBInformationMessage); }
/// <summary> /// Инициализирует последовательный порт фискального регистратора /// </summary> public static async void CashDesk_Init() { try { StartPage.UpdateStartLEDs(StartPage.StartPageInstance.UART1LED, Colors.Yellow); StartPage.UpdateProgress(5); StartPage.AddItemToLogBox("Поиск последовательного порта ККТ..."); string aqs = SerialDevice.GetDeviceSelector(); var dis = await DeviceInformation.FindAllAsync(aqs); foreach (var item in dis) { if (item.Name.Contains("FT232")) { CashDesk.CashDeskDeviceSerialPort = await SerialDevice.FromIdAsync(item.Id); StartPage.CashDeskDeviceID = item.Id; break; } } if (CashDesk.CashDeskDeviceSerialPort == null) { return; } CashDesk.CashDeskDeviceSerialPort.WriteTimeout = TimeSpan.FromMilliseconds(100); CashDesk.CashDeskDeviceSerialPort.ReadTimeout = TimeSpan.FromMilliseconds(100); CashDesk.CashDeskDeviceSerialPort.BaudRate = 9600; CashDesk.CashDeskDeviceSerialPort.Parity = SerialParity.None; CashDesk.CashDeskDeviceSerialPort.StopBits = SerialStopBitCount.One; CashDesk.CashDeskDeviceSerialPort.DataBits = 8; CashDesk.DeviceTypeReceived += CashDesk_DeviceTypeReceived; CashDesk.KKTPrinterStateReceived += CashDesk_KKTPrinterStateReceived; CashDesk.KKTStateReceived += CashDesk_KKTStateReceived; CashDesk.CashDeskCurrentStageParametersReceived += CashDesk_CashDeskCurrentStageParametersReceived; CashDesk.StageStateReceived += CashDesk_StageStateReceived; CashDesk.CurrentModeChanged += CashDesk_CurrentModeChanged; CashDesk.CloseStageResult += CashDesk_CloseStageResult; CashDesk.OpenStageResult += CashDesk_OpenStageResult; CashDesk.OpenReceiptResult += CashDesk_OpenReceiptResult; CashDesk.CancelReceiptResult += CashDesk_CancelReceiptResult; CashDesk.StartReceiptEntryResult += CashDesk_StartReceiptEntryResult; CashDesk.AddEntryDataResult += CashDesk_AddEntryDataResult; CashDesk.ReceiptPaymentResult += CashDesk_ReceiptPaymentResult; CashDesk.CloseReceiptResult += CashDesk_CloseReceiptResult; CashDesk.AllTasksCancelled += CashDesk_AllTasksCancelled; string a = "Последовательный порт ККТ успешно настроен: "; a += CashDesk.CashDeskDeviceSerialPort.BaudRate + "-"; a += CashDesk.CashDeskDeviceSerialPort.DataBits + "-"; a += CashDesk.CashDeskDeviceSerialPort.Parity.ToString() + "-"; a += CashDesk.CashDeskDeviceSerialPort.StopBits; StartPage.AddItemToLogBox(a); while (CashDesk.CashDeskDeviceSerialPort == null) { await Task.Delay(100); } StartPage.AddItemToLogBox("Порт ККТ открыт, ожидание данных..."); StartPage.UpdateStartLEDs(StartPage.StartPageInstance.UART1LED, Colors.Green); CashDesk.StartCommunication(); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Run(CashDesk.IncomingKKTDataWatcher, StartPage.GlobalCancellationTokenSource.Token); Task.Run(CashDesk.KKTTaskWatcher, StartPage.GlobalCancellationTokenSource.Token); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } catch (Exception ex) { StartPage.AddItemToLogBox(ex.Message); } }
/// <summary> /// результат смены режима /// </summary> /// <param name="ResultString"></param> private static void CashDesk_CurrentModeChanged(string ResultString) { StartPage.AddItemToLogBox(ResultString); }