Ultralight 2.0 commands with parameters (polling mode) - fiware

I have found some troubles working with commands. According to the sintaxis of the protocol, a command can be executed using an updateContext operation to the Orion Context Broker, which now it is working perfect.
The doubt is, how do I give the command some parameters, as specified in the protocol?
<device name>#<command name>|<param name>=<value>|....
If I send the following REST request, it gives me a 400 Bad request, complaining about strange characters:
curl -X PUT \
'http://MYIP:1026/v2/entities/1111/attrs/blink?type=Thing' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'fiware-service: howtoservice' \
-H 'fiware-servicepath: /howto' \
-d '{
"type": "command",
"value": "blink=true|another_param=false"
}'
Where should I issue the params if it is not in the "value" key?
If I use the following request, it acts as expected:
curl -X PUT \
'http://MYIP:1026/v2/entities/1111/attrs/blink?type=Thing' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'fiware-service: howtoservice' \
-H 'fiware-servicepath: /howto' \
-d '{
"type": "command",
"value": "true"
}'
Thanks in advance

There are a couple of things regarding this question. Both of them relate to a wrong documentation, I'm affraid.
Firstly, the documentation should say the general way of sending a command from the Agent to the UL device is:
<device name>#<command name>|<value>
<value> then can be as complex as your device needs. For instance, it can be as simple as sending a single value:
dev1#turn|left
I.e. we are telling our UL device to turn left a valve.
Or it can be a composed value like this one (just an example):
dev1#turn|direction:left,lapse:3
I.e. we are telling our UL device to turn left after a time lapse of 3 seconds. In this case, we are sending the direction:left,lapse:3 string because our UL device knows how to decode that. You could be passing many other alternatives, ir depends on what your UL device is able to understand; just some examples:
dev1#turn|direction:left|lapse:3 --> value is direction:left|lapse:3
dev1#turn|direction|left|lapse|3 --> value is direction|left|lapse|3
dev1#turn|direction left lapse 3 --> value is direction left lapse 3
Having this in mind, in the documentation example we must assume the <value> sent is:
<param1 name>=<value>|<param1 name>=<value>|...
Secondly, the above documentation example for <value> cannot be used :) Among all the possible combinations, we decided to documentate one that is not accepted by Orion CB (our apologies for that). Why? Because = is a forbidden character in Orion CB.
Since values given to the commands are specified through Orion CB "update context" operations, i.e. the attribute modeling the command must be updated in order the command is forwarded to the Agent (because the Agent is the context provider for the attribute), such value must be according to Orion CB specification.
Therefore, updating Orion CB with any of the above possibilities, i.e.:
direction:left|lapse:3
direction|left|lapse|3
direction left lapse 3
is perfectly valid. It is not the case of direction=left|lapse=3 or any other string containing =.
EDIT: documentation at IOTAgent repository regarding command syntax has been fixed.

Related

Not be able to retrieve entity types from FIWARE Orion Context Broker

I want to retrieve all the entity types that has been defined in the Orion context broker. I searched the tutorials and find this. But this API give an empty message: [].
I have also tried to add other headers like fiware-service and fiware-servicepath but it made no difference.
P.S:
this is the API I used for getting all the entity types :
curl localhost:1026/v2/types -s -S -H 'Accept: application/json'
and this is another one with two aforementioned headers :
curl 178.252.170.26:1026/v2/types -s -S -H 'Accept: application/json'\
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /'
The most probable cause of getting [] as response to GET /v2/types is that you don't have any entity in that service/subservice at all.
Do GET /v2/entities to check it. If the result is [] then my hypothesis gets confirmed. You can try to create some entity (using POST /v2/entities) and try again.

IoT Agent registration

