Semantic Tagging

Great tutorial! Thanks for posting!

I’ve a couple of suggestions which you can take or not as you see fit.

To avoid confusion, I’d take the “Rules” out of this heading.

I’d use the word “should” here. It is allowed and reasonable to assign Points directly to a Location. I don’t recommend this as it kind of messes with the way they appear on the Location cards in the UI in particular, but doing so does not break the model nor does it break the UI.

I’d also add rule 5, since this trips a bunch of people up:

“Any Location, Equipment, or Point can only be a member of exactly one semantically tagged Group. You cannot have the same Item be in two locations at once, or a part of more than one Equipment at the same time.”

A rule 6 might be “The location of an Equipment in the model should be the location as seen by members of your household. Even if the actual relay that controls the kitchen lights is in a cabinet the garage, the location for the kitchen lights in the model should be the kitchen. That’s where users of the home will expect to find them to control them.”

And a rule 7 is “Not all Items need to be in the semantic model.”

I’m not sure the model supports more than one semantic tag at a time. And “Brightness” isn’t one of the deffault set of property tags, is it? To avoid confusion I would remove it from here.

I also think it may make sense to separate the Point tags and Property tags in the table since they are two separate types of tags and the Properties tag is what controls how the Items are shown on the Properties tab.

Beyond that, a link to OH 4.1: Tutorial to manage custom semantic tags (will hopefully be in the main docs soonish, issue is open) along with a mention that if the default set of tags are not sufficient one can define their own tags. This works best for locations, equipment and properties. Care should be taken when defining custom Points as a lot of stuff (like which type of control to present in the UI by default) is driven by the Point tag. You have to create a file to define new tags but once defined and created, you can select the custom tags in the UI same as the default ones.

This isn’t one of the well known metadata options in the UI. Do you know if there is an issue to add this to MainUI and the docs?

I know about synonyms which lets you provide additional names for entities outside the Item name and label but this is the first I’ve encountered uiSemantics. I’ll need to play with that.

Another benefit is the semantic model information is available in rules through Actions | openHAB. For example, for my sensor Equipment I’ve added a “status” Item. When ever one of sensors in the equipment stop responding, I use these Actions to get the parent Equipment Item and then find the Item tagged with “Status” and “Availability” to find that status Item and set it to ON/OFF as appropriate. This is an alternative to the Associated Items design pattern that uses Item names instead of the model.

Example code:

var {alerting} = require('rlk_personal');
var logger = log('Sensor Alert');
var equipment = actions.Semantics.getEquipment(items[alertItem]);
var statusItem = equipment.members.find( i => i.tags.includes('Status') && i.tags.includes('Availability'));

if(isAlerting && statusItem.state != 'OFF') {
  statusItem.postUpdate('OFF');
  alerting.sendAlert('Offline: ' + equipment.label + ' has stopped reporting', logger);
}
else if(!isAlerting && statusItem.state != 'ON') {
  statusItem.postUpdate('ON');
  alerting.sendAlert('Online: ' + equipment.label + ' is back', logger);
}
else {
  console.info('Sensor status update alerting ' + isAlerting + ' initial ' + isInitialAlert + ' equipment ' + equipment.label + ' status ' + statusItem.state);
}

I have a Script Condition that also uses the semantic model to make sure that the Equipment actually exists and whether the status Item is in the wrong state.

var equipment = actions.Semantics.getEquipment(items[alertItem]);
var statusItem = equipment.members.find( i => i.tags.includes('Status') && i.tags.includes('Availability'));
if(equipment === null || statusItem === null) {
  console.warn(alertItem + ' does not belong to an equipment or equipment doesn\'t have a Status Item!');
  false;
}
else {
  var statusItem = equipment.members.find( i => i.tags.includes('Status') && i.tags.includes('Availability'));
  console.debug('Sensor status reporting called for ' + alertItem + ', equipment ' + equipment.label + ', is alerting ' + isAlerting + ', and is initial alert ' + isInitialAlert 
               + ', current equipment state is ' + statusItem.state);
  // Sensor is offline                         Sensor back online
  (isAlerting && statusItem.state != 'OFF') || (!isAlerting && statusItem.state != 'ON');
}

isAlerting and alertItem come from Threshold Alert and Open Reminder [4.0.0.0;4.9.9.9] in this example. The alerting import comes from a personal library.

1 Like