ContextBroker Vectors UPDATE with unchanged value causes ONCHANGE subscription notification - fiware-orion

I have a JSON formatted as this one:
{
"contextElements": [
{
"type": "environment",
"isPattern": "false",
"id": "labMax",
"attributes": [
{
"name": "users",
"type": "vector",
"value": [{"userId":"0001", "status":"0"},{"userId":"0002", "status":"0"}]
},
{
"name": "rooms",
"type": "vector",
"value": [{"room1": [ {"id":"room1"}, {"owner":"1"}]},{"id":"room2"}, {"owner":"2"}]
},
{
"name": "sensors",
"type": "vector",
"value": [
{"sensor1": [ {"id":"1"}, {"location":"room1"},{"value":"11"},{"status":"ok"}]},
{"sensor2": [ {"id":"2"}, {"location":"room1"},{"value":"22"},{"status":"update"}]}
]
}
]
}
],
"updateAction": "APPEND"
}
I have also a subscription ONCHANGE on the attribute "sensors" and when I update it, without changing any value inside the vector, it causes a notification. Probably this is a wrong behaviour because a subscriber should be only notified when a value changes. On the other side, if I use strings or integer as attributes values, it works correctly.

Up to Orion 0.16.0 at least, this is a known behaviour. An issue has been openend in the Orion github.com repository about it.

Related

AWS Stepfunction: Substring from input

As a general question is it possible do a substring function within step functions?
I receive the following event:
{
"input": {
"version": "0",
"id": "d9c5fec0-d08d-6abd-4ea5-0107fbbce47d",
"detail-type": "EBS Multi-Volume Snapshots Completion Status",
"source": "aws.ec2",
"account": "12345678",
"time": "2021-11-12T12:08:16Z",
"region": "us-east-1",
"resources": [
"arn:aws:ec2::us-east-1:snapshot/snap-0a98c2a42ee266123"
]
}
}
but need the snapshot id as input to DescribeInstances, therefore I need to extract snap-0a98c2a42ee266123 from arn:aws:ec2::us-east-1:snapshot/snap-0a98c2a42ee266123
Is there any simple way to do this within step functions?. That is to say without having to pass it to a lambda or something equally convoluted?
This has recently become possible with the addition of new intrinsic functions. ArrayGetItem gets an item by its index. StringSplit splits a string at a delimeter. Use a Pass state to extract the snapshot name from the resource ARN:
{
"StartAt": "ExtractSnapshotName",
"States": {
"ExtractSnapshotName": {
"Type": "Pass",
"Parameters": {
"input.$": "$.input",
"snapshotName.$": "States.ArrayGetItem(States.StringSplit(States.ArrayGetItem($.input.resources,0), '/'),1)"
},
"ResultPath": "$",
"End": true
}
}
}
output:
{
"input": {
"version": "0",
"id": "d9c5fec0-d08d-6abd-4ea5-0107fbbce47d",
"detail-type": "EBS Multi-Volume Snapshots Completion Status",
"source": "aws.ec2",
"account": "12345678",
"time": "2021-11-12T12:08:16Z",
"region": "us-east-1",
"resources": [
"arn:aws:ec2::us-east-1:snapshot/snap-0a98c2a42ee266123"
]
},
"snapshotName": "snap-0a98c2a42ee266123"
}

Google Action / Dialogflow : how to ask for geolocation

