Skip to content

Commit 41e7349

Browse files
authored
Merge pull request #245 from RWTH-EBC/243-support-keyValues-when-update-entities
feat: add entity update with keyValues
2 parents 4b58a6b + 1f0e7aa commit 41e7349

File tree

3 files changed

+121
-1
lines changed

3 files changed

+121
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- fix: compare subscriptions to prevent duplicated notifications @FWuellhorst, @RCX112 ([#138](https://github.com/RWTH-EBC/FiLiP/pull/138))
55
- update pandas version to `~=2.1.4` for `python>=3.9` ([#231](https://github.com/RWTH-EBC/FiLiP/pull/231))
66
- fix: wrong msg in iotac post device ([#214](https://github.com/RWTH-EBC/FiLiP/pull/214))
7+
- add support to update entities with keyValues @djs0109 ([#245](https://github.com/RWTH-EBC/FiLiP/pull/245))
78
- add function to override the existing entity ([#232 ](https://github.com/RWTH-EBC/FiLiP/pull/232 ))
89

910
#### v0.3.0

filip/clients/ngsi_v2/cb.py

+74
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,80 @@ def update_or_append_entity_attributes(
731731
self.log_error(err=err, msg=msg)
732732
raise
733733

734+
def update_entity_key_value(self,
735+
entity: Union[ContextEntityKeyValues, dict],):
736+
"""
737+
The entity are updated with a ContextEntityKeyValues object or a
738+
dictionary contain the simplified entity data. This corresponds to a
739+
'PATcH' request.
740+
Only existing attribute can be updated!
741+
742+
Args:
743+
entity: A ContextEntityKeyValues object or a dictionary contain
744+
the simplified entity data
745+
746+
"""
747+
if isinstance(entity, dict):
748+
entity = ContextEntityKeyValues(**entity)
749+
url = urljoin(self.base_url, f'v2/entities/{entity.id}/attrs')
750+
headers = self.headers.copy()
751+
params = {"type": entity.type,
752+
"options": AttrsFormat.KEY_VALUES.value
753+
}
754+
try:
755+
res = self.patch(url=url,
756+
headers=headers,
757+
json=entity.model_dump(exclude={'id', 'type'},
758+
exclude_unset=True),
759+
params=params)
760+
if res.ok:
761+
self.logger.info("Entity '%s' successfully "
762+
"updated!", entity.id)
763+
else:
764+
res.raise_for_status()
765+
except requests.RequestException as err:
766+
msg = f"Could not update attributes of entity" \
767+
f" {entity.id} !"
768+
self.log_error(err=err, msg=msg)
769+
raise
770+
771+
def update_entity_attributes_key_value(self,
772+
entity_id: str,
773+
attrs: dict,
774+
entity_type: str = None,
775+
):
776+
"""
777+
Update entity with attributes in keyValues form.
778+
This corresponds to a 'PATcH' request.
779+
Only existing attribute can be updated!
780+
781+
Args:
782+
entity_id: Entity id to be updated
783+
entity_type: Entity type, to avoid ambiguity in case there are
784+
several entities with the same entity id.
785+
attrs: a dictionary that contains the attribute values.
786+
e.g. {
787+
"temperature": 21.4,
788+
"humidity": 50
789+
}
790+
791+
Returns:
792+
793+
"""
794+
if entity_type:
795+
pass
796+
else:
797+
_entity = self.get_entity(entity_id=entity_id)
798+
entity_type = _entity.type
799+
800+
entity_dict = attrs.copy()
801+
entity_dict.update({
802+
"id": entity_id,
803+
"type": entity_type
804+
})
805+
entity = ContextEntityKeyValues(**entity_dict)
806+
self.update_entity_key_value(entity=entity)
807+
734808
def update_existing_entity_attributes(
735809
self,
736810
entity_id: str,

tests/clients/test_ngsi_v2_cb.py

+46-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
NamedContextAttribute, \
2626
NamedCommand, \
2727
Query, \
28-
ActionType
28+
ActionType, \
29+
ContextEntityKeyValues
2930

3031
from filip.models.ngsi_v2.base import AttrsFormat, EntityPattern, Status, \
3132
NamedMetadata
@@ -692,6 +693,50 @@ def on_disconnect(client, userdata, reasonCode, properties=None):
692693
mqtt_client.disconnect()
693694
time.sleep(1)
694695

696+
@clean_test(fiware_service=settings.FIWARE_SERVICE,
697+
fiware_servicepath=settings.FIWARE_SERVICEPATH,
698+
cb_url=settings.CB_URL)
699+
def test_update_entity_keyvalues(self):
700+
entity1 = self.entity.model_copy(deep=True)
701+
# initial entity
702+
self.client.post_entity(entity1)
703+
704+
# key value
705+
entity1_key_value = self.client.get_entity(
706+
entity_id=entity1.id,
707+
response_format=AttrsFormat.KEY_VALUES)
708+
709+
# update entity with ContextEntityKeyValues
710+
entity1_key_value.temperature = 30
711+
self.client.update_entity_key_value(entity=entity1_key_value)
712+
self.assertEqual(entity1_key_value,
713+
self.client.get_entity(
714+
entity_id=entity1.id,
715+
response_format=AttrsFormat.KEY_VALUES)
716+
)
717+
entity2 = self.client.get_entity(entity_id=entity1.id)
718+
self.assertEqual(entity1.temperature.type,
719+
entity2.temperature.type)
720+
721+
# update entity with dictionary
722+
entity1_key_value_dict = entity1_key_value.model_dump()
723+
entity1_key_value_dict["temperature"] = 40
724+
self.client.update_entity_key_value(entity=entity1_key_value_dict)
725+
self.client.get_entity(
726+
entity_id=entity1.id,
727+
response_format=AttrsFormat.KEY_VALUES).model_dump()
728+
self.assertEqual(entity1_key_value_dict,
729+
self.client.get_entity(
730+
entity_id=entity1.id,
731+
response_format=AttrsFormat.KEY_VALUES).model_dump()
732+
)
733+
entity3 = self.client.get_entity(entity_id=entity1.id)
734+
self.assertEqual(entity1.temperature.type,
735+
entity3.temperature.type)
736+
entity1_key_value_dict.update({"humidity": 50})
737+
with self.assertRaises(RequestException):
738+
self.client.update_entity_key_value(entity=entity1_key_value_dict)
739+
695740
@clean_test(fiware_service=settings.FIWARE_SERVICE,
696741
fiware_servicepath=settings.FIWARE_SERVICEPATH,
697742
cb_url=settings.CB_URL)

0 commit comments

Comments
 (0)