Coverage for tutorials/ngsi_v2/e7_semantic_iot/e7_semantic_iot_solutions.py: 0%

23 statements  

« prev     ^ index     » next       coverage.py v7.10.2, created at 2025-08-05 11:07 +0000

1""" 

2# # Exercise 7: Semantic IoT Systems 

3# 

4# We now want to add a semantic meaning to our measurements. Therefore we 

5# semantically connect the context entities that we created in 

6# `e3_context_entities.py` 

7 

8# The input sections are marked with 'ToDo' 

9 

10# #### Steps to complete: 

11# 1. Set up the missing parameters in the parameter section 

12# 2. Add relationships that connect the weather station to the building, 

13# and vice versa 

14# 3. Add relationships that connect the thermal zone temperature sensor and 

15# the heater to the building, and vice versa 

16# 4. Retrieve all entities and print them 

17# 5. Congratulations! You are now ready to build your own semantic systems. For 

18# advanced semantic functions check on our semantics examples 

19""" 

20 

21# ## Import packages 

22import json 

23from pathlib import Path 

24from typing import List 

25from pydantic import TypeAdapter 

26 

27# import from filip 

28from filip.clients.ngsi_v2 import ContextBrokerClient, IoTAClient 

29from filip.models.base import FiwareHeader 

30from filip.models.ngsi_v2.base import NamedMetadata 

31from filip.models.ngsi_v2.context import ContextEntity, NamedContextAttribute 

32from filip.models.ngsi_v2.iot import Device, ServiceGroup, StaticDeviceAttribute 

33from filip.models.ngsi_v2.units import Unit 

34from filip.utils.cleanup import clear_context_broker, clear_iot_agent 

35 

36# ## Parameters 

37# ToDo: Enter your context broker host and port, e.g. http://localhost:1026. 

38CB_URL = "http://localhost:1026" 

39# ToDo: Enter your IoT-Agent host and port, e.g. http://localhost:4041. 

40IOTA_URL = "http://localhost:4041" 

41 

42# ToDo: Change the name of your service to something unique. If you run 

43# on a shared instance this very is important in order to avoid user 

44# collisions. You will use this service through the whole tutorial. 

45# If you forget to change it, an error will be raised! 

46# FIWARE-Service 

47SERVICE = "filip_tutorial" 

48# FIWARE-Service path 

49SERVICE_PATH = "/" 

50 

51# ToDo: Change the APIKEY to something unique. This represents the "token" 

52# for IoT devices to connect (send/receive data) with the platform. In the 

53# context of MQTT, APIKEY is linked with the topic used for communication. 

54APIKEY = "your_apikey" 

55 

56# path to read json-files from previous exercises 

57READ_GROUPS_FILEPATH = Path("../e5_iot_thermal_zone_control_solution_groups.json") 

58READ_DEVICES_FILEPATH = Path("../e5_iot_thermal_zone_control_solution_devices.json") 

59READ_ENTITIES_FILEPATH = Path("../e3_context_entities_solution_entities.json") 

60 

61# opening the files 

62with open(READ_GROUPS_FILEPATH, "r") as groups_file, open( 

63 READ_DEVICES_FILEPATH, "r" 

64) as devices_file, open(READ_ENTITIES_FILEPATH, "r") as entities_file: 

65 json_groups = json.load(groups_file) 

66 json_devices = json.load(devices_file) 

67 json_entities = json.load(entities_file) 

68 

69# ## Main script 

70if __name__ == "__main__": 

71 # create a fiware header object 

72 fiware_header = FiwareHeader(service=SERVICE, service_path=SERVICE_PATH) 

73 # clear the state of your service and scope 

74 clear_iot_agent(url=IOTA_URL, fiware_header=fiware_header) 

75 clear_context_broker(url=CB_URL, fiware_header=fiware_header) 

76 

77 # create clients and restore devices and groups from file 

78 groups = TypeAdapter(List[ServiceGroup]).validate_python(json_groups) 

79 devices = TypeAdapter(List[Device]).validate_python(json_devices) 

80 entities = TypeAdapter(List[ContextEntity]).validate_python(json_entities) 

81 cbc = ContextBrokerClient(url=CB_URL, fiware_header=fiware_header) 

82 for entity in entities: 

83 cbc.post_entity(entity=entity) 

84 

85 iotac = IoTAClient(url=IOTA_URL, fiware_header=fiware_header) 

86 iotac.post_groups(service_groups=groups) 

87 iotac.post_devices(devices=devices) 

88 

89 # ToDo: Retrieve all iot resources from the IoT-Agent. 

90 # get the group and device configurations from the server 

91 group = iotac.get_group(resource="/iot/json", apikey=APIKEY) 

92 weather_station = iotac.get_device(device_id="device:001") 

93 zone_temperature_sensor = iotac.get_device(device_id="device:002") 

94 heater = iotac.get_device(device_id="device:003") 

95 

96 # ToDo: Get context entities from the Context Broker 

97 # (exclude the IoT device ones). 

98 building = cbc.get_entity( 

99 entity_id="urn:ngsi-ld:building:001", entity_type="Building" 

100 ) 

101 thermal_zone = cbc.get_entity( 

102 entity_id="ThermalZone:001", entity_type="ThermalZone" 

103 ) 

104 

105 # ToDo: Semantically connect the weather station and the building. By 

106 # adding a `hasWeatherStation` attribute of type `Relationship`. For the 

