Coverage for tutorials/ngsi_v2/e8_multientity_and_expression_language/e8_multientity_and_expression_language.py: 0%
16 statements
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-05 11:07 +0000
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-05 11:07 +0000
1"""
2# # Exercise 8: MultiEntity and Expression Language
4# The MultiEntity plugin allows the devices provisioned in the IoTAgent to map their
5attributes to more than one entity, declaring the target entity through the
6Configuration or Device provisioning APIs.
8# The IoTAgent Library provides an expression language for measurement transformation,
9that can be used to adapt the # information coming from the South Bound APIs to the
10information reported to the Context Broker. This is really useful when you need to
11adapt measure.
13# There are available two different expression languages jexl and legacy. The
14recommended language to use is jexl, which is newer and most powerful.
16# The input sections are marked with 'TODO'
18# #### Steps to complete:
19# 1. Setting up the expression language jexl
20# 2. Applying the expression language to device attributes
21# 3. Testing the expression language via MQTT messages
22# 4. Applying the expression language to device attributes in a multi-entity scenario
23"""
25# Import packages
26import time
27import datetime
29from filip.clients.ngsi_v2 import IoTAClient, ContextBrokerClient
30from filip.models.base import FiwareHeader
31from filip.models.ngsi_v2.context import ContextEntity, NamedContextAttribute
32from filip.models.ngsi_v2.iot import (
33 Device,
34 ServiceGroup,
35 TransportProtocol,
36 PayloadProtocol,
37 DeviceAttribute,
38 ExpressionLanguage,
39)
40from filip.utils.cleanup import clear_all
41from paho.mqtt import client as mqtt_client
42from paho.mqtt.client import CallbackAPIVersion
44# Host address of Context Broker
45CB_URL = "http://localhost:1026"
47# Host address of IoT-Agent
48IOTA_URL = "http://localhost:4041"
50# MQTT Broker
51MQTT_BROKER_HOST = "localhost"
52MQTT_BROKER_PORT = 1883
54# ToDo: Change the name of your service to something unique. If you run
55# on a shared instance this very important in order to avoid user
56# collisions. You will use this service through the whole tutorial.
57# If you forget to change it an error will be raised!
58# FIWARE Service
59SERVICE = "filip_tutorial"
60SERVICE_PATH = "/"
62# ToDo: Change the APIKEY to something unique. This represent the "token"
63# for IoT devices to connect (send/receive data ) with the platform. In the
64# context of MQTT, APIKEY is linked with the topic used for communication.
65APIKEY = "your_apikey"
67if __name__ == "__main__":
68 # FIWARE Header
69 fiware_header = FiwareHeader(service=SERVICE, service_path=SERVICE_PATH)
71 # Cleanup at the beginning
72 clear_all(fiware_header=fiware_header, cb_url=CB_URL, iota_url=IOTA_URL)
74 # IoT Agent and OCB Client
75 iota_client = IoTAClient(url=IOTA_URL, fiware_header=fiware_header)
76 cb_client = ContextBrokerClient(url=CB_URL, fiware_header=fiware_header)
78 # TODO: Setting expression language to JEXL at Service Group level
79 service_group1 = ServiceGroup(
80 entity_type="Thing",
81 resource="/iot/json",
82 apikey=APIKEY,
83 # ...
84 )
85 iota_client.post_group(service_group=service_group1)
87 # TODO: Create a device with two attributes 'location' and 'fillingLevel' that use
88 # expressions. These attributes are based on the attributes 'longitude',
89 # 'latitude' and 'level', while:
90 # 1. 'location' is an array with 'longitude' and 'latitude'.
91 # 2. 'fillingLevel' is 'level' divided by 100
92 device1 = Device(
93 device_id="waste_container_001",
94 entity_name="urn:ngsi-ld:WasteContainer:001",
95 entity_type="WasteContainer",
96 transport=TransportProtocol.MQTT,
97 protocol=PayloadProtocol.IOTA_JSON,
98 # ...
99 )
100 iota_client.post_device(device=device1)
102 # TODO: Setting expression language to JEXL at Device level with five attributes, while
103 # 1. The attribute 'value' (Number) is itself multiplied by 5. The attribute
104 # 2. 'consumption' (Text) is the trimmed version of the attribute 'spaces' (Text).
105 # 3. The attribute 'iso_time' (Text) is the current 'timestamp' (Number) transformed into the ISO format.
106 device2 = Device(
107 device_id="waste_container_002",
108 entity_name="urn:ngsi-ld:WasteContainer:002",
109 entity_type="WasteContainer",
110 transport=TransportProtocol.MQTT,
111 protocol=PayloadProtocol.IOTA_JSON,
112 # ...
113 )
114 iota_client.post_device(device=device2)
116 client = mqtt_client.Client(callback_api_version=CallbackAPIVersion.VERSION2)
117 client.username_pw_set(username="", password="")
118 client.connect(MQTT_BROKER_HOST, MQTT_BROKER_PORT)
119 client.loop_start()
121 # TODO: Publish attributes 'level', 'longitude' and 'latitude' of device1
122 client.publish(...)
124 # TODO: Publish attributes 'value', 'spaces' and 'timestamp' (in ms) of device2
125 client.publish(...)
127 client.disconnect()
129 time.sleep(2)
131 # Printing context entities of OCB
132 for context_entity in cb_client.get_entity_list(entity_types=["WasteContainer"]):
133 print(context_entity.model_dump_json(indent=4))
135 # Creating two SubWeatherStation entities
136 entity1 = ContextEntity(
137 id="urn:ngsi-ld:SubWeatherStation:001", type="SubWeatherStation"
138 )
139 entity1.add_attributes(attrs=[NamedContextAttribute(name="vol", type="Number")])
140 cb_client.post_entity(entity1)
142 entity2 = ContextEntity(
143 id="urn:ngsi-ld:SubWeatherStation:002", type="SubWeatherStation"
144 )
145 entity2.add_attributes(attrs=[NamedContextAttribute(name="vol", type="Number")])
146 cb_client.post_entity(entity2)
148 # TODO: Create a weather station device with multi entity attributes (Number).
149 # 'v' is multiplied by 100 and is a standard attribute.
150 # 'v1' and 'v2' are multiplied by 100 and should be linked with entities of
151 # the SubWeatherStation.
152 # The name of each attribute is 'vol'.
153 device3 = Device(
154 device_id="weather_station_001",
155 entity_name="urn:ngsi-ld:WeatherStation:001",
156 entity_type="WeatherStation",
157 transport=TransportProtocol.MQTT,
158 protocol=PayloadProtocol.IOTA_JSON,
159 # ...
160 )
161 iota_client.post_device(device=device3)
163 client = mqtt_client.Client(callback_api_version=CallbackAPIVersion.VERSION2)
164 client.username_pw_set(username="", password="")
165 client.connect(MQTT_BROKER_HOST, MQTT_BROKER_PORT)
166 client.loop_start()
168 # TODO: Publish values to all attributes of device3
169 client.publish(...)
171 client.disconnect()
173 time.sleep(2)
175 # Printing context entities of OCB
176 for context_entity in cb_client.get_entity_list(
177 entity_types=["WeatherStation", "SubWeatherStation"]
178 ):
179 print(context_entity.model_dump_json(indent=4))