Subscribe to our newsletter
Documentation
Overview
openAAL documentation should help developer and project manager alike to discover more about openAAL.
- The System Setup section describes the openAAL and OSGi setup process that leads to running openAAL plattform.
- The General Overview section gives an introduction to openAAL components and features.
- The Hands On Tutorials exemplifies use of openAAL interfaces and provide help in day-to-day situations.
Please keep in mind that this documentation is not final and will be extended and adapted in the future. Have fun!!!
System Setup
Easy-to-use installation manual can be found in every openAAL download. You have to:
- Download openAAL zip file from the download section,
- Unzip the file, and, finally,
- Installation guidelines are to be found in Open-AAL\documentation\Setting up Eclipse and running openAAL 1.0.docx.
General Overview
Tutorial
openAAL tutorials focus on developers who want to use openAAL as platform for their innovative AAL applications. However, these tutorials focus on openAAL functionality not on OSGi. Nevertheless, since the whole openAAL platform is based on the OSGi implementation equinox, an in-depth knowledge of OSGi is necessary. Fortunately, OSGi is a easy-to-use technology for everybody familiar to java and a lot of OSGi training material is available. For our German readers especially, we suggest Die OSGI Service Platform-Eine Einführung mit Eclipse Equinox.
Currently, this documentation contains the following tutorials:
- Context Manager Tutorial
- Ontology Creator Tutorial
- Ontology Modelling Tutorial
- More tutorials coming soon
These tutorials are based on openAAL version 1.1 which will be online soon. It gives tutorials on the main openAAL tools and components.
Context Manager Tutorial
Context Manager Intro
The Context Manager (CM) is a shared data storage tailored to the needs of situation detection algorithms. It defines statements that can be made about the domain in question together with timestamps and confidence information. The context data schema is driven by the openAAL ontology. It defines which kind of information can be stored and queried in the context manager.
The CM’s main interface is in ContextManager.java as found in the org.openaal.sam.interface.contextmanager package. You can use this interface to manipulate and query information stored in the CM:
- Create new instances of existing ontology classes
- Query for instances
- Create new statements compliant to the ontology using instances that have already been stored
- Query for instances by using statement patterns
- Delete all information
Additionally, you can register EventListeners to the osgi-registry or introduce new event-condition-action rules by means of other interfaces. Additionally, we have with the javaClassOntology a more object-oriented interface that is far easier to use. The openAAL team recommends using this interface instead of the ContextManager interface; consulting the latter only in cases where functionality is not supported by the javaClassOntology.
The following hands on tutorial exemplify use of the main CM interfaces and functions. It is also part of the org.openaal.example bundle since version 1.1.
Context Manager Hands On Tutorial
Information Representation
Within openAAL Information such as class, properties and instance names are represented as URI (Uniform Resource Identifier) Strings. URIs consist of the openAAL identifier, followed by an optional ontology package name a delimiter and the class, property or instance specifier.
String openAALId = "http://www.openaal.org/SAM/Ontology";
String highLevelThingPackageName = "/highLevelThing";
String delimiter = "#";
//class specifier are usually capitalized
String kitchenSpecifier = "Kitchen";
String uriDoor = "http://www.openaal.org/SAM/Ontology/highLevelThing#Door";
String uriKitchen = openAALId + highLevelThingPackageName + delimiter + kitchenSpecifier;
//Instances are usually represented starting with a lower letter
String uriMyFronDoor = "http://www.openaal.org/SAM/Ontology/highLevelThing#front-door";
String uriMyKitchen = openAALId + highLevelThingPackageName + delimiter + "myKitchen";
//properties carry no package identifier
String uriPropertyHasOpenState = "http://www.openaal.org/SAM/Ontology#has-open-state";
String uriPropertyDetectsOpenState = openAALId + delimiter + "detects-open-state";
Different types of URIs as well as data values, e.g Integers or Strings are wrapped by the Resource class.
Resource doorRes = Resource.fromURI(uriDoor);
Resource frontDoorRes = Resource.fromURI(uriMyFronDoor);
Resource doubleRes = Resource.fromDouble(21.5d);
Resource openRes = Resource.fromURI(openAALId + highLevelThingPackageName + delimiter + "open");
All information that is exchanged with openAAL is either a resource or based on objects of type Resource.
Note that the Resource class is a typical value class which means that the creation of a Resource is actually not creating anything in the Context Manager date store. It just creates an object that represents a value that can be stored.
Dealing with Instances
To store Resources you can use the Context Manager interface.
frontDoorRes = contextManager.generateNewInstance(frontDoorRes, doorRes);
Other methods in the CM interface allow for queries of instances etc.
boolean isTrue = contextManager.getDefiningConcept(frontDoorRes) == doorRes;
boolean isAlsoTrue = contextManager.getInstances(doorRes).contains(frontDoorRes);
boolean isTrueAsWell = contextManager.isInstance(frontDoorRes);
Statements
The primary information type is a Statement. Statements consist of subject, predicate and object, like a sentence, and some additional meta information to capture timestamp, confidence, source etc. of the statement.
Statement doorhasBeenOpened =
new Statement(frontDoorRes,
Resource.fromURI(uriPropertyHasOpenState),
openRes,
MetaLiterals.getInstance());
Metaliterals can be used to define meta information about a Statement. Usually the default object is sufficient, though.
MetaLiterals likeCallingGetInstance = new MetaLiterals(1, ContextSource.OTHER, Integer.MAX_VALUE);
Again Statement is just a value object. Only by storing information into the Context Manager the statement is really "made", i.e. stored.
contextManager.storeNewStatement(doorhasBeenOpened);
JavaClassOntology API
Of course, all information that is stored into the CM must be ontology compliant. This means instance must instantiate classes that are specified in the ontology. Statements can only made with instances that are already stored and considering the (subject, property, object) triple the corresponding (subjectClass, property, objectClass) triple must be defined in the ontology. Complying to these restriction can be cumbersome with the CM interface. The javaClassOntology makes things easier and we highly recommend its usage.
Door frontDoor = Door.create(frontDoorRes);
//note that Open is a singleton class. Its only instance can be accessed by getInstance()
Open open = Open.getInstance();
OntologyStatement likedoorhasBeenOpened =
frontDoor.addHas_open_state(open, MetaLiterals.getInstance());
Kitchen myKitchen = Kitchen.create(Resource.fromURI(uriKitchen)); // or just Kitchen.create();
OpenAAL_Double temperature = OpenAAL_Double.create(21.5d);
myKitchen.addHas_temperature_in_celsius(temperature, MetaLiterals.getInstance());
Statement Pattern
Both interfaces, the javaClassOntology and the CM interface, can be used to query the CM with help of StatementPatterns. StatementPatterns have the same structure as Statement but can contain class instead of instance names for subject and/or object and they specify a Filter object that restricts MetaLiteral values.
StatementPattern doorsThatAreOpen = new StatementPattern (
doorRes, //here is the difference to a statement definition
Resource.fromURI(uriPropertyHasOpenState),
openRes,
Filter.getInstance());
StatementPatterns can be used to query the CM.Using the getAllStatements(...) method all Statements that match the pattern are returned.
Set
With getAllStatementsResolved(...) the CM applies conflict resolution on the date and tries to return only the statements that are currently expected to be in line with reality. In the current version of the CM this simply means: if there is a newer statement suggesting the door is closed this door's statement is omitted.
Set
Of course, the same can be done with the javaClassOntologyInterface in an easier manner. Like getting all doors that are currently open.
Set
Note the difference to identifying whether a specific door is open.
boolean isFrontDoorOpen =
(frontDoor.getHas_open_state(Open.class, Filter.getInstance()) != null);
Note: Open is a singleton Class, i.e. class and instance are the same.
Or if you just want to know the status of a specific door.
Open_State open_state = frontDoor.getHas_open_state(Filter.getInstance());
Note: The ontology says: Open_State can be Open or Closed
Kitchen kitchen1 = Kitchen.create();
Person create2 = Person.create();
Person peter = Person.create(Resource.fromURI("http://peter"));
new MetaLiterals(0.5, ContextSource.USER_INTERFACE, Integer.MAX_VALUE);
peter.addHas_email_address(OpenAAL_String.create("Peter@fzi.de"), MetaLiterals.getInstance());
Set
Set
Set
Door.getHas_device_state__Static(Open.class, Filter.getInstance());
Door door1 = Door.create();
door1.addIs_in_room(kitchen1, MetaLiterals.getInstance());
Set
kitchen1.getIs_in_room__Inverse(Filter.getInstance());
Publish Subscribe
It is also possible to communicate with the publish-subscribe pattern. You can register for StatementChanges via registering a EventListener object to the OSGi service registry. This is also called Whiteboardpattern. The example shows registering events indicating that doors in my kitchen are opened.
//First, get all doors in my kitchen
Set doorsInKitchen = myKitchen.getIs_in_room__Inverse(Door.class, Filter.getInstance());
//Second, create StatementPattern and register EventListener those doors
for (Door door : doorsInKitchen) {
final StatementPattern kitchenDoorOpens = new StatementPattern(
door.getInstanceResource(),
Door.HAS_OPEN_STATE,
Open.CLASS_RESOURCE,
Filter.getInstance());
osgiContext.registerService(EventListener.class.getName(), new EventListener() {
@Override
public EventPattern getEventPattern() {
//Return events that you are interested in
return new EventPattern(kitchenDoorOpens);
}
@Override
public void notifyAboutEvent(Event e) {
// do what you like
Statement postStatement = e.getPostStatement();
}
}, null);
}
You can also publish statements as events to the CM by using OSGi's EventAdmin.
Dictionary statement = new Hashtable();
statement.put(OpenAALConstants.EVENT_SUBJECT, frontDoor.getInstanceResource());
statement.put(OpenAALConstants.EVENT_PREDICATE, Door.HAS_OPEN_STATE);
statement.put(OpenAALConstants.EVENT_OBJECT, Open.getInstance().getInstanceResource());
statement.put(OpenAALConstants.EVENT_METALITERALS, MetaLiterals.getInstance());
org.osgi.service.event.Event osgiEvent =
new org.osgi.service.event.Event(OpenAALConstants.CONTEXT_EVENT_TOPIC, statement);
eventAdmin.postEvent(osgiEvent);
Uplifter
One main idea of openAAL is to allow for reasoning on context data. Simple Event-Condition-Action rules are directly supported by the interface. More complex ones can be accomplished by registering to events. The example shows how leaving can be derived from front door opening.
//First, create pattern indicating opening of front door
StatementPattern frontDoorOpened = new StatementPattern(
frontDoor.getInstanceResource(),
Door.HAS_OPEN_STATE,
Open.getInstance().getInstanceResource(),
Filter.getInstance());
//and personAtKitchen (frontDoor is in Kitchen, remember?
//other modeling would allow direct connection, for example, with person uses device).
StatementPattern personAtFrontDoor = new StatementPattern(
Person.CLASS_RESOURCE,
Person.IS_IN_ROOM,
myKitchen.getInstanceResource(), Filter.getInstance());
//Create uplifter; notice how the 'a' acts as a variable for intermediate values
Uplifter isLeavingUplifter = new SimpleRuleUplifter(
new PlaceholderPattern(frontDoorOpened, ' ', ' '),
new PlaceholderPattern(personAtFrontDoor, 'a', ' '),
new PlaceholderStatement( new Statement(
Person.CLASS_RESOURCE,
Person.IS_IN_ACTIVITY,
Activity.create().getInstanceResource(),
MetaLiterals.getInstance()), 'a', ' '), contextManager);
//Finally, activate the Uplifter
isLeavingUplifter.activate(osgiContext);
If now an statement matching to the PlaceholderPattern event is stored the Uplifter will be triggered and do its work
frontDoor.addHas_open_state(open, MetaLiterals.getInstance());
Procedural Manager Tutorial
Coming Soon
Ontology Creator Tutorial
Starting with openAAL version 1.1, the OntologyCreator is available. OntologyCreator helps you to easily create a new javaClassOntology interface from an existing owl-file.
To use the OntologyCreator you have just to:
- Install Ant version (tested for 1.8.0 or later, other versions might work too; see http://ant.apache.org/),
- Download the OntologyCreator tool (get it here: http://openaal.org/download),
- Unzip the OntologyCreator.zip and import the whole OntologyCreator folder into your eclipse as java-project,
- Go to the ant directory and open the createOntology.xml file with the editor,
- In line 4 set the owlFile property to reference your openAAL-compliant owl-file,
- Do a right-click on the createOntology.xml in eclipse and select “Run Asâ€->â€Ant Buildâ€,
- Copy the resulting jar/ org.openaal.sam.ontology.jar file in your target platform folder (usually mbs-equinox/bundles),
- If you use eclipse to run OSGi, Update the target platform in your OSGi –eclipse environment and select the org.openaal.sam.ontology in your run configuration.
Ontology Modelling Tutorial
openAAL is an ontology-driven system. This means there is one ontology file in the background from which interfaces and data-structures are derived.
Ontology, in computer science, means roughly a specification of knowledge that was developed by group rather than one person and that a computer can understand. In the case of openAAL the knowledge modeled in the openAAL ontology is mainly focusing on the AAL-domain but is also very application specific, i.e. the ontology captures what is needed to run certain use cases with openAAL and does not claim to capture the AAL domain in general.
The background ontology, the one from which interfaces and data-structures are derived, is presented in one single OWL-file (see openaal\mbs-equinox\bin\vms\jdk\OpenAALOntology.owl). OWL stands for Web Ontology Language. If you want to know more about ontologies as used in computer science or OWL, please take a look at http://www.w3.org/TR/owl-guide/. In order to get an openAAL-compliant OWL ontology you can use only a subset of OWL constructs and you have to use them in a particular way. This openAAL compliant use is described in the next sections by using the shipped OpenAALOntology.owl file and the Protégé ontology modeling tool 3.4.4.
On the picture you can see the OpenAALOntology.owl that has been shipped with openAAL version 1.1 opened in Protégé. The focus in the picture is on the OWL Classes tab. Notice the most abstract class directly below owl:thing is meta:OpenAALThing. This class must be defined and all other classes must subclass this class. Other classes that are mandatory are meta:OpenAALStatement, dt:OpenAAL-Datatype and all its subclasses. I repeat: Do not change these classes and how they relate to each other. Also, you cannot introduce new dt:OpenAAL-Datatype classes without changing large parts of openAAL code. So don’t do that.
Notice also the namespaces used here, like meta, a, dt, l, ht and p. On the Metadata tab you can actually see how they are defined, for example “a†translates to “http://www.openaal.org/SAM/Ontology/appointment#â€. Do not change the meta and dt namespaces. If you change the other namespaces or redistribute the classes or properties that belong to those, this will most likely break some of the openAAL test cases. It is no problem whatsoever to introduce new namespaces for new classes and properties that you define. Notice that these namespaces will be translated into java packages by the OntologyCreator tool, so that tha part of the java class ontology API that can be used to interact with classes belonging to the "http://www.openaal.org/SAM/Ontology/appointment#" namespace are to found in the org.openaal.sam.ontology.appointment package later on.
I decide to extend the given ontology, let’s say with a new class a:Medication-Appointment that is part of the a package and, of course, a subclass of a:Appointment just create it and make it a subclass of a:Appointment. Notice to be openAAL compliant classes cannot have more than one super class. So, it is not possible to establish an additional subclass relationship between m:Message and a:Medication-Appointment. Notice also that all other class related constructs are forbidden if you want to be openAAL-compliant. This means, for example, no unifications, no disjunctions, no nominals, no property restrictions etc.
What you can do, though, is comment a class with the rsdf:comment annotation property (see in picture) and also define a class as singleton class by using the isSingletonClass annotation property. If you want a class to be singleton just set it to true; leave a class without this property or assign false to isSingletonClass and it will me a normal class. Singleton classes define a class to have just exactly one instance. In the picture you see that a:Due is a singleton class which makes sense since it is a somewhat abstract concept where it does not make sense to have more than one instance. a:Medication-Appointment would probably not be singleton, since one can think of situations where you have different medication appointments for different days or medicines. Singleton classes and comments will also reflect in the javadoc comments and interfaces that are created with the OntologyCreator tool. In this ontology a:Due, a:Not-Due, ht:On, ht:Off, ht:Standby, ht:Open, ht:Closed, m:Yes, m:No, m:Confirmation, p:German, p:English are singleton classes.

Switching to second picture and the Protégé Property tab you can see the property definition. As in the case of classes all properties have to sub the has-no-super-prop property, all props must not have more than one super property and all classes can be commented by using rdfs:comment. The namespace of properties is the default namespace that translates to “http://www.openaal.org/SAM/Ontology#â€; needless to say, that you should not change this. As you can see in the picture with the example has-open-state, you must always define range and domain of the property explicitly; for has-open-state it is ht:Device and ht:Open-Status. Do not leave those fields blank for a property and do not enter more than one class into either field. Sometimes, when creating a new property, Protégé tries to infer the right domain or range class which is then displayed in a lighter yellow. If this happens you nevertheless have add the domain and range classes by hand, even in case it is the same class that was inferred. If you do not do that this will probably mess with xml-representation which will mess with the JenaAPI tool which will mess with the up the resulting interfaces and data structures (see more in FAQ section at www.openAAL.org for related problems).
To indicate a special kind of properties, you can mark a property as functional (see picture). Considering a statement (x, y, z, metaliterals1), where x is instance of Class A, z is instance of class B and y is a functional property, this means that at a given point in time, there cannot be any other statement (x, y, ?, metaliterals2), where ? is any instance other than z. For example, my office door can only be open or closed at one point in time or I can be at only one location at one point in time. Contrary, is-connected-to-room is not functional, since it makes sense to have the corridor connected to living room and bedroom at one point in time.
As you might suspect, functional properties do reflect in interfaces and data structures that are inferred and, yes, the isSingletonClass annotation property has to be ignored for properties. As with classes, if you want to be openAAL-compliant, do not use other OWL constructs, like cardinality constraints, inverse-functional, symmetry, transitivity, inversePropertyOf etc. On a last note, the interfaces that can automatically be created with the OntologyCreator tool contain the possibility to access properties inversely.

Related to both classes and properties, you can actually create your own annotation data type properties to convey additional information. One scenario could be the avid ontology manager that supports openAAL systems. He or she might want to establish a isDeprecated property, so that interfaces created by the OntologyCreator are automatically marked as deprecated when they belong to certain properties of classes that have a isDeprecated annotation property set. This can easily be done by introducing a new isDeprecated annotation data type property that takes Boolean values. All annotation data type properties that are set for a certain class of property can be utilized within the OntologyCreator tool to adapt the creation of interfaces to individual needs (see OntologyCreator section at www.openAAL.org).