Is it possible to configure rules for all items based on semantic properties? For example, I want to create a rule that opens all blinds in my home.
In OH2 I had to create a group and manually insert all blind controls there. In OH3 we have semantic tags, so I was wondering if I can send a command to all items that share the same tag?
I have never tried it with Rule DSL so I can just assume that it is something like this:
import org.openhab.core.model.script.ScriptServiceUtil
val allBatteries = ScriptServiceUtil.getItemRegistry.getItemsByTag("Battery");
allBatteries.members.forEach[ i |
val state = i.getState();
]
But as I wrote this is just an assumption on I have not tried it.
Unfortunately, it doesn’t work for me. Neither as script nor as rule.
It fails with the import and then a lot of subsequent errors. 1. The method or field import is undefined; line 1, column 0, length 6
I am running OH 3.0.0-2.
Copy the full contents of Stefan’s first example (the one with “rule Battery Test”).
I just ran it, it works.
It does not appear to work, or I can’t figure out how to make it work, through the UI with Rules DSL. There is no way I can see to access the ImageRegistry as the import is not allowed.
You have to decide if you want to use the JS option or the DSL engine. In JS you can do the following:
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var allBlinds = itemRegistry.getItemsByTag("Blinds");
for (var i in allBlinds) {
var blinds = allBlinds[i];
logger.info('Closing' + blinds.name);
events.sendCommand(blinds.name, '85');
}
I’m new to OH3, and I would like something similar, but a subgroup. Can I turn on all lights on the ground floor? In the solution above, it mentioned to pull out by a tag. I could tag by location, and type, but this seems just as wordy as assigning items to groups, which I could also do. I’d like to define once and use everywhere.
In my case, I have a building with three floors, the main floor is broken into three main areas, and each area may be further subdivided. It would be very nice to get a group of all lights in the dance hall, regardless of if they are over the dance floor, or in the stage, or in the bar.
Your easiest approach will be to define the Groups yourself, outside of the model. Then you can just send commands to the Group and that command will be forwarded to all of its members. No need do anything more than that.
I was afraid of that. So, basically, I need to flatten out my ontology and duplicate that information. I was really hoping we could use relations to build a group on the fly. Going with groups, or tags, I would need an extra piece of information for each level.
In my locations groups below, it would be nice to be able to pull out Gf_H, and all decedents, and whatever shows up as a light in that group, to turn it on.
You can absolutely do that as demonstrated above. Call getAllMembers on the Group Item for the location and filter them based on the tags. It’ll just be easier to create the Group and then you have a one liner in your Rules and something you can put in your Pages or even in your Model to control them all as a Group.
To do it in a rule though (JavaScript):
var Collectors = Java.type("java.util.stream.Collectors");
var MyLocationGroup = ir.getItem("MyLocationGroup");
MyLocationGroup
.getAllMembers()
.stream()
.filter(function(i) { return i instanceof Switch && i.getTags().contains("Light"); })
.forEach(function(i){ events.sendCommand(i.name, "OFF"); });
Note I just typed that in, there are likely typos.
Notice though that I have to filer based on the Item type too because a Lux sensor would also have the Light tag. You’ll have to be careful about that sort of thing (another reason this becomes tricky).
You don’t have to do anything to your ontology really. The extra Groups would either be outside of your ontology or they could even become a Point inside your ontology. If you want to be able to control all the lights on a floor or in a room I would think you’d want to be able to do so from your UI in addition to being able to do this from your Rules alone.