Working with an endpoint - GideonLeGrange/panstamp-java GitHub Wiki

For application developers, endpoints are likely going to be the most directly useful and important constructs. An Endpoint is a programmer friendly interface on top of Register that adds meta data from the panStamp device defintions, allowing us to access endpoints by name, associate units with values, convert and scale data to match the units, and read and set values using convenient types.

Unlike the other three classes in the hierarchy (Network, PanStamp and Register), Endpoint is an interface, with several implementations.

In [this](Working with a register) section we saw how to find or receive endpoints.

Get endpoint information

We can retrieve the name, type and units (if any) of an endpoint like this:

    String name = ep.getName();
    Endpoint.Type type = ep.getType();
    List<String> units = ep.getUnits();

All of these properties are defined by the device definition, and are read-only.

Read and set endpoint value

We can test if an endpoint has a value set by using hasValue:

java boolean hasData = ep.hasValue();


The value for an endpoint can be retrieved by calling ```getValue()```.  Endpoints are generically typed, so developers can write type-safe code without casting. Here is how to use ```getValue()```, where whe know that endpoint "Temperature" will return a double:

```java
 	Endpoint<Double> ep = reg.getEndpoint("Temperature");
	double temp = ep.getValue();

Setting endpoint values work as expected, by using setValue(). Let's say we have an endpoint which switches a light on and off:

    Endpoint<Boolean> light0 = reg.getEndpoint("Light switch");
    light0.setValue(true); // switch the light on

Or we can have a volume control which works with volume as a percentage:

    Endpoint<Double> volume = reg.getEndpoint("Volume");
    volume.setValue(50.0); // set volume to 50%

Request an endpoint value from a panStamp

You can request the latest value for a endpoint from a panStamp. This will generate a SWAP Query message for the register containing the endpoint, and if the panStamp is listenening for queries or updates (isn't in sleep mode), it will respond with a register value, which will update the endpoint values. This update will generate a valueReceived event (see below).

	ep.requestValue();

Handling register events

It is possible to attach a listener interface to an Endpoint to receive notification of endpoint events. The endpoint will call it's event handlers when a value is received from the network for the endpoint.

Note that like Endpoint, EndpointListener is typed.

The following examples shows how to implement EndpointListener to receive this event:

    ep.addListener(new EndpointListener<Boolean>() {

        @Override
        public void valueReceived(Endpoint<Boolean> ep, Boolean value) {
            System.out.printf("Light was switched %s\n", value ? "on" : "off");
        }
    }
    );

Convenience class

For completeness sake, we provide a convenience implementation of EndpointListener, called AbstractEndpointListener.

Units

Some endpoints support units which are defined in their device definitions. A very good example is a "Temperature" endpoint which contains a conversion from the received temperature to Celcius (C), Farenheit (F) or Kelvin (K). The partial XML device defnition can look something like this:

      <endpoint name="Temperature" type="num" dir="inp">
        <position>0</position>
        <size>2</size>
        <units>
          <unit name="C" factor="0.1" offset="-50"/>
          <unit name="F" factor="0.18" offset="-58"/>
          <unit name="K" factor="0.1" offset="223.15"/>
        </units>
      </endpoint>

By default, when we call getValue() on an endpoint, the library will use the first unit specified in the device defintion to convert the received value to a scaled value. The same conversion is applied to values sent to the valueReceived event. For setValue() the conversion is applied in reverse. If a defintion only specifies one unit, that unit is always used. If a definition specifies no units, no conversion is done.

In the example above, the default would be C (Celcius).

We can specify which unit we wish getValue(), setValue() and valueReceived() to use by setting it with setUnit():

	ep.setUnit("F"); // we'er American, let's use Farenheit

We can also retrieve the currently selected unit by using getUnit():

  System.out.printf("It is %.1f degrees %s in the outhouse\n", ep.getValue(), ep.getUnit()); // print value with unit

We can read and write endpoint values with a different unit than the currently set one by explicitly calling getValue() and setValue() with a unit parameter. Here is a good example:

 	Endpoint<Double> ep = reg.getEndpoint("Temperature");
    System.out.printf("It is %.1f C which is %.1f F or %.1f K", ep.getValue("C"), ep.getValue("F"), ep.getValue("K"));

If our volume control example allows us to set the volume in dB as well, we can do this:

    Endpoint<Double> volume = reg.getEndpoint("Volume");
    volume.setValue("dB", 70.0); 
⚠️ **GitHub.com Fallback** ⚠️