/// <summary> /// Connect to an unconnected IMBLE device. /// </summary> /// <param name="device">An UnconnectedImbleDevice instance corresponding to the IMBLE device to connect to.</param> /// <param name="cancellationToken"></param> /// <returns></returns> public static async Task<ImbleDevice> ConnectAsync(UnconnectedImbleDevice device, CancellationToken cancellationToken) { var imble = new ImbleDevice(); // I tried to use DeviceInformation.FindAllAsync combined with BluetoothLEDevice.GetDeviceSelectorFromBluetoothAddress // to obtain a device information corresponding to a Bluetooth address. // But this implementation is not feasible because DeviceInformation.FindAllAsync takes 10 to 20 seconds. // Thus, I've decided to use BluetoothLEDevice.FromBluetoothAddressAsync instead of DeviceInformation.FindAllAsync. var bleDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(device.Address); var deviceInformation = bleDevice.DeviceInformation; bleDevice.Dispose(); // Do not forget to dispose BLE related objects. await imble.Initialize(deviceInformation, device.Address, cancellationToken); return imble; }
public UnconnectedDeviceViewModel(UnconnectedImbleDevice device) { this.Device = device; this.Name = this.Device.Advertisement.LocalName; var addressBytes = BitConverter.GetBytes(this.Device.Address); if (!BitConverter.IsLittleEndian) { Array.Reverse(addressBytes); } this.Address = string.Join(":", addressBytes.Select(@byte => @byte.ToString("X02"))); this.Rssi = this.Device.Rssi; this.ConnectCommand = new ReactiveCommand(); this.ConnectCommand .Select(_ => Observable.FromAsync(token => this.Device.Connect(token))) .Switch() .OnErrorRetry() .Subscribe() .AddTo(this.disposables); }
public DevicePageViewModel(UnconnectedImbleDevice unconnectedDevice) { this.Device = Observable.FromAsync(token => unconnectedDevice.Connect(token)) .CatchIgnore((Exception e) => { }) .ToReadOnlyReactiveProperty() .AddTo(this.disposables); this.IsConnected = this.Device.Select(device => device != null).ToReadOnlyReactiveProperty().AddTo(this.disposables); this.DeviceStatus = this.Device .Where(device => device != null) .Select(device => device.ObserveProperty(self => self.Status)) .Switch() .Do(value => Debug.WriteLine(value)) .ObserveOnUIDispatcher() .ToReadOnlyReactiveProperty() .AddTo(this.disposables); this.ReceivedMessage = this.Device .Where(device => device != null) .Select(device => Observable.FromEventPattern <DataArrivedEventArgs>(handler => device.DataArrived += handler, handler => device.DataArrived -= handler)) .Switch() .Select(args => new ReceivedMessageViewModel(args.EventArgs.Data, args.EventArgs.Timestamp)) .OnErrorRetry() .ToReadOnlyReactiveProperty() .AddTo(this.disposables); var notBusyNotifier = new BooleanNotifier(false); this.Name = new ReactiveProperty <string>("Fuga") .SetValidateNotifyError(value => value != null && Encoding.UTF8.GetByteCount(value) < 12 ? null : "Input short message") .AddTo(this.disposables); this.CanSendCommand = Observable.CombineLatest( this.DeviceStatus.Select(status => status == ImbleDeviceStatus.Running), this.Name.ObserveHasErrors, notBusyNotifier.Do(value => Debug.WriteLine(value)), (isRunning, hasErrors, notBusy) => isRunning && !hasErrors && notBusy) .ToReadOnlyReactiveProperty().AddTo(this.disposables); notBusyNotifier.TurnOn(); this.SendCommand = this.CanSendCommand.ToReactiveCommand().AddTo(this.disposables); this.SendCommand .Do(_ => notBusyNotifier.TurnOff()) .Select(_ => { var data = Encoding.UTF8.GetBytes(this.Name.Value); return(Observable.FromAsync(token => { using (var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5))) using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutTokenSource.Token)) { return this.Device.Value.SendAsync(data, 0, data.Length, linkedTokenSource.Token); } }) .Finally(() => notBusyNotifier.TurnOn())); }) .Switch() .OnErrorRetry((Exception e) => Debug.WriteLine(e)) .Subscribe() .AddTo(this.disposables); }
public DevicePageViewModel(UnconnectedImbleDevice unconnectedDevice) { this.Device = Observable.FromAsync(token => unconnectedDevice.Connect(token)) .CatchIgnore((Exception e) => { }) .ToReadOnlyReactiveProperty() .AddTo(this.disposables); this.IsConnected = this.Device.Select(device => device != null).ToReadOnlyReactiveProperty().AddTo(this.disposables); this.DeviceStatus = this.Device .Where(device => device != null) .Select(device => device.ObserveProperty(self => self.Status)) .Switch() .Do(value => Debug.WriteLine(value)) .ObserveOnUIDispatcher() .ToReadOnlyReactiveProperty() .AddTo(this.disposables); this.ReceivedMessage = this.Device .Where(device => device != null) .Select(device => Observable.FromEventPattern<DataArrivedEventArgs>(handler => device.DataArrived += handler, handler => device.DataArrived -= handler)) .Switch() .Select(args => new ReceivedMessageViewModel(args.EventArgs.Data, args.EventArgs.Timestamp)) .OnErrorRetry() .ToReadOnlyReactiveProperty() .AddTo(this.disposables); var notBusyNotifier = new BooleanNotifier(false); this.Name = new ReactiveProperty<string>("Fuga") .SetValidateNotifyError(value => value != null && Encoding.UTF8.GetByteCount(value) < 12 ? null : "Input short message") .AddTo(this.disposables); this.CanSendCommand = Observable.CombineLatest( this.DeviceStatus.Select(status => status == ImbleDeviceStatus.Running), this.Name.ObserveHasErrors, notBusyNotifier.Do(value => Debug.WriteLine(value)), (isRunning, hasErrors, notBusy) => isRunning && !hasErrors && notBusy) .ToReadOnlyReactiveProperty().AddTo(this.disposables); notBusyNotifier.TurnOn(); this.SendCommand = this.CanSendCommand.ToReactiveCommand().AddTo(this.disposables); this.SendCommand .Do(_ => notBusyNotifier.TurnOff()) .Select(_ => { var data = Encoding.UTF8.GetBytes(this.Name.Value); return Observable.FromAsync(token => { using (var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5))) using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutTokenSource.Token)) { return this.Device.Value.SendAsync(data, 0, data.Length, linkedTokenSource.Token); } }) .Finally(() => notBusyNotifier.TurnOn()); }) .Switch() .OnErrorRetry((Exception e) => Debug.WriteLine(e)) .Subscribe() .AddTo(this.disposables); }