Coverage for tutorials/ngsi_v2/e4_iot_thermal_zone_sensors/e4_iot_thermal_zone_sensors.py: 0%
28 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 4: Virtual Thermal Zone
4# Create two virtual IoT devices. One of them represents the temperature
5# sensor for the air temperature of a thermal zone, whereas the second
6# represents a virtual weather station. Both devices publish their values to
7# the platform via MQTT. Use the simulation model of
8# e1_virtual_weatherstation.py
9#
10# The input sections are marked with 'ToDo'
11#
12# #### Steps to complete:
13# 1. Set up the missing parameters in the parameter section
14# 2. Create a service group and two corresponding devices
15# 3. Provision the service group and the devices
16# 4. Create an MQTT client using the filip.client.mqtt package and register
17# your service group and your devices
18# 5. Check if the IoT-Agent correctly creates the corresponding entities
19# 5. Create a function that publishes the simulated temperature via MQTT,
20# retrieves the entity data after each message and writes the values to a
21# history
22# 6. Run the simulation and plot the results
23"""
25# ## Import packages
26import json
27from pathlib import Path
28import time
29from urllib.parse import urlparse
30import matplotlib.pyplot as plt
31import paho.mqtt.client as mqtt
33# import from filip
34from filip.clients.ngsi_v2 import ContextBrokerClient, IoTAClient
35from filip.clients.mqtt import IoTAMQTTClient
36from filip.models.base import FiwareHeader
37from filip.models.ngsi_v2.iot import Device, DeviceAttribute, ServiceGroup
38from filip.utils.cleanup import clear_context_broker, clear_iot_agent
40# import simulation model
41from tutorials.ngsi_v2.simulation_model import SimulationModel
43# ## Parameters
44# ToDo: Enter your context broker host and port, e.g. http://localhost:1026.
45CB_URL = "http://localhost:1026"
46# ToDo: Enter your IoT-Agent host and port, e.g. http://localhost:4041.
47IOTA_URL = "http://localhost:4041"
48# ToDo: Enter your mqtt broker url, e.g. mqtt://test.mosquitto.org:1883.
49MQTT_BROKER_URL = "mqtt://localhost:1883"
50# ToDo: If required, enter your username and password.
51MQTT_USER = ""
52MQTT_PW = ""
54# ToDo: Change the name of your service to something unique. If you run
55# on a shared instance this is 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"
60# FIWARE-Service path
61SERVICE_PATH = "/"
63# ToDo: Change the APIKEY to something unique. This represents the "token"
64# for IoT devices to connect (send/receive data) with the platform. In the
65# context of MQTT, APIKEY is linked with the topic used for communication.
66APIKEY = "your_apikey"
68# path to json-files to device configuration data for follow-up exercises
69WRITE_GROUPS_FILEPATH = Path("../e4_iot_thermal_zone_sensors_groups.json")
70WRITE_DEVICES_FILEPATH = Path("../e4_iot_thermal_zone_sensors_devices.json")
72# set parameters for the temperature simulation
73TEMPERATURE_MAX = 10 # maximal ambient temperature
74TEMPERATURE_MIN = -5 # minimal ambient temperature
75TEMPERATURE_ZONE_START = 20 # start value of the zone temperature
77T_SIM_START = 0 # simulation start time in seconds
78T_SIM_END = 24 * 60 * 60 # simulation end time in seconds
79COM_STEP = 60 * 60 * 0.25 # 15 min communication step in seconds
81# ## Main script
82if __name__ == "__main__":
83 # create a fiware header object
84 fiware_header = FiwareHeader(service=SERVICE, service_path=SERVICE_PATH)
85 # clear the state of your service and scope
86 clear_iot_agent(url=IOTA_URL, fiware_header=fiware_header)
87 clear_context_broker(url=CB_URL, fiware_header=fiware_header)
89 # instantiate simulation model
90 sim_model = SimulationModel(
91 t_start=T_SIM_START,
92 t_end=T_SIM_END,
93 temp_max=TEMPERATURE_MAX,
94 temp_min=TEMPERATURE_MIN,
95 temp_start=TEMPERATURE_ZONE_START,
96 )
98 # define lists to store historical data
99 history_weather_station = []
100 history_zone_temperature_sensor = []
102 # create a service group with your api key
103 service_group = ServiceGroup(apikey=APIKEY, resource="/iot/json")
105 # ToDo: Create two IoTA-MQTT devices for the weather station and the zone
106 # temperature sensor. Also add the simulation time as `active attribute`
107 # to each device!
108 # create the weather station device
109 # create the `sim_time` attribute and add it to the weather station's attributes
110 t_sim = DeviceAttribute(name="sim_time", object_id="t_sim", type="Number")
112 weather_station = Device(
113 device_id="device:001",
114 entity_name="urn:ngsi-ld:WeatherStation:001",
115 entity_type="WeatherStation",
116 protocol="IoTA-JSON",
117 transport="MQTT",
118 apikey=APIKEY,
119 attributes=[t_sim],
120 commands=[],
121 )
123 # create a temperature attribute and add it via the api of the
124 # `device`-model. Use the `t_amb` as `object_id`. `object_id` specifies
125 # what key will be used in the MQTT Message payload
126 t_amb = DeviceAttribute(name="temperature", object_id="t_amb", type="Number")
128 weather_station.add_attribute(t_amb)
130 # ToDo: Create the zone temperature device and add the `t_sim` attribute upon
131 # creation.
132 zone_temperature_sensor = Device(...)
134 # ToDo: Create the temperature attribute. Use the `t_zone` as `object_id`.
135 # `object_id` specifies what key will be used in the MQTT Message payload.
136 t_zone = DeviceAttribute(...)
138 zone_temperature_sensor.add_attribute(t_zone)
140 # ToDo: Create an IoTAClient.
141 iotac = ...
142 # ToDo: Provision service group and add it to your IoTAMQTTClient.
143 ...
144 # ToDo: Provision the devices at the IoTA-Agent.
145 # provision the weather station device
146 iotac.post_device(device=weather_station, update=True)
147 # ToDo: Provision the zone temperature device.
148 ...
150 # ToDo: Create a context broker client.
151 # ToDo: Check in the context broker whether the entities corresponding to your
152 # devices were correctly created.
153 cbc = ContextBrokerClient(url=CB_URL, fiware_header=fiware_header)
154 # get weather station entity
155 print(
156 f"Weather station:\n{cbc.get_entity(weather_station.entity_name).model_dump_json(indent=2)}"
157 )
158 # ToDo: Get zone temperature sensor entity.
159 print(...)
161 # ToDo: Create an MQTTv5 client using filip.clients.mqtt.IoTAMQTTClient.
162 mqttc = IoTAMQTTClient(protocol=...)
163 # ToDo: Register the service group with your MQTT-Client.
164 mqttc.add_service_group(service_group=service_group)
165 # ToDo: Register devices with your MQTT-Client.
166 # register the weather station
167 mqttc.add_device(weather_station)
168 # ToDo: Register the zone temperature sensor.
169 ...
171 # The IoTAMQTTClient automatically creates outgoing topics from the
172 # device configuration during runtime. Hence, we need to construct them
173 # manually in order to subscribe to them. This is usually not required as
174 # only the platform should listen to the incoming traffic.
175 # If you want to listen subscribe to the following topics:
176 # "/json/<APIKEY>/<weather_station.device_id>/attrs"
177 # "/json/<APIKEY>/<zone_temperature_sensor.device_id>/attrs"
179 # ToDO: Connect to the MQTT broker and subscribe to your topic.
180 ...
182 # subscribe to topics
183 # subscribe to all incoming command topics for the registered devices
184 mqttc.subscribe()
185 # create a non-blocking thread for mqtt communication
186 mqttc.loop_start()
188 # ToDo: Create a loop that publishes a message every 100 milliseconds
189 # to the broker that holds the simulation time `sim_time` and the
190 # corresponding temperature `temperature`. You may use the `object_id`
191 # or the attribute name as a key in your payload.
192 for t_sim in range(
193 sim_model.t_start, sim_model.t_end + int(COM_STEP), int(COM_STEP)
194 ):
195 # publish the simulated ambient temperature
196 mqttc.publish(
197 device_id=weather_station.device_id,
198 payload={"temperature": sim_model.t_amb, "sim_time": sim_model.t_sim},
199 )
201 # ToDo: Publish the simulated zone temperature.
202 ...
204 # simulation step for the next loop
205 sim_model.do_step(int(t_sim + COM_STEP))
206 # wait for one second before publishing the next values
207 time.sleep(0.1)
209 # get corresponding entities and store the data
210 weather_station_entity = cbc.get_entity(
211 entity_id=weather_station.entity_name,
212 entity_type=weather_station.entity_type,
213 )
214 # append the data to the local history
215 history_weather_station.append(
216 {
217 "sim_time": weather_station_entity.sim_time.value,
218 "temperature": weather_station_entity.temperature.value,
219 }
220 )
222 # ToDo: Get zone temperature sensor and store the data.
223 zone_temperature_sensor_entity = ...
225 history_zone_temperature_sensor.append(...)
227 # close the mqtt listening thread
228 mqttc.loop_stop()
229 # disconnect the mqtt device
230 mqttc.disconnect()
232 # plot the results
233 fig, ax = plt.subplots()
234 t_simulation = [item["sim_time"] / 3600 for item in history_weather_station]
235 temperature = [item["temperature"] for item in history_weather_station]
236 ax.plot(t_simulation, temperature)
237 ax.title.set_text("Weather Station")
238 ax.set_xlabel("time in h")
239 ax.set_ylabel("ambient temperature in °C")
241 fig2, ax2 = plt.subplots()
242 t_simulation = [item["sim_time"] / 3600 for item in history_zone_temperature_sensor]
243 temperature = [item["temperature"] for item in history_zone_temperature_sensor]
244 ax2.plot(t_simulation, temperature)
245 ax2.title.set_text("Zone Temperature Sensor")
246 ax2.set_xlabel("time in h")
247 ax2.set_ylabel("zone temperature in °C")
249 plt.show()