107 # connection from the weather station to the building add a static 

108 # attribute to the weather station. 

109 

110 # create the context attribute for the building and add it to the 

111 # building entity 

112 has_weather_station = NamedContextAttribute( 

113 name="hasWeatherStation", type="Relationship", value=weather_station.entity_name 

114 ) 

115 building.add_attributes(attrs=[has_weather_station]) 

116 

117 # create a static attribute that connects the weather station to the 

118 # building 

119 cbc.update_entity(entity=building) 

120 

121 ref_building = StaticDeviceAttribute( 

122 name="refBuilding", type="Relationship", value=building.id 

123 ) 

124 weather_station.add_attribute(ref_building) 

125 iotac.update_device(device=weather_station) 

126 

127 # ToDo: Semantically connect the zone temperature sensor and the thermal 

128 # zone by adding a `hasTemperatureSensor` attribute of type 

129 # `Relationship` to the thermal zone entity. 

130 # For the connection from the sensor to the zone add a static 

131 # attribute to the temperature sensor device. 

132 

133 # ToDo: Create a context attribute for the thermal zone and add it to the 

134 # thermal zone entity. 

135 has_sensor = NamedContextAttribute( 

136 name="hasTemperatureSensor", 

137 type="Relationship", 

138 value=zone_temperature_sensor.entity_name, 

139 ) 

140 thermal_zone.add_attributes(attrs=[has_sensor]) 

141 

142 # ToDo: Create a static attribute that connects the zone temperature zone to 

143 # the thermal zone. 

144 cbc.update_entity(entity=thermal_zone) 

145 

146 ref_thermal_zone = StaticDeviceAttribute( 

147 name="refThermalZone", type="Relationship", value=thermal_zone.id 

148 ) 

149 zone_temperature_sensor.add_attribute(ref_thermal_zone) 

150 iotac.update_device(device=zone_temperature_sensor) 

151 

152 # ToDo: Semantically connect the zone temperature sensor and the thermal 

153 # zone by adding a `hasTemperatureSensor` attribute of type 

154 # `Relationship` to the thermal zone entity. 

155 # For the connection from the sensor to the zone add a static 

156 # attribute to the temperature sensor device. 

157 

158 # ToDo: Create a context attribute for the thermal zone and add it to the 

159 # thermal zone entity. 

160 has_heater = NamedContextAttribute( 

161 name="hasHeater", type="Relationship", value=heater.entity_name 

162 ) 

163 thermal_zone.add_attributes(attrs=[has_heater]) 

164 

165 # ToDo: Create a static attribute that connects the zone temperature zone to 

166 # the thermal zone. 

167 cbc.update_entity(entity=thermal_zone) 

168 

169 ref_thermal_zone = StaticDeviceAttribute( 

170 name="refThermalZone", type="Relationship", value=thermal_zone.id 

171 ) 

172 heater.add_attribute(ref_thermal_zone) 

173 iotac.update_device(device=heater) 

174 

175 # ToDo: Add unit metadata to the temperature and sim_time attributes of 

176 # all devices. Here we use unit code information. If you can not find 

177 # your unit code, you can use our unit models for help. 

178 # get code from Unit model for seconds 

179 code = Unit(name="second [unit of time]").code 

180 # add metadata to sim_time attribute of the all devices 

181 metadata_sim_time = NamedMetadata(name="unitCode", type="Text", value=code) 

182 attr_sim_time = weather_station.get_attribute(attribute_name="sim_time") 

183 attr_sim_time.metadata = metadata_sim_time 

184 weather_station.update_attribute(attribute=attr_sim_time) 

185 zone_temperature_sensor.update_attribute(attribute=attr_sim_time) 

186 heater.update_attribute(attribute=attr_sim_time) 

187 

188 # ToDo: Get code from Unit model for degree celsius. 

189 code = Unit(name="degree Celsius").code 

190 # ToDo: Add metadata to temperature attribute of the weather 

191 # station and the zone temperature sensor. 

192 metadata_t_amb = NamedMetadata(name="unitCode", type="Text", value=code) 

193 attr_t_amb = weather_station.get_attribute(attribute_name="temperature") 

194 attr_t_amb.metadata = metadata_t_amb 

195 weather_station.update_attribute(attribute=attr_t_amb) 

196 

197 metadata_t_zone = NamedMetadata(name="unitCode", type="Text", value=code) 

198 attr_t_zone = zone_temperature_sensor.get_attribute(attribute_name="temperature") 

199 attr_t_zone.metadata = metadata_t_zone 

200 zone_temperature_sensor.update_attribute(attribute=attr_t_zone) 

201 

202 # Currently adding metadata via updating does not work perfectly, 

203 # therefore, we delete and update them. 

204 iotac.delete_device(device_id=weather_station.device_id) 

205 iotac.post_device(device=weather_station) 

206 iotac.delete_device(device_id=zone_temperature_sensor.device_id) 

207 iotac.post_device(device=zone_temperature_sensor) 

208 iotac.delete_device(device_id=heater.device_id) 

209 iotac.post_device(device=heater) 

210 

211 # ToDo: Retrieve all Context Entities and print them. 

212 entities = cbc.get_entity_list() 

213 for entity in entities: 

214 print(entity.model_dump_json(indent=2)) 

215 

216 clear_iot_agent(url=IOTA_URL, fiware_header=fiware_header) 

217 clear_context_broker(url=CB_URL, fiware_header=fiware_header)