I'm trying to implement a simple app for Google Assistant.
All works fine, but now I have a problem with the "permission" helper :
https://developers.google.com/actions/assistant/helpers#helper_intents
I have an intent connected with webhook to my java application. When an user types a sentence similar to "near to me", I want to ask to him his location and then use lat/lon to perform a search.
es: Brazilian restaurant near to me
my intent "searchRestaurant" is fired
I receive the webhook request and I parse it
if I find a parameter that is connected to a sentence like "near to me", so instead to response with a "Card" or a "List" I return a JSON that represent the helper request :
{
"conversationToken": "[]",
"expectUserResponse": true,
"expectedInputs": [
{
"inputPrompt": {
"initialPrompts": [
{
"textToSpeech": "PLACEHOLDER_FOR_PERMISSION"
}
],
"noInputPrompts": []
},
"possibileIntents": [
{
"intent": "actions.intent.PERMISSION",
"inputValueData": {
"#type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
"optContext": "Posso accedere alla tua posizione?",
"permission": [
"NAME",
"DEVICE_PRECISE_LOCATION"
]
}
}
]
}
]
}
but something seems to be wrong, and I receive an error:
"{\n \"responseMetadata\": {\n \"status\": {\n \"code\": 10,\n \"message\": \"Failed to parse Dialogflow response into AppResponse because of empty speech response\",\n \"details\": [{\n \"#type\": \"type.googleapis.com/google.protobuf.Value\",\n \"value\": \"{\\"id\\":\\"1cc45c5e-c398-4ea7-98a5-408f31ce142d\\",\\"timestamp\\":\\"2018-08-02T14:45:05.752Z\\",\\"lang\\":\\"it\\",\\"result\\":{},\\"alternateResult\\":{},\\"status\\":{\\"code\\":206,\\"errorType\\":\\"partial_content\\",\\"errorDetails\\":\\"Webhook call failed. Error: Failed to parse webhook JSON response: Cannot find field: conversationToken in message google.cloud.dialogflow.v2.WebhookResponse.\\"},\\"sessionId\\":\\"1533221100163\\"}\"\n }]\n }\n }\n}"
The "conversationToken" is filled, so I don't understand the error message.
Maybe I'm trying to perform the operation in a wrong way.
So, which is the correct way to call this helper?
--> I've created a second intent "askGeolocation" that have "actions_intent_PERMISSION" as "Event", and ... if I understand correctly the documentation, should be trigger if the request for helper is correct.
How can I get this working?
UPDATE :
I find some example of the json response for ask permission and seems that it should be different from the one above that i'm using :
https://github.com/dialogflow/fulfillment-webhook-json/blob/master/responses/v2/ActionsOnGoogle/AskForPermission.json
{
"payload": {
"google": {
"expectUserResponse": true,
"systemIntent": {
"intent": "actions.intent.PERMISSION",
"data": {
"#type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
"optContext": "To deliver your order",
"permissions": [
"NAME",
"DEVICE_PRECISE_LOCATION"
]
}
}
}
}
}
so, i've implemented it and now the response seems to be good (no more error on parsing it), but i still receive an error on it validation :
UnparseableJsonResponse
API Version 2: Failed to parse JSON response string with 'INVALID_ARGUMENT' error: "permission: Cannot find field."
so, a problem still persist.
Anyone know the cause?
Thanks
After some tests i found the problem.
I was returning a wrong json repsonse with "permission" instead of "permissions":
"permission**s**": [
"NAME",
"DEVICE_PRECISE_LOCATION"
]
So the steps to ask for location are correct. I report them here as a little tutorial in order to help who is facing on it for the first time:
1) In DialogFlow, add some logic to your Intent, in order to understand when is ok to ask to user his location. In my case, i've added a "parameter" that identify sentences like "nearby" and so on.
2) When my Intent is fired i receive to my java application a request like this :
...
"queryResult": {
"queryText": "ristorante argentino qui vicino",
"action": "bycategory",
"parameters": {
"askgeolocation": "qui vicino",
"TipoRistorante": ["ristorante", "argentino"]
},
...
3) If "askgeolocation" parameter is filled, instead to return a "simple message" o other type of message, i return a json for ask the permission to geolocation :
{
"payload": {
"google": {
"expectUserResponse": true,
"systemIntent": {
"intent": "actions.intent.PERMISSION",
"data": {
"#type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
"optContext": "To deliver your order",
"permissions": [
"NAME",
"DEVICE_PRECISE_LOCATION"
]
}
}
}
}
}
4) You MUST have a second Intent that is configured with "actions_intent_PERMISSION " event :
No training phrases
No Action and params
No Responses
But with Fulfillment active :
5) Once your response arrive to Google Assistant this is the message that appear :
6) Now, if user answer "ok" you receive this json on your webhook :
{
"responseId": "32cf46cf-80d8-xxxxxxxxxxxxxxxxxxxxx",
"queryResult": {
"queryText": "actions_intent_PERMISSION",
"action": "geoposition",
"parameters": {
},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [{
"text": {
"text": [""]
}
}],
"outputContexts": [{
"name": "projects/xxxxxxxxxxxxxxxxxxxxx"
}, {
"name": "projects/xxxxxxxxxxxxxxxxxxxxx",
"parameters": {
"PERMISSION": true
}
}, {
"name": "projects/xxxxxxxxxxxxxxxxxxxxx"
}, {
"name": "projects/xxxxxxxxxxxxxxxxxxxxx"
}, {
"name": "projects/xxxxxxxxxxxxxxxxxxxxx"
}, {
"name": "projects/xxxxxxxxxxxxxxxxxxxxx"
}],
"intent": {
"name": "projects/xxxxxxxxxxxxxxxxxxxxx",
"displayName": "geoposition"
},
"intentDetectionConfidence": 1.0,
"languageCode": "it"
},
"originalDetectIntentRequest": {
"source": "google",
"version": "2",
"payload": {
"isInSandbox": true,
"surface": {
"capabilities": [{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
}, {
"name": "actions.capability.SCREEN_OUTPUT"
}, {
"name": "actions.capability.AUDIO_OUTPUT"
}, {
"name": "actions.capability.WEB_BROWSER"
}]
},
"requestType": "SIMULATOR",
"inputs": [{
"rawInputs": [{
"inputType": "KEYBOARD"
}],
"arguments": [{
"textValue": "true",
"name": "PERMISSION",
"boolValue": true
}],
"intent": "actions.intent.PERMISSION"
}],
"user": {
"lastSeen": "2018-08-03T08:55:20Z",
"permissions": ["NAME", "DEVICE_PRECISE_LOCATION"],
"profile": {
"displayName": ".... full name of the user ...",
"givenName": "... name ...",
"familyName": "... surname ..."
},
"locale": "it-IT",
"userId": "xxxxxxxxxxxxxxxxxxxxx"
},
"device": {
"location": {
"coordinates": {
"latitude": 45.xxxxxx,
"longitude": 9.xxxxxx
}
}
},
"conversation": {
"conversationId": "xxxxxxxxxxxxxxxxxxxxx",
"type": "ACTIVE",
"conversationToken": "[]"
},
"availableSurfaces": [{
"capabilities": [{
"name": "actions.capability.SCREEN_OUTPUT"
}, {
"name": "actions.capability.AUDIO_OUTPUT"
}, {
"name": "actions.capability.WEB_BROWSER"
}]
}]
}
},
"session": "projects/xxxxxxxxxxxxxxxxxxxxx"
}
that contains, name/surname and latitude/longitude. This information can be saved in your application, in order to not perform again this steps.
I hope this helps.
Davide
In your intent, you can ask for a parameter with a custom Entity. This you can do like this:
entity you can define as "near"
put all the synonyms for near for which you want to trigger location permission in this entity
do not mark this parameter as "required"
do not put any prompt
in the training phrases, add some phrases with this parameter
in your webhook, keep a check on the parameter, if present ask for permission if not continue.
add a permission event to another intent
do your post permission processing in that intent
Entity
Intent
I hope you get it.
There are samples on this topic specifically that guide you through exactly what's needed for requesting permissions in Node and Java.
Note: There are helper intents samples available in Node and Java as well.

