Migrating OH2 group rule to OH3

Hi

This community helped me to create this wonderful rule in openHAB2 that ring fences the minutes & hours value of alarm group members.
It also nudges the hour value up or down as required.

import org.eclipse.smarthome.model.script.ScriptServiceUtil

rule "Confine Minute"

when	
	Member of gMinute changed
then
	
	   logInfo("Minute Limiting", "Minute Value of "+triggeringItem.name+" Currently "+triggeringItem.state)
	
	if (triggeringItem.state > 59) {
	
	sendCommand(triggeringItem.name,"0")
//	logInfo("Alarm Times",triggeringItem.name.split('Min').get(0)+"Hour")
	
	var HourName = ""
	HourName = triggeringItem.name.split('Min').get(0)+"Hour"
		logInfo("Alarm Times",HourName)
		
	var Number HourValue = 0
	HourValue = ScriptServiceUtil.getItemRegistry.getItem(HourName).state
	logInfo("Alarm Times","Hour is currently " + HourValue)
	
	
	var Number NewHour = 0
	NewHour=1 + HourValue
		logInfo("Alarm Times","New Hour value is " + NewHour)
		
		




						sendCommand(HourName, NewHour.toString)
	}
	
	
	
	
	
		if (triggeringItem.state < 0) {
	
	sendCommand(triggeringItem.name,"45")

	
	var HourName = ""
	HourName = triggeringItem.name.split('Min').get(0)+"Hour"
		logInfo("Alarm Times",HourName)
		
	var Number HourValue = 0
	HourValue = ScriptServiceUtil.getItemRegistry.getItem(HourName).state
	logInfo("Alarm Times","Hour is currently " + HourValue)
	
	
	var Number NewHour = 0
	NewHour=HourValue -1 
		logInfo("Alarm Times","New Hour value is " + NewHour)
		
		




						sendCommand(HourName, NewHour.toString)

	}
	
end


rule "Confine Hour"

when	
	Member of gHour changed
then
	
	   logInfo("Hour Limiting", "Hour Value of "+triggeringItem.name+" Currently "+triggeringItem.state)
	
	if (triggeringItem.state > 23) {
	
	sendCommand(triggeringItem.name,"0")
//		logInfo("Alarm Times",triggeringItem.name.split('Hou').get(0))
	}
	
		if (triggeringItem.state < 0) {
	
	sendCommand(triggeringItem.name,"23")
//		logInfo("Alarm Times",triggeringItem.name.split('Hou').get(0))
	}
	
end
	

When I try to use this rule in openHAB3, the section that polls the hour value fails.

It’s some kind of DSL magic that I just don’t understand.

Currently, I have deleted it, but it would be nice to have it back.

My thanks in advance.

This is an example of members of the groups in question.

