diff --git a/BrickController2/BrickController2.Tests/UI/Images/DeviceImagesResourceTests.cs b/BrickController2/BrickController2.Tests/UI/Images/DeviceImagesResourceTests.cs
index 5c4044f1e..1d691a228 100644
--- a/BrickController2/BrickController2.Tests/UI/Images/DeviceImagesResourceTests.cs
+++ b/BrickController2/BrickController2.Tests/UI/Images/DeviceImagesResourceTests.cs
@@ -76,6 +76,7 @@ private static DeviceImageRegistry CreateRegistry()
var registry = new DeviceImageRegistry();
registry.Register(DeviceType.BuWizz2, "buwizz_image.png", "buwizz_image_small.png");
registry.Register(DeviceType.RemoteControl, "remotecontrol_image_small.png", "remotecontrol_image_small.png");
+ registry.Register(DeviceType.Infrared, "powerfunctions_image.png", "powerfunctions_image_small.png");
return registry;
}
}
diff --git a/BrickController2/BrickController2/DeviceManagement/BluetoothAdvertisingDevice.cs b/BrickController2/BrickController2/DeviceManagement/BluetoothAdvertisingDevice.cs
index 2620908b3..1e192bb35 100644
--- a/BrickController2/BrickController2/DeviceManagement/BluetoothAdvertisingDevice.cs
+++ b/BrickController2/BrickController2/DeviceManagement/BluetoothAdvertisingDevice.cs
@@ -9,7 +9,7 @@ namespace BrickController2.DeviceManagement
///
/// Baseclass of Bluetooth LE Advertising devices
///
- internal abstract class BluetoothAdvertisingDevice : Device
+ internal abstract class BluetoothAdvertisingDevice : Device, IBluetoothDevice
{
///
/// BluetoothAdvertisingDeviceHandler
diff --git a/BrickController2/BrickController2/DeviceManagement/BluetoothDevice.cs b/BrickController2/BrickController2/DeviceManagement/BluetoothDevice.cs
index 2b1e3d8fc..f25c4c35c 100644
--- a/BrickController2/BrickController2/DeviceManagement/BluetoothDevice.cs
+++ b/BrickController2/BrickController2/DeviceManagement/BluetoothDevice.cs
@@ -6,7 +6,7 @@
namespace BrickController2.DeviceManagement
{
- internal abstract class BluetoothDevice : Device
+ internal abstract class BluetoothDevice : Device, IBluetoothDevice
{
protected readonly IBluetoothLEService _bleService;
diff --git a/BrickController2/BrickController2/DeviceManagement/DI/DeviceManagementModule.cs b/BrickController2/BrickController2/DeviceManagement/DI/DeviceManagementModule.cs
index f9e9d3741..24c17c5c5 100644
--- a/BrickController2/BrickController2/DeviceManagement/DI/DeviceManagementModule.cs
+++ b/BrickController2/BrickController2/DeviceManagement/DI/DeviceManagementModule.cs
@@ -11,13 +11,11 @@ public class DeviceManagementModule : Module
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType().As().SingleInstance();
- builder.RegisterType().As().SingleInstance();
builder.RegisterType().As().SingleInstance();
builder.RegisterType().As().SingleInstance();
builder.RegisterType().As().SingleInstance();
- builder.RegisterType().Keyed(DeviceType.Infrared);
builder.RegisterType().Keyed(DeviceType.CircuitCubes);
builder.RegisterType().Keyed(DeviceType.PfxBrick);
diff --git a/BrickController2/BrickController2/DeviceManagement/DeviceFactoryData.cs b/BrickController2/BrickController2/DeviceManagement/DeviceFactoryData.cs
index cd94e88f2..72183f18b 100644
--- a/BrickController2/BrickController2/DeviceManagement/DeviceFactoryData.cs
+++ b/BrickController2/BrickController2/DeviceManagement/DeviceFactoryData.cs
@@ -19,6 +19,7 @@ public DeviceFactoryData(TVendor vendor, string name, string address, byte[] dev
public DeviceType DeviceType => TDevice.Type;
+ public bool IsAvailable => Vendor.IsAvailable;
public TVendor Vendor { get; }
public string Name { get; }
public string Address { get; }
diff --git a/BrickController2/BrickController2/DeviceManagement/DeviceManager.cs b/BrickController2/BrickController2/DeviceManagement/DeviceManager.cs
index e542dccb8..406cb30b4 100644
--- a/BrickController2/BrickController2/DeviceManagement/DeviceManager.cs
+++ b/BrickController2/BrickController2/DeviceManagement/DeviceManager.cs
@@ -12,7 +12,6 @@ namespace BrickController2.DeviceManagement
internal class DeviceManager : NotifyPropertyChangedSource, IDeviceManager
{
private readonly IBluetoothDeviceManager _bluetoothDeviceManager;
- private readonly IInfraredDeviceManager _infraredDeviceManager;
private readonly IDeviceRepository _deviceRepository;
private readonly DeviceFactory _deviceFactory;
private readonly IMainThreadService _uiThreadService;
@@ -25,14 +24,12 @@ internal class DeviceManager : NotifyPropertyChangedSource, IDeviceManager
public DeviceManager(
IBluetoothDeviceManager bluetoothDeviceManager,
- IInfraredDeviceManager infraredDeviceManager,
IDeviceRepository deviceRepository,
DeviceFactory deviceFactory,
IMainThreadService uiThreadService,
ILogger logger)
{
_bluetoothDeviceManager = bluetoothDeviceManager;
- _infraredDeviceManager = infraredDeviceManager;
_deviceRepository = deviceRepository;
_deviceFactory = deviceFactory;
_uiThreadService = uiThreadService;
@@ -88,12 +85,7 @@ public async Task ScanAsync(CancellationToken token)
try
{
- var infraScan = _infraredDeviceManager.ScanAsync(CreateDeviceAsync!, token);
- var bluetoothScan = _bluetoothDeviceManager.ScanAsync(CreateDeviceAsync!, token);
-
- await Task.WhenAll(infraScan, bluetoothScan);
-
- return infraScan.Result && bluetoothScan.Result;
+ return await _bluetoothDeviceManager.ScanAsync(CreateDeviceAsync!, token);
}
catch (Exception)
{
diff --git a/BrickController2/BrickController2/DeviceManagement/IBluetoothDevice.cs b/BrickController2/BrickController2/DeviceManagement/IBluetoothDevice.cs
new file mode 100644
index 000000000..9e2ccbba6
--- /dev/null
+++ b/BrickController2/BrickController2/DeviceManagement/IBluetoothDevice.cs
@@ -0,0 +1,6 @@
+namespace BrickController2.DeviceManagement
+{
+ internal interface IBluetoothDevice
+ {
+ }
+}
diff --git a/BrickController2/BrickController2/DeviceManagement/IDeviceFactoryData.cs b/BrickController2/BrickController2/DeviceManagement/IDeviceFactoryData.cs
index 5af67008b..4441d3d4d 100644
--- a/BrickController2/BrickController2/DeviceManagement/IDeviceFactoryData.cs
+++ b/BrickController2/BrickController2/DeviceManagement/IDeviceFactoryData.cs
@@ -5,6 +5,7 @@ namespace BrickController2.DeviceManagement
{
public interface IDeviceFactoryData
{
+ bool IsAvailable { get; }
DeviceType DeviceType { get; }
string Name { get; }
string Address { get; }
diff --git a/BrickController2/BrickController2/DeviceManagement/IInfraredDeviceManager.cs b/BrickController2/BrickController2/DeviceManagement/IInfraredDeviceManager.cs
deleted file mode 100644
index 9602ba020..000000000
--- a/BrickController2/BrickController2/DeviceManagement/IInfraredDeviceManager.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Threading.Tasks;
-
-namespace BrickController2.DeviceManagement
-{
- internal interface IInfraredDeviceManager : IDeviceScanner
- {
- Task ConnectDevice(InfraredDevice device);
- Task DisconnectDevice(InfraredDevice device);
-
- void SetOutput(InfraredDevice device, int channel, int value);
- }
-}
diff --git a/BrickController2/BrickController2/DeviceManagement/PowerFunctions/IPowerFunctionsManager.cs b/BrickController2/BrickController2/DeviceManagement/PowerFunctions/IPowerFunctionsManager.cs
new file mode 100644
index 000000000..baaabe278
--- /dev/null
+++ b/BrickController2/BrickController2/DeviceManagement/PowerFunctions/IPowerFunctionsManager.cs
@@ -0,0 +1,12 @@
+using System.Threading.Tasks;
+
+namespace BrickController2.DeviceManagement.PowerFunctions
+{
+ internal interface IPowerFunctionsManager
+ {
+ Task ConnectDevice(PowerFunctionsDevice device);
+ Task DisconnectDevice(PowerFunctionsDevice device);
+
+ void SetOutput(PowerFunctionsDevice device, int channel, int value);
+ }
+}
diff --git a/BrickController2/BrickController2/DeviceManagement/PowerFunctions/PowerFunctions.cs b/BrickController2/BrickController2/DeviceManagement/PowerFunctions/PowerFunctions.cs
new file mode 100644
index 000000000..07a4e511b
--- /dev/null
+++ b/BrickController2/BrickController2/DeviceManagement/PowerFunctions/PowerFunctions.cs
@@ -0,0 +1,37 @@
+using Autofac;
+using BrickController2.DeviceManagement.DI;
+using BrickController2.DeviceManagement.Vendors;
+using BrickController2.PlatformServices.Infrared;
+
+namespace BrickController2.DeviceManagement.PowerFunctions;
+
+///
+/// Vendor for Power Functions devices
+///
+internal class PowerFunctions : Vendor
+{
+ private IInfraredService? _infraredService;
+
+ public override string VendorName => "LEGO";
+
+ public override bool IsAvailable => _infraredService != null && _infraredService.IsInfraredSupported && _infraredService.IsCarrierFrequencySupported(PowerFunctionsManager.IR_FREQUENCY);
+
+ protected override void Register(VendorBuilder builder)
+ {
+ // device manager
+ builder.ContainerBuilder.RegisterType().As().SingleInstance();
+
+ builder.ContainerBuilder.RegisterBuildCallback(scope =>
+ {
+ _infraredService = scope.Resolve();
+ });
+
+ // manually added devices
+ builder.RegisterDevice()
+ .WithImages("powerfunctions_image.png", "powerfunctions_image_small.png")
+ .WithDeviceFactory("0", "PF Infra 1")
+ .WithDeviceFactory("1", "PF Infra 2")
+ .WithDeviceFactory("2", "PF Infra 3")
+ .WithDeviceFactory("3", "PF Infra 4");
+ }
+}
diff --git a/BrickController2/BrickController2/DeviceManagement/InfraredDevice.cs b/BrickController2/BrickController2/DeviceManagement/PowerFunctions/PowerFunctionsDevice.cs
similarity index 60%
rename from BrickController2/BrickController2/DeviceManagement/InfraredDevice.cs
rename to BrickController2/BrickController2/DeviceManagement/PowerFunctions/PowerFunctionsDevice.cs
index 03ecd0f1f..a54452922 100644
--- a/BrickController2/BrickController2/DeviceManagement/InfraredDevice.cs
+++ b/BrickController2/BrickController2/DeviceManagement/PowerFunctions/PowerFunctionsDevice.cs
@@ -3,19 +3,22 @@
using System.Threading;
using System.Threading.Tasks;
-namespace BrickController2.DeviceManagement
+namespace BrickController2.DeviceManagement.PowerFunctions
{
- internal class InfraredDevice : Device
+ internal class PowerFunctionsDevice : Device, IDeviceType
{
- private readonly IInfraredDeviceManager _infraredDeviceManager;
+ private readonly IPowerFunctionsManager _powerFunctionsManager;
- public InfraredDevice(string name, string address, byte[] deviceData, IInfraredDeviceManager infraredDeviceManager, IDeviceRepository deviceRepository)
+ public PowerFunctionsDevice(string name, string address, byte[] deviceData, IPowerFunctionsManager powerFunctionsManager, IDeviceRepository deviceRepository)
: base(name, address, deviceRepository)
{
- _infraredDeviceManager = infraredDeviceManager;
+ _powerFunctionsManager = powerFunctionsManager;
}
- public override DeviceType DeviceType => DeviceType.Infrared;
+ public static DeviceType Type => DeviceType.Infrared;
+
+ public static string TypeName => "Power Functions";
+ public override DeviceType DeviceType => Type;
public override int NumberOfChannels => 2;
public override async Task ConnectAsync(
@@ -28,7 +31,7 @@ public override async Task ConnectAsync(
{
DeviceState = DeviceState.Connecting;
- var result = await _infraredDeviceManager.ConnectDevice(this);
+ var result = await _powerFunctionsManager.ConnectDevice(this);
DeviceState = result == DeviceConnectionResult.Ok ? DeviceState.Connected : DeviceState.Disconnected;
return result;
@@ -38,7 +41,7 @@ public override async Task DisconnectAsync()
{
DeviceState = DeviceState.Disconnecting;
- await _infraredDeviceManager.DisconnectDevice(this);
+ await _powerFunctionsManager.DisconnectDevice(this);
DeviceState = DeviceState.Disconnected;
}
@@ -49,7 +52,7 @@ public override void SetOutput(int channel, float value)
value = CutOutputValue(value);
var intValue = (int)(7 * value);
- _infraredDeviceManager.SetOutput(this, channel, intValue);
+ _powerFunctionsManager.SetOutput(this, channel, intValue);
}
}
}
diff --git a/BrickController2/BrickController2/DeviceManagement/InfraredDeviceManager.cs b/BrickController2/BrickController2/DeviceManagement/PowerFunctions/PowerFunctionsManager.cs
similarity index 85%
rename from BrickController2/BrickController2/DeviceManagement/InfraredDeviceManager.cs
rename to BrickController2/BrickController2/DeviceManagement/PowerFunctions/PowerFunctionsManager.cs
index 2b2cd24eb..22a07696d 100644
--- a/BrickController2/BrickController2/DeviceManagement/InfraredDeviceManager.cs
+++ b/BrickController2/BrickController2/DeviceManagement/PowerFunctions/PowerFunctionsManager.cs
@@ -4,11 +4,11 @@
using BrickController2.PlatformServices.Infrared;
using BrickController2.Helpers;
-namespace BrickController2.DeviceManagement
+namespace BrickController2.DeviceManagement.PowerFunctions
{
- internal class InfraredDeviceManager : IInfraredDeviceManager
+ internal class PowerFunctionsManager : IPowerFunctionsManager
{
- private const int IR_FREQUENCY = 38000;
+ public const int IR_FREQUENCY = 38000;
private const int IR_MARK_US = 158;
private const int IR_START_GAP_US = 1026;
@@ -29,33 +29,12 @@ internal class InfraredDeviceManager : IInfraredDeviceManager
private Task? _irTask;
private CancellationTokenSource? _irTaskCancelationTokenSource;
- public InfraredDeviceManager(IInfraredService infraredService)
+ public PowerFunctionsManager(IInfraredService infraredService)
{
_infraredService = infraredService;
}
- public async Task ScanAsync(Func deviceFoundCallback, CancellationToken token)
- {
- using (await _asyncLock.LockAsync())
- {
- if (_infraredService.IsInfraredSupported && _infraredService.IsCarrierFrequencySupported(IR_FREQUENCY))
- {
- for (int i = 0; i < 4; i++)
- {
- if (token.IsCancellationRequested)
- {
- break;
- }
-
- await deviceFoundCallback(DeviceType.Infrared, $"PF Infra {i + 1}", $"{i}", null);
- }
- }
- }
-
- return true;
- }
-
- public async Task ConnectDevice(InfraredDevice device)
+ public async Task ConnectDevice(PowerFunctionsDevice device)
{
using (await _asyncLock.LockAsync())
{
@@ -74,7 +53,7 @@ public async Task ConnectDevice(InfraredDevice device)
}
}
- public async Task DisconnectDevice(InfraredDevice device)
+ public async Task DisconnectDevice(PowerFunctionsDevice device)
{
using (await _asyncLock.LockAsync())
{
@@ -91,7 +70,7 @@ public async Task DisconnectDevice(InfraredDevice device)
}
}
- public void SetOutput(InfraredDevice device, int channel, int value)
+ public void SetOutput(PowerFunctionsDevice device, int channel, int value)
{
if (int.TryParse(device.Address, out int address))
{
diff --git a/BrickController2/BrickController2/DeviceManagement/Vendors/Vendor.cs b/BrickController2/BrickController2/DeviceManagement/Vendors/Vendor.cs
index 76cd92c49..24fd0b357 100644
--- a/BrickController2/BrickController2/DeviceManagement/Vendors/Vendor.cs
+++ b/BrickController2/BrickController2/DeviceManagement/Vendors/Vendor.cs
@@ -12,6 +12,8 @@ public abstract class Vendor : Module, IVendorModule
{
public abstract string VendorName { get; }
+ public virtual bool IsAvailable => true;
+
protected abstract void Register(VendorBuilder builder);
protected sealed override void Load(ContainerBuilder builder)
diff --git a/BrickController2/BrickController2/UI/Controls/DeviceChannelSelector.xaml b/BrickController2/BrickController2/UI/Controls/DeviceChannelSelector.xaml
index 530242b2b..dd974e99b 100644
--- a/BrickController2/BrickController2/UI/Controls/DeviceChannelSelector.xaml
+++ b/BrickController2/BrickController2/UI/Controls/DeviceChannelSelector.xaml
@@ -132,8 +132,8 @@
-
-
+
+
@@ -141,13 +141,13 @@
-
+
-
+
-
+
diff --git a/BrickController2/BrickController2/UI/Controls/DeviceChannelSelector.xaml.cs b/BrickController2/BrickController2/UI/Controls/DeviceChannelSelector.xaml.cs
index 04a3fa1dd..5f1c68c2b 100644
--- a/BrickController2/BrickController2/UI/Controls/DeviceChannelSelector.xaml.cs
+++ b/BrickController2/BrickController2/UI/Controls/DeviceChannelSelector.xaml.cs
@@ -29,8 +29,8 @@ public DeviceChannelSelector()
BuWizz3Channel3.Command = new SafeCommand(() => SelectedChannel = 3);
BuWizz3Channel4.Command = new SafeCommand(() => SelectedChannel = 4);
BuWizz3Channel5.Command = new SafeCommand(() => SelectedChannel = 5);
- InfraredChannel0.Command = new SafeCommand(() => SelectedChannel = 0);
- InfraredChannel1.Command = new SafeCommand(() => SelectedChannel = 1);
+ PowerFunctionsChannel0.Command = new SafeCommand(() => SelectedChannel = 0);
+ PowerFunctionsChannel1.Command = new SafeCommand(() => SelectedChannel = 1);
PoweredUpChannel0.Command = new SafeCommand(() => SelectedChannel = 0);
PoweredUpChannel1.Command = new SafeCommand(() => SelectedChannel = 1);
BoostChannelA.Command = new SafeCommand(() => SelectedChannel = 0);
@@ -173,7 +173,7 @@ private void OnDeviceChanged(Device device)
SbrickLightSection.IsVisible = deviceType == DeviceType.SBrickLight;
BuWizzSection.IsVisible = deviceType == DeviceType.BuWizz || deviceType == DeviceType.BuWizz2;
BuWizz3Section.IsVisible = deviceType == DeviceType.BuWizz3;
- InfraredSection.IsVisible = deviceType == DeviceType.Infrared;
+ PowerFunctionsSection.IsVisible = deviceType == DeviceType.Infrared;
PoweredUpSection.IsVisible = deviceType == DeviceType.PoweredUp;
BoostSection.IsVisible = deviceType == DeviceType.Boost;
TechnicHubSection.IsVisible = deviceType == DeviceType.TechnicHub;
@@ -222,8 +222,8 @@ private void OnSelectedChannelChanged(int selectedChannel)
BuWizz3Channel3.SelectedChannel = selectedChannel;
BuWizz3Channel4.SelectedChannel = selectedChannel;
BuWizz3Channel5.SelectedChannel = selectedChannel;
- InfraredChannel0.SelectedChannel = selectedChannel;
- InfraredChannel1.SelectedChannel = selectedChannel;
+ PowerFunctionsChannel0.SelectedChannel = selectedChannel;
+ PowerFunctionsChannel1.SelectedChannel = selectedChannel;
PoweredUpChannel0.SelectedChannel = selectedChannel;
PoweredUpChannel1.SelectedChannel = selectedChannel;
BoostChannelA.SelectedChannel = selectedChannel;
diff --git a/BrickController2/BrickController2/UI/Images/infrared_image.png b/BrickController2/BrickController2/UI/Images/powerfunctions_image.png
similarity index 100%
rename from BrickController2/BrickController2/UI/Images/infrared_image.png
rename to BrickController2/BrickController2/UI/Images/powerfunctions_image.png
diff --git a/BrickController2/BrickController2/UI/Images/infrared_image_small.png b/BrickController2/BrickController2/UI/Images/powerfunctions_image_small.png
similarity index 100%
rename from BrickController2/BrickController2/UI/Images/infrared_image_small.png
rename to BrickController2/BrickController2/UI/Images/powerfunctions_image_small.png
diff --git a/BrickController2/BrickController2/UI/ViewModels/ChannelSetupPageViewModel.cs b/BrickController2/BrickController2/UI/ViewModels/ChannelSetupPageViewModel.cs
index 4f1c08ddc..bff63327e 100644
--- a/BrickController2/BrickController2/UI/ViewModels/ChannelSetupPageViewModel.cs
+++ b/BrickController2/BrickController2/UI/ViewModels/ChannelSetupPageViewModel.cs
@@ -101,7 +101,7 @@ public override async void OnAppearing()
_isDisappearing = false;
base.OnAppearing();
- if (Device.DeviceType != DeviceType.Infrared)
+ if (Device is IBluetoothDevice)
{
if (!await _deviceManager.IsBluetoothOnAsync())
{
diff --git a/BrickController2/BrickController2/UI/ViewModels/DevicePageViewModel.cs b/BrickController2/BrickController2/UI/ViewModels/DevicePageViewModel.cs
index 710220d36..baa1c040b 100644
--- a/BrickController2/BrickController2/UI/ViewModels/DevicePageViewModel.cs
+++ b/BrickController2/BrickController2/UI/ViewModels/DevicePageViewModel.cs
@@ -88,7 +88,7 @@ public override async void OnAppearing()
_isDisappearing = false;
base.OnAppearing();
- if (Device.DeviceType != DeviceType.Infrared)
+ if (Device is IBluetoothDevice)
{
if (!await _deviceManager.IsBluetoothOnAsync())
{
diff --git a/BrickController2/BrickController2/UI/ViewModels/ManualDeviceListPageViewModel.cs b/BrickController2/BrickController2/UI/ViewModels/ManualDeviceListPageViewModel.cs
index ddf253ca1..627f0425c 100644
--- a/BrickController2/BrickController2/UI/ViewModels/ManualDeviceListPageViewModel.cs
+++ b/BrickController2/BrickController2/UI/ViewModels/ManualDeviceListPageViewModel.cs
@@ -56,6 +56,7 @@ public ManualDeviceListPageViewModel(
var groups = manualDeviceManager.FactoryDataList
// apply ordering per vendor and device type
+ .Where(o => o.IsAvailable)
.OrderBy(o => o.VendorName)
.ThenBy(o => o.DeviceTypeName)
.GroupBy(o => (o.VendorName, o.DeviceType, o.DeviceTypeName), x => new DeviceEntry(x, GetDeviceInstance(x)));
diff --git a/BrickController2/BrickController2/UI/ViewModels/PlayerPageViewModel.cs b/BrickController2/BrickController2/UI/ViewModels/PlayerPageViewModel.cs
index aa671f200..6c0de58d0 100644
--- a/BrickController2/BrickController2/UI/ViewModels/PlayerPageViewModel.cs
+++ b/BrickController2/BrickController2/UI/ViewModels/PlayerPageViewModel.cs
@@ -101,7 +101,7 @@ public override async void OnAppearing()
_isDisappearing = false;
base.OnAppearing();
- if (_devices.Any(d => d.DeviceType != DeviceType.Infrared) && !await _deviceManager.IsBluetoothOnAsync())
+ if (_devices.Any(d => d is IBluetoothDevice) && !await _deviceManager.IsBluetoothOnAsync())
{
await _dialogService.ShowMessageBoxAsync(
Translate("Warning"),