//todo fix sending public async Task ExecuteCommandAsync(BedControlCommand command) { AssertInitParams(); var isFree = await _semaphoreSlim .WaitAsync(_config.Timeout) .ConfigureAwait(false); if (!isFree) { throw new DeviceConnectionException( $"Не удалось подключиться к инверсионному столу в течение {_config.Timeout.TotalMilliseconds}"); } await Task.Factory.StartNew(() => { try { AssertConnection(); var message = new BedMessage(BedMessageEventType.Write); var sendMessage = message.GetBedCommandMessage(command); _udpSendingClient.Send(sendMessage, sendMessage.Length); //todo зачем после каждой отправки мы ожидаем ответа? Мы делаем из UDP свой TCP _udpReceivingClient.Receive(ref _remoteRecievedIpEndPoint); } catch (DeviceConnectionException) { IsConnected = false; throw; } catch (SocketException e) { IsConnected = false; throw new DeviceConnectionException("Ошибка соединения с инверсионным столом", e); } catch (ObjectDisposedException e) { IsConnected = false; throw new DeviceConnectionException("Ошибка соединения с инверсионным столом", e); } catch (Exception e) { IsConnected = false; throw new DeviceProcessingException("Ошибка отправки команды инверсионному столу", e); } finally { _semaphoreSlim.Release(); } }) .ConfigureAwait(false); }
/// <summary> /// Установить/снять блокировку кровати (на время измерения с КМ) /// </summary> /// <param name="isBlock"></param> /// <returns></returns> /// <exception cref="DeviceConnectionException"></exception> //todo fix public async Task SetBedBlock(bool isBlock) { AssertInitParams(); AssertConnection(); // немного подождем, чтобы завершилось начатое обновление данных var waitingTimeout = GetWaitingTimeout(); var isFree = await _semaphoreSlim .WaitAsync(waitingTimeout) .ConfigureAwait(false); if (!isFree) { throw new DeviceConnectionException( $"Не удалось подключиться к инверсинному столу в течение {waitingTimeout.TotalMilliseconds} мс"); } await Task.Factory.StartNew(() => { try { var message = new BedMessage(); var sendMessage = message.SetBedBlockMessage(isBlock); //todo а получить подтверждение _udpSendingClient.Send(sendMessage, sendMessage.Length); } catch (SocketException e) { IsConnected = false; throw new DeviceConnectionException("Ошибка отключения от инверсионного стола", e); } catch (ObjectDisposedException e) { IsConnected = false; throw new DeviceConnectionException("Ошибка отключения от инверсионного стола", e); } catch (Exception e) { IsConnected = false; throw new DeviceProcessingException("Ошибка отключения от инверсионного стола", e); } finally { _semaphoreSlim.Release(); } }).ConfigureAwait(false); }
/// <summary> /// Обновляет значения регистров с кровати /// </summary> private async Task UpdateRegistersValueAsync() { // немного подождем, чтобы завершилось начатое обновление данных var waitingTimeout = GetWaitingTimeout(); var isFree = await _semaphoreSlim .WaitAsync(waitingTimeout) .ConfigureAwait(false); if (!isFree) { throw new DeviceConnectionException( $"Не удалось подключиться к инверсинному столу в течение {waitingTimeout.TotalMilliseconds} мс"); } await Task.Factory.StartNew(() => { try { AssertConnection(); //здесь запрос данных и их парсинг var message = new BedMessage(BedMessageEventType.ReadAll); var getAllRegister = message.GetAllRegisterMessage(); _udpSendingClient.Send(getAllRegister, getAllRegister.Length); var receiveMessage = _udpReceivingClient.Receive(ref _remoteRecievedIpEndPoint); var previouslRegisterValues = _registerValues; _registerValues = message.GetAllRegisterValues(receiveMessage); if ((previouslRegisterValues.BedStatus == BedStatus.SessionStarted || previouslRegisterValues.BedStatus == BedStatus.Pause) && _registerValues.BedStatus == BedStatus.Reverse) { OnReverseFromDeviceRequested?.Invoke(this, EventArgs.Empty); } if (previouslRegisterValues.BedStatus == BedStatus.SessionStarted && _registerValues.BedStatus == BedStatus.Pause) { OnPauseFromDeviceRequested?.Invoke(this, EventArgs.Empty); } if (previouslRegisterValues.BedStatus == BedStatus.Pause && _registerValues.BedStatus == BedStatus.SessionStarted) { OnResumeFromDeviceRequested?.Invoke(this, EventArgs.Empty); } if (previouslRegisterValues.BedStatus != BedStatus.EmergencyStop && _registerValues.BedStatus == BedStatus.EmergencyStop) { OnEmeregencyStopFromDeviceRequested?.Invoke(this, EventArgs.Empty); } } catch (DeviceConnectionException) { IsConnected = false; throw; } catch (SocketException e) { IsConnected = false; throw new DeviceConnectionException("Ошибка соедининия с инверсионным столом", e); } catch (ObjectDisposedException e) { IsConnected = false; throw new DeviceConnectionException("Ошибка соедининия с инверсионным столом", e); } catch (Exception e) { IsConnected = false; throw new DeviceProcessingException("Ошибка получения данных от инверсионного стола", e); } finally { _semaphoreSlim.Release(); } }).ConfigureAwait(false); }
public async Task PrepareDeviceForSessionAsync() { AssertInitParams(); if (_initialisingStatus == DeviceIsInitialising) { throw new InvalidOperationException("Инициализация уже выполняется"); } Interlocked.Exchange(ref _initialisingStatus, DeviceIsInitialising); // немного подождем, чтобы завершилось начатое обновление данных var waitingTimeout = GetWaitingTimeout(); var isFree = await _semaphoreSlim .WaitAsync(waitingTimeout) .ConfigureAwait(false); if (!isFree) { throw new DeviceConnectionException( $"Не удалось подключиться к инверсинному столу в течение {waitingTimeout.TotalMilliseconds} мс"); } AssertConnection(); try { // очистим перед подключением все накопленные ошибки while (_lastExceptions.TryDequeue(out _)) { } await Task.Factory.StartNew(async() => { var message = new BedMessage(BedMessageEventType.Write); var sendMessage = message.SetMaxAngleValueMessage(_config.MaxAngleX); _udpSendingClient.Send(sendMessage, sendMessage.Length); _udpReceivingClient.Receive(ref _remoteRecievedIpEndPoint); await Task.Delay(_bedInitStepDelay) .ConfigureAwait(false); sendMessage = message.SetFreqValueMessage(_config.MovementFrequency); _udpSendingClient.Send(sendMessage, sendMessage.Length); _udpReceivingClient.Receive(ref _remoteRecievedIpEndPoint); await Task.Delay(_bedInitStepDelay) .ConfigureAwait(false); sendMessage = message.SetCycleCountValueMessage((byte)_config.CyclesCount); _udpSendingClient.Send(sendMessage, sendMessage.Length); _udpReceivingClient.Receive(ref _remoteRecievedIpEndPoint); }) .ConfigureAwait(false); } catch (SocketException e) { IsConnected = false; throw new DeviceConnectionException("Ошибка подключения к инверсионному столу", e); } catch (ObjectDisposedException e) { IsConnected = false; throw new DeviceConnectionException("Ошибка подключения к инверсионному столу", e); } catch (Exception e) { IsConnected = false; throw new DeviceProcessingException("Ошибка старта сеанса инверсионного стола", e); } finally { Interlocked.Exchange(ref _initialisingStatus, DeviceIsNotInitialising); _semaphoreSlim.Release(); } }