How to integrate a device with custom API calls? - fiware

We would like to add an IoT device which uses specific API calls / responses, and we would like to know the best way to do it. Can we do this integration using the FIWARE JSON IoT Agent? We have to develop a custom FIWARE IoT Agent?

If you have a JSON payload (or you can create one) then the JSON IoT Agent is a good baseline to start from. There are two basic approaches:
Gateway Solution
Custom IoT Agent
In the first approach you could create a separate gateway component which listens to your API and it reads and interprets measures and posts back onto an MQTT topic /attrs. For commands, the gateway receives a JSON payload on /cmdExe MQTT topic and sends it on using your API. Your gateway would be responsible for marshalling/unmarshalling payloads.
In the second approach, you are writing your own IoT Agent. Effectively you are responsible for creating your own binding mapping to your API.
The advantage of the Gateway Solution is that you can continue to upgrade using the standard IoT Agent, so you will get bug fixes for free. The custom IoT Agent may be cleaner architecturally - you don't (ab)use MQTT as a message bus - but keeping the custom IoT Agent updated becomes your responsibility.
In general, I would recommend that a custom IoT Agent is used whenever the protocol is in wide enough use that multiple end-users and developers could benefit from it. Custom IoT Agents can also be developed if there are a large number of extra dependencies involved. Most IoT Agents are developed in Node.js
For a single proprietary API, gateway is probably better. If you look at the accompanying video, you'll see that in the IOTA case, both the payload and the transport are customised. A Gateway could be developed in any code language (provided it has an MQTT client available.)

Thank you #jason-fox. We have just finished the development of our custom gateway and we're trying to test it. We've just created the service group into the IoT JSON Agent:
"services": [
{
"apikey": "our-api-key",
"protocol": [
"IoTA-JSON"
],
"cbroker": "url-context-broker:1026",
"entity_type": "Device",
"resource": "/iot/shelly/json"
}
]
And provisioning the device:
"devices": [
{
"device_id": "shelly003",
"entity_name": "shelly-xxxx",
"entity_type": "Device",
"protocol": "IoTA-JSON",
"transport": "HTTP",
"endpoint": "gateway-url",
"commands": [
{
"name": "turn",
"type": "command"
}
]
}
]
We're trying to send command to the device via Context Broker sending the following body to the endpoint:
"turn": {
"type" : "command",
"value" : "on"
}
But we're getting always error. What are we doing wrong?

Related

Calling external APIs through fiware orion context broker to validate using keyrock