Magento 2 REST API - get product by slug, or get media in REST search

I have an ember app which I'm using as the front end. I need to fetch a product from the REST api but instead of using the SKU, I need to use the slug. So I access the following endpoint which works fine: http://*.com/index.php/rest/V1/products?searchCriteria[filter_groups][0][filters][0][field]=url_key&searchCriteria[filter_groups][0][filters][0][value]=daniels-icecream-slug
However, the result is obviously a product list as opposed to the product endpoint, so some of the data is omitted. Namely, the media_gallery_entries field. So is there anyways I can either return this data in the /products?searchCriteria endpoint or is there a way I can fetch /products/:slug instead of /products/:sku for the product endpoint?
you need to define conditionType as well with the API Call like following
V1/products/?searchCriteria[filterGroups][0][filters][0][field]=url_key&searchCriteria[filterGroups][0][filters][0][value]=%shirt%&searchCriteria[filterGroups][0][filters][0][condition_type]=like
Parameters :
searchCriteria[filterGroups][0][filters][0][field]=url_key
searchCriteria[filterGroups][0][filters][0][value]=%shirt%
searchCriteria[filterGroups][0][filters][0][condition_type]=like
Note: Make sure to prefix & suffix % in value as per your requirements.
I am using the same in my api Calls and it works
I'm using Magento v2.2, and when I do a search, each item has a image attribute (in the custom_attributes list) that mangento automatically adds to a product when up add an image to it:
{
"items": [{
"sku": "MH07-XS-Black",
"name": "Hero Hoodie-XS-Black",
"custom_attributes": [{
"attribute_code": "description",
"value": "<p>Gray and black color blocking sets you apart as the Hero Hoodie keeps you warm on the bus, campus or cold mean streets. Slanted outsize front pockets keep your style real . . . convenient.</p>\n<p>• Full-zip gray and black hoodie.<br />• Ribbed hem.<br />• Standard fit.<br />• Drawcord hood cinch.<br />• Water-resistant coating.</p>"
},
{
"attribute_code": "image",
"value": "/m/h/mh07-black_main.jpg"
},
{
"attribute_code": "small_image",
"value": "/m/h/mh07-black_main.jpg"
},
{
"attribute_code": "thumbnail",
"value": "/m/h/mh07-black_main.jpg"
},
{
"attribute_code": "color",
"value": "49"
},
{
"attribute_code": "minimal_price",
"value": "54.0000"
},
{
"attribute_code": "category_ids",
"value": [
"15"
]
},
{
"attribute_code": "options_container",
"value": "container2"
},
{
"attribute_code": "required_options",
"value": "0"
},
{
"attribute_code": "has_options",
"value": "0"
},
{
"attribute_code": "url_key",
"value": "hero-hoodie-xs-black"
},
{
"attribute_code": "msrp_display_actual_price_type",
"value": "0"
},
{
"attribute_code": "tax_class_id",
"value": "2"
},
{
"attribute_code": "size",
"value": "167"
}
]
}]
}