I'm trying to understand how data flows between the Orion Context-Broker and an IoT Agent.
For this the first thing to understand is the initial registration request. I haven't found any example describing this.
Afterwards I wanna send command throught the Context-Broker to a device (or IoT Agent in the beginning).
Can someone provide concrete examples for these use cases?
The full NGSI-v2 data flow is described in the IoT Agent documentation a couple of practical examples can be found in the Step-by-Step Tutorials
The equivalent for NGSI-LD can be found here
A full example of an NGSI-v2 actuation can be found here. The action on the broker looks something like this:
curl -iX PATCH \
'http://localhost:1026/v2/entities/urn:ngsi-ld:Door:001/attrs' \
-H 'Content-Type: application/json' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-d '{
"open": {
"type" : "command",
"value" : ""
}
}'

IBM Watson Tone Analyzer Invalid JSON Error

I must be missing something very simple here. I am following the Example Tutorial Instructions. I already created a free account and I have my API key and the URL. I copied the JSON file as instructed. Here is the command I issued:
curl -X POST -u "apikey:MY-API-KEY" \
--header "Content-Type: application/json" \
--data-binary PATH-TO-FILE \
"MY-URL"
Where MY-API-KEY equals my personal key specified on my Manage page.
Where PATH-TO-FILE equals the path to my local copy of tone.json
Where MY-URL equals the url specified on my Manage page.
Here is the error I am getting:
{"code":400,"sub_code":"C00012","error":"Invalid JSON input at line 1, column 2"}
I copied the JSON exactly from the directions:
{
"text": "Team, I know that times are tough! Product sales have been disappointing for the past three quarters. We have a competitive product, but we need to do a better job of selling it!"
}
I also attempted the following JSON and it received the same error:
{"text":"Hello world"}
What obvious thing am I missing here?
I knew it was going to be something silly.
The directions have this as an example:
curl -X POST -u "apikey:{apikey}" \
--header "Content-Type: application/json" \
--data-binary #{path_to_file}tone.json \
"{url}/v3/tone?version=2017-09-21"
For the path to the file, I had to keep the # symbol in front. so let's assume the full path to the file is /home/joe/Desktop/tone.json, that line has to be:
--data-binary #/home/joe/Desktop/tone.json \

Fiware - IDAS: TimeInstant attribute

I’m using the MQTT Ultralight agent. I have seen that when the agent registers into the context broker an entity related to a device, the agent adds to that entity the “TimeInstant” attribute. This attribute seems to be on UTC+0.
I would like to work with UTC +1. I tried modifying the device’s “TimeZone” when registering it, but seems that this doesn’t work, because the time continues to be on UTC+0. Here an example:
curl -X POST 172.21.0.23:8090/iot/devices \
-i \
-H "Content-Type: application/json" \
-H "Fiware-Service: red_entrada_4" \
-H "Fiware-ServicePath: /Prueba" \
-d '{
"devices":[
{
"device_id": "AC_2",
"entity_name":"disp_entrada:AC_2",
"protocol":"PDI-IoTA-MQTT-UltraLight",
"entity_type": "disp_entrada",
"timezone": "Europe/Madrid"
}
]}'
Is there any way of modifying the default value of the “TimeInstant” attribute, in order to work with a specific UTC?
This field was introduced as a future capability and, as it is said in the documentation, it is not in use today. This is the reason why ¡you are not able to change it at present.
Thanks for using IDAS and sorry for our late reply this time!

Is there an API call for changing user password on keycloak?

