From bc668465f4767b1c732a2e08d7f38215337ef1e0 Mon Sep 17 00:00:00 2001 From: "T. Thiery" Date: Thu, 22 Apr 2021 21:56:37 +0200 Subject: [PATCH] Add option to decode to double (#160) - Reorganized decoder (PortValueSingleEncoder) - Reorganized Single/MultiValueMode infrastructure of devices - Re-aligned all devices to new TOutputType - No Testing yet - No override to double for any port mode #126 breaking --- .../ExampleDynamicDevice.cs | 6 +- .../Devices/AbsoluteMotor.cs | 6 +- .../Devices/BasicMotor.cs | 6 +- .../Devices/ColorDistanceSensor.cs | 106 +++++++++--------- src/SharpBrick.PoweredUp/Devices/Current.cs | 12 +- src/SharpBrick.PoweredUp/Devices/Device.cs | 8 +- .../Devices/DuploTrainBaseColorSensor.cs | 16 +-- .../Devices/DuploTrainBaseMotor.cs | 4 +- .../Devices/DuploTrainBaseSpeaker.cs | 4 +- .../Devices/DuploTrainBaseSpeedometer.cs | 10 +- .../Devices/MarioHubAccelerometer.cs | 8 +- .../Devices/MarioHubPants.cs | 4 +- .../Devices/MarioHubTagSensor.cs | 8 +- src/SharpBrick.PoweredUp/Devices/Mode.cs | 31 +++-- .../Devices/MoveHubTiltSensor.cs | 22 ++-- .../Devices/MultiValueMode.cs | 16 +-- .../Devices/RemoteControlButton.cs | 4 +- .../Devices/RemoteControlRssi.cs | 4 +- .../Devices/SingleValueMode.cs | 16 +-- .../Devices/TachoMotor.cs | 12 +- .../Devices/TechnicColorSensor.cs | 28 ++--- .../Devices/TechnicDistanceSensor.cs | 16 +-- .../Devices/TechnicMediumHubAccelerometer.cs | 4 +- .../Devices/TechnicMediumHubGestSensor.cs | 4 +- .../Devices/TechnicMediumHubGyroSensor.cs | 4 +- .../TechnicMediumHubTemperatureSensor.cs | 6 +- .../Devices/TechnicMediumHubTiltSensor.cs | 10 +- src/SharpBrick.PoweredUp/Devices/Value.cs | 8 +- src/SharpBrick.PoweredUp/Devices/Voltage.cs | 12 +- .../Formatter/PortValueSingleEncoder.cs | 104 ++++++----------- .../Protocol/Knowledge/PortModeInfo.cs | 1 + .../Messages/MessageOfPortValuesModel.cs | 12 +- .../Protocol/Messages/PortValueData.cs | 2 +- .../PortValueCombinedModeEncoderTest.cs | 6 +- .../Formatter/PortValueEncoderTest.cs | 8 +- 35 files changed, 258 insertions(+), 270 deletions(-) diff --git a/examples/SharpBrick.PoweredUp.Examples/ExampleDynamicDevice.cs b/examples/SharpBrick.PoweredUp.Examples/ExampleDynamicDevice.cs index b3b786c..381ab77 100644 --- a/examples/SharpBrick.PoweredUp.Examples/ExampleDynamicDevice.cs +++ b/examples/SharpBrick.PoweredUp.Examples/ExampleDynamicDevice.cs @@ -54,9 +54,9 @@ await technicMediumHub.VerifyDeploymentModelAsync(mb => mb await dynamicDeviceWhichIsAMotor.UnlockFromCombinedModeNotificationSetupAsync(true); // get the individual modes for input and output - var powerMode = dynamicDeviceWhichIsAMotor.SingleValueMode(0); - var posMode = dynamicDeviceWhichIsAMotor.SingleValueMode(2); - var aposMode = dynamicDeviceWhichIsAMotor.SingleValueMode(3); + var powerMode = dynamicDeviceWhichIsAMotor.SingleValueMode(0); + var posMode = dynamicDeviceWhichIsAMotor.SingleValueMode(2); + var aposMode = dynamicDeviceWhichIsAMotor.SingleValueMode(3); // use their observables to report values using var disposable = posMode.Observable.Subscribe(x => Log.LogWarning($"Position: {x.SI} / {x.Pct}")); diff --git a/src/SharpBrick.PoweredUp/Devices/AbsoluteMotor.cs b/src/SharpBrick.PoweredUp/Devices/AbsoluteMotor.cs index 7e12d89..ffec2a8 100644 --- a/src/SharpBrick.PoweredUp/Devices/AbsoluteMotor.cs +++ b/src/SharpBrick.PoweredUp/Devices/AbsoluteMotor.cs @@ -8,12 +8,12 @@ namespace SharpBrick.PoweredUp { public abstract class AbsoluteMotor : TachoMotor { - protected SingleValueMode _absoluteMode; + protected SingleValueMode _absoluteMode; public byte ModeIndexAbsolutePosition { get; protected set; } = 3; public short AbsolutePosition => _absoluteMode.SI; public short AbsolutePositionPct => _absoluteMode.Pct; - public IObservable> AbsolutePositionObservable => _absoluteMode.Observable; + public IObservable> AbsolutePositionObservable => _absoluteMode.Observable; public AbsoluteMotor() { } @@ -21,7 +21,7 @@ public AbsoluteMotor() protected AbsoluteMotor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _absoluteMode = SingleValueMode(ModeIndexAbsolutePosition); + _absoluteMode = SingleValueMode(ModeIndexAbsolutePosition); ObserveForPropertyChanged(_absoluteMode.Observable, nameof(AbsolutePosition), nameof(AbsolutePositionPct)); } diff --git a/src/SharpBrick.PoweredUp/Devices/BasicMotor.cs b/src/SharpBrick.PoweredUp/Devices/BasicMotor.cs index f638a69..4806dbd 100644 --- a/src/SharpBrick.PoweredUp/Devices/BasicMotor.cs +++ b/src/SharpBrick.PoweredUp/Devices/BasicMotor.cs @@ -7,12 +7,12 @@ namespace SharpBrick.PoweredUp { public abstract class BasicMotor : Device { - protected SingleValueMode _powerMode; + protected SingleValueMode _powerMode; public byte ModeIndexPower { get; protected set; } = 0; public sbyte Power => _powerMode.SI; public sbyte PowerPct => _powerMode.Pct; - public IObservable> PowerObservable => _powerMode.Observable; + public IObservable> PowerObservable => _powerMode.Observable; public BasicMotor() { } @@ -20,7 +20,7 @@ public BasicMotor() public BasicMotor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _powerMode = SingleValueMode(ModeIndexPower); + _powerMode = SingleValueMode(ModeIndexPower); ObserveForPropertyChanged(_powerMode.Observable, nameof(Power), nameof(PowerPct)); } diff --git a/src/SharpBrick.PoweredUp/Devices/ColorDistanceSensor.cs b/src/SharpBrick.PoweredUp/Devices/ColorDistanceSensor.cs index 12f513f..715fc85 100644 --- a/src/SharpBrick.PoweredUp/Devices/ColorDistanceSensor.cs +++ b/src/SharpBrick.PoweredUp/Devices/ColorDistanceSensor.cs @@ -9,62 +9,62 @@ namespace SharpBrick.PoweredUp { - public class ColorDistanceSensor : Device, IPoweredUpDevice - { - protected SingleValueMode _colorMode; - protected SingleValueMode _proximityMode; - protected SingleValueMode _countMode; - protected SingleValueMode _reflectionMode; - protected SingleValueMode _ambientLightMode; - protected SingleValueMode _lightMode; - protected MultiValueMode _rgbMode; + public class ColorDistanceSensor : Device, IPoweredUpDevice + { + protected SingleValueMode _colorMode; + protected SingleValueMode _proximityMode; + protected SingleValueMode _countMode; + protected SingleValueMode _reflectionMode; + protected SingleValueMode _ambientLightMode; + protected SingleValueMode _lightMode; + protected MultiValueMode _rgbMode; - public byte ModeIndexColor { get; protected set; } = 0; - public byte ModeIndexProximity { get; protected set; } = 1; - public byte ModeIndexCount { get; protected set; } = 2; - public byte ModeIndexReflection { get; protected set; } = 3; - public byte ModeIndexAmbientLight { get; protected set; } = 4; - public byte ModeIndexLight { get; protected set; } = 5; - public byte ModeIndexRgb { get; protected set; } = 6; - public byte ModeIndexIRTx { get; protected set; } = 7; - public byte ModeIndexSPEC1 { get; protected set; } = 8; - public byte ModeIndexDebug { get; protected set; } = 9; - public byte ModeIndexCalibration { get; protected set; } = 10; + public byte ModeIndexColor { get; protected set; } = 0; + public byte ModeIndexProximity { get; protected set; } = 1; + public byte ModeIndexCount { get; protected set; } = 2; + public byte ModeIndexReflection { get; protected set; } = 3; + public byte ModeIndexAmbientLight { get; protected set; } = 4; + public byte ModeIndexLight { get; protected set; } = 5; + public byte ModeIndexRgb { get; protected set; } = 6; + public byte ModeIndexIRTx { get; protected set; } = 7; + public byte ModeIndexSPEC1 { get; protected set; } = 8; + public byte ModeIndexDebug { get; protected set; } = 9; + public byte ModeIndexCalibration { get; protected set; } = 10; - public TechnicColor Color => (TechnicColor)_colorMode.SI; - public IObservable ColorObservable => _colorMode.Observable.Select(v => (TechnicColor)v.SI); - public IObservable ProximityObservable => _proximityMode.Observable.Select(v => v.SI); - public IObservable CountObservable => _countMode.Observable.Select(v => v.SI); - public IObservable ReflectionObservable => _reflectionMode.Observable.Select(v => v.SI); - public IObservable AmbientLightObservable => _ambientLightMode.Observable.Select(v => v.SI); - public IObservable<(short red, short green, short blue)> RgbObservable => _rgbMode.Observable.Select(v => (v.SI[0], v.SI[1], v.SI[2])); + public TechnicColor Color => (TechnicColor)_colorMode.SI; + public IObservable ColorObservable => _colorMode.Observable.Select(v => (TechnicColor)v.SI); + public IObservable ProximityObservable => _proximityMode.Observable.Select(v => v.SI); + public IObservable CountObservable => _countMode.Observable.Select(v => v.SI); + public IObservable ReflectionObservable => _reflectionMode.Observable.Select(v => v.SI); + public IObservable AmbientLightObservable => _ambientLightMode.Observable.Select(v => v.SI); + public IObservable<(short red, short green, short blue)> RgbObservable => _rgbMode.Observable.Select(v => (v.SI[0], v.SI[1], v.SI[2])); - public ColorDistanceSensor() - { } - public ColorDistanceSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) - : base(protocol, hubId, portId) - { - _colorMode = SingleValueMode(ModeIndexColor); - _proximityMode = SingleValueMode(ModeIndexProximity); - _countMode = SingleValueMode(ModeIndexCount); - _reflectionMode = SingleValueMode(ModeIndexReflection); - _ambientLightMode = SingleValueMode(ModeIndexAmbientLight); - _lightMode = SingleValueMode(ModeIndexLight); - _rgbMode = MultiValueMode(ModeIndexRgb); - } + public ColorDistanceSensor() + { } + public ColorDistanceSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) + : base(protocol, hubId, portId) + { + _colorMode = SingleValueMode(ModeIndexColor); + _proximityMode = SingleValueMode(ModeIndexProximity); + _countMode = SingleValueMode(ModeIndexCount); + _reflectionMode = SingleValueMode(ModeIndexReflection); + _ambientLightMode = SingleValueMode(ModeIndexAmbientLight); + _lightMode = SingleValueMode(ModeIndexLight); + _rgbMode = MultiValueMode(ModeIndexRgb); + } - protected override uint GetDefaultDeltaInterval(byte modeIndex) - => modeIndex switch - { - 0 => 1, - 2 => 1, - _ => base.GetDefaultDeltaInterval(modeIndex), - }; + protected override uint GetDefaultDeltaInterval(byte modeIndex) + => modeIndex switch + { + 0 => 1, + 2 => 1, + _ => base.GetDefaultDeltaInterval(modeIndex), + }; - public IEnumerable GetStaticPortInfoMessages(Version softwareVersion, Version hardwareVersion, SystemType systemType) - => ((softwareVersion, hardwareVersion, systemType) switch - { - (_, _, _) => @" + public IEnumerable GetStaticPortInfoMessages(Version softwareVersion, Version hardwareVersion, SystemType systemType) + => ((softwareVersion, hardwareVersion, systemType) switch + { + (_, _, _) => @" 0B-00-43-01-01-07-0B-5F-06-A0-00 07-00-43-01-02-4F-00 12-00-44-01-00-00-43-4F-4C-4F-52-00-00-00-00-00-00-00 @@ -145,6 +145,6 @@ public IEnumerable GetStaticPortInfoMessages(Version softwareVersion, Ve 08-00-44-01-0A-05-10-00 0A-00-44-01-0A-80-08-01-05-00 " - }).Trim().Split("\n").Select(s => BytesStringUtil.StringToData(s)); - } + }).Trim().Split("\n").Select(s => BytesStringUtil.StringToData(s)); + } } diff --git a/src/SharpBrick.PoweredUp/Devices/Current.cs b/src/SharpBrick.PoweredUp/Devices/Current.cs index 6143bf4..bc09cbf 100644 --- a/src/SharpBrick.PoweredUp/Devices/Current.cs +++ b/src/SharpBrick.PoweredUp/Devices/Current.cs @@ -8,18 +8,18 @@ namespace SharpBrick.PoweredUp { public class Current : Device, IPoweredUpDevice { - protected SingleValueMode _currentLMode; - protected SingleValueMode _currentSMode; + protected SingleValueMode _currentLMode; + protected SingleValueMode _currentSMode; public byte ModeIndexCurrentL { get; protected set; } = 0x00; public byte ModeIndexCurrentS { get; protected set; } = 0x01; public short CurrentL => _currentLMode.SI; public short CurrentLPct => _currentLMode.Pct; - public IObservable> CurrentLObservable => _currentLMode.Observable; + public IObservable> CurrentLObservable => _currentLMode.Observable; public short CurrentS => _currentSMode.SI; public short CurrentSPct => _currentSMode.Pct; - public IObservable> CurrentSObservable => _currentSMode.Observable; + public IObservable> CurrentSObservable => _currentSMode.Observable; public Current() { } @@ -27,8 +27,8 @@ public Current() public Current(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _currentLMode = SingleValueMode(ModeIndexCurrentL); - _currentSMode = SingleValueMode(ModeIndexCurrentS); + _currentLMode = SingleValueMode(ModeIndexCurrentL); + _currentSMode = SingleValueMode(ModeIndexCurrentS); ObserveForPropertyChanged(_currentLMode.Observable, nameof(CurrentL), nameof(CurrentLPct)); ObserveForPropertyChanged(_currentSMode.Observable, nameof(CurrentS), nameof(CurrentSPct)); diff --git a/src/SharpBrick.PoweredUp/Devices/Device.cs b/src/SharpBrick.PoweredUp/Devices/Device.cs index dbb8a9e..c9d5e5c 100644 --- a/src/SharpBrick.PoweredUp/Devices/Device.cs +++ b/src/SharpBrick.PoweredUp/Devices/Device.cs @@ -46,10 +46,10 @@ public Device(ILegoWirelessProtocol protocol, byte hubId, byte portId) BuildModes(); } - public SingleValueMode SingleValueMode(byte modeIndex) - => _modes.TryGetValue(modeIndex, out var mode) ? mode as SingleValueMode : default; - public MultiValueMode MultiValueMode(byte modeIndex) - => _modes.TryGetValue(modeIndex, out var mode) ? mode as MultiValueMode : default; + public SingleValueMode SingleValueMode(byte modeIndex) + => _modes.TryGetValue(modeIndex, out var mode) ? mode as SingleValueMode : default; + public MultiValueMode MultiValueMode(byte modeIndex) + => _modes.TryGetValue(modeIndex, out var mode) ? mode as MultiValueMode : default; protected void BuildModes() { diff --git a/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseColorSensor.cs b/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseColorSensor.cs index cd6a278..3f6ed0d 100644 --- a/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseColorSensor.cs +++ b/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseColorSensor.cs @@ -9,10 +9,10 @@ namespace SharpBrick.PoweredUp { public class DuploTrainBaseColorSensor : Device, IPoweredUpDevice { - protected SingleValueMode _colorMode; - protected SingleValueMode _colorTagMode; - protected SingleValueMode _reflectionMode; - protected MultiValueMode _rgbMode; + protected SingleValueMode _colorMode; + protected SingleValueMode _colorTagMode; + protected SingleValueMode _reflectionMode; + protected MultiValueMode _rgbMode; public byte ModeIndexColor { get; protected set; } = 0; public byte ModeIndexColorTag { get; protected set; } = 1; @@ -37,10 +37,10 @@ public DuploTrainBaseColorSensor() public DuploTrainBaseColorSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _colorMode = SingleValueMode(ModeIndexColor); - _colorTagMode = SingleValueMode(ModeIndexColorTag); - _reflectionMode = SingleValueMode(ModeIndexReflection); - _rgbMode = MultiValueMode(ModeIndexRgb); + _colorMode = SingleValueMode(ModeIndexColor); + _colorTagMode = SingleValueMode(ModeIndexColorTag); + _reflectionMode = SingleValueMode(ModeIndexReflection); + _rgbMode = MultiValueMode(ModeIndexRgb); ObserveForPropertyChanged(_colorMode.Observable, nameof(Color)); ObserveForPropertyChanged(_colorTagMode.Observable, nameof(ColorTag)); diff --git a/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseMotor.cs b/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseMotor.cs index f70361d..5c62a0c 100644 --- a/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseMotor.cs +++ b/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseMotor.cs @@ -12,7 +12,7 @@ namespace SharpBrick.PoweredUp { public class DuploTrainBaseMotor : Device, IPoweredUpDevice { - public SingleValueMode _onSecMode; + public SingleValueMode _onSecMode; public byte ModeIndexMotor { get; protected set; } = 0; public byte ModeIndexOnSec { get; protected set; } = 1; @@ -26,7 +26,7 @@ public DuploTrainBaseMotor() public DuploTrainBaseMotor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _onSecMode = SingleValueMode(ModeIndexOnSec); + _onSecMode = SingleValueMode(ModeIndexOnSec); ObserveForPropertyChanged(_onSecMode.Observable, nameof(OnSeconds)); } diff --git a/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseSpeaker.cs b/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseSpeaker.cs index 0492877..42e9e2d 100644 --- a/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseSpeaker.cs +++ b/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseSpeaker.cs @@ -11,7 +11,7 @@ namespace SharpBrick.PoweredUp public class DuploTrainBaseSpeaker : Device, IPoweredUpDevice { - protected SingleValueMode _soundMode; + protected SingleValueMode _soundMode; public byte ModeIndexTone { get; protected set; } = 0; public byte ModeIndexSound { get; protected set; } = 1; @@ -23,7 +23,7 @@ public DuploTrainBaseSpeaker() public DuploTrainBaseSpeaker(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _soundMode = SingleValueMode(ModeIndexSound); + _soundMode = SingleValueMode(ModeIndexSound); } public async Task PlaySoundAsync(DuploTrainBaseSound sound) diff --git a/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseSpeedometer.cs b/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseSpeedometer.cs index 6238817..4349d50 100644 --- a/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseSpeedometer.cs +++ b/src/SharpBrick.PoweredUp/Devices/DuploTrainBaseSpeedometer.cs @@ -10,15 +10,15 @@ namespace SharpBrick.PoweredUp { public class DuploTrainBaseSpeedometer : Device, IPoweredUpDevice { - protected SingleValueMode _speedMode; - protected SingleValueMode _countMode; + protected SingleValueMode _speedMode; + protected SingleValueMode _countMode; public byte ModeIndexSpeed { get; protected set; } = 0; public byte ModeIndexCount { get; protected set; } = 1; public short Speed => _speedMode.SI; public short SpeedPct => _speedMode.Pct; - public IObservable> SpeedObservable => _speedMode.Observable; + public IObservable> SpeedObservable => _speedMode.Observable; public int Count => _countMode.SI; public IObservable CountObservable => _countMode.Observable.Select(v => v.SI); @@ -29,8 +29,8 @@ public DuploTrainBaseSpeedometer() public DuploTrainBaseSpeedometer(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _speedMode = SingleValueMode(ModeIndexSpeed); - _countMode = SingleValueMode(ModeIndexCount); + _speedMode = SingleValueMode(ModeIndexSpeed); + _countMode = SingleValueMode(ModeIndexCount); ObserveForPropertyChanged(_speedMode.Observable, nameof(Speed), nameof(SpeedPct)); ObserveForPropertyChanged(_countMode.Observable, nameof(Count)); diff --git a/src/SharpBrick.PoweredUp/Devices/MarioHubAccelerometer.cs b/src/SharpBrick.PoweredUp/Devices/MarioHubAccelerometer.cs index fd34014..064757e 100644 --- a/src/SharpBrick.PoweredUp/Devices/MarioHubAccelerometer.cs +++ b/src/SharpBrick.PoweredUp/Devices/MarioHubAccelerometer.cs @@ -9,8 +9,8 @@ namespace SharpBrick.PoweredUp { public class MarioHubAccelerometer : Device, IPoweredUpDevice { - protected MultiValueMode _rawMode; - protected MultiValueMode _gestMode; + protected MultiValueMode _rawMode; + protected MultiValueMode _gestMode; public byte ModeIndexRaw { get; protected set; } = 0; public byte ModeIndexGesture { get; protected set; } = 1; @@ -26,8 +26,8 @@ public MarioHubAccelerometer() public MarioHubAccelerometer(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _rawMode = MultiValueMode(ModeIndexRaw); - _gestMode = MultiValueMode(ModeIndexGesture); + _rawMode = MultiValueMode(ModeIndexRaw); + _gestMode = MultiValueMode(ModeIndexGesture); //ObserveForPropertyChanged(_rawMode.Observable, nameof(Coins)); } diff --git a/src/SharpBrick.PoweredUp/Devices/MarioHubPants.cs b/src/SharpBrick.PoweredUp/Devices/MarioHubPants.cs index b1b6fd1..928da07 100644 --- a/src/SharpBrick.PoweredUp/Devices/MarioHubPants.cs +++ b/src/SharpBrick.PoweredUp/Devices/MarioHubPants.cs @@ -10,7 +10,7 @@ namespace SharpBrick.PoweredUp // https://github.com/bricklife/LEGO-Mario-Reveng/blob/master/IOType-0x4a.md public class MarioHubPants : Device, IPoweredUpDevice { - protected SingleValueMode _pantsMode; + protected SingleValueMode _pantsMode; public byte ModeIndexPants { get; protected set; } = 0; @@ -23,7 +23,7 @@ public MarioHubPants() public MarioHubPants(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _pantsMode = SingleValueMode(ModeIndexPants); + _pantsMode = SingleValueMode(ModeIndexPants); ObserveForPropertyChanged(_pantsMode.Observable, nameof(Pants)); } diff --git a/src/SharpBrick.PoweredUp/Devices/MarioHubTagSensor.cs b/src/SharpBrick.PoweredUp/Devices/MarioHubTagSensor.cs index 81a15c0..09b2463 100644 --- a/src/SharpBrick.PoweredUp/Devices/MarioHubTagSensor.cs +++ b/src/SharpBrick.PoweredUp/Devices/MarioHubTagSensor.cs @@ -10,8 +10,8 @@ namespace SharpBrick.PoweredUp { public class MarioHubTagSensor : Device, IPoweredUpDevice { - protected MultiValueMode _tagMode; - protected MultiValueMode _rgbMode; + protected MultiValueMode _tagMode; + protected MultiValueMode _rgbMode; public byte ModeIndexTag { get; protected set; } = 0; public byte ModeIndexRgb { get; protected set; } = 1; @@ -31,8 +31,8 @@ public MarioHubTagSensor() public MarioHubTagSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _tagMode = MultiValueMode(ModeIndexTag); - _rgbMode = MultiValueMode(ModeIndexRgb); + _tagMode = MultiValueMode(ModeIndexTag); + _rgbMode = MultiValueMode(ModeIndexRgb); ObserveForPropertyChanged(_tagMode.Observable, nameof(Barcode)); ObserveForPropertyChanged(_tagMode.Observable, nameof(ColorNo)); diff --git a/src/SharpBrick.PoweredUp/Devices/Mode.cs b/src/SharpBrick.PoweredUp/Devices/Mode.cs index 49c2b48..14d59c2 100644 --- a/src/SharpBrick.PoweredUp/Devices/Mode.cs +++ b/src/SharpBrick.PoweredUp/Devices/Mode.cs @@ -27,19 +27,32 @@ public static Mode Create(ILegoWirelessProtocol protocol, byte hubId, byte portI { var modeInfo = protocol.Knowledge.PortMode(hubId, portId, modeIndex); - Mode result = (modeInfo.DatasetType, modeInfo.NumberOfDatasets) switch + Mode result = modeInfo switch { - (PortModeInformationDataType.SByte, 1) => new SingleValueMode(protocol, modeInfo, modeValueObservable), - (PortModeInformationDataType.SByte, _) => new MultiValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.SByte, NumberOfDatasets: 1, OverrideDatasetTypeToDouble: false } => new SingleValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.SByte, NumberOfDatasets: _, OverrideDatasetTypeToDouble: false } => new MultiValueMode(protocol, modeInfo, modeValueObservable), - (PortModeInformationDataType.Int16, 1) => new SingleValueMode(protocol, modeInfo, modeValueObservable), - (PortModeInformationDataType.Int16, _) => new MultiValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.Int16, NumberOfDatasets: 1, OverrideDatasetTypeToDouble: false } => new SingleValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.Int16, NumberOfDatasets: _, OverrideDatasetTypeToDouble: false } => new MultiValueMode(protocol, modeInfo, modeValueObservable), - (PortModeInformationDataType.Int32, 1) => new SingleValueMode(protocol, modeInfo, modeValueObservable), - (PortModeInformationDataType.Int32, _) => new MultiValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.Int32, NumberOfDatasets: 1, OverrideDatasetTypeToDouble: false } => new SingleValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.Int32, NumberOfDatasets: _, OverrideDatasetTypeToDouble: false } => new MultiValueMode(protocol, modeInfo, modeValueObservable), - (PortModeInformationDataType.Single, 1) => new SingleValueMode(protocol, modeInfo, modeValueObservable), - (PortModeInformationDataType.Single, _) => new MultiValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.Single, NumberOfDatasets: 1, OverrideDatasetTypeToDouble: false } => new SingleValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.Single, NumberOfDatasets: _, OverrideDatasetTypeToDouble: false } => new MultiValueMode(protocol, modeInfo, modeValueObservable), + + // override to allow scaling crossing the boundary of the original data type + { DatasetType: PortModeInformationDataType.SByte, NumberOfDatasets: 1, OverrideDatasetTypeToDouble: true } => new SingleValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.SByte, NumberOfDatasets: _, OverrideDatasetTypeToDouble: true } => new MultiValueMode(protocol, modeInfo, modeValueObservable), + + { DatasetType: PortModeInformationDataType.Int16, NumberOfDatasets: 1, OverrideDatasetTypeToDouble: true } => new SingleValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.Int16, NumberOfDatasets: _, OverrideDatasetTypeToDouble: true } => new MultiValueMode(protocol, modeInfo, modeValueObservable), + + { DatasetType: PortModeInformationDataType.Int32, NumberOfDatasets: 1, OverrideDatasetTypeToDouble: true } => new SingleValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.Int32, NumberOfDatasets: _, OverrideDatasetTypeToDouble: true } => new MultiValueMode(protocol, modeInfo, modeValueObservable), + + { DatasetType: PortModeInformationDataType.Single, NumberOfDatasets: 1, OverrideDatasetTypeToDouble: true } => new SingleValueMode(protocol, modeInfo, modeValueObservable), + { DatasetType: PortModeInformationDataType.Single, NumberOfDatasets: _, OverrideDatasetTypeToDouble: true } => new MultiValueMode(protocol, modeInfo, modeValueObservable), _ => throw new NotSupportedException("Mode of unknown data type"), }; diff --git a/src/SharpBrick.PoweredUp/Devices/MoveHubTiltSensor.cs b/src/SharpBrick.PoweredUp/Devices/MoveHubTiltSensor.cs index 00ae75c..49eb581 100644 --- a/src/SharpBrick.PoweredUp/Devices/MoveHubTiltSensor.cs +++ b/src/SharpBrick.PoweredUp/Devices/MoveHubTiltSensor.cs @@ -12,11 +12,11 @@ namespace SharpBrick.PoweredUp { public class MoveHubTiltSensor : Device, IPoweredUpDevice { - protected MultiValueMode _twoAxisFullMode; - protected SingleValueMode _twoAxisStateMode; - protected SingleValueMode _threeAxisStateMode; - protected SingleValueMode _impactsMode; - protected MultiValueMode _threeAxisFullMode; + protected MultiValueMode _twoAxisFullMode; + protected SingleValueMode _twoAxisStateMode; + protected SingleValueMode _threeAxisStateMode; + protected SingleValueMode _impactsMode; + protected MultiValueMode _threeAxisFullMode; /// /// Two axis full values @@ -51,7 +51,7 @@ public class MoveHubTiltSensor : Device, IPoweredUpDevice public IObservable<(sbyte roll, sbyte pitch)> TwoAxisFullObservable => _twoAxisFullMode.Observable.Select(v => (v.SI[0], v.SI[1])); public IObservable TwoAxisStateObservable => _twoAxisStateMode.Observable.Select(x => (MoveHubTiltSimpleOrientation)x.SI); public IObservable ThreeAxisStateObservable => _threeAxisStateMode.Observable.Select(x => (MoveHubTiltOrientation)x.SI); - public IObservable> ImpactsObservable => _impactsMode.Observable; + public IObservable> ImpactsObservable => _impactsMode.Observable; public IObservable<(sbyte roll, sbyte pitch, sbyte yaw)> ThreeAxisFullObservable => _threeAxisFullMode.Observable.Select(v => (v.SI[0], v.SI[1], v.SI[2])); public MoveHubTiltSensor() @@ -60,11 +60,11 @@ public MoveHubTiltSensor() public MoveHubTiltSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _twoAxisFullMode = MultiValueMode(ModeIndexTwoAxisFull); - _twoAxisStateMode = SingleValueMode(ModeIndexTwoAxisState); - _threeAxisStateMode = SingleValueMode(ModeIndexThreeAxisState); - _impactsMode = SingleValueMode(ModeIndexImpacts); - _threeAxisFullMode = MultiValueMode(ModeIndexThreeAxisFull); + _twoAxisFullMode = MultiValueMode(ModeIndexTwoAxisFull); + _twoAxisStateMode = SingleValueMode(ModeIndexTwoAxisState); + _threeAxisStateMode = SingleValueMode(ModeIndexThreeAxisState); + _impactsMode = SingleValueMode(ModeIndexImpacts); + _threeAxisFullMode = MultiValueMode(ModeIndexThreeAxisFull); ObserveForPropertyChanged(_twoAxisFullMode.Observable, nameof(TwoAxisFull)); ObserveForPropertyChanged(_twoAxisStateMode.Observable, nameof(TwoAxisState)); diff --git a/src/SharpBrick.PoweredUp/Devices/MultiValueMode.cs b/src/SharpBrick.PoweredUp/Devices/MultiValueMode.cs index bb9f8c3..5412282 100644 --- a/src/SharpBrick.PoweredUp/Devices/MultiValueMode.cs +++ b/src/SharpBrick.PoweredUp/Devices/MultiValueMode.cs @@ -6,13 +6,13 @@ namespace SharpBrick.PoweredUp { - public class MultiValueMode : Mode + public class MultiValueMode : Mode { - public TPayload[] Raw { get; private set; } - public TPayload[] SI { get; private set; } - public TPayload[] Pct { get; private set; } + public TDatasetType[] Raw { get; private set; } + public TOutputType[] SI { get; private set; } + public TOutputType[] Pct { get; private set; } - public IObservable> Observable { get; } + public IObservable> Observable { get; } public MultiValueMode(ILegoWirelessProtocol protocol, PortModeInfo modeInfo, IObservable modeValueObservable) : base(protocol, modeInfo, modeValueObservable) @@ -21,10 +21,10 @@ public MultiValueMode(ILegoWirelessProtocol protocol, PortModeInfo modeInfo, IOb ObserveOnLocalProperty(Observable, v => Raw = v.Raw, v => SI = v.SI, v => Pct = v.Pct); ObserveForPropertyChanged(Observable, nameof(Raw), nameof(SI), nameof(Pct)); } - protected IObservable> CreateObservable() + protected IObservable> CreateObservable() => _modeValueObservable - .Cast>() - .Select(pvd => new Value() + .Cast>() + .Select(pvd => new Value() { Raw = pvd.InputValues, SI = pvd.SIInputValues, diff --git a/src/SharpBrick.PoweredUp/Devices/RemoteControlButton.cs b/src/SharpBrick.PoweredUp/Devices/RemoteControlButton.cs index c5c211a..410949e 100644 --- a/src/SharpBrick.PoweredUp/Devices/RemoteControlButton.cs +++ b/src/SharpBrick.PoweredUp/Devices/RemoteControlButton.cs @@ -14,7 +14,7 @@ public class RemoteControlButton : Device, IPoweredUpDevice protected sbyte RedBitMask = 0b0000_0010; protected sbyte MinusBitMask = 0b0000_0100; - protected SingleValueMode _keyBitFieldMode; + protected SingleValueMode _keyBitFieldMode; public byte ModeIndexBitField { get; protected set; } = 3; public bool Plus => IsBitMaskSet(_keyBitFieldMode.SI, PlusBitMask); @@ -32,7 +32,7 @@ public RemoteControlButton() public RemoteControlButton(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _keyBitFieldMode = SingleValueMode(ModeIndexBitField); + _keyBitFieldMode = SingleValueMode(ModeIndexBitField); ObserveForPropertyChanged(PlusObservable, nameof(Plus)); ObserveForPropertyChanged(RedObservable, nameof(Red)); diff --git a/src/SharpBrick.PoweredUp/Devices/RemoteControlRssi.cs b/src/SharpBrick.PoweredUp/Devices/RemoteControlRssi.cs index 86551d9..22275ce 100644 --- a/src/SharpBrick.PoweredUp/Devices/RemoteControlRssi.cs +++ b/src/SharpBrick.PoweredUp/Devices/RemoteControlRssi.cs @@ -10,7 +10,7 @@ namespace SharpBrick.PoweredUp.Devices { public class RemoteControlRssi : Device, IPoweredUpDevice { - protected SingleValueMode _rssiMode; + protected SingleValueMode _rssiMode; public byte ModeIndexRssi { get; protected set; } = 0; public sbyte Rssi => _rssiMode.SI; @@ -22,7 +22,7 @@ public RemoteControlRssi() public RemoteControlRssi(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _rssiMode = SingleValueMode(ModeIndexRssi); + _rssiMode = SingleValueMode(ModeIndexRssi); ObserveForPropertyChanged(_rssiMode.Observable, nameof(Rssi)); } diff --git a/src/SharpBrick.PoweredUp/Devices/SingleValueMode.cs b/src/SharpBrick.PoweredUp/Devices/SingleValueMode.cs index f970b9e..bdeb82c 100644 --- a/src/SharpBrick.PoweredUp/Devices/SingleValueMode.cs +++ b/src/SharpBrick.PoweredUp/Devices/SingleValueMode.cs @@ -6,13 +6,13 @@ namespace SharpBrick.PoweredUp { - public class SingleValueMode : Mode + public class SingleValueMode : Mode { - public TPayload Raw { get; private set; } - public TPayload SI { get; private set; } - public TPayload Pct { get; private set; } + public TDatasetType Raw { get; private set; } + public TOutputType SI { get; private set; } + public TOutputType Pct { get; private set; } - public IObservable> Observable { get; } + public IObservable> Observable { get; } public SingleValueMode(ILegoWirelessProtocol protocol, PortModeInfo modeInfo, IObservable modeValueObservable) : base(protocol, modeInfo, modeValueObservable) @@ -21,10 +21,10 @@ public SingleValueMode(ILegoWirelessProtocol protocol, PortModeInfo modeInfo, IO ObserveOnLocalProperty(Observable, v => Raw = v.Raw, v => SI = v.SI, v => Pct = v.Pct); ObserveForPropertyChanged(Observable, nameof(Raw), nameof(SI), nameof(Pct)); } - protected IObservable> CreateObservable() + protected IObservable> CreateObservable() => _modeValueObservable - .Cast>() - .Select(pvd => new Value() + .Cast>() + .Select(pvd => new Value() { Raw = pvd.InputValues[0], SI = pvd.SIInputValues[0], diff --git a/src/SharpBrick.PoweredUp/Devices/TachoMotor.cs b/src/SharpBrick.PoweredUp/Devices/TachoMotor.cs index 8c52e1a..025a8c9 100644 --- a/src/SharpBrick.PoweredUp/Devices/TachoMotor.cs +++ b/src/SharpBrick.PoweredUp/Devices/TachoMotor.cs @@ -7,18 +7,18 @@ namespace SharpBrick.PoweredUp { public abstract class TachoMotor : BasicMotor { - protected SingleValueMode _speedMode; - protected SingleValueMode _positionMode; + protected SingleValueMode _speedMode; + protected SingleValueMode _positionMode; public byte ModeIndexSpeed { get; protected set; } = 1; public byte ModeIndexPosition { get; protected set; } = 2; public sbyte Speed => _speedMode.SI; public sbyte SpeedPct => _speedMode.Pct; - public IObservable> SpeedObservable => _speedMode.Observable; + public IObservable> SpeedObservable => _speedMode.Observable; public int Position => _positionMode.SI; public int PositionPct => _positionMode.Pct; - public IObservable> PositionObservable => _positionMode.Observable; + public IObservable> PositionObservable => _positionMode.Observable; public TachoMotor() { } @@ -26,8 +26,8 @@ public TachoMotor() protected TachoMotor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _speedMode = SingleValueMode(ModeIndexSpeed); - _positionMode = SingleValueMode(ModeIndexPosition); + _speedMode = SingleValueMode(ModeIndexSpeed); + _positionMode = SingleValueMode(ModeIndexPosition); ObserveForPropertyChanged(_speedMode.Observable, nameof(Speed), nameof(SpeedPct)); ObserveForPropertyChanged(_positionMode.Observable, nameof(Position), nameof(PositionPct)); diff --git a/src/SharpBrick.PoweredUp/Devices/TechnicColorSensor.cs b/src/SharpBrick.PoweredUp/Devices/TechnicColorSensor.cs index 6c20bc1..ca817df 100644 --- a/src/SharpBrick.PoweredUp/Devices/TechnicColorSensor.cs +++ b/src/SharpBrick.PoweredUp/Devices/TechnicColorSensor.cs @@ -11,15 +11,15 @@ namespace SharpBrick.PoweredUp { public class TechnicColorSensor : Device, IPoweredUpDevice { - protected SingleValueMode _colorMode; - protected SingleValueMode _reflectionMode; - protected SingleValueMode _ambientLightMode; - protected MultiValueMode _lightMode; + protected SingleValueMode _colorMode; + protected SingleValueMode _reflectionMode; + protected SingleValueMode _ambientLightMode; + protected MultiValueMode _lightMode; - protected MultiValueMode _rawReflectionMode; - protected MultiValueMode _rgbMode; - protected MultiValueMode _hsvMode; - protected MultiValueMode _shsvMode; + protected MultiValueMode _rawReflectionMode; + protected MultiValueMode _rgbMode; + protected MultiValueMode _hsvMode; + protected MultiValueMode _shsvMode; public byte ModeIndexColor { get; protected set; } = 0; public byte ModeIndexReflection { get; protected set; } = 1; @@ -48,12 +48,12 @@ public TechnicColorSensor() public TechnicColorSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _colorMode = SingleValueMode(ModeIndexColor); - _reflectionMode = SingleValueMode(ModeIndexReflection); - _ambientLightMode = SingleValueMode(ModeIndexAmbientLight); - _lightMode = MultiValueMode(ModeIndexLight); - _rgbMode = MultiValueMode(ModeIndexRgbIntern); - _hsvMode = MultiValueMode(ModeIndexHSV); + _colorMode = SingleValueMode(ModeIndexColor); + _reflectionMode = SingleValueMode(ModeIndexReflection); + _ambientLightMode = SingleValueMode(ModeIndexAmbientLight); + _lightMode = MultiValueMode(ModeIndexLight); + _rgbMode = MultiValueMode(ModeIndexRgbIntern); + _hsvMode = MultiValueMode(ModeIndexHSV); } public async Task SetSectorLightAsync(byte sector1, byte sector2, byte sector3) diff --git a/src/SharpBrick.PoweredUp/Devices/TechnicDistanceSensor.cs b/src/SharpBrick.PoweredUp/Devices/TechnicDistanceSensor.cs index e2f2258..b655771 100644 --- a/src/SharpBrick.PoweredUp/Devices/TechnicDistanceSensor.cs +++ b/src/SharpBrick.PoweredUp/Devices/TechnicDistanceSensor.cs @@ -10,10 +10,10 @@ namespace SharpBrick.PoweredUp { public class TechnicDistanceSensor : Device, IPoweredUpDevice { - protected SingleValueMode _distlMode; - protected SingleValueMode _distsMode; - protected SingleValueMode _singlMode; - protected MultiValueMode _lightMode; + protected SingleValueMode _distlMode; + protected SingleValueMode _distsMode; + protected SingleValueMode _singlMode; + protected MultiValueMode _lightMode; public byte ModeIndexDistance { get; protected set; } = 0; public byte ModeIndexShortOnlyDistance { get; protected set; } = 1; @@ -32,10 +32,10 @@ public TechnicDistanceSensor() public TechnicDistanceSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _distlMode = SingleValueMode(ModeIndexDistance); - _distsMode = SingleValueMode(ModeIndexShortOnlyDistance); - _singlMode = SingleValueMode(ModeIndexSingleMeasurement); - _lightMode = MultiValueMode(ModeIndexLight); + _distlMode = SingleValueMode(ModeIndexDistance); + _distsMode = SingleValueMode(ModeIndexShortOnlyDistance); + _singlMode = SingleValueMode(ModeIndexSingleMeasurement); + _lightMode = MultiValueMode(ModeIndexLight); ObserveForPropertyChanged(_distlMode.Observable, nameof(Distance)); ObserveForPropertyChanged(_distsMode.Observable, nameof(ShortOnlyDistance)); diff --git a/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubAccelerometer.cs b/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubAccelerometer.cs index 045ee61..c2ceb3b 100644 --- a/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubAccelerometer.cs +++ b/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubAccelerometer.cs @@ -10,7 +10,7 @@ namespace SharpBrick.PoweredUp // accelerometers measure translation public class TechnicMediumHubAccelerometer : Device, IPoweredUpDevice { - protected MultiValueMode _gravityMode; + protected MultiValueMode _gravityMode; public byte ModeIndexGravity { get; protected set; } = 0; public byte ModeIndexCalibration { get; protected set; } = 1; @@ -24,7 +24,7 @@ public TechnicMediumHubAccelerometer() public TechnicMediumHubAccelerometer(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _gravityMode = MultiValueMode(ModeIndexGravity); + _gravityMode = MultiValueMode(ModeIndexGravity); ObserveForPropertyChanged(_gravityMode.Observable, nameof(Gravity)); } diff --git a/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubGestSensor.cs b/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubGestSensor.cs index fcb079b..704b91b 100644 --- a/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubGestSensor.cs +++ b/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubGestSensor.cs @@ -11,7 +11,7 @@ namespace SharpBrick.PoweredUp { public class TechnicMediumHubGestureSensor : Device, IPoweredUpDevice { - protected SingleValueMode _gestureMode; + protected SingleValueMode _gestureMode; public byte ModeIndexGesture { get; protected set; } = 0; public Gesture Gesture => (Gesture)_gestureMode.SI; @@ -23,7 +23,7 @@ public TechnicMediumHubGestureSensor() public TechnicMediumHubGestureSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _gestureMode = SingleValueMode(ModeIndexGesture); + _gestureMode = SingleValueMode(ModeIndexGesture); ObserveForPropertyChanged(_gestureMode.Observable, nameof(Gesture)); } diff --git a/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubGyroSensor.cs b/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubGyroSensor.cs index 04fd0b1..c38c461 100644 --- a/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubGyroSensor.cs +++ b/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubGyroSensor.cs @@ -10,7 +10,7 @@ namespace SharpBrick.PoweredUp // gyroscopes measure rotation public class TechnicMediumHubGyroSensor : Device, IPoweredUpDevice { - protected MultiValueMode _rotationMode; + protected MultiValueMode _rotationMode; public byte ModeIndexRotation { get; protected set; } = 0; public (short x, short y, short z) Rotation => (_rotationMode.SI[0], _rotationMode.SI[1], _rotationMode.SI[2]); @@ -22,7 +22,7 @@ public TechnicMediumHubGyroSensor() public TechnicMediumHubGyroSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _rotationMode = MultiValueMode(ModeIndexRotation); + _rotationMode = MultiValueMode(ModeIndexRotation); ObserveForPropertyChanged(_rotationMode.Observable, nameof(Rotation)); } diff --git a/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubTemperatureSensor.cs b/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubTemperatureSensor.cs index 7b46990..ff5b2df 100644 --- a/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubTemperatureSensor.cs +++ b/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubTemperatureSensor.cs @@ -8,12 +8,12 @@ namespace SharpBrick.PoweredUp { public class TechnicMediumHubTemperatureSensor : Device, IPoweredUpDevice { - protected SingleValueMode _temperatureMode; + protected SingleValueMode _temperatureMode; public byte ModeIndexTemperature { get; protected set; } = 0; public short Temperature => _temperatureMode.SI; public short TemperaturePct => _temperatureMode.Pct; - public IObservable> TemperatureObservable => _temperatureMode.Observable; + public IObservable> TemperatureObservable => _temperatureMode.Observable; public TechnicMediumHubTemperatureSensor() { } @@ -21,7 +21,7 @@ public TechnicMediumHubTemperatureSensor() public TechnicMediumHubTemperatureSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _temperatureMode = SingleValueMode(ModeIndexTemperature); + _temperatureMode = SingleValueMode(ModeIndexTemperature); ObserveForPropertyChanged(_temperatureMode.Observable, nameof(Temperature), nameof(TemperaturePct)); } diff --git a/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubTiltSensor.cs b/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubTiltSensor.cs index da3d63a..e2fe996 100644 --- a/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubTiltSensor.cs +++ b/src/SharpBrick.PoweredUp/Devices/TechnicMediumHubTiltSensor.cs @@ -11,8 +11,8 @@ namespace SharpBrick.PoweredUp { public class TechnicMediumHubTiltSensor : Device, IPoweredUpDevice { - protected MultiValueMode _positionMode; - protected SingleValueMode _impactsMode; + protected MultiValueMode _positionMode; + protected SingleValueMode _impactsMode; public byte ModeIndexPosition { get; protected set; } = 0; public byte ModeIndexImpacts { get; protected set; } = 1; public byte ModeIndexConfig { get; protected set; } = 2; @@ -20,7 +20,7 @@ public class TechnicMediumHubTiltSensor : Device, IPoweredUpDevice public (short x, short y, short z) Position => (_positionMode.SI[0], _positionMode.SI[1], _positionMode.SI[2]); public int Impacts => _impactsMode.SI; public IObservable<(short x, short y, short z)> PositionObservable => _positionMode.Observable.Select(v => (v.SI[0], v.SI[1], v.SI[2])); - public IObservable> ImpactsObservable => _impactsMode.Observable; + public IObservable> ImpactsObservable => _impactsMode.Observable; public TechnicMediumHubTiltSensor() { } @@ -28,8 +28,8 @@ public TechnicMediumHubTiltSensor() public TechnicMediumHubTiltSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _positionMode = MultiValueMode(ModeIndexPosition); - _impactsMode = SingleValueMode(ModeIndexImpacts); + _positionMode = MultiValueMode(ModeIndexPosition); + _impactsMode = SingleValueMode(ModeIndexImpacts); ObserveForPropertyChanged(_positionMode.Observable, nameof(Position)); ObserveForPropertyChanged(_impactsMode.Observable, nameof(Impacts)); diff --git a/src/SharpBrick.PoweredUp/Devices/Value.cs b/src/SharpBrick.PoweredUp/Devices/Value.cs index de5c64f..0ac2681 100644 --- a/src/SharpBrick.PoweredUp/Devices/Value.cs +++ b/src/SharpBrick.PoweredUp/Devices/Value.cs @@ -1,9 +1,9 @@ namespace SharpBrick.PoweredUp { - public class Value + public class Value { - public TPayload Raw { get; set; } - public TPayload SI { get; set; } - public TPayload Pct { get; set; } + public TDatasetType Raw { get; set; } + public TOutputType SI { get; set; } + public TOutputType Pct { get; set; } } } \ No newline at end of file diff --git a/src/SharpBrick.PoweredUp/Devices/Voltage.cs b/src/SharpBrick.PoweredUp/Devices/Voltage.cs index 1410a2c..8fd34aa 100644 --- a/src/SharpBrick.PoweredUp/Devices/Voltage.cs +++ b/src/SharpBrick.PoweredUp/Devices/Voltage.cs @@ -8,18 +8,18 @@ namespace SharpBrick.PoweredUp { public class Voltage : Device, IPoweredUpDevice { - protected SingleValueMode _voltageLMode; - protected SingleValueMode _voltageSMode; + protected SingleValueMode _voltageLMode; + protected SingleValueMode _voltageSMode; public byte ModeIndexVoltageL { get; protected set; } = 0; public byte ModeIndexVoltageS { get; protected set; } = 1; public short VoltageL => _voltageLMode.SI; public short VoltageLPct => _voltageLMode.Pct; - public IObservable> VoltageLObservable => _voltageLMode.Observable; + public IObservable> VoltageLObservable => _voltageLMode.Observable; public short VoltageS => _voltageSMode.SI; public short VoltageSPct => _voltageSMode.Pct; - public IObservable> VoltageSObservable => _voltageSMode.Observable; + public IObservable> VoltageSObservable => _voltageSMode.Observable; public Voltage() { } @@ -27,8 +27,8 @@ public Voltage() public Voltage(ILegoWirelessProtocol protocol, byte hubId, byte portId) : base(protocol, hubId, portId) { - _voltageLMode = SingleValueMode(ModeIndexVoltageL); - _voltageSMode = SingleValueMode(ModeIndexVoltageS); + _voltageLMode = SingleValueMode(ModeIndexVoltageL); + _voltageSMode = SingleValueMode(ModeIndexVoltageS); ObserveForPropertyChanged(_voltageLMode.Observable, nameof(VoltageL), nameof(VoltageLPct)); ObserveForPropertyChanged(_voltageSMode.Observable, nameof(VoltageS), nameof(VoltageSPct)); diff --git a/src/SharpBrick.PoweredUp/Protocol/Formatter/PortValueSingleEncoder.cs b/src/SharpBrick.PoweredUp/Protocol/Formatter/PortValueSingleEncoder.cs index e1d1f3f..dcde911 100644 --- a/src/SharpBrick.PoweredUp/Protocol/Formatter/PortValueSingleEncoder.cs +++ b/src/SharpBrick.PoweredUp/Protocol/Formatter/PortValueSingleEncoder.cs @@ -67,97 +67,67 @@ internal static PortValueData CreatPortValueData(PortModeInfo modeInfo, in Span< _ => throw new NotSupportedException(), }; - internal static PortValueData CreatePortValueDataSByte(PortModeInfo modeInfo, in Span dataSlice) + internal static PortValueData CreatePortValueDataSByte(PortModeInfo modeInfo, in Span dataSlice) { var rawValues = MemoryMarshal.Cast(dataSlice).ToArray(); - var siValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.SIMin, modeInfo.SIMax)).Select(f => Convert.ToSByte(f)).ToArray(); - var pctValues = modeInfo.DisablePercentage switch - { - false => rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.PctMin, modeInfo.PctMax)).Select(f => Convert.ToSByte(f)).ToArray(), - true => new sbyte[rawValues.Length], - }; + var scaledSIValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.SIMin, modeInfo.SIMax)); + var scaledPctValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.PctMin, modeInfo.PctMax)); - return new PortValueData( - PortId: modeInfo.PortId, - ModeIndex: modeInfo.ModeIndex, - DataType: modeInfo.DatasetType, - InputValues: rawValues, - SIInputValues: siValues, - PctInputValues: pctValues - ); + return CreatePortValueData(modeInfo, rawValues, scaledSIValues, scaledPctValues, f => Convert.ToSByte(f)); } - internal static PortValueData CreatePortValueDataInt16(PortModeInfo modeInfo, in Span dataSlice) + internal static PortValueData CreatePortValueDataInt16(PortModeInfo modeInfo, in Span dataSlice) { var rawValues = MemoryMarshal.Cast(dataSlice).ToArray(); - var siValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.SIMin, modeInfo.SIMax)).Select(f => Convert.ToInt16(f)).ToArray(); - var pctValues = modeInfo.DisablePercentage switch - { - false => rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.PctMin, modeInfo.PctMax)).Select(f => Convert.ToInt16(f)).ToArray(), - true => new short[rawValues.Length], - }; + var scaledSIValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.SIMin, modeInfo.SIMax)); + var scaledPctValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.PctMin, modeInfo.PctMax)); - return new PortValueData( - PortId: modeInfo.PortId, - ModeIndex: modeInfo.ModeIndex, - DataType: modeInfo.DatasetType, - InputValues: rawValues, - SIInputValues: siValues, - PctInputValues: pctValues - ); + return CreatePortValueData(modeInfo, rawValues, scaledSIValues, scaledPctValues, f => Convert.ToInt16(f)); } - internal static PortValueData CreatePortValueDataInt32(PortModeInfo modeInfo, in Span dataSlice) + internal static PortValueData CreatePortValueDataInt32(PortModeInfo modeInfo, in Span dataSlice) { var rawValues = MemoryMarshal.Cast(dataSlice).ToArray(); - var siValues = modeInfo switch - { - { DisableScaling: true } => rawValues, - _ => rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.SIMin, modeInfo.SIMax)).Select(f => Convert.ToInt32(f)).ToArray(), - }; - - var pctValues = modeInfo switch - { - { DisablePercentage: true } => new int[rawValues.Length], - { DisableScaling: true } => rawValues, - _ => rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.PctMin, modeInfo.PctMax)).Select(f => Convert.ToInt32(f)).ToArray(), - }; + var scaledSIValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.SIMin, modeInfo.SIMax)); + var scaledPctValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.PctMin, modeInfo.PctMax)); - return new PortValueData( - PortId: modeInfo.PortId, - ModeIndex: modeInfo.ModeIndex, - DataType: modeInfo.DatasetType, - InputValues: rawValues, - SIInputValues: siValues, - PctInputValues: pctValues - ); + return CreatePortValueData(modeInfo, rawValues, scaledSIValues, scaledPctValues, f => Convert.ToInt32(f)); } - internal static PortValueData CreatePortValueDataSingle(PortModeInfo modeInfo, in Span dataSlice) + internal static PortValueData CreatePortValueDataSingle(PortModeInfo modeInfo, in Span dataSlice) { var rawValues = MemoryMarshal.Cast(dataSlice).ToArray(); - var siValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.SIMin, modeInfo.SIMax)).ToArray(); - var pctValues = modeInfo.DisablePercentage switch - { - false => rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.PctMin, modeInfo.PctMax)).ToArray(), - true => new float[rawValues.Length], - }; + var scaledSIValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.SIMin, modeInfo.SIMax)); + var scaledPctValues = rawValues.Select(rv => Scale(rv, modeInfo.RawMin, modeInfo.RawMax, modeInfo.PctMin, modeInfo.PctMax)); - return new PortValueData( - PortId: modeInfo.PortId, - ModeIndex: modeInfo.ModeIndex, - DataType: modeInfo.DatasetType, - InputValues: rawValues, - SIInputValues: siValues, - PctInputValues: pctValues - ); + return CreatePortValueData(modeInfo, rawValues, scaledSIValues, scaledPctValues, f => Convert.ToSingle(f)); } - internal static float Scale(float value, float rawMin, float rawMax, float min, float max) + internal static PortValueData CreatePortValueData(PortModeInfo modeInfo, TDatasetType[] rawValues, IEnumerable scaledSIValues, IEnumerable scaledPctValues, Func converter) + => modeInfo switch + { + { DisableScaling: true, OverrideDatasetTypeToDouble: _, DisablePercentage: _ } => new PortValueData(modeInfo.PortId, modeInfo.ModeIndex, modeInfo.DatasetType, rawValues, + rawValues.ToArray(), + rawValues.ToArray()), + { DisableScaling: false, OverrideDatasetTypeToDouble: true, DisablePercentage: true } => new PortValueData(modeInfo.PortId, modeInfo.ModeIndex, modeInfo.DatasetType, rawValues, + scaledSIValues.ToArray(), + new double[scaledPctValues.Count()]), + { DisableScaling: false, OverrideDatasetTypeToDouble: true, DisablePercentage: false } => new PortValueData(modeInfo.PortId, modeInfo.ModeIndex, modeInfo.DatasetType, rawValues, + scaledSIValues.ToArray(), + scaledPctValues.ToArray()), + { DisableScaling: false, OverrideDatasetTypeToDouble: false, DisablePercentage: true } => new PortValueData(modeInfo.PortId, modeInfo.ModeIndex, modeInfo.DatasetType, InputValues: rawValues, + SIInputValues: scaledSIValues.Select(converter).ToArray(), + PctInputValues: new TDatasetType[scaledPctValues.Count()]), + { DisableScaling: false, OverrideDatasetTypeToDouble: false, DisablePercentage: false } => new PortValueData(modeInfo.PortId, modeInfo.ModeIndex, modeInfo.DatasetType, InputValues: rawValues, + SIInputValues: scaledSIValues.Select(converter).ToArray(), + PctInputValues: scaledPctValues.Select(converter).ToArray()), + }; + + internal static double Scale(double value, double rawMin, double rawMax, double min, double max) { var positionInRawRange = (value - rawMin) / (rawMax - rawMin); diff --git a/src/SharpBrick.PoweredUp/Protocol/Knowledge/PortModeInfo.cs b/src/SharpBrick.PoweredUp/Protocol/Knowledge/PortModeInfo.cs index 115c056..131e2fa 100644 --- a/src/SharpBrick.PoweredUp/Protocol/Knowledge/PortModeInfo.cs +++ b/src/SharpBrick.PoweredUp/Protocol/Knowledge/PortModeInfo.cs @@ -57,5 +57,6 @@ public class PortModeInfo // Additional Settings public bool DisablePercentage { get; set; } = false; public bool DisableScaling { get; set; } = false; + public bool OverrideDatasetTypeToDouble { get; set; } = false; } } \ No newline at end of file diff --git a/src/SharpBrick.PoweredUp/Protocol/Messages/MessageOfPortValuesModel.cs b/src/SharpBrick.PoweredUp/Protocol/Messages/MessageOfPortValuesModel.cs index b6b6ca9..6871652 100644 --- a/src/SharpBrick.PoweredUp/Protocol/Messages/MessageOfPortValuesModel.cs +++ b/src/SharpBrick.PoweredUp/Protocol/Messages/MessageOfPortValuesModel.cs @@ -8,10 +8,14 @@ public record PortValueSingleMessage(PortValueData[] Data) public static string FormatPortValueDataArray(byte hubId, in PortValueData[] data) => string.Join(";", data.Select(d => d switch { - PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", - PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", - PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", - PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", + PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", + PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", + PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", + PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", + PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", + PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", + PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", + PortValueData dd => $"Mode {hubId}/{dd.PortId}/{dd.ModeIndex}: {string.Join(",", dd.InputValues)} ({dd.DataType})", _ => "Undefined Data Type", })); diff --git a/src/SharpBrick.PoweredUp/Protocol/Messages/PortValueData.cs b/src/SharpBrick.PoweredUp/Protocol/Messages/PortValueData.cs index 18e4bb6..eed26d9 100644 --- a/src/SharpBrick.PoweredUp/Protocol/Messages/PortValueData.cs +++ b/src/SharpBrick.PoweredUp/Protocol/Messages/PortValueData.cs @@ -1,6 +1,6 @@ namespace SharpBrick.PoweredUp.Protocol.Messages { public record PortValueData(byte PortId, byte ModeIndex, PortModeInformationDataType DataType); - public record PortValueData(byte PortId, byte ModeIndex, PortModeInformationDataType DataType, TPayload[] InputValues, TPayload[] SIInputValues, TPayload[] PctInputValues) + public record PortValueData(byte PortId, byte ModeIndex, PortModeInformationDataType DataType, TDatasetType[] InputValues, TOutputType[] SIInputValues, TOutputType[] PctInputValues) : PortValueData(PortId, ModeIndex, DataType); } \ No newline at end of file diff --git a/test/SharpBrick.PoweredUp.Test/Protocol/Formatter/PortValueCombinedModeEncoderTest.cs b/test/SharpBrick.PoweredUp.Test/Protocol/Formatter/PortValueCombinedModeEncoderTest.cs index 32a6519..bb4b7c3 100644 --- a/test/SharpBrick.PoweredUp.Test/Protocol/Formatter/PortValueCombinedModeEncoderTest.cs +++ b/test/SharpBrick.PoweredUp.Test/Protocol/Formatter/PortValueCombinedModeEncoderTest.cs @@ -46,15 +46,15 @@ public void PortValueCombinedModeEncoder_Decode(string dataAsString, byte expect Assert.Equal(expectedDataType[pos], portValueData.DataType); Assert.Equal(expectedDataType[pos], portValueData.DataType); - if (portValueData is PortValueData actual) + if (portValueData is PortValueData actual) { Assert.Equal(expectedData[pos], actual.InputValues[0]); } - if (portValueData is PortValueData actual2) + if (portValueData is PortValueData actual2) { Assert.Equal(expectedData[pos], actual2.InputValues[0]); } - if (portValueData is PortValueData actual3) + if (portValueData is PortValueData actual3) { Assert.Equal(expectedData[pos], actual3.InputValues[0]); } diff --git a/test/SharpBrick.PoweredUp.Test/Protocol/Formatter/PortValueEncoderTest.cs b/test/SharpBrick.PoweredUp.Test/Protocol/Formatter/PortValueEncoderTest.cs index 35ba6e1..5ade8c2 100644 --- a/test/SharpBrick.PoweredUp.Test/Protocol/Formatter/PortValueEncoderTest.cs +++ b/test/SharpBrick.PoweredUp.Test/Protocol/Formatter/PortValueEncoderTest.cs @@ -14,9 +14,9 @@ public class PortValueSingleEncoderTest [Theory] [InlineData("0A-00-45-63-21-00-F9-FF-FD-FF", 0x63, PortModeInformationDataType.Int16, new short[] { 33, -7, -3 })] public void PortValueSingleEncoder_Decode_Short(string dataAsString, byte expectedPortId, PortModeInformationDataType expectedDataType, short[] expectedData) - => PortValueSingleEncoder_Decode(dataAsString, expectedPortId, expectedDataType, expectedData); + => PortValueSingleEncoder_Decode(dataAsString, expectedPortId, expectedDataType, expectedData); - private void PortValueSingleEncoder_Decode(string dataAsString, byte expectedPortId, PortModeInformationDataType expectedDataType, T[] expectedData) + private void PortValueSingleEncoder_Decode(string dataAsString, byte expectedPortId, PortModeInformationDataType expectedDataType, TDatasetType[] expectedData) { var knowledge = new ProtocolKnowledge(); @@ -40,9 +40,9 @@ private void PortValueSingleEncoder_Decode(string dataAsString, byte expected Assert.Equal(d.PortId, expectedPortId); Assert.Equal(d.DataType, expectedDataType); - if (d is PortValueData actual) + if (d is PortValueData actual) { - Assert.Collection(actual.InputValues, expectedData.Cast().Select>(expected => actual => Assert.Equal(expected, actual)).ToArray()); + Assert.Collection(actual.InputValues, expectedData.Cast().Select>(expected => actual => Assert.Equal(expected, actual)).ToArray()); } } );