// Ensure these groups are active in at least 1 Items file and add the Minute and Hour limiting rule
// Group 	gMinute		"Limit Alarm Minute"
// Group 	ghour		"Limit Alarm Hour"



	Switch	BackBedroom_ClockAlarm_ClockAlarm1Enabled 				"BackBedroom Alarm 1 Enabled"					{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm1Enabled"}
	String	BackBedroom_ClockAlarm_ClockAlarm1Type 					"BackBedroom Alarm 1 Type"						{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm1Type"}
	Number	BackBedroom_ClockAlarm_ClockAlarm1WakeupHour			"BackBedroom Alarm 1 Wake Hour"		(gHour)		{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm1WakeupHour"}
	Number	BackBedroom_ClockAlarm_ClockAlarm1WakeupMinute			"BackBedroom Alarm 1 Wake Minute"	(gMinute)	{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm1WakeupMinute"}
	Number	BackBedroom_ClockAlarm_ClockAlarm1BedtimeHour			"BackBedroom Alarm 1 Bed Hour"		(gHour)		{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm1BedtimeHour"}
	Number	BackBedroom_ClockAlarm_ClockAlarm1BedtimeMinute			"BackBedroom Alarm 1 Bed Minute"	(gMinute)	{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm1BedtimeMinute"}
	Switch	BackBedroom_ClockAlarm_ClockAlarm2Enabled				"BackBedroom Alarm 2 Enabled"					{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm2Enabled"}
	String	BackBedroom_ClockAlarm_ClockAlarm2Type          	 	"BackBedroom Alarm 2 Type"						{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm2Type"}
	Number	BackBedroom_ClockAlarm_ClockAlarm2WakeupHour     		"BackBedroom Alarm 2 Wake Hour"		(gHour)		{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm2WakeupHour"}
	Number	BackBedroom_ClockAlarm_ClockAlarm2WakeupMinute  	 	"BackBedroom Alarm 2 Wake Minute"	(gMinute)	{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm2WakeupMinute"}
	Number	BackBedroom_ClockAlarm_ClockAlarm2BedtimeHour    		"BackBedroom Alarm 2 Bed Hour"		(gHour)		{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm2BedtimeHour"}
	Number	BackBedroom_ClockAlarm_ClockAlarm2BedtimeMinute  		"BackBedroom Alarm 2 Bed Minute"	(gMinute)	{channel="velbus:vmbgp2:VelbusNetworkBridge:1C:clockAlarm#clockAlarm2BedtimeMinute"}

It’s really going to help if you show the logs that your rules produce, and the error messages.

There are substantial changes to datetime handling in OH3 rules, but I think your rules just bump numbers around.
However, they don’t look very robust against trying to get values from uninitialized Items.

This is definitely broke for OH3. “There is no smarthome”, all the namespaces changed

1 Like

Good point, I’ll add those when I get back.

Yes, they aren’t fancy, but they do play an important role.

And yes, I haven’t allowed for unpopulated items, but as they are all linked to live hardware, it shouldn’t be an issue.

Thanks, I hadn’t seen this.

That single line change fixed it instantly :slight_smile:

Thanks to you both

@rossko57 @rlkoshak

Have you seen Creating Capabilities with Rule Templates: Time of Day?

You might not even need this rule at all any more. I’m assuming you are setting a time for an alarm or the like. MainUI now how a Date Time entry widget and the Alarm Clock Rule template lets you schedule one of your rules to be run based on the state of a DateTime Item. No longer does one need to maintain a separate hours, minutes and seconds Item to enable a time to be changed from the UI.

And since it’s a rule templates and UI widgets from the Marketplace you only have to write the code that needs to run at the time specified by the DateTime Item. Everything else just gets installed and configured.

Thanks Rich

This rule is specifically for managing the alarm times within www.velbus.eu modules.

(Which have all the events and offsets stored within the modules, which makes it very resilient)

That said, it’s great to know that OH3 can handle scheduling now, that will help greatly where people have requirements outside of the capabilities of a pure Velbus solution.

From an OH UI perspective, it might be worth using a DateTime Item and widget anyway then have a rule that splits it out to the separate Items needed by Velbus. That too would eliminate the need for this rule since the range checking would take place in the UI. The example I linked to shows a Date and Time Picker but you can also use just a Time Picker.

The advances made in MainUI on this front are huge.

Now that is a great idea. :smile: :+1:

It would certainly make life a lot easier.

Here’s the YAML for a stand alone input widget that presents a Time selector.

uid: rlk_time_standalone
tags: []
props:
  parameters:
    - description: Label for the widget
      label: Label
      name: label
      required: false
      type: TEXT
    - context: item
      description: An item to control
      label: Item
      name: item
      required: false
      type: TEXT
  parameterGroups: []
component: oh-input-card
config:
  clearButton: false
  footer: '=(items[props.item].displayState === undefined) ? items[props.item].state : items[props.item].displayState'
  inputmode: text
  item: =props.item
  outline: true
  placeholder: '=(items[props.item].displayState === undefined) ? items[props.item].state : items[props.item].displayState'
  sendButton: true
  title: =props.label
  type: time

Here is one for a List Item widget

uid: rlk_time_list
tags: []
props:
  parameters:
    - description: Label for the wiodget
      label: Label
      name: label
      required: false
      type: TEXT
    - context: item
      description: An item to control
      label: Item
      name: item
      required: false
      type: TEXT
  parameterGroups: []
component: ""
config:
  inputmode: time
  label: =props.label
  name: alarmtime
  outline: true
  placeholder: '--:-- --'
  sendButton: true
  subtitle: '=(items["props.item"].displayState === undefined) ? items["props.item"].state : items["Default_AFTERNOON"].displayState'
  title: =props.label
  type: text

In MainUI go to Developer Tools, select Custom Widgets. Click the + icon and paste the first widget above into the code. Save. Repeat for the second one.

Then in your Items add the first one “rlk_time_standalone” as the “Default Standalone Widget” metadata, setting the two parameters as desired. Add “rlk_time+list” as the “Default List Widget” again setting the two parameters.

That will make anywhere that this DateTime Item appears in MainUI use these widgets by default. If you go back and change the widget’s main code it will update all the Items that use that widget too.

These are really simple and straight forward but if it’s helpful I can publish them to the Marketplace like the Date Time selectors.

The rule is pretty simple too. As Rules DSL in .rules files it would be something like:

rule "Parse date time update"
when
    Item MyDateTime changed
then
    val asZDT = (MyDateTime.state as DateTimeType).getZonedDateTime()
    val hour = asZDT.getHours()
    val min = asZDT.getMinute()
    val sec = as ZDT.getSecond()

    MyHours.postUpdate(hour)
    MyHours.postUpdate(min)
    MyHours.postUpdate(sec)
end

Making it generic is an exercise for the student. :wink:

1 Like