I am trying to implement my own form for changing a user's password. I tried to find an API for changing a user's password in Keycloak but I couldn't find anything in the documentation.
Is there an API for doing it?
you can use PUT /auth/admin/realms/{realm}/users/{id}/reset-password
{id} is the user id in keycloak (not the login)
Here is s sample body.
{ "type": "password", "temporary": false, "value": "my-new-password" }
UPDATE Keycloak 12
The solution described below will no longer work in Keycloak Versions 12 or higher as the developers decided to remove all Account Rest APIs as described in this issue.
Thanks to #Radivarig for pointing this out!
Solution for Keycloak 11
Keycloak recently introduced this feature, but it's currently still in preview and therefore not documented.
To make it work, you need to activate the account_api feature by starting keycloak with the parameter -Dkeycloak.profile.feature.account_api=enabled like so:
bin/standalone.sh -Dkeycloak.profile.feature.account_api=enabled
(source: https://www.keycloak.org/docs/latest/server_installation/index.html#profiles)
After that, you can use POST /auth/realms/your-realm/account/credentials/password and provide the http Header Accept: application/json. The header will make keycloak use a RestAPI-Service which is accepting and returning JSON (instead of the default form-based one which is only accepting x-www-form-urlencoded and returns HTML.)
As Request-Body, provide a JSON like this:
{
"currentPassword": "oldPassword",
"newPassword": "newPassword",
"confirmation": "newPassword"
}
A full example with curl would look like this:
curl --request POST 'https://path-to-your-host.com/auth/realms/your-realm/account/credentials/password' \
--header 'Accept: application/json' \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data-raw '{
"currentPassword": "oldPassword",
"newPassword": "newPassword",
"confirmation": "newPassword"
}'
Note that - as written above - this feature is still in preview and might change in the future. So use it with caution!
Rather than specifying a new password manually a better security practice is to use the
PUT /auth/admin/realms/{realm}/users/{id}/execute-actions-email
admin call with "UPDATE_PASSWORD" as the required action. This causes Keycloak to send an email to the user that gives a magic link for the user to set a new password.
Note: {id} is the user id in keycloak (not the login)
As Keycloak Admin REST API suggests you can send a PUT requqest to keycloakEndpoint/auth/{realm}/users/{id}/execute-actions-email to execute actions against user. you need to obtain an admin access token as described here
TL;DR: The better way to do it via web app
keycloak.login({
action: "UPDATE_PASSWORD",
})
For more info: https://www.keycloak.org/docs/latest/securing_apps/#login-options
:-)
#!/bin/bash
#CHANGE ADMIN PASSWORD
apt update
apt install -y curl jq
KEYCLOAK_HOST=http://127.0.0.1:8080
ADMIN_USER_OLD_PASSWORD=
ADMIN_USER_NEW_PASSWORD=
TOKEN=$(curl -s -X POST -H 'Content-Type: application/x-www-form-urlencoded' -d "username=admin&password=$ADMIN_USER_OLD_PASSWORD&client_id=admin-cli&grant_type=password" "$KEYCLOAK_HOST/auth/realms/master/protocol/openid-connect/token" | jq -r ".access_token" ;)
ADMIN_USER_ID=$(curl -s -X GET -H "Authorization: Bearer $TOKEN" -H "Content-type: application/json;charset=UTF-8" -H 'Accept: application/json' "$KEYCLOAK_HOST/auth/admin/realms/master/users" | jq -r '.[] | select(.username=="admin") | .id' )
curl -s -X PUT -H "Authorization: Bearer $TOKEN" -H "Content-type: application/json;charset=UTF-8" -H 'Accept: application/json' "$KEYCLOAK_HOST/auth/admin/realms/master/users/$ADMIN_USER_ID/reset-password" -d "{\"type\":\"password\",\"value\":\"$ADMIN_USER_NEW_PASSWORD\",\"temporary\":false}"
constructor(
private keycloakService: KeycloakService,
) { }
onPasswordChangeButtonClick(){
this.keycloakService.login({
action: "UPDATE_PASSWORD",
});
}
please try this approach to change the password
This worked for me:
https://github.com/keycloak/keycloak/pull/7393#issuecomment-1103532595
But you have to see if you can use a custom theme, if you want a different form than the default from keycloak.
No, OAuth and OpenID Connect protocols doesn't define such feature and Keycloak also doesn't have ability to do this on user's behalf. There is a server-to-Server Admin API that alows to change the user's password or reset it but you can't call it from GUI.
But the Keycloak provides some kind of "My Account Page" by url like http://localhost:8080/auth/realms/your-realm/account/ - replace your-realm part of URL and just redirect a user to it.
In documentation it called User Account Service
Also if you use auto discovery you can obtain the url by reading account-service from JSON by URL http://localhost:8080/auth/realms/your-realm