Skip to content
Carsten Stocklöw edited this page Apr 26, 2018 · 7 revisions

Table of Contents

Description

The Utility API Library is a quick way of coding universAAL applications. The library has no other dependencies than the universAAL Middleware, and because it is just a library and not a bundle, it can be run in whatever (Java) uAAL Container.

You may wonder how this Utility API relates to the Annotated API. Well, it practically does the same: assisting you in using uAAL by writing less code, but in a different approach. The Utility API is just Java code, it does not use annotations. You can consider it as an API that wraps the Native API, encapsulating its features into shorter methods, reduced classes and defaulted features. This also means that you can use pieces of it directly into the Native API at different levels.

Here it is assumed that you already know at least the basic technical concepts of universAAL. It is also intended to get you started with the Utility API, but for delving into details it´s better to read the Javadoc whenever you need it. The Utility API Library contains a lot of verbose Javadoc with examples to which you can refer in case of doubt. You can access it directly here. Perform "mvn javadoc:javadoc" if you want to to generate it locally.

Installation

If you want to use, you just need to add this artifact to your app dependencies and then install it in your running environment:

  • org.universAAL.support/utilities.api/x.y.z
Because it´s not a bundle, remember to precede "wrap" in the run configurations, and you can leave the version blank to use the latest one. The sources can be found in https://github.com/universAAL/utilities/tree/master/utilities.api.

Basic Helper API

You can start using universAAL features with the simplest API included in the Utility: The UAAL Helper class. Just create an instance with the right uAAL Module Context and you´ll be ready to use the basic methods:

 // Obtain the Module Context, for instance from an OSGi Bundle Context bcontext
 ModuleContext context = uAALBundleContainer.THE_CONTAINER.registerModule(new Object[] { bcontext });
 
 // Instantiate the UAAL helper
 UAAL u = new UAAL(context);

You can now use the u instance throughout your app to perform uAAL operations. When your application is supposed to stop, remember to free the uAAL resources by calling:

 u.terminate();

Send a Context Event

The UAAL Helper lets you send Context Events into the Context Bus directly. Assuming you already have the Context Event instance you want to send, all you need to do is:

 u.sendC(event);

If you are wondering how the event instance is created, well, there is no simplification for that because the Native API is already simple. You should head to Reference Documentation to find out.

Subscribe to Context Events

In the Native API you would need to implement your own extension of ContextSubscriber, with its subscription and its handleContextEvent method. The UAAL Helper nails it to just those two items whenever you want to subscribe for events. Assuming you already have the Context Event Patterns you want to subscribe to:

 u.subscribeC(ceparray, new ICListener() {
     public void handleContextEvent(ContextEvent event) {
    // Do something with the received event
     }
 });

As you see an interface ICListener is used, which performs the only thing useful from a ContextSubscriber: the handleContextEvent method, which is passed the received event. If you want to know how to make the Context Event Patterns that form that ceparray array, you can look into Reference Documentation or use the Utility API class Pattern.

Call a Service

Just like with Context Events, UAAL Helper lets you send Service Requests directly to the Service Bus, but you also get the Service Response in return. If you already have the Service Request prepared you just do:

 ServiceResponse r = u.callS(srequest);

You don´t gain too much in comparison to the Native API in this case: you just avoid having to create a DefaultServiceCaller. In any case the complex thing here has always been creating that srequest ServiceRequest and handling the ServiceResponse. But Utility API can help you with that with its Service APIs. You will notice that this method is the only one of UAAL that returns a value, because service calls are the only ones that can have a synchronous response.

Provide a Service

Very much like you subscribe for events with UAAL Helper, you can provide ServiceProfiles and handle the calls to them, without having to extend ServiceCallee on your own. As long as you already have your ServiceProfiles defined you can do:

 u.provideS(sprofilesarray, new ISListener() {
     public ServiceResponse handleCall(ServiceCall s) {
    // Check the call URI, do the right thing and return your response
     }
 });

Again we are only interested in the handleCall method of the ServiceCallee, and we implement it within a simple ISListener. However the hard thing here is defining the provided ServiceProfiles that go into the sprofilesarray. The Utility API can help you too, by using its Service API.

Handle User Interaction

Finally if you want to show something to the user and handle its response, with UAAL Helper it´s as simple as the above methods, assuming that you already have the UI request with the output you wan to show:

 u.requestUI(uireq, new IUIListener() {
     public void handleUIResponse(UIResponse r) {
    // Read the user response, and make new requests if you like...
     }
 });

