Coverage for tutorials/ngsi_v2/e7_semantic_iot/e7_semantic_iot.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# FIWARE-Service 

43SERVICE = "filip_tutorial" 

44# FIWARE-Service path 

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

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

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

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

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_groups.json") 

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

59READ_ENTITIES_FILEPATH = Path("../e3_context_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 = ... 

136 

137 thermal_zone.add_attributes(...) 

138 

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

140 # the thermal zone. 

141 cbc.update_entity(entity=thermal_zone) 

142 

143 ref_thermal_zone = StaticDeviceAttribute(...) 

144 

145 zone_temperature_sensor.add_attribute(ref_thermal_zone) 

146 iotac.update_device(device=zone_temperature_sensor) 

147 

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

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

150 # `Relationship` to the thermal zone entity. 

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

152 # attribute to the temperature sensor device. 

153 

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

155 # thermal zone entity. 

156 has_heater = ... 

157 

158 thermal_zone.add_attributes(...) 

159 

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

161 # the thermal zone. 

162 cbc.update_entity(entity=thermal_zone) 

163 

164 ref_thermal_zone = ... 

165 

166 heater.add_attribute(ref_thermal_zone) 

167 iotac.update_device(device=heater) 

168 

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

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

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

172 # get code from Unit model for seconds 

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

174 # add metadata to sim_time attribute of the all devices 

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

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

177 attr_sim_time.metadata = metadata_sim_time 

178 weather_station.update_attribute(attribute=attr_sim_time) 

179 zone_temperature_sensor.update_attribute(attribute=attr_sim_time) 

180 heater.update_attribute(attribute=attr_sim_time) 

181 

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

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

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

185 # station and the zone temperature sensor. 

186 metadata_t_amb = NamedMetadata(...) 

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

188 attr_t_amb.metadata = metadata_t_amb 

189 weather_station.update_attribute(attribute=attr_t_amb) 

190 

191 metadata_t_zone = NamedMetadata(...) 

192 attr_t_zone = zone_temperature_sensor.get_attribute(attribute_name="...") 

193 attr_t_zone.metadata = ... 

194 zone_temperature_sensor.update_attribute(...) 

195 

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

197 # therefore, we delete and update them. 

198 iotac.delete_device(device_id=weather_station.device_id) 

199 iotac.post_device(device=weather_station) 

200 iotac.delete_device(device_id=zone_temperature_sensor.device_id) 

201 iotac.post_device(device=zone_temperature_sensor) 

202 iotac.delete_device(device_id=heater.device_id) 

203 iotac.post_device(device=heater) 

204 

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

206 entities = ... 

207 for entity in entities: 

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

209 

210 clear_iot_agent(url=IOTA_URL, fiware_header=fiware_header) 

211 clear_context_broker(url=CB_URL, fiware_header=fiware_header)