Пример #1
0
        public async Task <bool> ConnectDevice(SensorDevice sensorDevice, CancellationTokenSource tokenSource, int slotIndex = -1)
        {
            _isBusy = true;
            // Cannot connect to an already connected device or devices that is neither master or slave.
            if (sensorDevice.IsConnected || sensorDevice.Type == DeviceType.None)
            {
                return(false);
            }

            _log.Info("Connecting to a device.");

            if (_deviceSlotService.AllSlotsAreFull)
            {
                _userDialogs.Alert(new AlertConfig
                {
                    Message = $"The device list is full. Please disconnect a device before attempting to connect another one."
                });
                _isBusy = false;
                return(false);
            }

            DeviceSlot emptySlot;

            if (slotIndex > -1)
            {
                emptySlot = _deviceSlotService.DeviceSlots[slotIndex];
            }
            else
            {
                emptySlot = _deviceSlotService.GetEmptySlot(sensorDevice.Type);
            }

            if (emptySlot == null)
            {
                _userDialogs.Alert(new AlertConfig
                {
                    Message = $"Cannot connect to more devices of this type."
                });
                _isBusy = false;
                return(false);
            }

            _log.Debug($"Connecting to {sensorDevice.Type}");
            // Attempt to connect to device.
            int timeout = 4000; // 4 second timeout
            var task    = _adapter.ConnectToDeviceAsync(device: sensorDevice.Device, cancellationToken: tokenSource.Token);

            try
            {
                if (await Task.WhenAny(task, Task.Delay(timeout)) != task)
                {
                    tokenSource.Cancel();
                    _userDialogs.Alert(new AlertConfig
                    {
                        Message = $"Connection to {sensorDevice.Name} timed out."
                    });
                    _isBusy = false;
                    return(false);
                }
            }
            catch (DeviceConnectionException)
            {
                _userDialogs.Alert(new AlertConfig
                {
                    Message = $"Could not connect to {sensorDevice.Name}."
                });
                _isBusy = false;
                return(false);
            }

            // Clear the Last active output data types list.
            _sensorDataService.RecentOutputAdditions.Clear();

            try
            {
                // TODO: Add file service for sensor data logging.
                sensorDevice.Characteristics = await GetAvailableCharacteristics(sensorDevice);


                _log.Debug($"New {sensorDevice.Type} Device Address: " + sensorDevice.Id);

                if (sensorDevice.Characteristics.Count == 0)
                {
                    _userDialogs.Alert(new AlertConfig
                    {
                        Message = $"Error: No valid characteristics were detected for {sensorDevice.Name}. Disconnecting from the device."
                    });

                    await DisconnectDevice(sensorDevice);

                    _isBusy = false;
                    return(false);
                }
                // Subscribe to data characteristics
                foreach (var characteristic in sensorDevice.Characteristics)
                {
                    if (characteristic.Uuid == CMD_CHARACTERISTIC)
                    {
                        sensorDevice.CommandCharacteristic = characteristic;
                    }
                    else if (characteristic.Uuid == DATA_CHARACTERISTIC)
                    {
                        sensorDevice.DownloadDataCharacteristic = characteristic;
                        await sensorDevice.DownloadDataCharacteristic.StartUpdatesAsync();
                    }
                    else if (characteristic.Uuid == INFO_CHARACTERISTIC)
                    {
                        sensorDevice.InfoCharacteristic = characteristic;
                        await sensorDevice.InfoCharacteristic.StartUpdatesAsync();
                    }
                    else if (characteristic.Uuid == BATTERY_UUID)
                    {
                        sensorDevice.BatteryCharacteristic = characteristic;


                        byte[] battery_pkg = await sensorDevice.BatteryCharacteristic.ReadAsync();

                        _deviceSlotService.UpdateBatteryStatus(emptySlot.Index, battery_pkg[0]);

                        await sensorDevice.BatteryCharacteristic.StartUpdatesAsync();
                    }
                    else if (characteristic.CanUpdate)
                    {
                        var datatype = _dataTypeForCharacteristicUUID[characteristic.Uuid];

                        DataType tempDataType = datatype;
                        // Necessary temp conversion due to DataType clash in different chest and limb devices.
                        if (datatype == DataType.temp)
                        {
                            if (sensorDevice.Type == DeviceType.Chest)
                            {
                                tempDataType = DataType.chest_temp;
                            }
                            else if (sensorDevice.Type == DeviceType.Limb)
                            {
                                tempDataType = DataType.foot_temp;
                            }
                        }
                        if (!_dataTypeToOutputType.ContainsKey(tempDataType))
                        {
                            continue;
                        }
                        foreach (var outputType in _dataTypeToOutputType[tempDataType])
                        {
                            var outputTuple = Tuple.Create(emptySlot.Index, outputType);
                            int outputID    = outputTuple.GetHashCode();
                            OutputData.Add(outputID);
                            emptySlot.OutputDataIDs.Add(outputID);
                            _sensorDataService.AddToDataBuffer(outputID);

                            SubscribedCharacteristicsList.Add(outputType);
                            _sensorDataService.RecentOutputAdditions.Add(outputTuple);
                        }

                        var func = new EventHandler <CharacteristicUpdatedEventArgs>((sender, args) => CharacteristicOnValueUpdated(sender, args, sensorDevice));
                        _characteristicEventAggregator.TryAdd(characteristic, func);
                        // Cleanup previous event handler.

                        characteristic.ValueUpdated -= func;
                        // Attach event handler to characteristic value update.
                        characteristic.ValueUpdated += func;

                        // Start Getting Sensor Data.
                        await characteristic.StartUpdatesAsync();
                    }
                }
                _deviceSlotService.AddDeviceToSlot(emptySlot.Index, sensorDevice);
            }
            catch (Exception e)
            {
                _log.Debug(e.Message);
            }

            _isBusy = false;
            return(true);
        }