You probably guessed that if you want to create that uireq UIRequest you can take advantage of the Utility API and its UI classes. And again you just use a simple IUIListener interface instead of extending the Native UICaller. However in this case the behaviour of the UAAL Helper is more limited because it doesn´t handle calls from Main Menu and it is a bit tricky with multiple requests. Refer to the Javadoc for details.

Context Utility API

The rest of Utility APIs are specialized in each of the uAAL buses: Context, Service and UI. They all have their classes divided into different levels of "complexity", depending on how close they are to the Native API. Each level builds on top of the previous one.

Defining Context Event Patterns

The lowest level has a class that lets you crate simple Context Event Patterns by directly specifying the kind of Subject, Predicate and Object you want to filter.

 // Pattern for events with [Subject: User, Predicate: hasLocation]
 ContextEventPattern cep = new Pattern(User.MY_URI, User.PROP_PHYSICAL_LOCATION, null);

Defining Context Provider information

When you create your own Context Publisher you always need an instance of ContextProvider. The next level of Context Utility API lets you create a simple one in one line, with or without specific provided Context Events (check the Javadoc).

 // A Gauge provider that publishes events with [Subject: User, Predicate: hasLocation]
 ContextProvider cpinfo = new Provider("http://ontology.universAAL.org/Example.owl#MyProvider",
    ContextProviderType.gauge,
    User.MY_URI, User.PROP_PHYSICAL_LOCATION, null));

Creating a Context Publisher

If you want to go straight into creating a Context Publisher, instead of extending the Native API one you can extend the simple one from the Context Utility API, which is easier (You can also instantiate UtilPublisher directly, if you think that´s enough!). Then you can create it quickly with:

 // MySimplePublisher extends UtilPublisher from Utility API. It will publish events with [Subject: User, Predicate: hasLocation]
 ContextPublisher cpublisher = new MySimplePublisher(context,
    "http://ontology.universAAL.org/Example.owl#MyProvider",
    ContextProviderType.gauge,
    User.MY_URI, User.PROP_PHYSICAL_LOCATION, null));

Creating a Context Subscriber

And in the same way you can create a Context Subscriber by extending the Context Utility API´s simple subscriber. You can argue that it´s the same as extending the native ContextSubscriber, but the advantage is that you can specify the subscription directly in the constructor, like in the above examples:

 public class SubscriberExample extends UtilSubscriber{
 
     protected SubscriberExample(ModuleContext context, String subjTypeURI, String predicate, String objTypeURI) {
    super(context, subjTypeURI, predicate, objTypeURI);
     }
 
     public void handleContextEvent(ContextEvent event) {
     // Called when received events
     }
     
     public void communicationChannelBroken() {
         // Called when bus is lost
     }
 }

Service Utility API

The Service Utility API gives you all the tools you need to easily compose requests, profiles, and default callers and callees.

Define a Service Profile

A Service Profile in short is a collection of arguments that all together describe an operation. Each argument is defined by a property path from the root service concept and a "leaf" at the end of that path that is suposed to behave in some way. The Service Utility API lets you compose profiles this way:

 // This profile dims a certain lamp to a level: An Variable Input of type LightSource, and a Change Effect on its Brightness
 // Create the profile from the root service concept
 Profile prof2=new Profile(new Lighting(SERVICE_TURN_DIM));
 // Put the first argument, as Variable Input, in the path [Lighting] > PROP_CONTROLS  
 prof2.put(Path.at(Lighting.PROP_CONTROLS),
    Arg.in(LightSource.MY_URI),
    INPUT_LAMP_URI);
 // Put a second argument, as Change Effect, in the path [Lighting] > PROP_CONTROLS > [LightSource] > PROP_SOURCE_BRIGHTNESS
 prof2.put(Path.at(Lighting.PROP_CONTROLS).to(LightSource.PROP_SOURCE_BRIGHTNESS),
    Arg.change(TypeMapper.getDatatypeURI(Integer.class)),
    INPUT_BRIGHTNESS);
 // Finally extract the profile
 profiles[2]=prof2.getTheProfile();

As you can see, property paths are easily defined with the Service Utility API Path class. The leaf at the end of that path can as well be easily created with the Arg class, or any of the several Value subclasses, from the API.

Define a Service Request

