Coverage for tutorials/ngsi_v2/e3_context_entities/e3_context_entities.py: 0%
11 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 3: Context Entities and Relationships
4# Create a building context entity of type 'Building' according to FIWARE's
5# SmartData Models with the properties: `id`, `type`, `address`, `category`,
6# https://github.com/smart-data-models/dataModel.Building/blob/master/Building/doc/spec.md
8# For the single properties check the "Data Model description of
9# properties" section. The input sections are marked with 'ToDo'
11# #### Steps to complete:
12# 1. Set up the missing parameters in the parameter section
13# 2. Find the Building data model online:
14# https://github.com/smart-data-models/dataModel.Building/blob/master/Building/doc/spec.md
15# 3. Create a `ContextEntity` object for your building
16# 4. Create the required `ContextAttributes` and add them to your building model
17# 5. Create a `ContextBrokerClient` and add post your building to the
18# ContextBroker. Afterwards, check if the Context Broker returns the
19# correct information about your building
20# 6. Create an `opening hours` attribute add them to the server
21# 7. Retrieve the `opening hours`, manipulate them and update the model in the
22# server
23# 8. Repeat the procedure with a thermal zone. Currently, the smart data
24# models hold no definition of a thermal zone. Therefore, we first only add a
25# description attribute.
26# 9. Add a `Relationship` attribute to your thermal zone with the name
27# `refBuilding` and type `Relationship` pointing to your building and post
28# the model to the context broker
29# 10. Add a `Relationship` attribute to your building with name
30# `hasZone` and type `Relationship` pointing to your thermal zone and
31# update the model in the context broker.
32# 11. Update the thermal zone and the building in the context broker
33# 12. Retrieve the data by using query statements for their relationships.
34"""
36# ## Import packages
37import json
38from pathlib import Path
40# filip imports
41from filip.clients.ngsi_v2 import ContextBrokerClient
42from filip.models import FiwareHeader
43from filip.models.ngsi_v2.context import ContextEntity, NamedContextAttribute
44from filip.utils.cleanup import clear_context_broker
45from filip.utils.simple_ql import QueryString
47# ## Parameters
48# ToDo: Enter your context broker host and port, e.g. http://localhost:1026.
49CB_URL = "http://localhost:1026"
51# ToDo: Change the name of your service to something unique. If you run
52# on a shared instance this is very important in order to avoid user
53# collisions. You will use this service through the whole tutorial.
54# If you forget to change it, an error will be raised!
55# FIWARE-Service
56SERVICE = "filip_tutorial"
57# FIWARE-Service path
58SERVICE_PATH = "/"
60# ToDo: Path to json-files to store entity data for follow up exercises,
61# e.g. ../e3_my_entities.json. Files that are used in exercises and files
62# that are used in solutions are different from each other so be careful
63# when working with them. You can of course change the paths as you wish,
64# but it is recommended to use the already given path names.
65WRITE_ENTITIES_FILEPATH = Path("../e3_context_entities.json")
67# ## Main script
68if __name__ == "__main__":
69 # create a fiware header object
70 fiware_header = FiwareHeader(service=SERVICE, service_path=SERVICE_PATH)
71 # clear the state of your service and scope
72 clear_context_broker(url=CB_URL, fiware_header=fiware_header)
74 # Create a context entity for a `building` following the smart data models
75 # specifications
76 building = ContextEntity(id="urn:ngsi-ld:building:001", type="Building")
78 # create the property `category` to your building
79 category = NamedContextAttribute(name="category", type="Array", value=["office"])
81 # ToDo: Create a property `address` for your building. Follow the full yaml
82 # description in the specifications. It reuses the specification from
83 # here: https://schema.org/PostalAddress
84 address = NamedContextAttribute(name="address", type="PostalAddress", value={...})
86 # ToDo: Create a `description` property for your building.
87 building_description = NamedContextAttribute(...)
89 # add all properties to your building using the
90 # `add_attribute` function of your building object
91 building.add_attributes(attrs=[building_description, category, address])
93 # ToDo: Create a context broker client and add the fiware_header.
94 cbc = ...
95 # ToDo: Send your building model to the context broker. Check the client
96 # for proper functioning.
97 ...
99 # Update your local building model with the one from the server
100 building = cbc.get_entity(entity_id=building.id, entity_type=building.type)
102 # print your `building model` as json
103 print(f"This is your building model: \n {building.model_dump_json(indent=2)} \n")
105 # ToDo: Create an `opening hours` property and add it to the building object
106 # in the context broker. Do not update the whole entity! In real
107 # scenarios it might have been modified by other users.
108 opening_hours = NamedContextAttribute(
109 name="openingHours", type="array", value=[...]
110 )
112 cbc.update_or_append_entity_attributes(
113 entity_id=building.id, entity_type=building.type, attrs=[opening_hours]
114 )
116 # ToDo: Retrieve and print the property `opening hours`.
117 hours = cbc.get_attribute_value(...)
119 print(f"Your opening hours: {hours} \n")
121 # ToDo: Modify the property `opening hours` of the building.
122 cbc.update_attribute_value(...)
124 # ToDo: At this point you might have already noticed that your local
125 # building model and the building model in the context broker are out of
126 # sync. Hence, synchronize them again!
127 building = cbc.get_entity(entity_id=building.id, entity_type=building.type)
129 # print your building
130 print(f"Your updated building model: \n {building.model_dump_json(indent=2)} \n")
132 # ToDo: Create an entity of the thermal zone and add a description property
133 # to it.
134 thermal_zone = ContextEntity(id="ThermalZone:001", type="ThermalZone")
136 thermal_zone_description = NamedContextAttribute(
137 name="description",
138 type="Text",
139 value="This zones covers " "the entire building",
140 )
141 thermal_zone.add_attributes(attrs=[thermal_zone_description])
143 # ToDo: Create and add a property that references your building model. Use the
144 # `Relationship` for type and `refBuilding` for its name.
145 ref_building = NamedContextAttribute(
146 name="refBuilding", type="Relationship", value=building.id
147 )
148 thermal_zone.add_attributes(attrs=[ref_building])
150 # print all relationships of your thermal zone
151 for relationship in thermal_zone.get_relationships():
152 print(
153 f"Relationship properties of your thermal zone model: \n "
154 f"{relationship.model_dump_json(indent=2)} \n"
155 )
157 # ToDo: Post your thermal zone model to the context broker.
158 ...
159 ...
161 # ToDo: Create and add a property that references your thermal zone. Use the
162 # `Relationship` for type and `hasZone` for its name. Make sure that
163 # your local model and the server model are in sync afterwards.
164 ref_zone = NamedContextAttribute(...)
166 cbc.update_or_append_entity_attributes(...)
168 building = cbc.get_entity(entity_id=building.id, entity_type=building.type)
170 # ToDo: Create a filter request that retrieves all entities from the
171 # server that have `refBuilding` attribute that reference your building
172 # by using the FIWARE's simple query language.
173 # `filip.utils.simple_ql` module helps you to validate your query string.
174 # 1. Prepare the query string using the `filip.utils.simple_ql`.
175 # 2. Use the string in a context broker request and retrieve the entities.
176 query = QueryString(qs=("refBuilding", "==", building.id))
177 for entity in cbc.get_entity_list(q=query):
178 print(
179 f"All entities referencing the building: "
180 f"\n {entity.model_dump_json(indent=2)}\n"
181 )
183 # ToDo: Create a filter request that retrieves all entities from the
184 # server that have `hasZone` attribute that reference your thermal zone
185 # by using the FIWARE's simple query language.
186 # `filip.utils.simple_ql` module helps you to validate your query string.
187 # 1. Prepare the query string using the `filip.utils.simple_ql`.
188 # 2. Use the string in a context broker request and retrieve the entities.
189 query = ...
190 for entity in cbc.get_entity_list(q=query):
191 print(
192 f"All entities referencing the thermal zone: "
193 f"\n {entity.model_dump_json(indent=2)} \n"
194 )
196 # write entities to file and clear server state
197 assert (
198 WRITE_ENTITIES_FILEPATH.suffix == ".json"
199 ), f"Wrong file extension! {WRITE_ENTITIES_FILEPATH.suffix}"
200 WRITE_ENTITIES_FILEPATH.touch(exist_ok=True)
201 with WRITE_ENTITIES_FILEPATH.open("w", encoding="utf-8") as f:
202 entities = [item.model_dump() for item in cbc.get_entity_list()]
203 json.dump(entities, f, ensure_ascii=False, indent=2)
205 clear_context_broker(url=CB_URL, fiware_header=fiware_header)