Home
Categories
Dictionary
Glossary
Download
Project Details
Changes Log
What Links Here
FAQ
License

Developing a UA



This article explains how to develop a User Application usable in the UA application built-in plugin.

Overview

A UA is a subclass of AbstractFunctionalUA.

The following methods are useful to override:

Default fields

Your AbstractFunctionalUA has these useful fields, automatically created by the UAAppli Application:
  • api: the ARINC 661 client API to communicate with the ARINC661 server. This is an instance of the arinc661.client.api.StateFullAPI interface
  • runtimeAPIHelper: the helper class allowing to use the simpler Functional UA runtime API to communicate with the ARINC661 server. This is an instance of the A661RuntimeAPI interface
  • logger: the framework logger
  • module: the UAAppli Application module

init

Main Article: init EntryPoint

Overriding the init() method allows to perform code at the module initialization.

You must be aware that the module will only be able to access properties and services when it has been initialized. For example the following code will throw an exception because the module won't be created yet:
      public class MyUAAppli extends AbstractFunctionalUA {
         private ServiceInstance sendService = null;
         public MyUAAppli() {
           this.sendService = module.getService("sendService");
         }
      }
Instead you can perform:
      public class MyUAAppli extends AbstractFunctionalUA {
         private ServiceInstance sendService = null;
         public MyUAAppli() {
         }

         public init() {
           this.sendService = module.getService("sendService");
         }
      }
Also bear in mind that you won't be able to send anything to the server at this time. You will only be able to send buffers to the server after the connected method has been called.

preConfigure

Overriding the preConfigure() method allows to define properties programmatically. For example, the following code adds a param property.
      module.addPropertyType("params", URL.class, null, false);

Using the ARINC 661 API


There are two ways to use the ARINC 661 API:

connected

Main Article: start EntryPoint

Overriding the start() method allows to perform code at the module start. You must be aware that:
  • The module will only be able to ne notified from services and invoke service at this time
  • The ARINC 661 server will only be connected at this time

Subscribing to Services

The FunctionalUA.subscribe(ServiceInstance) method is called when the User Application is notified from one of the Services on which the UA is subscribed to. Note that only the services for which the User Application is subscribed to will fire the method:
  • If there is only one User Application for the UA (using the uaImpl and uaPath properties), then this User Application is subscribed for all the services for which the UA module is subscribed to
  • If we used the uaConfig property, then only the services for which the User Application is explicitly subscribed will fire the method


Several methods are provided in the AbstractFunctionalUA class to get the values of the datas in the Service:
  • Some methods do not take as argument the service name, and they will look for a Data in any Service
  • Some methods take as argument the service name, those will look for values for the service which is explictly specified

Detecting if a data value has changed

There are two methods to detect if a Data value has changed:

Getting a data value

Main Article: Data manipulation

There are two sets of methods to get the value of a Data:
  • The getxxxValue(String) methods return the value of a Data in a specified type, if there is only one Service which has a Data with this name[2]
    This will not work correctly if two Services have two different Datas of the same name
    . Note that if there is no data of this name, and more than one service having this data, the method will return a default value
  • The getxxxValue(String, String) methods return the value of a Data in a specified type for the specified Service name
  • The getxxxValue(String, , String, String) methods return the value of a Data in a specified type for the specified Service uri and name


For example:

Examples

      // return the float value of a data named "myDataName"
      // if there is no data for all services named "myDataName", or more than one service having a data with this name,
      // the method will return 0
      float valueF = getFloatValue("myDataName");

      // return the int value of a data named "myDataName", for the Service "myService" (with no namespace)
      // if there is no data for the service named "myDataName" the method will return 0
      int valueI = getIntValue("myService", "myDataName");

      // return the boolean value of a data named "myDataName", for the Service "myService" (with namespace "http://my.namespace")
      // if there is no data for the service named "myDataName" the method will return false
      boolean b = getBooleanValue("http://my.namespace", "myService", "myDataName");

Formatting a numeric data as a String

Several methods allow to format a numeric data as a String:

Examples

      // **** First Example ***
      // format the value of a numeric data named "myDataName". The format will keep the int part of the value,
      // and the two first decimals
      // if there is no data for all services named "myDataName", or more than one service having a data with this name,
      // the method will return an empty String
      // if the data is not numeric, the method will just return the data converted to a String

      // return the formatted String value of a data named "myDataName", for the Service "myService" (with no namespace)
      // if there is no data for the service named "myDataName" the method will return an empty String
      // if the data value is 5.2346, the result will be "5.23"
      String formattedValue = formatValueAsString("myDataName", "%.2f");

      // **** Second Example ***
      String formattedValue = formatValueAsString("myDataName", "%08d");

      // return the formatted String value of a data named "myDataName", for the Service "myService" (with no namespace)
      // if there is no data for the service named "myDataName" the method will return an empty String
      // if the data value is 55555, the result will be "00005555"

Setting a data value

Main Article: Data manipulation

To set the value for a Data, you should first get the Data of a specified name:

Then you can set the value of this Data through the Data class. For example to set the value of a Data as a float:

Examples

For the defaultSubscribeService:
      public void subscribe(ServiceInstance service) {
        if (hasChanged("value")) {
          String value = getStringValue("value");
          api.setWidgetParameter(LAYER, LABEL, ARINC661.A661_STRING, value);
          api.sendAll();
        }
      }
For a specified service:
      public void subscribe(ServiceInstance service) {
        if (hasChanged("publishedService", "value")) {
          String value = getStringValue("publishedService", "value");
          api.setWidgetParameter(LAYER, LABEL, ARINC661.A661_STRING, value);
          api.sendAll();
        }
      }

Invoking Services

It is possible to invoke Services using the ServiceInstance.invoke() method.

For example:
      service.setDataBooleanValue("event", isSelected);
      service.invoke();

Example

In the following example, the "event" service with the associated state of the button is invoked when th user click on the button.

      public void init() {
        this.eventService = (SendEventServiceInstance) module.getService("event");
        api.addWidgetEventListener(LAYER, TOGGLE_BUTTON, new ARINCEventListener() {
          public void eventReceived(ARINCEvent evt) {
            WidgetEvent widgetEvt = (WidgetEvent) evt;
            try {
              boolean isSelected = ((Boolean) widgetEvt.getValues().get(0));
              eventService.setDataBooleanValue("event", isSelected);
              eventService.invoke();
            } catch (ARINCRuntimeException ex) {
              logger.error(module, ex.getMessage());
            }
          }
        });
      }

Showing or hiding the displays

The AbstractFunctionalUA.hideServerFrame() allows to hide the displays. The AbstractFunctionalUA.showServerFrame() allows to show them back.

Notes

  1. ^ It is the case when a publish Service is called cyclically for the UA Application, for example: <cyclic service="position" frequency="100ms" />
  2. ^ [1] [2] [3] [4] This will not work correctly if two Services have two different Datas of the same name

See also


Categories: builtin-applis | uaappli

Copyright 2017-2020 Dassault Aviation. All Rights Reserved. Documentation and source under the LGPL v3 licence