Добрый день.
Пару недель назад я столкнулся с проблемой, что нормальной и современной статьи по первому получению данных с Bluetooth просто нет. И пришлось повозиться чтобы понять с чего начать и как это вообще осуществить. И чтобы люди не повторяли мои ошибки, вот краткое эссе о том как это можно сделать.

Но для начала пару пафосных слов, для чего это вообще нужно. Современный мир все больше погружается в идеологию интернет вещей. Сейчас всё друг с другом взаимодействует, холодильник с плитой, утюг с пылесосом и т.д. Много шума подняли из-за ЭКГ в Apple Watch, но современные тонометры, пульсометры, термометры уже давно умеют передавать данные через Bluetooth. И вот это всё нужно как-то соединить в единую сеть. И ключевым элементом в этой сети является, как ни крути, компьютер. В связи с этим возникла задача получать данные с определённого устройства через Bluetooth.
Начну с того, что уже у нас было и что усугубило поиск решения. А у нас было приложение написанное на .Net Core. В чем суть приложения неважно, для простоты будем считать, что у нас просто консоль на .Net Core. Ну а устройство буду называть литерой N.
Первые попытки найти что-то работающее с Bluetooth через C# приведут к библиотеке 32feet.
В NuGet пакетах она звучит так 32feet.NET.
И она, кстати, в своей последней продуктовой редакции, даже находит устройства Bluetooth, но не стандарта BLE [как выяснилось гораздо позже]. Например тот же OnePlus 5T стабильно отыскивался, но необходимое устройство N нет. Параллельно с этим удалось отыскать и официальный ответ автора, что его библиотека с BLE не взаимодействует в принципе, и даже нет смысла пробовать. Хотя на Github и есть предварительная версия InTheHand.Devices.Bluetooth, которая должна поддерживать BLE, но в ней так много все подменено, а документации вовсе никакой нет, что даже скомпилировать проект с идеями взятыми с 32feet.NET не сложилось.
Новые изыскания привели меня к более стандартным решениям, а именно к Universal Windows Platform (UWP). При разработке данной платформы, Microsoft, охваченная идеей универсальности и единым приложением для компьютера и телефона, постаралась и сделала взаимодействие с Bluetooth. И вот здесь как раз всё хорошо работает, но… У нас проект на .Net Core… И этим уже ничего не поделаешь.
Сразу скажу, что решения по взаимодействию библиотек UWP с .Net Core отыскать не удалось и проект пришлось переключать на 4.7.1., благо это не сложно. Хотя были мысли как оставить проект на .Net Core и например сделать отдельный Windows сервис с передачей данных по именованный каналам (named pipe) или поднять WCF сервис и с ним уже наладить взаимодействие, но в нашем случае это не имело практического смысла.
Так что в итоге мы имеем перед стартом:
Для начала нужно подключить пару библиотек ручками, а именно
И собственно всё, далее сама работа с устройством идет по документация без проблем.
Взаимодействовать с BLE осуществляется через класс BluetoothLEAdvertisementWatcher
Но нужно не забывать, что не имея API самого устройства что-то толковое сделать не получиться.
Вот мой пример кода, как получить данные с устройства.
Данный код рассчитан на то, что устройство уже добавлено (соединено).
Спасибо за внимание.
Пару недель назад я столкнулся с проблемой, что нормальной и современной статьи по первому получению данных с Bluetooth просто нет. И пришлось повозиться чтобы понять с чего начать и как это вообще осуществить. И чтобы люди не повторяли мои ошибки, вот краткое эссе о том как это можно сделать.

