It is documented at Actions | openHAB, though as with the rest of the Actions probably inadequately. But it’s really straight forward and works the same as any other Action like createTimer or executeCommandLine.
var location = getLocation(MyItem)
Simple as that. Core actions are imported by default.
In JavaScript you’d have to type/import the class first and pull the Item from the ItemRegistry instead of using just the name.
var Semantics = Java.type("org.openhab.core.model.script.actions.Semantics");
var location = Semantics.getLocation(ir.getItem("MyItem"));
Python would be the same overall approach.
import Semantics from org.openhab.core.model.script.actions
location = Semantics.getLocation(ir.getItem("MyItem"));
Hey Rick,
many thanks formyour reply.
I already tried exactly the same, but as I got an error message, I thought I was sure that I am using a wrong syntax.
This is the error message:
[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Test-1' failed: An error occurred during the script execution: Could not invoke method: org.openhab.core.model.script.actions.Semantics.getLocation(org.openhab.core.items.Item) on instance: null in Test
Did anybody got it working?
this is my test code:
var string strRaum = getLocation("TestItem")
logInfo(fileName,"Location: {}",strRaum)
thanks rossko!
anyway, here are two working code examples just in case someone else needs some guidance:
Example 1: Group is triggered
val fileName = "Test.rules"
rule "Test"
when
Member of gTest changed
then
var string strRaum = getLocation(triggeringItem)
logInfo(fileName, "Raum: '{}'",strRaum)
end
Example 2: Item is triggered
import org.openhab.core.model.script.ScriptServiceUtil
val fileName = "Test.rules"
rule "Test"
when
Item TestItem changed
then
var string strRaum = getLocation(ScriptServiceUtil.getItemRegistry.getItem(triggeringItemName))
// you could also directly provide a string like this:
// var string strRaum = getLocation(ScriptServiceUtil.getItemRegistry.getItem("TestItem"))
logInfo(fileName, "Raum: '{}'",strRaum)
end
if someone else knows of a better/easier way, please let me know
Well, getLocation requires an Item. If all you have is the name of the Item (e.g. triggeringItemName instead of triggeringItem) you have to pull the Item out of the registry. So that one line is as good as it gets.
In real rules, you’ll probably have the Item object already - it was the trigger, or you’re going to read or update the state, etc.
If you don’t, then that is how to get it.
One gotcha there though is in Rules DSL there isn’t a triggeringItem any more in OH 3 except for Member of rule triggers. Rules that have Item triggers will only have triggeringItemName which requires the actual Item to be pulled from the registry.
I’m inclined to file an issue to add versions of the actions that accept the name of the Item because of this. It’s not hard to implement and it would make rules in all the languages easier to write. Of course, it’s also easy to implement in something like the Helper Libraries too, but that won’t help Rules DSL users.
4 Likes
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
11
Thanks Rich
That explains why this week’s test rule didn’t work.
But the tip about member of will help streamline the rule I’m trying to create.
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
12
Thanks Rich
Your tip here helped me to streamline a group rule for colour pickers.
(I need to create a large number of these for a job soon, this makes the whole thing much easier)
rule "colour"
when
Member of ColourPickers received command
then
logInfo("Colour","Colour = "+triggeringItem.name.toString+" Changed to "+triggeringItem.state.toString)
if (triggeringItem.state.toString == "ON") {sendCommand(triggeringItem.name.toString,"0,0,100")}
if (triggeringItem.state.toString == "OFF") {sendCommand(triggeringItem.name.toString,"0,0,0")}
else
{
var HSBType hsbValue = triggeringItem.state as HSBType
var int redValue = hsbValue.red.intValue
var int greenValue = hsbValue.green.intValue
var int blueValue = hsbValue.blue.intValue
var RED = triggeringItem.name+"_RED"
var GREEN = triggeringItem.name+"_GREEN"
var BLUE = triggeringItem.name+"_BLUE"
logInfo("Colour",triggeringItem.name.toString+" HSB Value ="+hsbValue+"\nRGB Values \n"+RED+" = "+redValue+"% \n"+GREEN+" = "+greenValue+"%\n"+BLUE+" = "+blueValue)
sendCommand(RED,redValue.toString)
sendCommand(GREEN,greenValue.toString)
sendCommand(BLUE,blueValue.toString)
}
end
Associated Items (for anyone interested)
Group ColourPickers "All Colour Pickers"
// Edit the following to suit the Dimmer channels in use - Any colour item should be put into the (ColourPickers) group
Color BathroomColour "Bathroom Colour" <colorpicker> (ColourPickers) {ga="light", alexa="BrightnessController.brightness,PowerController.powerState,ColorController.color"}
Dimmer BathroomColour_RED "Bathroom Red" <slider> {channel="velbus:vmb4dc:VelbusNetworkBridge:BF:CH1"}
Dimmer BathroomColour_GREEN "Bathroom Green" <slider> {channel="velbus:vmb4dc:VelbusNetworkBridge:BF:CH2"}
Dimmer BathroomColour_BLUE "Bathroom Blue" <slider> {channel="velbus:vmb4dc:VelbusNetworkBridge:BF:CH3"}
Dimmer Bathroom4DCCH4 "Bathroom White" <slider> {channel="velbus:vmb4dc:VelbusNetworkBridge:BF:CH4", ga="Light" [roomHint="Bathroom"], alexa="PowerController.powerState,BrightnessController.brightness"}
Color MidRoomColour "Middle Bedroom Colour" <colorpicker> (ColourPickers) {ga="light", alexa="BrightnessController.brightness,PowerController.powerState,ColorController.color"}
Dimmer MidRoomColour_RED "Middle Bedroom Red" <slider> {channel="velbus:vmb4dc:VelbusNetworkBridge:D2:CH1"}
Dimmer MidRoomColour_GREEN "Middle Bedroom Green" <slider> {channel="velbus:vmb4dc:VelbusNetworkBridge:D2:CH2"}
Dimmer MidRoomColour_BLUE "Middle Bedroom Blue" <slider> {channel="velbus:vmb4dc:VelbusNetworkBridge:D2:CH3"}
// Dimmer MidRoom4DCCH4 "NotUsed" <slider> {channel="velbus:vmb4dc:VelbusNetworkBridge:D2:CH4", ga="Light" [roomHint="Middle Bedroom"], alexa="PowerController.powerState,BrightnessController.brightness"}
I just need to work out what to do with the WHITE channels, I’m hoping there is a hsbValue.white
but if not, I’ll just turn the colour off if they turn the white channel on, or turn off the White when they select a new colour
One thing that I noticed regarding this action is: the getEquipment method returns only the parent equipment of an item if this item is not an equipment itself. Otherwise the getEquipment returns the input item. Since I do have a multi layered equipment structure in my semantic model (e.g. washing machine → washing Maschine power socket) it would be great to always get the parent even if the input is an equipment itself.
As far as I can see there is no way to achieve this with the action today or am I mistaken?
Failed to execute rule xxxxx: java.lang.UnsupportedOperationException: Unsupported operation identifier 'getGroupNames' and object '[object Object]'(language: JavaScript, type: Item). Identifier is not executable or instantiable.
Has something changed since you wrote this?
I’m using the most recent versions of OpenHAB and JSScripting.
This is one of the places where understanding the when you are dealing with Java and where you are dealing with JavaScript becomes vital.
In the above code, you can see that you are pulling Semantics from Java. Java doesn’t know anything about JavaScript.
As described in the JS Scripting add-on, items['testItem'] returns a JavaScript Item which is a wrapper so that you don’t have to worry about weirdness with interacting with Java Classes and Objects in JavaScript.
So, of course, the JavaScript Items isn’t going to be a viable Object to pass to the Java Semantics Class. It needs the Java Item which you can get from the Item Registry (as demonstrated in my code) or by calling rawItem on the JavaScript Item.