Did you get something on the hunt? I’m having trouble getting a State from a DateTimeItem coming from the ScriptServiceUtil.
In the rule I’ll loop through 6 different calendar entries and try to get their states (DateTimeItems and StringItems)
(...)
var DateTime EmailTime = ScriptServiceUtil.getItemRegistry?.getItem("Calendar_GoogleFamily_Event"+i+"_EmailTime") as DateTimeItem
var String Summary = ScriptServiceUtil.getItemRegistry?.getItem("Calendar_GoogleFamily_Event"+i+"_Summary") as StringItem
(...)
logInfo("Familienkalender", "Item from DateItem-Definition: [{}]",Calendar_GoogleFamily_Event1_EmailTime)
logInfo("Familienkalender", "State from Item-Definition [{}]",Calendar_GoogleFamily_Event1_EmailTime.state)
logInfo("Familienkalender", "State from String-Definition [{}]",Calendar_GoogleFamily_Event1_Summary.state)
logInfo("Familienkalender", "Item from DateScriptServiceUtil: [{}]",EmailTime)
logInfo("Familienkalender", "State from DateScriptServiceUtil: [{}]",EmailTime.state)
logInfo("Familienkalender", "State from StringScriptServiceUtil: [{}]",Summary.state)
I’ll then get in the logs:
2020-01-10 08:26:00.044 [INFO ] [rthome.model.script.Familienkalender] - Item from DateItem-Definition: [Calendar_GoogleFamily_Event1_EmailTime (Type=DateTimeItem, State=2020-01-10T07:46:00.000+0100, Label=FamKal Ev1 Email, Category=calendar, Groups=[gCalendar, gCalFamilyNotification])]
2020-01-10 08:26:00.050 [INFO ] [rthome.model.script.Familienkalender] - State from Item-Definition [2020-01-10T07:46:00.000+0100]
2020-01-10 08:26:00.055 [INFO ] [rthome.model.script.Familienkalender] - State from String-Definition [dingsbums anrufen]
2020-01-10 08:26:00.059 [INFO ] [rthome.model.script.Familienkalender] - Item from DateScriptServiceUtil: [Calendar_GoogleFamily_Event1_EmailTime (Type=DateTimeItem, State=2020-01-10T07:46:00.000+0100, Label=FamKal Ev1 Email, Category=calendar, Groups=[gCalendar, gCalFamilyNotification])]
2020-01-10 08:26:00.064 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Binder Familienkalender': 'state' is not a member of 'org.joda.time.DateTime'; line 33, column 72, length 15
2020-01-10 08:23:03.134 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Binder Familienkalender': 'state' is not a member of 'java.lang.String'; line 33, column 74, length 13
The items from the .items-file and the ones generated via ScriptServiceUtil seem to have the same attributes - but it seems I can’t access them…
I’d also like to make comparisons with the “EmailTime”-Date and stuff I can with the .items-generated items…
No. There is no way to access Item metadata from the rules DSL. The solution is to use scripted automation, which is the future of automation for OH and metadata can be easily accessed using the core helper libraries. My plan is to make this functionality available through a Scripting API, so that the core helper libraries are no longer needed. If you’re interested, it’s getting easier to get them setup…
There are some issues with your casting. In the DSL, it is best to be only as specific as you need to be. Try being less specific and let the DSL do the work for you…
var EmailTime = ScriptServiceUtil.getItemRegistry.getItem("Calendar_GoogleFamily_Event"+i+"_EmailTime")
var Summary = ScriptServiceUtil.getItemRegistry?.getItem("Calendar_GoogleFamily_Event"+i+"_Summary")
2020-01-10 10:18:02.748 [INFO ] [rthome.model.script.Familienkalender] - Item from DateItem-Definition: [Calendar_GoogleFamily_Event1_EmailTime (Type=DateTimeItem, State=2020-01-10T07:46:00.000+0100, Label=FamKal Ev1 Email, Category=calendar, Groups=[gCalendar, gCalFamilyNotification])]
2020-01-10 10:18:02.750 [INFO ] [rthome.model.script.Familienkalender] - State from Item-Definition [2020-01-10T07:46:00.000+0100]
2020-01-10 10:18:02.752 [INFO ] [rthome.model.script.Familienkalender] - State from String-Definition [dingsbums anrufen]
2020-01-10 10:18:02.754 [INFO ] [rthome.model.script.Familienkalender] - Item from DateScriptServiceUtil: [Calendar_GoogleFamily_Event1_EmailTime (Type=DateTimeItem, State=2020-01-10T07:46:00.000+0100, Label=FamKal Ev1 Email, Category=calendar, Groups=[gCalendar, gCalFamilyNotification])]
2020-01-10 10:18:02.755 [INFO ] [rthome.model.script.Familienkalender] - State from DateScriptServiceUtil: [2020-01-10T07:46:00.000+0100]
2020-01-10 10:18:02.757 [INFO ] [rthome.model.script.Familienkalender] - State from StringScriptServiceUtil: [dingsbums anrufen]
Do you have an idea, how I can compare the corresponding DateTime?
val jetzt = now.minusSeconds(20)
(line 37:)
if (jetzt.isBefore(new DateTime((EmailTime as DateTimeType).getZonedDateTime.toInstant.toEpochMilli))) {
(...)
leads to:
2020-01-10 10:21:02.852 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Binder Familienkalender': Could not cast Calendar_GoogleFamily_Event1_EmailTime (Type=DateTimeItem, State=2020-01-10T07:46:00.000+0100, Label=FamKal Ev1 Email, Category=calendar, Groups=[gCalendar, gCalFamilyNotification]) to org.eclipse.smarthome.core.library.types.DateTimeType; line 37, column 36, length 25
it seems, the “EmailTime”-defintion (without all those DateTime-references) gets the right values, but I’m still lacking understanding on how to cast accordingly… (I’m no devloper, casting and stuff is not in my blood ). The if-condition works with “real” items, as I use it elsewhere (also partly copied from the forum)
Although, I bet you were asking if a ZDT could be fed to createTimer without using Joda, and the answer to that is no.
The createTimer Action is part of the old rule engine, which will be removed in OH 3.0. Something similar will need to be created for the new rule engine, along with the other Core Actions. These will be made accessible for use within scripted automation through the scripting API. The mechanism will likely be a ScriptExtension, possibly through a default preset.
Does it make sense to push people to move to ZonedDateTime before exceptionally commonly used Actions like createTimer can accept it? When I look at my use of Joda DateTime in all of my rules, about 80% of the uses are related to calls to createTimer. Thus, it doesn’t make sense for me to migrate until I can use a ZonedDateTime in createTimer. It will be more work for me to switch now and then again when the replacement for createTimer comes along. I imagine I’m not unique in that.
3 Likes
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
34
Thanks to this post and little more digging, I’ve got this rule working.
In short, it keeps an eye on gMinute and gHour groups, so that minutes and hours are constrained, but also that when the minutes exceed the limits, it adjusts the coresponidng hour
I’ve left the logInfo lines in so you can see my working out.
import org.openhab.core.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
How do you add the import org.openhab.core.model.script.ScriptServiceUtil instruction in OH3, when the Rule script is not in a file, but created using Admin > Settings > Rules > Execute a given script
Yes it is still this way in OH 4 for Rules DSL. In all the other rules languages to include Blockly, the ItemRegistry is available and can be accessed without importing ScruiptServiceUtil to get it. In some languages, like JS Scripting, the only way to get an Item is through it’s string name.
Performance shouldn’t be an issue either way.
That’s not how it’s implemented in Rules DSL. Rules DSL uses the raw ItemRegistry which throws an ItemNotFoundException if the Item doesn’t exist. Other languages have different ways to handle it but most throw an exception.
If you want to catch the exception, you can use a try/catch
try {
val testItem = ScriptServiceUtil.getItemRegistry.getItem("Virtual_Switch_1")
// the rest of the code that uses testItem
} catch(org.openhab.core.items.ItemLookupException e) {
// what to do if the Item doesn't exist
}
I’m not sure what you’d do in the catch clause beyond logging that the Item doesn’t exist, which is going to happen anyway if you don’t catch the exception.
All things considered, if you are doing stuff like this it might be a sign you’ve outgrown the capabilities of Rules DSL. You might consider moving new development to another language such as Blockly, JS Scripting or jRuby.
Yes I know. JS would be my prefered language. But I have to wait always about 30s for compilation on my Raspberry 3. This is the main reason why I don’t want to develop with JS and will stay at the moment with DSL.
I would also prefer JS over DSL, but was put off when it was first introduced around v3. That is of course some time ago, so can you recommend any good guides to get started with JS?
thanks
Converting all DSL rules to js was easier than I thought as the code is very similiar to js.
I converted around 20 rules within a couple of hours.
If you change the syntax for send/postcommand, getstate and loginfo, you probably have done already 80% of the conversion.