Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
        public void OnDisconnected(SensorDevice sensorDevice, bool showMessage = false)
        {
            // Check if a valid sensor device model was referenced.
            if (sensorDevice == null)
            {
                return;
            }


            _isBusy = true;
            // Cleanup refrences for a device.
            if (sensorDevice.Type != DeviceType.None)
            {
                if (sensorDevice.Characteristics == null)
                {
                    _isBusy = false;
                    return;
                }

                // Cleanup data update listeners for characteristics.
                foreach (ICharacteristic characteristic in sensorDevice.Characteristics)
                {
                    try
                    {
                        if (_dataTypeForCharacteristicUUID.ContainsKey(characteristic.Uuid))
                        {
                            DataType 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])
                            {
                                SubscribedCharacteristicsList.Remove(outputType);
                            }
                        }

                        // Attempt to remove event handler.
                        _characteristicEventAggregator.TryGetValue(characteristic, out EventHandler <CharacteristicUpdatedEventArgs> CharacteristicOnValueUpdated);
                        characteristic.ValueUpdated -= CharacteristicOnValueUpdated;

                        // Attempt to remove reference to the event handler.
                        _characteristicEventAggregator.TryRemove(characteristic, out CharacteristicOnValueUpdated);
                    }
                    catch (Exception e)
                    {
                        _log.Debug("Characteristic unsubscription error: " + e.Message + characteristic.Name);
                    }
                }

                //if (sensorDevice.InfoCharacteristic != null)
                //{
                //    sensorDevice.InfoCharacteristic.ValueUpdated -= _infoUpdateEventHandler;
                //}

                // Clear out the corresponding device slot for connected devices.
                DeviceSlot occupingSlot = _deviceSlotService.GetSlotWithDevice(sensorDevice);
                if (occupingSlot == null)
                {
                    _isBusy = false;
                    return;
                }

                foreach (var outputID in occupingSlot.OutputDataIDs)
                {
                    OutputData.Remove(outputID);
                    _sensorDataService.RemoveFromDataBuffer(outputID);
                }

                // StopSession();

                _deviceSlotService.EmptySlot(occupingSlot.Index);
                _isBusy = false;
            }

            if (showMessage)
            {
                // If disconnection was unexpected.
                _log.Info($"Connection to {sensorDevice.Name} has been lost.");
                _userDialogs.Alert(new AlertConfig
                {
                    Message = "Connection to " + sensorDevice.Name + " has been lost."
                });
            }
            else
            {
                // If disconnection was made by user.
                _log.Info($"Device {sensorDevice.Name} has disconnected.");
            }
        }
Ejemplo n.º 3
0
 public bool CharacteristicIsActive(DataType type)
 {
     return(SubscribedCharacteristicsList.Contains(type));
 }