Skip to content

Commit 6e53be5

Browse files
committed
Add gen-mapper system tests
Signed-off-by: Didier Wenzek <didier.wenzek@free.fr>
1 parent a1888d2 commit 6e53be5

File tree

6 files changed

+176
-1
lines changed

6 files changed

+176
-1
lines changed

ci/build_scripts/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ BUILD_WITH="${BUILD_WITH:-zig}"
101101
COMMON_BUILD_OPTIONS=(
102102
"--release"
103103
)
104-
TOOLCHAIN="${TOOLCHAIN:-+1.78}"
104+
TOOLCHAIN="${TOOLCHAIN:-+1.82}"
105105
# Note: Minimum version that is supported with riscv64gc-unknown-linux-gnu is 2.27
106106
GLIBC_VERSION="${GLIBC_VERSION:-2.17}"
107107
RISCV_GLIBC_VERSION="${RISCV_GLIBC_VERSION:-2.27}"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export function process (timestamp, message) {
2+
let payload = JSON.parse(message.payload)
3+
if (!payload.time) {
4+
payload.time = timestamp.seconds + (timestamp.nanoseconds / 1e9)
5+
}
6+
7+
return [{
8+
topic: message.topic,
9+
payload: JSON.stringify(payload)
10+
}]
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
input_topics = ["te/+/+/+/+/m/+"]
2+
3+
stages = [
4+
{ filter = "add_timestamp.js" },
5+
{ filter = "te_to_c8y.js", meta_topics = ["te/+/+/+/+/m/+/meta"] },
6+
{ filter = "set_topic.js", config = { topic = "gen-mapper/c8y" } }
7+
]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export function process (timestamp, message, config) {
2+
return [{
3+
topic: config?.topic || "te/error",
4+
payload: message.payload
5+
}]
6+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/// Transform:
2+
///
3+
/// ```
4+
/// [te/device/main///m/example] {
5+
/// "time": "2020-10-15T05:30:47+00:00",
6+
/// "temperature": 25,
7+
/// "location": {
8+
/// "latitude": 32.54,
9+
/// "longitude": -117.67,
10+
/// "altitude": 98.6
11+
/// },
12+
/// "pressure": 98
13+
/// }
14+
/// ```
15+
///
16+
/// into
17+
///
18+
/// ```
19+
/// [c8y/measurement/measurements/create] {
20+
/// "time": "2020-10-15T05:30:47Z",
21+
/// "type": "example",
22+
/// "temperature": {
23+
/// "temperature": {
24+
/// "value": 25
25+
/// }
26+
/// },
27+
/// "location": {
28+
/// "latitude": {
29+
/// "value": 32.54
30+
/// },
31+
/// "longitude": {
32+
/// "value": -117.67
33+
/// },
34+
/// "altitude": {
35+
/// "value": 98.6
36+
/// }
37+
/// },
38+
/// "pressure": {
39+
/// "pressure": {
40+
/// "value": 98
41+
/// }
42+
/// }
43+
/// }
44+
/// ```
45+
export function process(t, message, config) {
46+
let topic_parts = message.topic.split( '/')
47+
let type = topic_parts[6]
48+
let payload = JSON.parse(message.payload)
49+
50+
let c8y_msg = {
51+
type: type
52+
}
53+
54+
let meta = (config || {})[`${message.topic}/meta`] || {}
55+
56+
for (let [k, v] of Object.entries(payload)) {
57+
let k_meta = (meta || {})[k] || {}
58+
if (k === "time") {
59+
let fragment = { time: v }
60+
Object.assign(c8y_msg, fragment)
61+
}
62+
else if (typeof(v) === "number") {
63+
if (Object.keys(k_meta).length>0) {
64+
v = { value: v, ...k_meta }
65+
}
66+
let fragment = { [k]: { [k]: v } }
67+
Object.assign(c8y_msg, fragment)
68+
} else for (let [sub_k, sub_v] of Object.entries(v)) {
69+
let sub_k_meta = k_meta[sub_k]
70+
if (typeof(sub_v) === "number") {
71+
if (sub_k_meta) {
72+
sub_v = { value: sub_v, ...sub_k_meta }
73+
}
74+
let fragment = { [k]: { [sub_k]: sub_v } }
75+
Object.assign(c8y_msg, fragment)
76+
}
77+
}
78+
}
79+
80+
return [{
81+
topic: "c8y/measurement/measurements/create",
82+
payload: JSON.stringify(c8y_msg)
83+
}]
84+
}
85+
86+
/// Update the config with measurement metadata.
87+
///
88+
/// These metadata are expected to have the same shape of the actual values.
89+
///
90+
/// ```
91+
/// [te/device/main///m/example/meta] { "temperature": { "unit": "°C" }}
92+
/// ```
93+
///
94+
/// and:
95+
/// ```
96+
/// [te/device/main///m/example] { "temperature": { "unit": 23 }}
97+
/// ```
98+
///
99+
/// will be merged by the process function into:
100+
/// ```
101+
/// [c8y/measurement/measurements/create] {
102+
/// "type": "example",
103+
/// "temperature": {
104+
/// "temperature": {
105+
/// "value": 23,
106+
/// "unit": "°C"
107+
/// }
108+
/// }
109+
/// }
110+
/// ```
111+
export function update_config(message, config) {
112+
let type = message.topic
113+
let metadata = JSON.parse(message.payload)
114+
115+
let fragment = {
116+
[type]: metadata
117+
}
118+
if (!config) {
119+
config = {}
120+
}
121+
Object.assign(config, fragment)
122+
123+
return config
124+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
*** Settings ***
2+
Library ThinEdgeIO
3+
4+
Test Setup Custom Setup
5+
Test Teardown Get Logs
6+
7+
Test Tags theme:tedge_mapper
8+
9+
*** Test Cases ***
10+
Add missing timestamps
11+
Execute Command tedge mqtt pub te/device/main// '{}'
12+
${transformed_msg} Should Have MQTT Messages gen-mapper/c8y
13+
Should Contain ${transformed_msg} item=time
14+
15+
*** Keywords ***
16+
Custom Setup
17+
${DEVICE_SN}= Setup
18+
Set Suite Variable $DEVICE_SN
19+
Copy Configuration Files
20+
Start Generic Mapper
21+
22+
Copy Configuration Files
23+
Execute Command mkdir /etc/tedge/gen-mapper/
24+
ThinEdgeIO.Transfer To Device ${CURDIR}/pipelines/* /etc/tedge/gen-mapper/
25+
26+
Start Generic Mapper
27+
Execute Command nohup tedge run tedge-mapper gen &

0 commit comments

Comments
 (0)