Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add entity update with keyValues #245

Merged
merged 5 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- fix: compare subscriptions to prevent duplicated notifications @FWuellhorst, @RCX112 ([#138](https://github.com/RWTH-EBC/FiLiP/pull/138))
- update pandas version to `~=2.1.4` for `python>=3.9` ([#231](https://github.com/RWTH-EBC/FiLiP/pull/231))
- fix: wrong msg in iotac post device ([#214](https://github.com/RWTH-EBC/FiLiP/pull/214))
- add support to update entities with keyValues @djs0109 ([#245](https://github.com/RWTH-EBC/FiLiP/pull/245))
- add function to override the existing entity ([#232 ](https://github.com/RWTH-EBC/FiLiP/pull/232 ))

#### v0.3.0
Expand Down
74 changes: 74 additions & 0 deletions filip/clients/ngsi_v2/cb.py
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,80 @@ def update_or_append_entity_attributes(
self.log_error(err=err, msg=msg)
raise

def update_entity_key_value(self,
entity: Union[ContextEntityKeyValues, dict],):
"""
The entity are updated with a ContextEntityKeyValues object or a
dictionary contain the simplified entity data. This corresponds to a
'PATcH' request.
Only existing attribute can be updated!

Args:
entity: A ContextEntityKeyValues object or a dictionary contain
the simplified entity data

"""
if isinstance(entity, dict):
entity = ContextEntityKeyValues(**entity)
url = urljoin(self.base_url, f'v2/entities/{entity.id}/attrs')
headers = self.headers.copy()
params = {"type": entity.type,
"options": AttrsFormat.KEY_VALUES.value
}
try:
res = self.patch(url=url,
headers=headers,
json=entity.model_dump(exclude={'id', 'type'},
exclude_unset=True),
params=params)
if res.ok:
self.logger.info("Entity '%s' successfully "
"updated!", entity.id)
else:
res.raise_for_status()
except requests.RequestException as err:
msg = f"Could not update attributes of entity" \
f" {entity.id} !"
self.log_error(err=err, msg=msg)
raise

def update_entity_attributes_key_value(self,
entity_id: str,
attrs: dict,
entity_type: str = None,
):
"""
Update entity with attributes in keyValues form.
This corresponds to a 'PATcH' request.
Only existing attribute can be updated!

Args:
entity_id: Entity id to be updated
entity_type: Entity type, to avoid ambiguity in case there are
several entities with the same entity id.
attrs: a dictionary that contains the attribute values.
e.g. {
"temperature": 21.4,
"humidity": 50
}

Returns:

"""
if entity_type:
pass
else:
_entity = self.get_entity(entity_id=entity_id)
entity_type = _entity.type

entity_dict = attrs.copy()
entity_dict.update({
"id": entity_id,
"type": entity_type
})
entity = ContextEntityKeyValues(**entity_dict)
self.update_entity_key_value(entity=entity)

def update_existing_entity_attributes(
self,
entity_id: str,
Expand Down
47 changes: 46 additions & 1 deletion tests/clients/test_ngsi_v2_cb.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
NamedContextAttribute, \
NamedCommand, \
Query, \
ActionType
ActionType, \
ContextEntityKeyValues

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

@clean_test(fiware_service=settings.FIWARE_SERVICE,
fiware_servicepath=settings.FIWARE_SERVICEPATH,
cb_url=settings.CB_URL)
def test_update_entity_keyvalues(self):
entity1 = self.entity.model_copy(deep=True)
# initial entity
self.client.post_entity(entity1)

# key value
entity1_key_value = self.client.get_entity(
entity_id=entity1.id,
response_format=AttrsFormat.KEY_VALUES)

# update entity with ContextEntityKeyValues
entity1_key_value.temperature = 30
self.client.update_entity_key_value(entity=entity1_key_value)
self.assertEqual(entity1_key_value,
self.client.get_entity(
entity_id=entity1.id,
response_format=AttrsFormat.KEY_VALUES)
)
entity2 = self.client.get_entity(entity_id=entity1.id)
self.assertEqual(entity1.temperature.type,
entity2.temperature.type)

# update entity with dictionary
entity1_key_value_dict = entity1_key_value.model_dump()
entity1_key_value_dict["temperature"] = 40
self.client.update_entity_key_value(entity=entity1_key_value_dict)
self.client.get_entity(
entity_id=entity1.id,
response_format=AttrsFormat.KEY_VALUES).model_dump()
self.assertEqual(entity1_key_value_dict,
self.client.get_entity(
entity_id=entity1.id,
response_format=AttrsFormat.KEY_VALUES).model_dump()
)
entity3 = self.client.get_entity(entity_id=entity1.id)
self.assertEqual(entity1.temperature.type,
entity3.temperature.type)
entity1_key_value_dict.update({"humidity": 50})
with self.assertRaises(RequestException):
self.client.update_entity_key_value(entity=entity1_key_value_dict)

@clean_test(fiware_service=settings.FIWARE_SERVICE,
fiware_servicepath=settings.FIWARE_SERVICEPATH,
cb_url=settings.CB_URL)
Expand Down