Orion - cygnus integration

We are trying to integrate Orion, Cygnus and Ckan together.
I have followed these steps in order to make this happen:
Install and configure Cygnus with the Fiware Ckan info(Cygnus up and running)
Login in Ckan and get the API key and configure this in the Cygnus settings
Orion steps:
queryUpdate = APPEND data
{
"contextElements": [{
"type": "Room",
"isPattern": "false",
"id": "26JanRoom",
"attributes": [{
"name": "temperature",
"type": "float",
"value": "888"
}]
}],
"updateAction": "APPEND"
}
subscribeContext = subscribe with the entity id created above(our Cygnus host is given as reference "reference": "CYGNUS HOST", )
{
"entities": [{
"type": "Room",
"isPattern": "false",
"id": "26JanRoom"
}],
"attributes": ["temperature"],
"reference": "CYGNUS HOST",
"duration": "P1M",
"notifyConditions": [{
"type": "ONCHANGE",
"condValues": ["temperature"]
}],
"throttling": "PT5S"
}
queryUpdate = UPDATE data
{
"contextElements": [{
"type": "Room",
"isPattern": "false",
"id": "26JanRoom",
"attributes": [{
"name": "temperature",
"type": "float",
"value": "111"
}]
}],
"updateAction": "UPDATE"
}
What we expect is to receive some notifications in the Cygnus side, but there is nothing sent from the Orion (orion.lab.fi-ware.org:1026/)
Could you please help us on this topic?
Thanks kr
Omer Ozdemir
Your are using
"condValues": ["pressure"]
which means that every time the attribute named pressure change, Orion will trigger a notification. However, your update is modifiygin temperature.
Please, have a look to the subscribe context operation section at Orion documentation.

OData REST Filter for deeply nested data

I have a working REST request that returns a large results collection. (trimmed here)
The original URL is:
http://intranet.domain.com//_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=#v)?#v='domain\kens'&$select=AccountName,DisplayName,Email,Title,UserProfileProperties
The response is:
{
"d": {
"__metadata": {
"id": "stuff",
"uri": "morestuff",
"type": "SP.UserProfiles.PersonProperties"
},
"AccountName": "domain\\KenS",
"DisplayName": "Ken Sanchez",
"Email": "KenS#domain.com",
"Title": "Research Assistant",
"UserProfileProperties": {
"results": [
{
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "UserProfile_GUID",
"Value": "1c419284-604e-41a8-906f-ac34fd4068ab",
"ValueType": "Edm.String"
},
{
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "SID",
"Value": "S-1-5-21-2740942301-4273591597-3258045437-1132",
"ValueType": "Edm.String"
},
{
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "ADGuid",
"Value": "",
"ValueType": "Edm.String"
},
{
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "AccountName",
"Value": "domain\\KenS",
"ValueType": "Edm.String"
}...
Is it possible to change the REST request with a $filter that only returns the Key Values from the results collection where Key=SID OR Key= other values?
I only need about 3 values from the results collection by name.
In OData, you can't filter an inner feed.
Instead you could try to query the entity set that UserProfileProperties comes from and expand the associated SP.UserProfiles.PersonProperties entity.
The syntax will need to be adjusted for your scenario, but I'm thinking something along these lines:
service.svc/UserProfileProperties?$filter=Key eq 'SID' and RelatedPersonProperties/AccountName eq 'domain\kens'&$expand=RelatedPersonProperties
That assumes you have a top-level entity set of UserProfileProperties and each is tied back to a single SP.UserProfiles.PersonProperties entity via a navigation property called (in my example) RelatedPersonProperties.