1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
4+ using System . Reactive . Linq ;
5+ using System . Threading . Tasks ;
6+ using SharpBrick . PoweredUp . Protocol ;
7+ using SharpBrick . PoweredUp . Protocol . Knowledge ;
8+ using SharpBrick . PoweredUp . Protocol . Messages ;
9+ using SharpBrick . PoweredUp . Utils ;
10+
11+ namespace SharpBrick . PoweredUp
12+ {
13+ public class DuploTrainBaseMotor : Device , IPoweredUpDevice
14+ {
15+ public SingleValueMode < int > _onSecMode ;
16+
17+ public byte ModeIndexMotor { get ; protected set ; } = 0 ;
18+ public byte ModeIndexOnSec { get ; protected set ; } = 1 ;
19+
20+ public int OnSeconds => _onSecMode . SI ;
21+ public IObservable < int > OnSecondsObservable => _onSecMode . Observable . Select ( x => x . SI ) ;
22+
23+ public DuploTrainBaseMotor ( )
24+ { }
25+
26+ public DuploTrainBaseMotor ( ILegoWirelessProtocol protocol , byte hubId , byte portId )
27+ : base ( protocol , hubId , portId )
28+ {
29+ _onSecMode = SingleValueMode < int > ( ModeIndexOnSec ) ;
30+
31+ ObserveForPropertyChanged ( _onSecMode . Observable , nameof ( OnSeconds ) ) ;
32+ }
33+
34+ public void ExtendPortMode ( PortModeInfo modeInfo )
35+ {
36+ if ( modeInfo . ModeIndex == ModeIndexOnSec )
37+ {
38+ modeInfo . DisablePercentage = true ;
39+ }
40+ }
41+
42+ /// <summary>
43+ /// Starts the motor with full speed at the given power level.
44+ /// </summary>
45+ /// <param name="power">
46+ /// - Power levels in percentage: 1 - 100 (CW), -1 - -100 (CCW)
47+ /// - Stop Motor (floating): 0
48+ /// - Stop Motor (breaking): 127
49+ /// </param>
50+ /// <returns>An awaitable Task.</returns>
51+ public async Task < PortFeedback > StartPowerAsync ( sbyte power )
52+ {
53+ AssertValidPower ( power , nameof ( power ) ) ;
54+ AssertIsConnected ( ) ;
55+
56+ var response = await _protocol . SendPortOutputCommandAsync ( new PortOutputCommandStartPowerMessage ( )
57+ {
58+ HubId = _hubId ,
59+ PortId = _portId ,
60+ StartupInformation = PortOutputCommandStartupInformation . ExecuteImmediately ,
61+ CompletionInformation = PortOutputCommandCompletionInformation . CommandFeedback ,
62+ Power = power ,
63+ } ) ;
64+
65+ return response ;
66+ }
67+
68+ /// <summary>
69+ /// Stops the motor (brake; no movement afterwards)
70+ /// </summary>
71+ /// <returns></returns>
72+ public Task StopByBrakeAsync ( )
73+ => StartPowerAsync ( ( sbyte ) SpecialSpeed . Brake ) ;
74+
75+ /// <summary>
76+ /// Stops the motor (float; freely floating by inertia)
77+ /// </summary>
78+ /// <returns></returns>
79+ public Task StopByFloatAsync ( )
80+ => StartPowerAsync ( ( sbyte ) SpecialSpeed . Float ) ;
81+
82+ /// <summary>
83+ /// Start the pair on motors with full speed on given power values.
84+ /// </summary>
85+ /// <param name="powerOnMotor1">
86+ /// - Power levels in percentage: 1 - 100 (CW), -1 - -100 (CCW)
87+ /// - Stop Motor (floating): 0
88+ /// - Stop Motor (breaking): 127
89+ /// </param>
90+ /// <param name="powerOnMotor2">
91+ /// - Power levels in percentage: 1 - 100 (CW), -1 - -100 (CCW)
92+ /// - Stop Motor (floating): 0
93+ /// - Stop Motor (breaking): 127
94+ /// </param>
95+ /// <returns></returns>
96+ public async Task < PortFeedback > StartPowerAsync ( sbyte powerOnMotor1 , sbyte powerOnMotor2 )
97+ {
98+ AssertValidPower ( powerOnMotor1 , nameof ( powerOnMotor1 ) ) ;
99+ AssertValidPower ( powerOnMotor2 , nameof ( powerOnMotor2 ) ) ;
100+ AssertIsConnected ( ) ;
101+ AssertIsVirtualPort ( ) ;
102+
103+ var response = await _protocol . SendPortOutputCommandAsync ( new PortOutputCommandStartPower2Message ( )
104+ {
105+ HubId = _hubId ,
106+ PortId = _portId ,
107+ StartupInformation = PortOutputCommandStartupInformation . ExecuteImmediately ,
108+ CompletionInformation = PortOutputCommandCompletionInformation . CommandFeedback ,
109+ Power1 = powerOnMotor1 ,
110+ Power2 = powerOnMotor2 ,
111+ } ) ;
112+
113+ return response ;
114+ }
115+
116+ protected void AssertValidPower ( sbyte power , string argumentName )
117+ {
118+ if (
119+ power < - 100 ||
120+ ( power > 100 && power != 127 )
121+ )
122+ {
123+ throw new ArgumentOutOfRangeException ( argumentName ) ;
124+ }
125+ }
126+
127+ public IEnumerable < byte [ ] > GetStaticPortInfoMessages ( Version softwareVersion , Version hardwareVersion , SystemType systemType )
128+ => @"
129+ 0B-00-43-00-01-03-02-02-00-01-00
130+ 05-00-43-00-02
131+ 11-00-44-00-00-00-54-20-4D-4F-54-00-00-00-00-00-00
132+ 0E-00-44-00-00-01-00-00-C8-C2-00-00-C8-42
133+ 0E-00-44-00-00-02-00-00-C8-C2-00-00-C8-42
134+ 0E-00-44-00-00-03-00-00-C8-C2-00-00-C8-42
135+ 0A-00-44-00-00-04-70-77-72-00
136+ 08-00-44-00-00-05-00-50
137+ 0A-00-44-00-00-80-01-00-03-00
138+ 11-00-44-00-01-00-4F-4E-53-45-43-00-00-00-00-00-00
139+ 0E-00-44-00-01-01-00-00-00-00-00-00-80-3F
140+ 0E-00-44-00-01-02-00-00-00-00-00-00-C8-42
141+ 0E-00-44-00-01-03-00-00-00-00-00-00-80-3F
142+ 0A-00-44-00-01-04-73-65-63-00
143+ 08-00-44-00-01-05-08-00
144+ 0A-00-44-00-01-80-01-02-04-00
145+ " . Trim ( ) . Split ( "\n " ) . Select ( s => BytesStringUtil . StringToData ( s ) ) ;
146+ }
147+ }
0 commit comments