Because Service Requests are supposed to match a Profile you can use almost the same code you used for the Profile and make sure they will match:

 // This request wants to dims a certain lamp to a level: An Variable Input of type LightSource, and a Change Effect on its Brightness
 // Create the request from the root service concept
 Request req = new Request(new Lighting());
 // Put the first argument, the desired light as Variable Input, in the path [Lighting] > PROP_CONTROLS
 req.put(Path.at(Lighting.PROP_CONTROLS),
    Arg.in(new LightSource(selected)));
 // Put second argument, desired value as Change Effect, in path [Lighting] > PROP_CONTROLS > [LightSource] > PROP_SOURCE_BRIGHTNESS
 req.put(Path.at(Lighting.PROP_CONTROLS).to(LightSource.PROP_SOURCE_BRIGHTNESS),
    Arg.change(val));

As you can see the code is practically the same, only that you don´t use URI (e.g. INPUT_LAMP_URI in the profile) when defining the arguments, and that you use the actual values you want for them. The created Request can be directly used in the call.

Using typical Requests and Profiles

The next level in the Service Utility API has some helper classes that contain typical requests and profiles for the most used service interactions: Sensors, Actuators and Editors. A Sensor has a GET VALUE service, an Actuator has GET VALUE, SET ON, and SET OFF, and finally an Editor has GET, ADD, CHANGE and REMOVE services. For instance if you already have an instance representing a LightSource you control, you can get all profiles with:

 ServiceProfile[] allprofiles = UtilActuator.getServiceProfiles(
    "http://ontology.universAAL.org/SimpleApp.owl#", Lighting.MY_URI, mylight);

To call those services you can get the matching requests the same way. For instance for calling the SET ON profile, if you already have an instance of the light with the same URI:

 ServiceRequest req = UtilActuator.requestSetOn(Lighting.MY_URI, mylight);

Implementing typical Callees

The Service Utility API provides you with typical implementations of Actuators, Sensors and Editors using the above premade profiles. If you intend to implement one of those services, you can do it easily by extending one of those classes. For instance, to implement your own Actuator class:

 public class MyActuatorCallee extends UtilActuatorCallee{
 
    public MyActuatorCallee(ModuleContext context, String namespace, OnOffActuator actuator) {
    super(context, namespace, actuator);
    }
 
    public boolean executeGet() {
    // Called when GET STATUS profile is requested ...
    }
 
    public boolean executeOff() {
    // Called when TURN OFF profile is requested ...
    }
 
    public boolean executeOn() {
    // Called when TURN ON profile is requested ...
    }
 }

UI Utility API

The UI Utility API comes in handy when you want to build your User Interfaces to be sent through UI Bus, and gives you helper classes in above levels to deal with them.

Composing User Interfaces

Instead of first creating a Form and then a UI Request as you would in the Native API, you can do it all together with the UI Utility API simple classes. Imagine that for a given user you want to create a Dialog for dimming a Light selectable from a list:

 // Create dialog for the user
 Dialog d=new Dialog(sampleUser, "My Title");
 // Add a selector from a list 
 SelectOne one=new SelectOne(PROP_PATH_SELECTED_LAMP, "Lamps");
 for(int i=0; i<lights.length;i++){
     one.addOption(((LightSource)lights[i]).getURI());
 }
 d.add(one);
 // Add a range selector for the dimmer
 d.add(Forms.range(PROP_PATH_DIM, "Dimmer", 0, 100));
 // Add a submit to execute, which requires the above inputs
 SubmitCmd sub4=new SubmitCmd(REF_DIM, "Dim");
 sub4.addMandatoryInput(one);
 sub4.addMandatoryInput(range);
 d.addSubmit(sub4);

This Dialog can be sent to the bus because it already is a UIRequest. As you see you can use the class Forms for an even simpler way of creating UI controls. But these are not compatible with Native API and are only for use with Utility API.

Implementing a typical UI Caller

In the Native API you would need to extend UICaller to handle User Interaction. But if you extend the simple UICaller of the UI Utility API instead it will be easier for you, as it also handles the button in the Main Menu. It would look like this:

 public class MyUICaller extends UtilUICaller{
 
    protected UIExample(ModuleContext context, String namespace, String url, String desc) {
    super(context, namespace, url, desc);
    }
 
    public void executeStartUI(Resource user) {
    // Called when initial dialog is requested by user -> show main dialog
    }
 
    public void handleUIResponse(UIResponse input) {
    // Called when user has completed a dialog
    }
 }

Examples

There are examples of real working code on how to use the features of the Utility API: