Skip to content

Commit 3eff4f4

Browse files
committed
Switch to JSON IoT Agent
1 parent 6b0e33e commit 3eff4f4

26 files changed

Lines changed: 583 additions & 362 deletions

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ CURL_VERSION=8.4.0
2222
MONGO_DB_PORT=27017
2323
MONGO_DB_VERSION=6.0
2424

25-
# IoT Agent Ultralight Variables
26-
ULTRALIGHT_VERSION=3.7.0-distroless
25+
# IoT Agent JSON Variables
26+
JSON_VERSION=3.14.0-distroless
2727
IOTA_NORTH_PORT=4041
2828
IOTA_SOUTH_PORT=7896
2929

.github/test/iot_device_smoke_test

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/bin/bash
2+
#
3+
# Smoke test: verify IoT device provisioning by sending an 'on' command to each
4+
# water sprinkler and confirming the context broker reflects the updated
5+
# on_status attribute after the full command round-trip:
6+
# Orion → IoT Agent → iot-sensors simulator → IoT Agent → Orion
7+
#
8+
9+
set -e
10+
11+
export $(cat .env | grep "#" -v)
12+
13+
BROKER="http://orion:1026"
14+
CONTEXT="http://context/user-context.jsonld"
15+
TENANT="openiot"
16+
DEVICES=("water001" "water002" "water003" "water004")
17+
18+
failures=0
19+
20+
run_curl () {
21+
docker run --rm --network fiware_default quay.io/curl/curl:"${CURL_VERSION}" "$@"
22+
}
23+
24+
send_on_command () {
25+
local device="$1"
26+
local status
27+
status=$(run_curl -s -o /dev/null -w "%{http_code}" \
28+
-L -X PATCH \
29+
"${BROKER}/ngsi-ld/v1/entities/urn:ngsi-ld:Device:${device}/attrs/on" \
30+
-H "NGSILD-Tenant: ${TENANT}" \
31+
-H 'Content-Type: application/json' \
32+
-H "Link: <${CONTEXT}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"" \
33+
--data-raw '{"type":"Property","value":" "}')
34+
if [ "${status}" != "204" ]; then
35+
echo "FAIL [${device}]: on command returned HTTP ${status} (expected 204)"
36+
return 1
37+
fi
38+
echo "PASS [${device}]: on command accepted (204)"
39+
}
40+
41+
check_on_status () {
42+
local device="$1"
43+
local response
44+
response=$(run_curl -s \
45+
"${BROKER}/ngsi-ld/v1/entities/urn:ngsi-ld:Device:${device}" \
46+
-H "NGSILD-Tenant: ${TENANT}" \
47+
-H "Link: <${CONTEXT}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"" \
48+
-H 'Accept: application/json')
49+
if ! echo "${response}" | grep -q '"on_status"'; then
50+
echo "FAIL [${device}]: on_status attribute missing from context broker"
51+
echo " Response: ${response}"
52+
return 1
53+
fi
54+
echo "PASS [${device}]: on_status confirmed in context broker"
55+
}
56+
57+
for device in "${DEVICES[@]}"; do
58+
send_on_command "${device}" || failures=$((failures + 1))
59+
done
60+
61+
echo "Waiting 5s for command round-trip..."
62+
sleep 5
63+
64+
for device in "${DEVICES[@]}"; do
65+
check_on_status "${device}" || failures=$((failures + 1))
66+
done
67+
68+
echo ""
69+
if [ "${failures}" -gt 0 ]; then
70+
echo "Smoke test FAILED: ${failures} assertion(s) did not pass"
71+
exit 1
72+
fi
73+
echo "Smoke test PASSED: all water devices are responding and context broker is updated"

.github/workflows/ci.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,12 @@ jobs:
2828
run: |
2929
./services create || true
3030
- name: Run Orion
31-
run: |
32-
./services orion && ./services stop
31+
run: ./services orion
32+
- name: Smoke Test (Orion)
33+
run: ./.github/test/iot_device_smoke_test
34+
- name: Stop (Orion)
35+
if: always()
36+
run: ./services stop
3337
- name: Run Stellio
3438
run: |
3539
./services stellio && ./services stop

NGSI-LD QuantumLeap.postman_collection.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

