Apama 10.7.2 | Connecting Apama Applications to External Components | Standard Connectivity Plug-ins | The Cumulocity IoT Transport Connectivity Plug-in | Using measurements | Creating a new measurement
 
Creating a new measurement
Measurement m := new Measurement;
m.type := <MEASUREMENT_TYPE>;
m.source := <SOURCE>;
m.time := currentTime;
MeasurementValue mv := new MeasurementValue;
mv.value := 1.0;
mv.unit := "V";
dictionary<string, MeasurementValue> dict := {"voltage": mv};
m.measurements.add(m.type, dict);
send m to Measurement.SEND_CHANNEL;
Where
*<SOURCE> is the source of the measurement (same as the ManagedObject identifier).
*<MEASUREMENT_TYPE> is the type of the measurement. For example, c8y_VoltageMeasurement.
Sending measurements requesting response and setting headers
When creating a new object, it is recommended that you use the withChannelResponse action. This allows your application to receive a response on completion on the Measurement.SUBSCRIBE_CHANNEL channel. You will need to subscribe to the Measurement.SUBSCRIBE_CHANNEL channel first. The response can be one of two possibilities:
*ObjectCommitted
This includes the reqId which is the identifier of the original request, the Id which is the identifier of the newly created or updated object, and the actual object in JSON form.
*ObjectCommitFailed
This includes the reqId which is the identifier of the original request, the statusCode which is the HTTP status code of the failure, and the body which is the content of the response from the API (this might be in HTML format).
When using withChannelResponse, it allows the ability to set headers. This can be used, for example, to determine what processing mode Cumulocity IoT will use as shown in the example below.
It is worth noting that when using withChannelResponse for measurements, it is not able to achieve the same throughput as sending them without a response. As they are not batched into a single HTTP request, there are just individual create/update requests sent to Cumulocity IoT.
Example of creating a measurement:
using com.apama.cumulocity.Measurement;
using com.apama.cumulocity.MeasurementValue;

using com.apama.cumulocity.ObjectCommitFailed;
using com.apama.cumulocity.ObjectCommitted;

monitor Test {
string deviceId; // Where this is populated from the actual device Id.
float timestamp; // Where this is populated from the timestamp of the
// device.

action onload {

monitor.subscribe(Measurement.SUBSCRIBE_CHANNEL);
Measurement mo := new Measurement;
mo.type := "test_measurement";
mo.source := deviceId;
mo.time := timestamp;

//Create a Measurement with two Measurement fragments.
MeasurementValue mv1 := new MeasurementValue;
mv1.value := 10.2;
mv1.unit := "km/hr";

MeasurementValue mv2 := new MeasurementValue;
mv2.value := 11.7;
mv2.unit := "km/hr";

dictionary<string, MeasurementValue> dict :=
{"speedX": mv1, "speedY": mv2};
mo.measurements.add("c8y_speed", dict);

integer reqId := com.apama.cumulocity.Util.generateReqId();
// Create a new Measurement in Cumulocity, ensuring that a response is
// returned
// and the processing mode, indicating how to process the request,
// sent to Cumulocity is Transient.
send mo.withChannelResponse(reqId, { "X-Cumulocity-Processing-Mode":
"Transient" }) to Measurement.SEND_CHANNEL;

// If the Measurement creation succeeded do something with the returned
// object or id.
on ObjectCommitted(reqId=reqId) as c and not
ObjectCommitFailed(reqId=reqId){
log "New measurement successfully created " + c.toString() at INFO;
}

// If the Measurement creation failed, log an error.
on ObjectCommitFailed(reqId=reqId) as cfail and not
ObjectCommitted(reqId=reqId){
log "Creating a new event failed " + cfail.toString() at ERROR;
}
}
}