Skip to content

Commit

Permalink
Add TechnicDistanceSensor
Browse files Browse the repository at this point in the history
- Add Distance and Light modes
- Do not add extension port (to less information)
- Fix MarioPants PropertyChanged notification.
- Fix SystemType binary representation in source code
- Add Example

#112 non-breaking
  • Loading branch information
tthiery committed Dec 21, 2020
1 parent 799fc18 commit 375eaa6
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using SharpBrick.PoweredUp;

namespace Example
{
public class ExampleTechnicDistanceSensor : BaseExample
{
public override async Task ExecuteAsync()
{
using (var hub = Host.FindByType<TechnicMediumHub>())
{
await hub.VerifyDeploymentModelAsync(modelBuilder => modelBuilder
.AddHub<TechnicMediumHub>(hubBuilder => hubBuilder
.AddDevice<TechnicDistanceSensor>(hub.A))
);

var technicDistanceSensor = hub.A.GetDevice<TechnicDistanceSensor>();

// measure distances (only single subscription)
using var m1 = technicDistanceSensor.DistanceObservable.Subscribe(x => Log.LogWarning($"Distl: {x}"));
using var m2 = technicDistanceSensor.DistsObservable.Subscribe(x => Log.LogWarning($"Dists: {x}"));
using var m3 = technicDistanceSensor.SinglObservable.Subscribe(x => Log.LogWarning($"Singl: {x}"));

await technicDistanceSensor.SetupNotificationAsync(technicDistanceSensor.ModeIndexDistance, true);

// play with the eye lights (0-100)
for (byte idx = 0; idx < 100; idx += 5)
{
await technicDistanceSensor.SetEyeLightAsync(0b0000_0000, idx, 0b0110_0100, idx);

Log.LogWarning($"Brightness: {idx}");
await Task.Delay(2_000);
}

await hub.SwitchOffAsync();
}
}
}
}
3 changes: 2 additions & 1 deletion examples/SharpBrick.PoweredUp.Examples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ static async Task Main(string[] args)
//example = new Example.ExampleMarioBarcode();
//example = new Example.ExampleMarioPants();
//example = new Example.ExampleMarioAccelerometer();
example = new Example.ExampleDuploTrainBase();
//example = new Example.ExampleDuploTrainBase();
example = new Example.ExampleTechnicDistanceSensor();

// NOTE: Examples are programmed object oriented style. Base class implements methods Configure, DiscoverAsync and ExecuteAsync to be overwriten on demand.
await example.InitHostAndDiscoverAsync(enableTrace);
Expand Down
2 changes: 2 additions & 0 deletions src/SharpBrick.PoweredUp/Devices/DeviceFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public Type GetTypeFromDeviceType(DeviceType deviceType)
DeviceType.TechnicMediumHubGestureSensor => typeof(TechnicMediumHubGestureSensor),
DeviceType.RemoteControlButton => typeof(RemoteControlButton),
DeviceType.RemoteControlRssi => typeof(RemoteControlRssi),
DeviceType.TechnicDistanceSensor => typeof(TechnicDistanceSensor),
DeviceType.TechnicMediumHubAccelerometer => typeof(TechnicMediumHubAccelerometer),
DeviceType.TechnicMediumHubGyroSensor => typeof(TechnicMediumHubGyroSensor),
DeviceType.TechnicMediumHubTiltSensor => typeof(TechnicMediumHubTiltSensor),
Expand Down Expand Up @@ -71,6 +72,7 @@ public static DeviceType GetDeviceTypeFromType(Type type)
nameof(TechnicMediumHubGestureSensor) => DeviceType.TechnicMediumHubGestureSensor,
nameof(RemoteControlButton) => DeviceType.RemoteControlButton,
nameof(RemoteControlRssi) => DeviceType.RemoteControlRssi,
nameof(TechnicDistanceSensor) => DeviceType.TechnicDistanceSensor,
nameof(TechnicMediumHubAccelerometer) => DeviceType.TechnicMediumHubAccelerometer,
nameof(TechnicMediumHubGyroSensor) => DeviceType.TechnicMediumHubGyroSensor,
nameof(TechnicMediumHubTiltSensor) => DeviceType.TechnicMediumHubTiltSensor,
Expand Down
2 changes: 1 addition & 1 deletion src/SharpBrick.PoweredUp/Devices/MarioHubPants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public MarioHubPants(ILegoWirelessProtocol protocol, byte hubId, byte portId)
{
_pantsMode = SingleValueMode<sbyte>(ModeIndexPants);

ObserveForPropertyChanged(_pantsMode.Observable, nameof(PantsObservable));
ObserveForPropertyChanged(_pantsMode.Observable, nameof(Pants));
}