Но для начала пару пафосных слов, для чего это вообще нужно. Современный мир все больше погружается в идеологию интернет вещей. Сейчас всё друг с другом взаимодействует, холодильник с плитой, утюг с пылесосом и т.д. Много шума подняли из-за ЭКГ в Apple Watch, но современные тонометры, пульсометры, термометры уже давно умеют передавать данные через Bluetooth. И вот это всё нужно как-то соединить в единую сеть. И ключевым элементом в этой сети является, как ни крути, компьютер. В связи с этим возникла задача получать данные с определённого устройства через Bluetooth.
Начну с того, что уже у нас было и что усугубило поиск решения. А у нас было приложение написанное на .Net Core. В чем суть приложения неважно, для простоты будем считать, что у нас просто консоль на .Net Core. Ну а устройство буду называть литерой N.
Первые попытки найти что-то работающее с Bluetooth через C# приведут к библиотеке 32feet.
В NuGet пакетах она звучит так 32feet.NET.
И она, кстати, в своей последней продуктовой редакции, даже находит устройства Bluetooth, но не стандарта BLE [как выяснилось гораздо позже]. Например тот же OnePlus 5T стабильно отыскивался, но необходимое устройство N нет. Параллельно с этим удалось отыскать и официальный ответ автора, что его библиотека с BLE не взаимодействует в принципе, и даже нет смысла пробовать. Хотя на Github и есть предварительная версия InTheHand.Devices.Bluetooth, которая должна поддерживать BLE, но в ней так много все подменено, а документации вовсе никакой нет, что даже скомпилировать проект с идеями взятыми с 32feet.NET не сложилось.
Новые изыскания привели меня к более стандартным решениям, а именно к Universal Windows Platform (UWP). При разработке данной платформы, Microsoft, охваченная идеей универсальности и единым приложением для компьютера и телефона, постаралась и сделала взаимодействие с Bluetooth. И вот здесь как раз всё хорошо работает, но… У нас проект на .Net Core… И этим уже ничего не поделаешь.
Сразу скажу, что решения по взаимодействию библиотек UWP с .Net Core отыскать не удалось и проект пришлось переключать на 4.7.1., благо это не сложно. Хотя были мысли как оставить проект на .Net Core и например сделать отдельный Windows сервис с передачей данных по именованный каналам (named pipe) или поднять WCF сервис и с ним уже наладить взаимодействие, но в нашем случае это не имело практического смысла.
Так что в итоге мы имеем перед стартом:
- Проект на 4.7.1.
- Win10 обновлен до версии Version 10.0.17134 Build 17134.
Для начала нужно подключить пару библиотек ручками, а именно
- «Windows от Universal Windows Platform»
C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17134.0\Windows.winmd - «System.Runtime.WindowsRuntime»
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll
И собственно всё, далее сама работа с устройством идет по документация без проблем.
Взаимодействовать с BLE осуществляется через класс BluetoothLEAdvertisementWatcher
Но нужно не забывать, что не имея API самого устройства что-то толковое сделать не получиться.
Вот мой пример кода, как получить данные с устройства.
Данный код рассчитан на то, что устройство уже добавлено (соединено).
public class BluetoothObserver { BluetoothLEAdvertisementWatcher Watcher { get; set; } public void Start() { Watcher = new BluetoothLEAdvertisementWatcher() { ScanningMode = BluetoothLEScanningMode.Active }; Watcher.Received += Watcher_Received; Watcher.Stopped += Watcher_Stopped; Watcher.Start(); } private bool isFindDevice { get; set; } = false; private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args) { if (isFindDevice) return; if (args.Advertisement.LocalName.Contains("deviceName")) { isFindDevice = true; BluetoothLEDevice bluetoothLeDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress); GattDeviceServicesResult result = await bluetoothLeDevice.GetGattServicesAsync(); if (result.Status == GattCommunicationStatus.Success) { var services = result.Services; foreach (var service in services) { if (!service.Uuid.ToString().StartsWith("serviceName")) { continue; } GattCharacteristicsResult characteristicsResult = await service.GetCharacteristicsAsync(); if (characteristicsResult.Status == GattCommunicationStatus.Success) { var characteristics = characteristicsResult.Characteristics; foreach (var characteristic in characteristics) { if (!characteristic.Uuid.ToString().StartsWith("characteristicName")) { continue; } GattCharacteristicProperties properties = characteristic.CharacteristicProperties; if (properties.HasFlag(GattCharacteristicProperties.Indicate)) { characteristic.ValueChanged += Characteristic_ValueChanged; GattWriteResult status = await characteristic.WriteClientCharacteristicConfigurationDescriptorWithResultAsync(GattClientCharacteristicConfigurationDescriptorValue.Indicate); return; } if (properties.HasFlag(GattCharacteristicProperties.Read)) { GattReadResult gattResult = await characteristic.ReadValueAsync(); if (gattResult.Status == GattCommunicationStatus.Success) { var reader = DataReader.FromBuffer(gattResult.Value); byte[] input = new byte[reader.UnconsumedBufferLength]; reader.ReadBytes(input); //Читаем input } } } } } } } } private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args) { var reader = DataReader.FromBuffer(args.CharacteristicValue); byte[] input = new byte[reader.UnconsumedBufferLength]; reader.ReadBytes(input); //Читаем input } private void Watcher_Stopped(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args) { ; } }
Спасибо за внимание.
