Moving over a little bit with this one - I was able to parse brick schema and source classes and class hierarchy for points and locations using below code:
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import org.apache.jena.n3.turtle.TurtleReader;
import org.apache.jena.ontology.OntClass;
import org.apache.jena.ontology.OntModel;
import org.apache.jena.rdf.model.Literal;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.util.iterator.ExtendedIterator;
public class BrickReader {
public static void main(String[] args) throws IOException {
final OntModel model = ModelFactory.createOntologyModel();
final TurtleReader reader = new TurtleReader();
final InputStream resource = BrickReader.class.getResourceAsStream("/Brick.ttl");
reader.read(model, resource, "");
PrintWriter out = new PrintWriter(new FileWriter("brick.csv"));
out.println("Type,Tag,Parent,Label,Synonyms,Description");
OntClass clazz = model.getOntClass("https://brickschema.org/schema/1.1/Brick#Location");
introspect(out, clazz, "Location", true);
clazz = model.getOntClass("https://brickschema.org/schema/1.1/Brick#Equipment");
introspect(out, clazz, "Equipment", true);
clazz = model.getOntClass("https://brickschema.org/schema/1.1/Brick#Point");
introspect(out, clazz, "Point", true);
clazz = model.getOntClass("https://brickschema.org/schema/1.1/Brick#Tag");
introspect(out, clazz, "Tag", true);
}
private static void introspect(PrintWriter out, OntClass clazz, String tag, boolean introspectSubClasses) {
introspect(out, clazz, tag, introspectSubClasses, 0);
}
private static void introspect(PrintWriter out, OntClass clazz, String tag, boolean introspectSubClasses, int nesting) {
final String clazzLabel = clazz.getLabel(null);
if (clazzLabel == null) {
return;
}
out.print(tag + "," + clazzLabel + ",");
OntClass superClass = clazz.getSuperClass();
if (superClass != null && superClass.getLabel(null) != null) {
out.print(superClass.getLabel(null) + ",,");
} else {
out.print(",,");
}
out.print(clazzLabel + ",");
Property definition = clazz.getModel().getProperty("http://www.w3.org/2004/02/skos/core#definition");
if (definition != null) {
RDFNode property = clazz.getPropertyValue(definition);
if (property != null && property.isLiteral()) {
out.print("\"" + ((Literal) property).getString() + "\"");
}
}
out.println();
for (ExtendedIterator<OntClass> it = clazz.listSubClasses(); it.hasNext(); ) {
OntClass subClazz = it.next();
if (subClazz.isClass()) {
if (introspectSubClasses) {
introspect(out, subClazz, tag, introspectSubClasses, nesting + 1);
}
}
}
}
}
Above program is quite simple, however it is able to navigate over ontology and source labels and descriptions which is pretty much everything needed to process model.
Now, the interesting question is how such thing could actually work with OH, cause OH semantic model is really fitted into items through groups and tags. Brick related metadata could possibly be maintained there too. Comaring quickly both - I see that openHAB have more names for locations (both outside and inside building), while Brick have more diverse pool of point definitions which come from variety of hardware it attempts to cover.
I’ll probably park it here since I currently have no time to continue work in this direction.
Example CSV I was able to generate: https://gist.github.com/splatch/9294a7d096f0d1d2d3374af1a0c68f93 - I even attempted to generate new semantics out of it using generateTagClasses.groovy
script, but it produces quite bad results due to whitespaces in tag names.