33using System . Collections . Concurrent ;
44using System . Collections . Generic ;
55using System . Linq ;
6+ using System . Threading ;
67using System . Threading . Tasks ;
78
89namespace RDMSharp . RDM . Device . Module ;
910
1011public sealed class LockModule : AbstractModule
1112{
13+ SemaphoreSlim semaphoreSlimLockState = new SemaphoreSlim ( 1 ) ;
1214 private const string _moduleName = "Lock" ;
1315 private const string _moduleDisplayName = "Lock" ;
1416 private static readonly ERDM_Parameter [ ] _moduleParameters = new ERDM_Parameter [ ]
@@ -25,6 +27,11 @@ public ushort? LockPin
2527 {
2628 get
2729 {
30+ if ( ParentDevice is null )
31+ return lockPin ;
32+
33+ if ( ParentDevice . GetAllParameterValues ( ) . TryGetValue ( ERDM_Parameter . LOCK_PIN , out object res ) && res is ushort pin )
34+ return lockPin = pin ;
2835 return lockPin ;
2936 }
3037 set
@@ -47,57 +54,76 @@ public ushort? LockPin
4754
4855 if ( ParentRemoteDevice is not null )
4956 {
57+ if ( semaphoreSlimLockState . CurrentCount == 0 )
58+ return ;
5059 Task . Run ( async ( ) =>
5160 {
52- if ( await SetLockPin ( value . Value ) )
53- OnPropertyChanged ( nameof ( LockPin ) ) ;
54- else
61+ await semaphoreSlimLockState . WaitAsync ( 3000 ) ;
62+ try
63+ {
64+ if ( await SetLockPin ( value . Value ) )
65+ OnPropertyChanged ( nameof ( LockPin ) ) ;
66+ else
67+ {
68+ lockPin = backup ;
69+ OnPropertyChanged ( nameof ( LockPin ) ) ;
70+ }
71+ }
72+ finally
5573 {
56- lockPin = backup ;
57- OnPropertyChanged ( nameof ( LockPin ) ) ;
74+ semaphoreSlimLockState . Release ( ) ;
5875 }
5976 } ) ;
6077 }
6178 }
6279 }
6380
64- private byte ? lockState ;
81+ private byte ? _lockState ;
6582 public byte ? LockState
6683 {
6784 get
6885 {
69- return lockState ;
86+ return _lockState ;
7087 }
7188 set
7289 {
7390 if ( value is null )
7491 return ;
7592
76- if ( lockState == value )
93+ if ( _lockState == value )
7794 return ;
7895
79- bool initial = lockState is null ;
80- var backup = lockState ;
81- lockState = value ;
96+ bool initial = _lockState is null ;
97+ var backup = _lockState ;
98+ _lockState = value ;
8299
83100 if ( ParentGeneratedDevice is not null )
84- {
85- ParentGeneratedDevice . setParameterValue ( ERDM_Parameter . LOCK_STATE , new GetLockStateResponse ( lockState . Value , this . count . Value ) ) ;
86- }
101+ ParentGeneratedDevice . setParameterValue ( ERDM_Parameter . LOCK_STATE , new GetLockStateResponse ( _lockState . Value , count . Value ) ) ;
87102
88103 if ( initial )
89104 return ;
90105
91106 if ( ParentRemoteDevice is not null )
92107 {
108+ if ( semaphoreSlimLockState . CurrentCount == 0 )
109+ return ;
93110 Task . Run ( async ( ) =>
94111 {
95- if ( await SetLockState ( value . Value ) )
96- OnPropertyChanged ( nameof ( LockState ) ) ;
97- else
112+ await semaphoreSlimLockState . WaitAsync ( 3000 ) ;
113+ try
114+ {
115+ if ( await SetLockPin ( value . Value ) )
116+ OnPropertyChanged ( nameof ( LockState ) ) ;
117+ else
118+ {
119+ _lockState = backup ;
120+ OnPropertyChanged ( nameof ( LockState ) ) ;
121+ }
122+ }
123+ finally
98124 {
99- lockState = backup ;
100- OnPropertyChanged ( nameof ( LockState ) ) ;
125+ await Task . Delay ( 200 ) ;
126+ semaphoreSlimLockState . Release ( ) ;
101127 }
102128 } ) ;
103129 }
@@ -188,9 +214,28 @@ protected override void ParameterChanged(ERDM_Parameter parameter, object newVal
188214 break ;
189215 case ERDM_Parameter . LOCK_STATE :
190216 if ( newValue is GetLockStateResponse lockStateResponse )
217+ {
191218 fillFromRemote ( lockStateResponse ) ;
192- if ( newValue is SetLockStateRequest lockStateRequest )
193- OnPropertyChanged ( nameof ( LockState ) ) ;
219+ if ( _lockState != lockStateResponse . CurrentLockStateId )
220+ {
221+ if ( semaphoreSlimLockState . CurrentCount == 0 )
222+ return ;
223+ Task . Run ( async ( ) =>
224+ {
225+ await semaphoreSlimLockState . WaitAsync ( 3000 ) ;
226+ try
227+ {
228+ _lockState = lockStateResponse . CurrentLockStateId ;
229+ OnPropertyChanged ( nameof ( LockState ) ) ;
230+ }
231+ finally
232+ {
233+ await Task . Delay ( 2000 ) ;
234+ semaphoreSlimLockState . Release ( ) ;
235+ }
236+ } ) ;
237+ }
238+ }
194239 break ;
195240 }
196241 }
@@ -212,8 +257,8 @@ private void fillFromRemote(GetLockStateResponse lockStateResponse)
212257 idDescriptionPair . Add ( i , $ "Lock State { i } ") ;
213258 OnPropertyChanged ( nameof ( IdDescriptionPair ) ) ;
214259 }
215-
216- LockState = lockStateResponse . CurrentLockStateId ;
260+ //if (!LockState.HasValue)
261+ // LockState = lockStateResponse.CurrentLockStateId;
217262 }
218263
219264 public override bool IsHandlingParameter ( ERDM_Parameter parameter , ERDM_Command command )
@@ -343,6 +388,20 @@ public async Task<bool> SetLockState(byte lockState)
343388 {
344389 throw new Exception ( $ "Failed to set Lock State to { lockState } !, Wrong Pin ({ lockPin } )?") ;
345390 }
391+ if ( _lockState != lockState )
392+ {
393+ await semaphoreSlimLockState . WaitAsync ( 3000 ) ;
394+ try
395+ {
396+ _lockState = lockState ;
397+ OnPropertyChanged ( nameof ( LockState ) ) ;
398+ }
399+ finally
400+ {
401+ await Task . Delay ( 2000 ) ;
402+ semaphoreSlimLockState . Release ( ) ;
403+ }
404+ }
346405 }
347406 return true ;
348407 }
0 commit comments