public IEnumerable<byte[]> GetStaticPortInfoMessages(Version softwareVersion, Version hardwareVersion, SystemType systemType)
Expand Down
120 changes: 120 additions & 0 deletions src/SharpBrick.PoweredUp/Devices/TechnicDistanceSensor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
using SharpBrick.PoweredUp.Protocol;
using SharpBrick.PoweredUp.Utils;

namespace SharpBrick.PoweredUp
{
public class TechnicDistanceSensor : Device, IPoweredUpDevice
{
protected SingleValueMode<short> _distlMode;
protected SingleValueMode<short> _distsMode;
protected SingleValueMode<short> _singlMode;
protected MultiValueMode<sbyte> _lightMode;

public byte ModeIndexDistance { get; protected set; } = 0;
public byte ModeIndexShortOnlyDistance { get; protected set; } = 1;
public byte ModeIndexSingleMeasurement { get; protected set; } = 2;
public byte ModeIndexLight { get; protected set; } = 5;

public short Distance => _distlMode.SI;
public IObservable<short> DistanceObservable => _distlMode.Observable.Select(x => x.SI);
public short ShortOnlyDistance => _distsMode.SI;
public IObservable<short> DistsObservable => _distsMode.Observable.Select(x => x.SI);
public short SingleDistanceMeasurementResult => _singlMode.SI;
public IObservable<short> SinglObservable => _singlMode.Observable.Select(x => x.SI);

public TechnicDistanceSensor()
{ }
public TechnicDistanceSensor(ILegoWirelessProtocol protocol, byte hubId, byte portId)
: base(protocol, hubId, portId)
{
_distlMode = SingleValueMode<short>(ModeIndexDistance);
_distsMode = SingleValueMode<short>(ModeIndexShortOnlyDistance);
_singlMode = SingleValueMode<short>(ModeIndexSingleMeasurement);
_lightMode = MultiValueMode<sbyte>(ModeIndexLight);

ObserveForPropertyChanged(_distlMode.Observable, nameof(Distance));
ObserveForPropertyChanged(_distsMode.Observable, nameof(ShortOnlyDistance));
ObserveForPropertyChanged(_singlMode.Observable, nameof(SingleDistanceMeasurementResult));
}

public Task SetEyeLightAsync(byte leftTop = 0x00, byte rightTop = 0x00, byte leftBottom = 0x00, byte rightBottom = 0x00)
=> _lightMode.WriteDirectModeDataAsync(new byte[] { leftTop, rightTop, leftBottom, rightBottom });

public IEnumerable<byte[]> GetStaticPortInfoMessages(Version softwareVersion, Version hardwareVersion, SystemType systemType)
=> ((softwareVersion, hardwareVersion, systemType) switch
{
(_, _, _) => @"
0B-00-43-00-01-03-09-9F-00-60-00
05-00-43-00-02
11-00-44-00-00-00-44-49-53-54-4C-00-00-00-00-00-00
0E-00-44-00-00-01-00-00-00-00-00-40-1C-45
0E-00-44-00-00-02-00-00-00-00-00-00-C8-42
0E-00-44-00-00-03-00-00-00-00-00-00-7A-43
0A-00-44-00-00-04-43-4D-00-00
08-00-44-00-00-05-91-00
0A-00-44-00-00-80-01-01-05-01
11-00-44-00-01-00-44-49-53-54-53-00-00-00-00-00-00
0E-00-44-00-01-01-00-00-00-00-00-00-A0-43
0E-00-44-00-01-02-00-00-00-00-00-00-C8-42
0E-00-44-00-01-03-00-00-00-00-00-00-00-42
0A-00-44-00-01-04-43-4D-00-00
08-00-44-00-01-05-F1-00
0A-00-44-00-01-80-01-01-04-01
11-00-44-00-02-00-53-49-4E-47-4C-00-00-00-00-00-00
0E-00-44-00-02-01-00-00-00-00-00-40-1C-45
0E-00-44-00-02-02-00-00-00-00-00-00-C8-42
0E-00-44-00-02-03-00-00-00-00-00-00-7A-43
0A-00-44-00-02-04-43-4D-00-00
08-00-44-00-02-05-90-00
0A-00-44-00-02-80-01-01-05-01
11-00-44-00-03-00-4C-49-53-54-4E-00-00-00-00-00-00
0E-00-44-00-03-01-00-00-00-00-00-00-80-3F
0E-00-44-00-03-02-00-00-00-00-00-00-C8-42
0E-00-44-00-03-03-00-00-00-00-00-00-80-3F
0A-00-44-00-03-04-53-54-00-00
08-00-44-00-03-05-10-00
0A-00-44-00-03-80-01-00-01-00
11-00-44-00-04-00-54-52-41-57-00-00-00-00-00-00-00
0E-00-44-00-04-01-00-00-00-00-00-C4-63-46
0E-00-44-00-04-02-00-00-00-00-00-00-C8-42
0E-00-44-00-04-03-00-00-00-00-00-C4-63-46
0A-00-44-00-04-04-75-53-00-00
08-00-44-00-04-05-90-00
0A-00-44-00-04-80-01-02-05-00
11-00-44-00-05-00-4C-49-47-48-54-00-00-00-00-00-00
0E-00-44-00-05-01-00-00-00-00-00-00-C8-42
0E-00-44-00-05-02-00-00-00-00-00-00-C8-42
0E-00-44-00-05-03-00-00-00-00-00-00-C8-42
0A-00-44-00-05-04-50-43-54-00
08-00-44-00-05-05-00-10
0A-00-44-00-05-80-04-00-03-00
11-00-44-00-06-00-50-49-4E-47-00-00-00-00-00-00-00
0E-00-44-00-06-01-00-00-00-00-00-00-80-3F
0E-00-44-00-06-02-00-00-00-00-00-00-C8-42
0E-00-44-00-06-03-00-00-00-00-00-00-80-3F
0A-00-44-00-06-04-50-43-54-00
08-00-44-00-06-05-00-90
0A-00-44-00-06-80-01-00-01-00
11-00-44-00-07-00-41-44-52-41-57-00-00-00-00-00-00
0E-00-44-00-07-01-00-00-00-00-00-00-80-44
0E-00-44-00-07-02-00-00-00-00-00-00-C8-42
0E-00-44-00-07-03-00-00-00-00-00-00-80-44
0A-00-44-00-07-04-50-43-54-00
08-00-44-00-07-05-90-00
0A-00-44-00-07-80-01-01-04-00
11-00-44-00-08-00-43-41-4C-49-42-00-00-00-00-00-00
0E-00-44-00-08-01-00-00-00-00-00-00-7F-43
0E-00-44-00-08-02-00-00-00-00-00-00-C8-42
0E-00-44-00-08-03-00-00-00-00-00-00-7F-43
0A-00-44-00-08-04-50-43-54-00
08-00-44-00-08-05-00-00
0A-00-44-00-08-80-07-00-03-00
"
}).Trim().Split("\n").Select(s => BytesStringUtil.StringToData(s));
}
}
3 changes: 2 additions & 1 deletion src/SharpBrick.PoweredUp/Enums/SystemType.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace SharpBrick.PoweredUp
{
// read binary interpretation careful: 3_5
public enum SystemType : byte
{
LegoWeDo20_WeDoHub = 0b000_00000,
Expand All @@ -9,7 +10,7 @@ public enum SystemType : byte
LegoSystem_BoostHub = 0b010_00000,
LegoSystem_TwoPortHub = 0b010_00001,
LegoSystem_TwoPortHandset = 0b010_00010,
LegoSystem_Mario = 0b0100_0011, // UNSPECED, https://github.com/bricklife/LEGO-Mario-Reveng, 0x43,
LegoSystem_Mario = 0b010_00011, // UNSPECED, https://github.com/bricklife/LEGO-Mario-Reveng, 0x43,

LegoTechnic_MediumHub = 0b100_00000, // UNSPECED
}
Expand Down

0 comments on commit 375eaa6

Please sign in to comment.