Sure you can.
But you cannot call a function in one xxx.rules
file from rules in some other zzz.rules
file.
Put all the rules that require some function in the same xxx.rules
file as the function.
Sure you can.
But you cannot call a function in one xxx.rules
file from rules in some other zzz.rules
file.
Put all the rules that require some function in the same xxx.rules
file as the function.
Wowā¦ two years later! Nowadays, you just use Jython and put the function in a module that can be called from any rule in any file or even from a UI rule.
I mean right this. From another rule files.
I would like to make a logging function, that sends logs to syslog, email and telegramm. Of course logs comes from different rules files.
Jyton. I have not heard about it. I asked google and it looks like another language and there is not much examples how to use it.
Maybe u know a good tutorial or thread here with explanation?
Thanks!
You can use the new rule engine and do scripted automation using Jython, which is Python for the JVM. The OH docs are a bit meager. It has some important information, but donāt follow those installation instructions. The raw automation API is extremely rough to use without living in the source code. Fortunately, there are helper libraries that make it very easy to use and are a game changer for OH automation. There is a lot of documentation to help and most design patterns now also have Jython examples. The installation isnāt too difficult, but Iām working on an addon to simplify things. Even @rlkoshak has migrated all of his rules from the rules DSL to Jython and @vzorglub is in process.
https://openhab-scripters.github.io/openhab-helper-libraries/index.html
Let me know if you have an questions or issuesā¦ but probably should be in a new topic .
If you post your logging messages to Item states, these are common to all rules, whatever their source - xxx.rules files, Jython, etc.
This is demonstrated in Design Pattern: Separation of Behaviors
Do lambas go in .rules files?
I ask because the example is giving me validation warnings with OH2.5M5:
2019-11-26 08:15:26.434 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'light.rules' has errors, therefore ignoring it: [97,1]: missing EOF at 'val'
TIA
Yes, but they must go at the top of the file before all your Rules. This error is coming from line 97 which means your lambda is likely after the definition of a Rule or the error is coming from a Rule.
I should note that global lambdas like this are a code smell in Rules DSL. They can be handy in a very small set of circumstances, but they have sever limitations that make them dangerous to use. For example, they are not thread safe. If it gets called twice the variables from the first call will become overwritten by the second call. Also, you cannot call the lambda outside of the .rules file it is defined in. There is almost always a better way. For example: Design Pattern: Separation of Behaviors
Iām looking into lamdas and found your post. Is it worth rewriting to include notes for JRS223 Python/Jython?
Maybe thereās a good design pattern article. Iām still searching
Regards,
Burzin
Functions are available as a basic part of the Scripted Automation languages. If you take a week long course on Python, functions will be introduced somewhere on the morning of the first day. I didnāt include Python or JavaScript in the above DP because, for all purposes, the above DP doesnāt apply to Scripted Automation. Use what ever is available for the language chosen.
Using lambdas in this way is a work around for the fact that Rules DSL doesnāt support functions. There is no such limitation in any of the other languages.
@rlkoshak is it possible that lambdas are no longer supported in Openhab 3? I upgraded yesterday and since have been trying to get a rule to work again. When changing reloading the model it says:
2021-01-04 17:15:47.814 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'alert.rules', using it anyway:
The field Tmp_alertRules.checkAndSendAlert refers to the missing type Object
When triggering the rule it just says:
2021-01-04 17:15:47.770 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'alert-1' failed: null in alert
Check the section concerning Rules here
Sadly, I did not find anything regarding lambdas there.
No, lambdas have to be supported or else you couldnāt create a Timer nor run a forEach or the like. Those require a lambda as an argument.
Iāve seen no reports of lambdas not working on the forum except this one.
No. But you might find a reason why your rule no longer works. Please post the rule.
Here is the rule in question:
val String fileName = "alert.rules"
val telegramBot = getActions("telegram", "telegram:bot:myOpenhabianBot")
val checkAndSendAlert = [ NumberItem temperature, NumberItem minimum, NumberItem maximum, SwitchItem normal |
logInfo(fileName, "Checking temperature")
var sensor = transform("MAP", "alert.map", temperature.name)
logInfo(fileName, sensor)
if ((temperature.state as Number) < (minimum.state as Number))
{
logInfo(fileName, "Teperature is below minimum")
if (normal.state == ON)
{
sendCommand(normal, OFF)
telegramBot.sendTelegram("ā” %s temperature at %.1fĀ°C\nSensor is *below* minimum of %.1fĀ°C",
sensor,
(temperature.state as DecimalType).floatValue(),
(minimum.state as DecimalType).floatValue())
}
}
else if ((temperature.state as Number) > (maximum.state as Number))
{
logInfo(fileName, "Teperature is above maximum")
if (normal.state == ON)
{
sendCommand(normal, OFF)
telegramBot.sendTelegram("ā” %s temperature at %.1fĀ°C\nSensor is *above* maximum of %.1fĀ°C",
sensor,
(temperature.state as DecimalType).floatValue(),
(maximum.state as DecimalType).floatValue())
}
}
else if (normal.state == OFF)
{
logInfo(fileName, "Teperature is normal")
sendCommand(normal, ON)
telegramBot.sendTelegram("ā” %s temperature at %.1fĀ°C\nSensor is back to *normal*",
sensor,
(temperature.state as DecimalType).floatValue())
}
]
rule "Send alert when VrRoom temperature goes out of limits"
when
Item VrRoom_Temperature changed or
Item VrRoom_Temperature_Min changed or
Item VrRoom_Temperature_Max changed
then
logInfo(fileName, "Checking")
checkAndSendAlert.apply(VrRoom_Temperature, VrRoom_Temperature_Min, VrRoom_Temperature_Max, VrRoom_Temperature_Normal)
end
A couple things I notice.
There is no reason to put this into a lambda unless you have multiple rules that call it that youāve not posted.
This lambda should have never worked in OH 2.5 either. checkAndSendAlert
is a global lambda. Global lambdas have no context. Consequently it cannot see other global variables unless you pass them to it as an argument. You are attempting to use fileName
and telegramBot
inside the lambda without passing them as arguments.
Iāve seen many many reports where trying to get the action as store it in a global variable does not work. You should move the call to getActions into where ever the action is called.
See Design Pattern: Associated Items
Rules | openHAB. Be sure to follow the links as well.
In general, a global lambda like this is a real code smell. There are a few cases where it can make sense but this isnāt one of them I think. Lambdas are not thread safe so if you do have more than one rule call it at the same time, the second rule will overwrite the variables from the first one while the first one is still running. And most of the time there is a better way.