|
16 | 16 |
|
17 | 17 | The IoTAgent Library provides an expression language for measurement transformation, that can be used to adapt the |
18 | 18 | information coming from the South Bound APIs to the information reported to the Context Broker. Expressions in this |
19 | | -language can be configured for provisioned attributes as explained in the Device Provisioning API section in the main |
20 | | -README.md. |
| 19 | +language can be configured for provisioned attributes as explained in the Device Provisioning API section in the |
| 20 | +main README.md. |
21 | 21 |
|
22 | 22 | ## Measurement transformation |
23 | 23 |
|
@@ -301,3 +301,94 @@ two possible types of expressions: Integer (arithmetic operations) or Strings. |
301 | 301 | - update (of type "Boolean"): true -> ${@update * 20} -> ${ 1 \* 20 } -> $ { 20 } -> $ { "20"} -> False |
302 | 302 | - update (of type "Boolean"): false -> ${@update * 20} -> ${ 0 \* 20 } -> $ { 0 } -> $ { "0"} -> False |
303 | 303 | - update (of type "Boolean"): true -> ${trim(@updated)} -> ${trim("true")} -> $ { "true" } -> $ { "true"} -> True |
| 304 | + |
| 305 | +## JEXL Based Transformations |
| 306 | + |
| 307 | +As an alternative, the IoTAgent Library supports as well [JEXL](https://github.com/TomFrost/jexl). |
| 308 | +To use JEXL, you will need to either configure it as default |
| 309 | +language using the `defaultExpressionLanguage` field to `jexl` |
| 310 | +(see [configuration documentation](installationguide.md)) or configuring |
| 311 | +the usage of JEXL as expression language for a given device: |
| 312 | + |
| 313 | +``` |
| 314 | +{ |
| 315 | + "devices":[ |
| 316 | + { |
| 317 | + "device_id":"45", |
| 318 | + "protocol":"GENERIC_PROTO", |
| 319 | + "entity_name":"WasteContainer:WC45", |
| 320 | + "entity_type":"WasteContainer", |
| 321 | + "expressionLanguage": "jexl", |
| 322 | + "attributes":[ |
| 323 | + { |
| 324 | + "name":"location", |
| 325 | + "type":"geo:point", |
| 326 | + "expression": "..." |
| 327 | + }, |
| 328 | + { |
| 329 | + "name":"fillingLevel", |
| 330 | + "type":"Number", |
| 331 | + "expression": "..." |
| 332 | + } |
| 333 | + ] |
| 334 | + } |
| 335 | + ] |
| 336 | +} |
| 337 | +``` |
| 338 | + |
| 339 | +In the following we provide examples of using JEXL to apply transformations. |
| 340 | + |
| 341 | +### Quick comparison to default language |
| 342 | + |
| 343 | +* JEXL supports the following types: Boolean, String, Number, Object, Array. |
| 344 | +* JEXL allows to navigate and [filter](https://github.com/TomFrost/jexl#collections) objects and arrays. |
| 345 | +* JEXL supports if..then...else... via [ternary operator](https://github.com/TomFrost/jexl#ternary-operator). |
| 346 | +* JEXL additionally supports the following operations: |
| 347 | + Divide and floor `//`, Modulus `%`, Logical AND `&&` and |
| 348 | + Logical OR `||`. Negation operator is `!` |
| 349 | +* JEXL supports [comparisons](https://github.com/TomFrost/jexl#comparisons). |
| 350 | + |
| 351 | + |
| 352 | +For more details, check JEXL language details |
| 353 | +[here](https://github.com/TomFrost/jexl#all-the-details). |
| 354 | + |
| 355 | +### Examples of expressions |
| 356 | + |
| 357 | +The following table shows expressions and their expected outcomes taking into |
| 358 | +account the following measures at southbound interface: |
| 359 | + |
| 360 | +* `value` with value 6 (number) |
| 361 | +* `name` with value `"DevId629"` (string) |
| 362 | +* `object` with value `{name: "John", surname: "Doe"}` (JSON object) |
| 363 | +* `array` with value `[1, 3]` (JSON Array) |
| 364 | + |
| 365 | + |
| 366 | +| Expression | Expected outcome | |
| 367 | +|:--------------------------- |:----------------------- | |
| 368 | +| `5 * value` | `30` | |
| 369 | +| `(6 + value) * 3` | `36` | |
| 370 | +| `value / 12 + 1` | `1.5` | |
| 371 | +| `(5 + 2) * (value + 7)` | `91` | |
| 372 | +| `value * 5.2` | `31.2` | |
| 373 | +| `"Pruebas " + "De Strings"` | `"Pruebas De Strings"` | |
| 374 | +| `name + "value is " +value` | `"DevId629 value is 6"` | |
| 375 | + |
| 376 | +Support for `trim`, `length`, `substr` and `indexOf` transformations was added. |
| 377 | + |
| 378 | +| Expression | Expected outcome | |
| 379 | +|:--------------------------- |:----------------------- | |
| 380 | +| <code>" a "|trim</code> | `a` | |
| 381 | +| <code>name|length</code> | `8` | |
| 382 | +| <code>name|indexOf("e")</code>| `1` | |
| 383 | +| <code>name|substring(0,name|indexOf("e")+1)</code>| `"De"` | |
| 384 | + |
| 385 | +The following are some expressions not supported by the legacy expression |
| 386 | +language: |
| 387 | + |
| 388 | +| Expression | Expected outcome | |
| 389 | +|:----------------------------------- |:----------------------- | |
| 390 | +| `value == 6? true : false` | `true` | |
| 391 | +| <code>value == 6 && name|indexOf("e")>0</code> | `true` | |
| 392 | +| `array[1]+1` | `3` | |
| 393 | +| `object.name` | `"John"` | |
| 394 | +| `{type:"Point",coordinates: [value,value]}`| `{type:"Point",coordinates: [6,6]}` | |
0 commit comments