README.ja.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ TimescaleDB は通常のテーブルのように見えるものを公開しま
113113
このチュートリアルの目的のために、一連のダミーの農業用 IoT デバイスが作成され、Context Broker に接続されます。使用
114114
されているアーキテクチャとプロトコルの詳細は、
115115
[IoT センサ・チュートリアル](https://github.com/FIWARE/tutorials.IoT-Sensors/tree/NGSI-LD)にあります。各デバイスの
116-
状態は、 UltraLight デバイス・モニタの Web ページは次の場所にあります: `http://localhost:3000/device/monitor`
116+
状態は、 JSON デバイス・モニタの Web ページは次の場所にあります: `http://localhost:3000/device/monitor`
117117

118118
![FIWARE Monitor](https://fiware.github.io/tutorials.Time-Series-Data/img/farm-devices.png)
119119

@@ -131,7 +131,7 @@ TimescaleDB は通常のテーブルのように見えるものを公開しま
131131
このアプリケーションは、[以前のチュートリアル](https://github.com/FIWARE/tutorials.IoT-Agent/)で作成された
132132
コンポーネントとダミー IoT デバイスに基づいて構築されています。
133133
[Orion Context Broker](https://fiware-orion.readthedocs.io/en/latest/),
134-
[IoT Agent for Ultralight 2.0](https://fiware-iotagent-ul.readthedocs.io/en/latest/),
134+
[IoT Agent for JSON](https://fiware-iotagent-json.readthedocs.io/en/latest/),
135135
[QuantumLeap](https://smartsdk.github.io/ngsi-timeseries-api/)
136136
の3つのFIWAREコンポーネントを使用します。
137137

@@ -141,8 +141,8 @@ TimescaleDB は通常のテーブルのように見えるものを公開しま
141141
[NGSI-LD](https://forge.etsi.org/swagger/ui/?url=https://forge.etsi.org/rep/NGSI-LD/NGSI-LD/raw/master/spec/updated/generated/full_api.json)
142142
を使用してリクエストを受信します
143143
- FIWARE
144-
[IoT Agent for Ultralight 2.0](https://fiware-iotagent-ul.readthedocs.io/en/latest/)
145-
は、Ultralight 2.0 形式のダミー IoT デバイスからノース・バウンドの測定値
144+
[IoT Agent for JSON](https://fiware-iotagent-json.readthedocs.io/en/latest/)
145+
は、JSON 形式のダミー IoT デバイスからノース・バウンドの測定値
146146
を受信し、Context Broker の
147147
[NGSI-LD](https://forge.etsi.org/swagger/ui/?url=https://forge.etsi.org/rep/NGSI-LD/NGSI-LD/raw/master/spec/updated/generated/full_api.json)
148148
リクエストに変換してコンテキスト・エンティティの状態を変更します
@@ -162,7 +162,7 @@ TimescaleDB は通常のテーブルのように見えるものを公開しま
162162

163163
- HTTP **Web-Server** は、システム内のコンテキスト・エンティティを定義する静的な `@context` ファイルを提供します
164164
- **チュートリアルアプリケーション** は次のことを行います:
165-
- HTTP上で実行される [UltraLight 2.0](https://fiware-iotagent-ul.readthedocs.io/en/latest/usermanual/index.html#user-programmers-manual)
165+
- HTTP上で実行される [JSON](https://fiware-iotagent-json.readthedocs.io/en/latest/usermanual/index.html#user-programmers-manual)
166166
プロトコルを使用して、ダミーの[農業用 IoT デバイス](https://github.com/FIWARE/tutorials.IoT-Sensors/tree/NGSI-LD)
167167
のセットとして機能します
168168

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ available licensed under the Apache License 2.0. More information can be found a
126126
For the purpose of this tutorial, a series of dummy agricultural IoT devices have been created, which will be attached
127127
to the context broker. Details of the architecture and protocol used can be found in the
128128
[IoT Sensors tutorial](https://github.com/FIWARE/tutorials.IoT-Sensors/tree/NGSI-LD) The state of each device can be
129-
seen on the UltraLight device monitor web page found at: `http://localhost:3000/device/monitor`
129+
seen on the JSON device monitor web page found at: `http://localhost:3000/device/monitor`
130130

131131
![FIWARE Monitor](https://fiware.github.io/tutorials.Time-Series-Data/img/farm-devices.png)
132132

@@ -142,7 +142,7 @@ web page found at: `http://localhost:3000/device/history/urn:ngsi-ld:Farm:001`
142142
This application builds on the components and dummy IoT devices created in
143143
[previous tutorials](https://github.com/FIWARE/tutorials.IoT-Agent/). It will use three FIWARE components: the
144144
[Orion Context Broker](https://fiware-orion.readthedocs.io/en/latest/), the
145-
[IoT Agent for Ultralight 2.0](https://fiware-iotagent-ul.readthedocs.io/en/latest/), and
145+
[IoT Agent for JSON](https://fiware-iotagent-json.readthedocs.io/en/latest/), and
146146
[QuantumLeap](https://smartsdk.github.io/ngsi-timeseries-api/) .
147147

148148
Therefore the overall architecture will consist of the following elements:
@@ -151,11 +151,11 @@ Therefore the overall architecture will consist of the following elements:
151151

152152
- The [Orion Context Broker](https://fiware-orion.readthedocs.io/en/latest/) which will receive requests using
153153
[NGSI-LD](https://forge.etsi.org/swagger/ui/?url=https://forge.etsi.org/rep/NGSI-LD/NGSI-LD/raw/master/spec/updated/generated/full_api.json)
154-
- The FIWARE [IoT Agent for UltraLight 2.0](https://fiware-iotagent-ul.readthedocs.io/en/latest/) which will
154+
- The FIWARE [IoT Agent for JSON](https://fiware-iotagent-json.readthedocs.io/en/latest/) which will
155155
receive southbound requests using
156156
[NGSI-LD](https://forge.etsi.org/swagger/ui/?url=https://forge.etsi.org/rep/NGSI-LD/NGSI-LD/raw/master/spec/updated/generated/full_api.json)
157157
and convert them to
158-
[UltraLight 2.0](https://fiware-iotagent-ul.readthedocs.io/en/latest/usermanual/index.html#user-programmers-manual)
158+
[JSON](https://fiware-iotagent-json.readthedocs.io/en/latest/usermanual/index.html#user-programmers-manual)
159159
commands for the devices
160160
- FIWARE [QuantumLeap](https://smartsdk.github.io/ngsi-timeseries-api/) subscribed to context changes and
161161
persisting them into a **CrateDB** database
@@ -175,7 +175,7 @@ Therefore the overall architecture will consist of the following elements:
175175
- The **Tutorial Application** does the following:
176176
- Acts as set of dummy [agricultural IoT devices](https://github.com/FIWARE/tutorials.IoT-Sensors/tree/NGSI-LD)
177177
using the
178-
[UltraLight 2.0](https://fiware-iotagent-ul.readthedocs.io/en/latest/usermanual/index.html#user-programmers-manual)
178+
[JSON](https://fiware-iotagent-json.readthedocs.io/en/latest/usermanual/index.html#user-programmers-manual)
179179
protocol running over HTTP.
180180

181181
Since all interactions between the elements are initiated by HTTP requests, the entities can be containerized and run

data/agri-crop.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
id,type,name,description,hasAgriSoil,hasAgriPest
2+
urn:ngsi-ld:AgriCrop:BuckWheat,AgriCrop,BuckWheat,"Buckwheat is a small, dark grain used for feeding animals and for making flour","[""urn:ngsi-ld:AgriSoil:clay""]","[""urn:ngsi-ld:AgriPest:aster-yellows"",""urn:ngsi-ld:AgriPest:root-rot""]"
3+
urn:ngsi-ld:AgriCrop:Corn,AgriCrop,Corn,"Corn is a cereal plant that yields large grains set in rows on a cob. Its origins trace back to the Americas, where ancient civilizations began cultivating it over 9,000 years ago. Corn is of significant economic importance as a staple food in many parts of the world and is also used as livestock feed, raw material in industry, and a component in biofuel production.","[""urn:ngsi-ld:AgriSoil:loam""]","[""urn:ngsi-ld:AgriPest:aster-yellows"",""urn:ngsi-ld:AgriPest:root-rot"",""urn:ngsi-ld:AgriPest:powdery-mildew""]"
4+
urn:ngsi-ld:AgriCrop:Grass,AgriCrop,Grass,"Crop grass refers to various grass species cultivated and harvested for agricultural purposes. These grasses are grown for their high nutritional content and versatility, typically used for fodder, silage, and sometimes for grain production. ","[""urn:ngsi-ld:AgriSoil:silt"",""urn:ngsi-ld:AgriSoil:sand"",""urn:ngsi-ld:AgriSoil:loam""]","[""urn:ngsi-ld:AgriPest:aphid"",""urn:ngsi-ld:AgriPest:cutworm"",""urn:ngsi-ld:AgriPest:thistle""]"

data/agri-farm.csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
id,type,addressLocality,addressRegion,postalCode,streetAddress,name,owner,location_type,lng,lat,alternateName,hasAgriParcel,hasBuilding
2+
urn:ngsi-ld:AgriFarm:farm001,AgriFarm,Tiergarten,Berlin,10557,Großer Stern 1,Victory Farm,urn:ngsi-ld:Person:person001,Point,13.3505,52.5144,,"[""urn:ngsi-ld:AgriParcel:001"",""urn:ngsi-ld:AgriParcel:002""]","[""urn:ngsi-ld:Building:tower003"",""urn:ngsi-ld:Building:farm001"",""urn:ngsi-ld:Building:barn002""]"
3+
urn:ngsi-ld:AgriFarm:farm002,AgriFarm,Tiergarten,Berlin,10787,Hardenbergplatz 8,Animal Farm,urn:ngsi-ld:Person:person002,Point,13.3368,52.5078,Manor Farm,"[""urn:ngsi-ld:AgriParcel:003"",""urn:ngsi-ld:AgriParcel:004"",""urn:ngsi-ld:AgriParcel:005"",""urn:ngsi-ld:AgriParcel:006""]","[""urn:ngsi-ld:Building:farm002""]"

data/agri-parcel.csv

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
id,type,name,cropStatus,soilTextureType,hasAgriSoil,hasAgriCrop,observation,prediction,temperature,humidity,hasDevices,providedBy,ownedBy
2+
urn:ngsi-ld:AgriParcel:001,AgriParcel,Wheatfield,seeded,Clay Loam,urn:ngsi-ld:AgriSoil:clay,urn:ngsi-ld:AgriCrop:BuckWheat,urn:ngsi-ld:WeatherObserved:001,urn:ngsi-ld:WeatherForecast:001,15.4,0.5,"[""urn:ngsi-ld:SoilSensor:humidity001"",""urn:ngsi-ld:Thermometer:temp001""]",urn:ngsi-ld:SoilSensor:humidity001,urn:ngsi-ld:Person:person001
3+
urn:ngsi-ld:AgriParcel:002,AgriParcel,Cornfield,growing,Loam,urn:ngsi-ld:AgriSoil:loam,urn:ngsi-ld:AgriCrop:Corn,urn:ngsi-ld:WeatherObserved:002,urn:ngsi-ld:WeatherForecast:001,,0.6,"[""urn:ngsi-ld:SoilSensor:humidity002""]",urn:ngsi-ld:SoilSensor:humidity002,urn:ngsi-ld:Person:person001
4+
urn:ngsi-ld:AgriParcel:005,AgriParcel,Water Meadow,maturing,Sandy Loam,urn:ngsi-ld:AgriSoil:sand,urn:ngsi-ld:AgriCrop:Grass,urn:ngsi-ld:WeatherObserved:004,urn:ngsi-ld:WeatherForecast:002,,0.7,"[""urn:ngsi-ld:SoilSensor:humidity003""]",urn:ngsi-ld:SoilSensor:humidity003,urn:ngsi-ld:Person:person002
5+
urn:ngsi-ld:AgriParcel:006,AgriParcel,The Paddock,maturing,Loam,urn:ngsi-ld:AgriSoil:loam,urn:ngsi-ld:AgriCrop:Grass,urn:ngsi-ld:WeatherObserved:005,urn:ngsi-ld:WeatherForecast:002,,0.6,"[""urn:ngsi-ld:SoilSensor:humidity004""]",urn:ngsi-ld:SoilSensor:humidity004,urn:ngsi-ld:Person:person002
6+
urn:ngsi-ld:AgriParcel:003,AgriParcel,North Pasture,maturing,Loam,urn:ngsi-ld:AgriSoil:loam,urn:ngsi-ld:AgriCrop:Grass,urn:ngsi-ld:WeatherObserved:003,urn:ngsi-ld:WeatherForecast:002,,0.6,"[""urn:ngsi-ld:SoilSensor:humidity005""]",urn:ngsi-ld:SoilSensor:humidity005,urn:ngsi-ld:Person:person002
7+
urn:ngsi-ld:AgriParcel:004,AgriParcel,East Pasture,maturing,Silt loam,urn:ngsi-ld:AgriSoil:silt,urn:ngsi-ld:AgriCrop:Grass,,,,0.6,"[""urn:ngsi-ld:SoilSensor:humidity006""]",urn:ngsi-ld:SoilSensor:humidity006,urn:ngsi-ld:Person:person002

data/agri-pest.csv

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
id,type,name,alternateName,description,agroVocConcept
2+
urn:ngsi-ld:AgriPest:aster-yellows,AgriPest,Aster yellows,Solidaster luteus,"Aster yellows is a chronic, systemic plant disease caused by several bacteria called phytoplasma.",http://aims.fao.org/aos/agrovoc/c_31924
3+
urn:ngsi-ld:AgriPest:root-rot,AgriPest,Root rot,Heterobasidion annosum,Root rot is a condition in which anoxic conditions in the soil or potting media around the roots of a plant cause them to rot. ,http://aims.fao.org/aos/agrovoc/f_10024
4+
urn:ngsi-ld:AgriPest:powdery-mildew,AgriPest,Powdery mildew,Golovinomyces cichoracearum,Powdery mildew is a fungal disease that appears as white powdery spots on the leaves and stems of many plants,http://aims.fao.org/aos/agrovoc/f_32224
5+
urn:ngsi-ld:AgriPest:aphid,AgriPest,Aphids,Aphididae,"Aphids are soft-bodied pear-shaped insects that come in a variety of colors like black, brown, red, pink, or green, and may even have transparent wings. ",http://aims.fao.org/aos/agrovoc/i_87345
6+
urn:ngsi-ld:AgriPest:cutworm,AgriPest,Cutworms,Noctuidae,"Cutworms are moth larvae that hide under litter or soil during the day, coming out in the dark to feed on plants. A larva typically attacks the first part of the plant it encounters, namely the stem, often of a seedling, and consequently cuts it down",http://aims.fao.org/aos/agrovoc/i_98898
7+
urn:ngsi-ld:AgriPest:grasshopper,AgriPest,Grasshoppers,horthippus parallelus,"Grasshoppers occur in greatest numbers in lowland tropical forests, semiarid regions, and grasslands. Although most grasshoppers are herbivorous, only a few species are important economically as crop pests. ",http://aims.fao.org/aos/agrovoc/c_89873
8+
urn:ngsi-ld:AgriPest:horse-fly,AgriPest,Horse Fly,Tabanidae,"Horse flies are large, stout-bodied flies that bite mammals, especially horses.",http://aims.fao.org/aos/agrovoc/p_978667
9+
urn:ngsi-ld:AgriPest:ear-tick,AgriPest,Ear Tick,Otobius megnini,"The spinose ear tick, is a soft-bodied tick that is only parasitic in the larval and nymphal stages. As its common name suggests, the spinose ear tick's parasitic forms are usually found within the ears of the host. This tick has a worldwide distribution, with common hosts that include horses, cattle, sheep, goats, and dogs",http://aims.fao.org/aos/agrovoc/p_978457
10+
urn:ngsi-ld:AgriPest:tick,AgriPest,Tick,Ixodes ricinus,"Ticks are parasitic arachnids of the order Ixodida. They are part of the mite superorder Parasitiformes. Adult ticks are approximately 3 to 5 mm in length depending on age, sex, and species, but can become larger when engorged. Ticks are external parasites, living by feeding on the blood of mammals",http://aims.fao.org/aos/agrovoc/p_97722
11+
urn:ngsi-ld:AgriPest:thistle,AgriPest,Thistles,Carduus nutans,Thistle is the common name of a group of flowering plants characterized by leaves with sharp spikes on the margins. Prickles can also occur all over the plant – on the stem and on the flat parts of the leaves. These prickles protect the plant from herbivores,http://aims.fao.org/aos/agrovoc/p_19245

0 commit comments

Comments
 (0)