From 97ef0725973e972c7f7ddd90478a865d660d9963 Mon Sep 17 00:00:00 2001 From: "T. Thiery" Date: Wed, 22 Jul 2020 22:23:50 +0200 Subject: [PATCH] Allow direct connection to known device - Extended PoweredUpHost with Create method. - Add example - Refactored BaseExample to allow alternatives to discovery #52 --- .../BaseExample.cs | 51 +++++++++++-------- .../ExampleBluetoothByKnownAddress.cs | 42 +++++++++++++++ .../SharpBrick.PoweredUp.Examples/Program.cs | 5 +- src/SharpBrick.PoweredUp/Hubs/HubFactory.cs | 17 +++++-- src/SharpBrick.PoweredUp/Hubs/IHubFactory.cs | 3 +- src/SharpBrick.PoweredUp/PoweredUpHost.cs | 12 ++++- 6 files changed, 101 insertions(+), 29 deletions(-) create mode 100644 examples/SharpBrick.PoweredUp.Examples/ExampleBluetoothByKnownAddress.cs diff --git a/examples/SharpBrick.PoweredUp.Examples/BaseExample.cs b/examples/SharpBrick.PoweredUp.Examples/BaseExample.cs index 6215bb9..a9c77fe 100644 --- a/examples/SharpBrick.PoweredUp.Examples/BaseExample.cs +++ b/examples/SharpBrick.PoweredUp.Examples/BaseExample.cs @@ -24,31 +24,16 @@ public virtual void Configure(IServiceCollection serviceCollection) .AddPoweredUp(); } - public void CreateHostAndDiscover(bool enableTrace) + public void InitHostAndDiscover(bool enableTrace) { - var serviceCollection = new ServiceCollection() - // configure your favourite level of logging. - .AddLogging(builder => - { - builder - .AddConsole(); - - if (enableTrace) - { - builder.AddFilter("SharpBrick.PoweredUp.Bluetooth.BluetoothKernel", LogLevel.Debug); - } - }) - .AddSingleton() - ; - - Configure(serviceCollection); - - serviceProvider = serviceCollection.BuildServiceProvider(); + InitHost(enableTrace); + Discover(enableTrace); + } + public virtual void Discover(bool enableTrace) + { var logger = serviceProvider.GetService().CreateLogger("Main"); - host = serviceProvider.GetService(); - Hub result = null; logger.LogInformation("Finding Service"); @@ -83,5 +68,29 @@ public void CreateHostAndDiscover(bool enableTrace) selectedHub = result; } + + public void InitHost(bool enableTrace) + { + var serviceCollection = new ServiceCollection() + // configure your favourite level of logging. + .AddLogging(builder => + { + builder + .AddConsole(); + + if (enableTrace) + { + builder.AddFilter("SharpBrick.PoweredUp.Bluetooth.BluetoothKernel", LogLevel.Debug); + } + }) + .AddSingleton() + ; + + Configure(serviceCollection); + + serviceProvider = serviceCollection.BuildServiceProvider(); + + host = serviceProvider.GetService(); + } } } \ No newline at end of file diff --git a/examples/SharpBrick.PoweredUp.Examples/ExampleBluetoothByKnownAddress.cs b/examples/SharpBrick.PoweredUp.Examples/ExampleBluetoothByKnownAddress.cs new file mode 100644 index 0000000..a33ed16 --- /dev/null +++ b/examples/SharpBrick.PoweredUp.Examples/ExampleBluetoothByKnownAddress.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading.Tasks; +using SharpBrick.PoweredUp; + +namespace Example +{ + public class ExampleBluetoothByKnownAddress : BaseExample + { + public const ulong ChangeMe_BluetoothAddress = 158897336311065; + public TechnicMediumHub DirectlyConnectedHub { get; private set; } + + // device needs to be switched on! + public override void Discover(bool enableTrace) + { + var hub = host.Create(ChangeMe_BluetoothAddress); + + selectedHub = DirectlyConnectedHub = hub; + + hub.ConnectAsync().Wait(); + } + + public override async Task ExecuteAsync() + { + using (var technicMediumHub = DirectlyConnectedHub) + { + await technicMediumHub.RgbLight.SetRgbColorsAsync(0xff, 0x00, 0x00); + + await Task.Delay(2000); + + await technicMediumHub.RgbLight.SetRgbColorsAsync(0x00, 0xff, 0x00); + + await Task.Delay(2000); + + await technicMediumHub.RgbLight.SetRgbColorsAsync(0xff, 0xff, 0x00); + + await Task.Delay(2000); + + await technicMediumHub.SwitchOffAsync(); + } + } + } +} \ No newline at end of file diff --git a/examples/SharpBrick.PoweredUp.Examples/Program.cs b/examples/SharpBrick.PoweredUp.Examples/Program.cs index e340e53..b6eed7b 100644 --- a/examples/SharpBrick.PoweredUp.Examples/Program.cs +++ b/examples/SharpBrick.PoweredUp.Examples/Program.cs @@ -25,9 +25,10 @@ static async Task Main(string[] args) //example = new Example.ExampleHubAlert(); //example = new Example.ExampleTechnicMediumHubTiltSensor(); //example = new Example.ExampleTechnicMediumHubTiltSensorImpacts(); - example = new Example.ExampleDynamicDevice(); + //example = new Example.ExampleDynamicDevice(); + example = new Example.ExampleBluetoothByKnownAddress(); - example.CreateHostAndDiscover(enableTrace); + example.InitHostAndDiscover(enableTrace); if (example.selectedHub != null) { diff --git a/src/SharpBrick.PoweredUp/Hubs/HubFactory.cs b/src/SharpBrick.PoweredUp/Hubs/HubFactory.cs index bc0aec0..86c2034 100644 --- a/src/SharpBrick.PoweredUp/Hubs/HubFactory.cs +++ b/src/SharpBrick.PoweredUp/Hubs/HubFactory.cs @@ -13,13 +13,22 @@ public HubFactory(IServiceProvider serviceProvider) _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); } - public Hub CreateByBluetoothManufacturerData(byte[] manufacturerData, IServiceProvider serviceProvider) - => (manufacturerData == null || manufacturerData.Length < 3) ? null : (PoweredUpHubManufacturerData)manufacturerData[1] switch + public Hub CreateByBluetoothManufacturerData(byte[] manufacturerData) + => (manufacturerData == null || manufacturerData.Length < 3) ? null : Create(GetSystemTypeFromManufacturerData((PoweredUpHubManufacturerData)manufacturerData[1])); + + private SystemType GetSystemTypeFromManufacturerData(PoweredUpHubManufacturerData poweredUpHubManufacturerData) + => (SystemType)poweredUpHubManufacturerData; + + public Hub Create(SystemType hubType) + => hubType switch { - PoweredUpHubManufacturerData.TechnicMediumHub => ActivatorUtilities.CreateInstance(_serviceProvider, (byte)0x00), - _ => throw new NotSupportedException($"Hub with type {(PoweredUpHubManufacturerData)manufacturerData[1]} not yet supported."), + SystemType.LegoTechnic_MediumHub => ActivatorUtilities.CreateInstance(_serviceProvider, (byte)0x00), + _ => throw new NotSupportedException($"Hub with type {hubType} not yet supported."), }; + public THub Create() where THub : class + => Create(GetSystemTypeFromType(typeof(THub))) as THub; + public static SystemType GetSystemTypeFromType(Type type) => type.Name switch { diff --git a/src/SharpBrick.PoweredUp/Hubs/IHubFactory.cs b/src/SharpBrick.PoweredUp/Hubs/IHubFactory.cs index 6e3b74a..9b223be 100644 --- a/src/SharpBrick.PoweredUp/Hubs/IHubFactory.cs +++ b/src/SharpBrick.PoweredUp/Hubs/IHubFactory.cs @@ -4,6 +4,7 @@ namespace SharpBrick.PoweredUp.Hubs { public interface IHubFactory { - Hub CreateByBluetoothManufacturerData(byte[] manufacturerData, IServiceProvider serviceProvider); + Hub CreateByBluetoothManufacturerData(byte[] manufacturerData); + THub Create() where THub : class; } } \ No newline at end of file diff --git a/src/SharpBrick.PoweredUp/PoweredUpHost.cs b/src/SharpBrick.PoweredUp/PoweredUpHost.cs index 7ff67c7..d0f5877 100644 --- a/src/SharpBrick.PoweredUp/PoweredUpHost.cs +++ b/src/SharpBrick.PoweredUp/PoweredUpHost.cs @@ -46,7 +46,7 @@ public void Discover(Func onDiscovery, CancellationToken token = defa { if (!_hubs.ContainsKey(deviceInfo.BluetoothAddress)) { - var hub = _hubFactory.CreateByBluetoothManufacturerData(deviceInfo.ManufacturerData, ServiceProvider); + var hub = _hubFactory.CreateByBluetoothManufacturerData(deviceInfo.ManufacturerData); hub.ConnectWithBluetoothAdapter(_bluetoothAdapter, deviceInfo.BluetoothAddress); _hubs.TryAdd(deviceInfo.BluetoothAddress, hub); @@ -55,5 +55,15 @@ public void Discover(Func onDiscovery, CancellationToken token = defa } }, token); } + + public THub Create(ulong bluetoothAddress) where THub : Hub + { + var hub = _hubFactory.Create(); + hub.ConnectWithBluetoothAdapter(_bluetoothAdapter, bluetoothAddress); + + _hubs.TryAdd(bluetoothAddress, hub); + + return hub; + } } } \ No newline at end of file