Position estimator for shutters

hi @rossko57 ,
yes i am using now

val Map<String, Number> ShutterStartTimestamps = newHashMap
val Map<String, Number> ShutterUpDurations = newHashMap
val Map<String, Number> ShutterDwDurations = newHashMap

even though they are constants. index for ShutterUpDurations and ShutterDwDurations is only Shutter1…Shutter3.

auto0 and auto100 is not needed for the moment, as I set my shutters in a way, that the relays open automatically after a certain time (30s i think), so it is always 100% / 0%, as this value is >25s which is the “real” duration.

The point i am struggling at the moment is more that the simple calculations

NewPosition = ( ActualPosition - ( Duration / ShutterDuration ) * 100 )

resp.

NewPosition = ( ActualPosition + ( Duration  / ShutterDuration ) * 100 )

fail with "

null in test

resp
Could not cast NULL to java.lang.Number; line 57, column 26, length 27 in test
as it can be seen in the log:

2021-03-23 21:39:27.758 [INFO ] [openhab.core.model.script.Test.rules] - Test run 4 start

==> /var/log/openhab/events.log <==

2021-03-23 21:39:27.746 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'Shutter1_UP' received command ON

2021-03-23 21:39:27.752 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Shutter1_UP' changed from OFF to ON

==> /var/log/openhab/openhab.log <==

2021-03-23 21:39:30.211 [INFO ] [openhab.core.model.script.Test.rules] - Duration of Shutter1_UP was 2.44800000 (=1616531970203 - 1616531967755 ) 

2021-03-23 21:39:30.225 [INFO ] [openhab.core.model.script.Test.rules] - 0 is actual position and direction UP

2021-03-23 21:39:30.230 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'test-2' failed: null in test

==> /var/log/openhab/events.log <==

2021-03-23 21:39:30.193 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'Shutter1_UP' received command OFF

2021-03-23 21:39:30.198 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Shutter1_UP' changed from ON to OFF

==> /var/log/openhab/openhab.log <==

2021-03-23 21:39:33.063 [INFO ] [openhab.core.model.script.Test.rules] - Test run 4 start

==> /var/log/openhab/events.log <==

2021-03-23 21:39:33.051 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'Shutter2_DW' received command ON

2021-03-23 21:39:33.056 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Shutter2_DW' changed from OFF to ON

==> /var/log/openhab/openhab.log <==

2021-03-23 21:39:35.255 [INFO ] [openhab.core.model.script.Test.rules] - Duration of Shutter2_DW was 2.18700000 (=1616531975247 - 1616531973060 ) 

2021-03-23 21:39:35.269 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'test-2' failed: Could not cast NULL to java.lang.Number; line 57, column 26, length 27 in test

==> /var/log/openhab/events.log <==

2021-03-23 21:39:35.238 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'Shutter2_DW' received command OFF

2021-03-23 21:39:35.245 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Shutter2_DW' changed from ON to OFF

and I do not understand really why…

This is the complete file

import java.util.Map

val Map<String, Number> ShutterStartTimestamps = newHashMap
val Map<String, Number> ShutterUpDurations = newHashMap
val Map<String, Number> ShutterDwDurations = newHashMap
	
// there is a way to initialize the Map statically but I always forget it so prefer a System started Rule
rule "initialize ShutterStartTimestamps"
when
    System started
then
    ShutterStartTimestamps.put("Shutter1_UP", 999999000)
    ShutterStartTimestamps.put("Shutter2_UP", 999999000)
    ShutterStartTimestamps.put("Shutter3_UP", 999999000)
	
    ShutterStartTimestamps.put("Shutter1_DW", 999999000)
    ShutterStartTimestamps.put("Shutter2_DW", 999999000)
    ShutterStartTimestamps.put("Shutter3_DW", 999999000)
	
	
    ShutterUpDurations.put("Shutter1", 25.0)
    ShutterUpDurations.put("Shutter2", 25.0)
    ShutterUpDurations.put("Shutter3", 25.0)
	
    ShutterDwDurations.put("Shutter1", 25.0)
    ShutterDwDurations.put("Shutter2", 25.0)
    ShutterDwDurations.put("Shutter3", 25.0)
	
	
end

rule "Shutter begins or stops to move"
   when
      Member of gtestItems changed
   then
   { 
      var long MyTimestamp = now.toInstant.toEpochMilli
      if (triggeringItem.state == ON) //start measurement
	  {
         logInfo("Test.rules", "Test run 4 start")
         ShutterStartTimestamps.put(triggeringItem.name, MyTimestamp)
      }
	  else  //end measurement
	  {
	    var Number NewPosition // = 0 // just to have an initial value
		var Number ShutterDuration
	    val StartTime = ShutterStartTimestamps.get(triggeringItem.name)
		val Duration = ( MyTimestamp - StartTime ) / 1000
		
          logInfo("Test.rules", "Duration of " + triggeringItem.name + " was " + Duration.toString + " (=" + MyTimestamp.toString + " - " + StartTime.toString + " ) ")
		  
		  
		  val ShutterName = triggeringItem.name.split('_').get(0)
		  val Direction = triggeringItem.name.split('_').get(1)
		  
		  val ShutterItem = gRollershutterItem.members.findFirst[ shutter | shutter.name == ShutterName ]
		  val ActualPosition = ShutterItem.state as Number
		  
		  if ( Direction == "UP" ) // 0 is upermost position
		  {
		     logInfo("Test.rules", ActualPosition.toString + " is actual position and direction UP" )
		     ShutterDuration = ShutterUpDurations.get(triggeringItem.name)
			 NewPosition = ( ActualPosition - ( Duration / ShutterDuration ) * 100 )
		  }
		  else //direction is "DW"
		  {
		     logInfo("Test.rules", ActualPosition.toString + " is actual position and direction  DW" )
		     ShutterDuration = ShutterDwDurations.get(triggeringItem.name)
			 NewPosition = ( ActualPosition + ( Duration  / ShutterDuration ) * 100 )
		  }
		  
		  logInfo("Test.rules", "New position = " + NewPosition.toString )
		  if (NewPosition < 0 )
	 	  {
		     postUpdate(ShutterName, 0 )
		  }
		  else
		  {
		     if (NewPosition > 100 )
			 {
			    postUpdate(ShutterName, 100 )
			 }
			 else
			 {
			    //postUpdate(ShutterName, NewPosition )
				ShutterItem.postUpdate(NewPosition )
			 }
		  }
		  
      }
   }
end

can you maybe tell me what the issue is with my calculation?!?