I am a student working on a project and exploring viability of using fiware for that. So far I've learnt that to call external APIs we can use registrations for an entity to fetch dynamic data.
Here is the situation:
In my project, I am calling external APIs for fetching some data at frontend.
I want to add access control for users so that they are restricted from calling the APIs if not permitted. For this reason I am trying to find out a way such that keyrock can validate the requests so that I don't have to manually validate these external APIs. Since these aren't related to any entity I don't want to use registration for this purpose.
I intend to do user management through keyrock itself. Currently keyrock can restrict based on resources (i.e. URL path) of the application and permission. I am very confused at this point that if I add an API call at any page to fetch data from external API, how can I make use of keyrock access control in this situation.
Also, can I make orion call the external API somehow and make the data an entity?
Any help and hint is greatly appreciated. Thanks in Advance.
A registration is a contract to return a series of attributes connected to an entity, how that is connected to an external API is up to you. There is an annotated example in the NGSI v2 tutorials - the code is also available for NGSI-LD but the documentation for NGSI-LD needs updating to reflect certain recent changes and clarifications made in NGSI-LD 1.6.1.
Regardless of the version of NGSI you use, the steps to call an external API are the same.
Create a proxy service with a handler to deal with one or more NGSI endpoints - for NGSI-v2 this will usually be the batch endpoint /op/query, for NGSI-LD I would recommend /ngsi-ld/v1/entities/<id>.
Create a registration from your context broker to this proxy e.g. for NGSI-v2:
curl -iX POST \
'http://localhost:1026/v2/registrations' \
-H 'Content-Type: application/json' \
-d '{
"description": "Random Weather Conditions",
"dataProvided": {
"entities": [
{
"id": "urn:ngsi-ld:Store:001",
"type": "Store"
}
],
"attrs": [
"relativeHumidity"
]
},
"provider": {
"http": {
"url": "http://location/of/the/proxy/interface"
}
}
}'
Note that you can also pass additional custom information using custom headers or annotating the path of the URL or whatever.
Within the proxy code make a request to the third party API and convert the response back to NGSI format. The tutorial example explains how to connect to Twitter or Cat Facts as examples.
I want to add access control for users so that they are restricted from calling the APIs if not permitted.
This is purely a matter of placing a PEP proxy in front of the call to the registrant. Imagine a context broker request like this one to Kong:
curl -X GET \
http://localhost:8000/orion/v2/entities/urn:ngsi-ld:Store:001?options=keyValues \
-H 'Authorization: Bearer {{X-Access-token}}'
Either you place the PEP in front of the context broker (in which case the entity is only returned if you have appropriate permissions, or you place a PEP in front of your registrant webservice, in which case the attributes are only appended to the entity if you have appropriate permissions. Note that the context broker Registration needs to be configured to ensure that the Authorization header will be passed on to the registrant as well.

Use Postman to Login a Cognito user with API alone

I'm migrating from Firebase where this was rather simple to do.
I'm building a custom api because the environment I need to build in will not let me use any official sdk's or anything, so this solely has to be done via rest type actions.
I essentially want to just post the username/password to aws cognito, and recieve an auth token that I can then append to the headers of future requests (to other api calls)
After hunting for quite a bit, almost all help has postman connecting to Amazon's login UI etc, and I cannot do that. It must completely handle the login process "behind the scenes" and not prompt the user with Amazon's own UI.
So, assuming this is possible:
What headers do I need (content-type etc)
How do I format the body json (or is it using something else?)
I assume I'd send it as "raw" body.
This is as far as I got so far and I'm scratching my head:
Url: https://[DOMAIN].auth.us-east-1.amazoncognito.com/oauth2/token
Body Json:
{
"ClientId": "1234etc",
"Password": "Password1_",
"UserAttributes": [
{
"Name": "email",
"Value": "test#test.com"
}
],
"Username": "test#test.com"
}
No idea if this is even the right format for the JSON I just scalped it from other posts.

Configure microsoft teams incoming webhook json payload

I am trying to set up an incoming webhook to a Microsoft teams channel using the incoming webhook connector.
The payload that I am trying to send from my platform looks like this and is form CleverTap (which is failing so I'm trying to debug it using postman). but I am getting the error Summary or Text is required.
{
"profiles": [
{
"email": "jack#gmail.com",
"identity": "foo",
"objectId": "-g55b74fb1030740e4a4931910a8abb862",
"profileData": {
"Last Score": 308,
"High Score": 308,
"Replayed": true
},
"name": "Jack"
}
]
}
What am I doing wrong?
will I need to change the JSON payload according to the adaptive card syntax for teams to accept the incoming webhook? If so, where can I add my custom payload in the adaptive card JSON body?
are there other authentication factors at the webhook endpoint (do I have to whitelist the ip address from where the POST message is being sent from)?
To send a message using incoming webhook, you must post a JSON payload to the webhook URL. This payload should be in the form of O365 Connector card. Payload of any other format is not acceptable in Teams. Here is an Example Connector card that you can post. You can now also send an Adaptive card using incoming webhook. Please check the docs here.

How do I configure context broker accept post requests from my remote sensor?

I have set my weather station with different sensors attached. My practice until now was to send the sensor data to a web address. But now that I have set up a CentOS 6.6 on a server with its IP address so now I want to send the sensor data directly to that machine that has orion context broker installed.
So my question is, how do I configure orion context broker to accept these post requests (from the weather station sensors) that are being sent to the CentOS machine?
You shouldn't have any problem sending post requests to a CentOS machine that is running Orion Context Broker. In fact, that is the supported OS for running Orion.
Just make sure you have the port open that Orion will be listening at (by default it's 1026), and that the payload in the post is acceptable.
For example, to send a value you could do a POST to <host>:<port>/v1/contextEntities/mySensor/attributes and a payload such as
{
"attributes" : [
{
"name" : "temperature",
"type" : "float",
"value" : "26.5"
},
{
"name" : "pressure",
"type" : "integer",
"value" : "763"
}
]
}
Start out simple by doing a GET :1026/version to see if it works and work up to more advanced queries (see the documentation for more good stuff :)

Accessing Google AppEngine Cloud Endpoints using ActionScript 3?

Is anyone aware of method of accessing Google AppEngine Cloud Enpoints using ActionScript 3 without having to go through the JavaScript layer? I have been going on the docs and Google to find any tutorials or examples but did not find anything useful.
We don't have AS3 client libraries and currently there are none planned that I know of, so you'll have to rely on HTTP to make your REST calls.
TLDR; Use the APIs Explorer
If you visit
https://your-app-id.appspot.com/_ah/api/explorer
(replacing your-app-id with your actual application ID), then you'll be redirected to your own custom version of the Google APIs Explorer.
In it you can click on individual APIs and see the list of all available methods. Within a the page for each method, you can try out forming requests and the Explorer will suggest the correct values to use.
After you click "Execute", the full HTTP request (headers and all) and response will be printed on your page, which will show you which commands to use.
Description of how to use the Discovery Document
The Discovery Document for your API will contain all the information you need to construct a request.
To find the root for calling your API, check out the baseUrl key. It should be something like:
https://your-app-id.appspot.com/_ah/api/tictactoe/v1/
To figure out how to call a specific method, there are descriptions of every method, nested down as resources in the Discovery Document. For example, for the Tic Tac Toe Python sample, the board_get_move method has a name of board.getmove in the #endpoints.api decorator. This means the method getmove is owned by the resource board.
If you look in the resources.board.methods key in the Discovery Document you can see the getmove method:
"getmove": {
"id": "tictactoe.board.getmove",
"path": "board",
"httpMethod": "POST",
"description": "Exposes...",
"request": {
"$ref": "TictactoeApiMessagesBoardMessage"
},
"response": {
"$ref": "TictactoeApiMessagesBoardMessage"
}
}
Combining the path with our baseUrl we know requests will need to be sent to
https://your-app-id.appspot.com/_ah/api/tictactoe/v1/board
and from httpMethod we know requests will use the HTTP method POST.
Finally, to specify the request, we see a reference to a schema:
"$ref": "TictactoeApiMessagesBoardMessage"
Looking in the schemas.TictactoeApiMessagesBoardMessage key in the Discovery Document we see:
"TictactoeApiMessagesBoardMessage": {
"id": "TictactoeApiMessagesBoardMessage",
"type": "object",
"description": "ProtoRPC message definition to represent a board.",
"properties": {
"state": {
"type": "string"
}
}
}
so we know the payload must contain a single field called state and that field must be a string.