In making my semantic model I have setup all my rooms and everything is to my liking - how can you aggregate data on higher level locations, like “House” or “1st Floor”, so values like number of open windows/doors, number of active alarms, etc can be shown.
Eg. say I have 2 rooms on my 1st floor - bedroom and office. If there are 2 open windows in my bedroom, this is shown as a badge with the number 2 beside it, on the Bedroom Location Card. The office has 1 open window, also shown on the respective Location Card. I’d like to have a Location card for the entire floor, where the open window badge is shown, with the number 3 next to it.
Currently if I add the windows to both the 1st Floor location and the room, the property disappears from one of them, as I cannot have a piece of equipment in 2 locations at once. But how can I aggregate this to display on a “1st Floor” Location Card?
In total i probably have around 150 items that need to be “handled”
I know a solution would be to make new items, make rules or channels so that these new items have the same values, but is there an easier way?
Or if not, is there an efficient way to copy a set of items all made in UI, and replicate that set of items creating new ones with a pre- or suffix added, and next to link these new item states to the existing items, so the states follow each other?
I’m pretty sure you can’t. At least not without also showing the lower level locations on the same overview page.
It might work to hide the lower level locations.
Assuming these are all linked to Channels of Things, the easiest would be to navigate to the Thing and use “add equipment from thing” to create the new Items.
Short of that, using the API Explorter to query for and then copy/paste/edit/post to create new Items would be the best.
You can also stop OH and manually edit the JSONDB file.
There is no (practical) limit to the number of groups an item can be added to. I solve this issue by simply creating 1 additional group for each aggregate data point that I want. For example, my light card:
This tells me that there are 3 lights on overall, and that 2 of them are on the second floor and 1 on the main floor. Each of those numbers comes from a group with an aggregation function. For example the total number group:
This information will not be inlcuded on the autogenerated location cards, but you can create (as I have here) your own widget to display it however you want.
Thanks for your insights Gents.
I ended up taking a sort-of middle road and add a twist - I added the items into a non-semantic group to get the aggregation desired, and when a member of that group changes to a given state, a new item is created or deleted under a different Equipment in the higher level. This way points can be dynamically created and deleted to populate the aggregate data I was after.
In order to prevent duplicates in the Equipment and Properties tabs I’ve given the new items a unique value, so these can be hidden - eg. all my aggregate Alarms have the “Current” property as this is not used anywhere else in my model.
For reference here is the rule I’ve used:
val itemName = triggeringItem.name + "_Suffix"
val itemLabel = triggeringItem.label + " Suffix"
val itemType = "Switch"
val groupItem = "gGroupItem_Name"
if (triggeringItem.state == ON) {
if (org.openhab.core.model.script.ScriptServiceUtil.getItemRegistry.getItems(itemName).isEmpty) {
val newItem = new SwitchItem(itemName)
newItem.label = itemLabel
newItem.addTags("Alarm", "Current")
org.openhab.core.model.script.ScriptServiceUtil.getItemRegistry.add(newItem)
newItem.postUpdate(triggeringItem.state)
val anotherGroup = org.openhab.core.model.script.ScriptServiceUtil.getItemRegistry.getItem(groupItem) as GroupItem
if (!anotherGroup.members.contains(newItem)) {
anotherGroup.addMember(newItem)
}
org.openhab.core.model.script.ScriptServiceUtil.getItemRegistry.update(newItem)
logInfo("Test - CreateNewSwitchItem", "Created new switch item: " + newItem + " and added to group")
} else {
logWarn("Test - CheckItem", "Item " + itemName + " exists.")
return
}
} else if (triggeringItem.state == OFF) {
org.openhab.core.model.script.ScriptServiceUtil.getItemRegistry.remove(itemName)
logInfo("Test - CreateNewSwitchItem", "Deleting Created item: " + itemName)
}
There is however 1 addition I would like to make - currently the dynamically created items have a toggle function - how can I make that be a label instead with OK/ALARM states? I have other items that have these values as default, but what determines how a Switch item behaves with regard to this, is this what the Read Only feature does?
Yes, the Read Only feature means that the Switch item, instead of displaying the toggle interface will only display the text value of the state (ON or OFF). So after you have enabled read only then you just use the Options section of the State description to map ON/OFF to OK/ALARM:
Is there a way to define these Read Only properties within the rule? As the items are created and deleted dynamically I need this to be done automatically at creation time. (Mind you, the rule to do this is written in DSL, and I know there are some limitations, but I’m not sure if this is one of them)
Read only and the state options are both set in the item’s state description. It is probably possible to set these with rules DSL, but I couldn’t say how, off the top of head, and there is a non-zero chance that it is not possible at all. My gut feeling is that if you want to go down that road, you’ve hit the point where it will be more time efficient to move the rule to one of more feature-full languages than to experiment with DSL further.
To be honest, however, I’m not entirely sure what this process of dynamic item creation gets you that just having the statically created model items does not. Unless you are getting some additional benefit to this beyond seeing the badges on the location cards, most likely this is just extra work, compared to simply creating all the items in the model once and leaving them be. Now, I’m not one to talk here since I often consider “just learning if this is possible” or “poking something until it I find its limits” sufficient additional benefit in situations like this, but you may feel differently.
You are so right - but for the life of me I could not get it to work in JS - I’m not sure if it is because I’m still on OH3.4, and that using ECMA 2021 is missing alot of the features that I can see in the rules that are on the forum, matching what I need, because it seems there are plentiful examples it seems. But for some reason I couldn’t get them to work. So I went (back) with DSL…If nobody else comes along with a solution, I’ll probably go back to this in a few days with a clean mind, and see if I can migrate the rule to JS, as upgrading to OH4 is still some time away for me.
I’m somewhat wired the same way, only I’m mostly fueled by stubborness …because I agree, it is probably a waste of time and the cost vs value I get from this is absolutely not worth it, but just like the CSS badge stuff you helped me with I get a lot of added bonus by just learning new things during the process.
Even if you are on 3.4, there are instructions for updating the jsscripting helper library to the newest version, which can easily do all the things you need. I’m also pretty sure that at this point blobkly can even do nearly all of it, but you made need to be one on of the 4.x versions for the relevant blockly blocks. But, it’s worth a look at blockly to see because if the blocks are there for your version they can also be a great reference by just looking at the js they produce.