IoT-AgentUL how to get data - fiware

Currently I've got my own LoRaWAN network, with around 45 devices sending data with this payload: ID=D0001&T=23&H=60 where ID is the sensorId; T-Temperature; H - Humidity.
What steps do I have to make next to get context from my devices?
These are the steps that I've made:
1 - Installed IoT-Agent Ultralight
2 - Configured MQTT on the config.js file with my MQTT data
config.mqtt = {
host: 'HOST_NAME',
port: 1883,
protocol : mqtt,
username: 'USERNAME',
password: 'PASSWORD',
retain: false,
retries: 5,
retryTime: 5,
keepalive: 0,
avoidLeadingSlash: false
};
3 - IoTAgent-ul (node bin/iot-agentul), getting this message: time=2020-12-01T10:44:48.197Z | lvl=INFO | corr=526cdc56-62b8-4791-b95d-f5110ca18b7e | trans=526cdc56-62b8-4791-b95d-f5110ca18b7e | op=IOTAUL.MQTT.Binding | from=n/a | srv=n/a | subsrv=n/a | msg=connected | comp=IoTAgent

It is unclear whether you need the IoT Agent for Ultralight or the IoT Agent for LoRaWAN. Ultralight is a payload syntax, the Ultralight IoT Agent supports HTTP, MQTT and AMPQ transports. LoRaWAN is a transport, it supports a couple of COAP protocols.
If you are really sending LoRa COAP messages then you'll need the LoRaWAN agent.
If you are using Ultralight over MQTT, then your message payload should look like this
ID|D0001|T|23|H|60
An Ultralight over MQTT Tutorial exists within the Step-by-Step Guide.
If you are using COAP over LoRaWAN, then your message payload would be a stream of base64 bytes coming from the LoRa gateway. The Things network tutorial describes the set-up.
If your payload literally is: ID=D0001&T=23&H=60, you're going to need to create your own parser like the Custom IoT Agent Tutorial and follow the steps in altering the IoT Agent codebase.
Specifically, the flow of control with the HTTPBindings parseData() function. The ulParser would need to be re-written to accept your alternate syntax. It looks similar enough that all you'd need to do is:
if (payload) {
data = ulParser.parse(payload.replace(/&/g, "|").replace(/=/g, "|"));
}
(Even better if that could be done prior to sending to the Ultralight IoT Agent)
The advantage of re-using an existing IoT Agent (or writing a new one using the IoT Agent Node lib) is that functions such as the creation of entities and mapping of attributes is achieved using the existing code.

Related

Disable Auto-provisioning of Devices in Fiware MQTT JSON IoT Agent

We are using FIWARE Orion NGSI V2 version and MQTT JSON IoT Agent. We have attached the version of Context Broker and IoT Agent we are using below.
By default, whenever we send telemetry data through MQTT broker, for a device which does not exist in Fiware, the IoT Agent is automatically provisioning/creating the device in IoT Agent and corresponding entity in Context Broker.
We want to restrict this behavior and do not want the IoT Agent to auto-provision devices, but to only accept telemetry data for already registered devices.
We have already tried to set the IOTA_APPEND_MODE environment variable to false, also tried to set the autoprovision flag to false when creating the service group. None of these options are working and autoprovisioning is still happening.
Need your help and guidance on how do we disable the auto-provisioning IoT Agent.
IoT Agent version:
{"libVersion":"2.12.0-next","port":"4041","baseRoot":"/","version":"1.14.0-next"}
Context Broker Version:
{
"orion" : {
"version" : "2.3.0",
"uptime" : "12 d, 18 h, 50 m, 12 s",
"git_hash" : "764f44bff1e73f819d4e0ac52e878272c375d322",
"compile_time" : "Tue Nov 5 09:16:27 UTC 2019",
"compiled_by" : "root",
"compiled_in" : "cfe8becf7aae",
"release_date" : "Tue Nov 5 09:16:27 UTC 2019",
"doc" : "https://fiware-orion.rtfd.io/en/2.3.0/"
}
}
Have you tried to deactivate the autoprovision flag for a given iotagent device group?
https://github.com/telefonicaid/iotagent-node-lib/blob/f2e0305ca13a181140ee1fd1df8debb5a0838bee/doc/advanced-topics.md#autoprovision-configuration-autoprovision
Best
Version 1.18.0 seems it fix some issues related with autoprovision flag. As #fgalan mentioned, the version you are running is quite old, so probably you need to upgrade at least to 1.18.0. I really encourage you to upgrade since it is backward compatible.

Can IoT device with different protocols use IoT Agents to "talk" with each other?

I'm playing around with FIWARE Orion, IoT Agent JSON, and IoT Agent OPC UA. I'm wondering that since all the IoT Agents connect with Orion and map different IoT protocols into NGSI, is it possible for devices using different protocols to communicate with each other without adding any additional application logic?
Let's consider a MQTT device A and an OPC UA server B, For example, is it possible for:
B reports its measurements to the Orion Context Broker, A subscribe to that attribute. Some thing like
B-->IoT Agent OPC UA-->Orion-->IoT Agent JSON-->mosquitto-->A
(I tried to make a context provider registration. However, the url of the B entity attributes(orion:1026/v2/B/attrs/XXX) obviously doesn't work since Orion will send POST to an orion:1026/v2/B/attrs/XXX/op/query which doesn't exist), and the provided attribute is not provisioned at IoT Agent JSON...I feel like I'm taking the totally wrong direction)
A and B access the same entity and report their measurements to that entity in the Orion. Since A and B both need their own IoT Agents, and the same entity can not be provisioned at each agent due to duplicated...
Is it a super bad idea that trying to mess up one entity with several protocols' devices...Thank you so much for answering my doubts in advance!!!
Each NGSI entity should map to something that has state in the real world. In your case your data models should be based on Device and you should have a separate OPC-UA-based Device entity and a second separate JSON Device entity. These are the low level entities within your system, which would hold readings from the IoT Devices and would also hold additional data (such as battery-level or a link to the documentation or whatever).
If you want to model the state of a second aggregated entity then you can do that as well - just subscribe to changes in context in the device and Upsert the values and metadata over to the other entity.
curl --location --request POST 'http://localhost:1027/v2/subscriptions/' \
--header 'Content-Type: application/json' \
--header 'fiware-service: openiot' \
--data-raw '{
"description": "Notify Subscription Listener of Lamp context changes",
"subject": {
"entities": [
{
"idPattern": "Lamp.*"
}
],
"condition": {
"attrs": ["luminosity"]
}
},
"notification": {
"http": {
"url": "http://tutorial:3000/device/subscription/luminosity"
},
"attrs": ["luminosity", "controlledAsset", "supportedUnits"]
},
"throttling": 5
}'
Sample code to do the work from the listening endpoint ( /device/subscription/luminosity ) can be found here - it is a tutorial which is still a work-in-progress, so the full documentation is currently missing.
function shadowDeviceMeasures(req, res) {
const attrib = req.params.attrib;
async function copyAttributeData(device, index) {
await upsertDeviceEntityAsLD(device);
if (device[attrib]) {
await upsertLinkedAttributeDataAsLD(device, 'controlledAsset', attrib);
}
}
req.body.data.forEach(copyAttributeData);
res.status(204).send();
}
The point here is that you can (and should) think of data entities at different levels -
I have a thermometer Device - it is sending temperature readings. It has a temperature attribute
I have a Building - it has a thermometer in it - the Building has a temperature attribute and metadata.providedBy linking back to the Device
Depending on your use case you may only need to consider entities at one layer or you may need to use both.

How to use Openshift Exposing Object Fields?

The openshift documentation has a feature Exposing Object Fields that I am struggling to comprehend. When I load my secret I am exposing it as per the documentation. Yet it is unclear from the language of the documentation what are the actual mechanism to bind to the exposed variables. The docs state:
An example response to a bind operation given the above partial
template follows:
{ "credentials": {
"username": "foo",
"password": "YmFy",
"service_ip_port": "172.30.12.34:8080",
"uri": "http://route-test.router.default.svc.cluster.local/mypath" } }
Yet that example isn't helpful as its not clear what was bound and how it was bound to actually pick-up the exposed variables. What I am hoping it is all about is that the exposed values become ambient and that when I run some other templates into the same project (???) it will automatically resolve (bind) the variables. Then I can decouple secret creation (happening at product creation time) and secret usage (happening when developers populate their project). Am I correct that this feature creates ambient properties and that they are picked up by any template? Are there any examples of using this feature to decouple secret creation from secret usage (i.e. using this feature for segregation fo duties).
I am running Redhat OCP:
OpenShift Master:
v3.5.5.31.24
Kubernetes Master:
v1.5.2+43a9be4

Amazon SNS: JSON toasts to Windows Phones

When I use the Amazon SNS console to send toast messages to a Windows Phone 8 device (i.e. with the MPNS system), I can only send messages in text format. Selecting "Use platform specific JSON message dictionaries" and sending a JSON toast never seems to get to the device. The default message that you see when you select the platform specific format is a tile notification message, and that does work.
For exmple, the following message neither gives an error nor is displayed in the device:
{
"MPNS": "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\"><wp:Toast><wp:Text1>Amazon</wp:Text1><wp:Text2>hooray</wp:Text2><wp:Param>this_is/my?extra=parameter</wp:Param></wp:Toast></wp:Notification>"
}
This has been tested with a couple of devices: Lumia 620 with Windows Phone 8.0 and Lumia 1020 with 8.1 beta. I have also tried sending messages from a Java backend, but it just shows up as a raw JSON text toast ({ "MPNS": ...) again. What could possibly be wrong? The JSON is valid, the XML is well-formed... I'm at loss.
I have run into the same issue recently, and found a solution. The SNS documentation for MPNS does not emphasise an important step, but it can be found in the sample code and eventually in the message attributes section of the docs.
You must set two MPNS-specific MessageAttributes on the PublishRequest. Omitting them will cause the delivery to fail with no clues left to investigate: i.e. even if you enable delivery status logs with CloudWatch, providerResponse will be missing.
For reference, the attributes are the following:
Attribute name: AWS.SNS.MOBILE.MPNS.Type
Possible values: token (for tile notifications), toast or raw
Attribute name: AWS.SNS.MOBILE.MPNS.NotificationClass
Possible values: realtime*, priority, regular
(realtime worked for me)
That said, it seems that it is not possible to send custom content to MPNS using the SNS console. But using the API works, so here is an excerpt from the Java sample for using the Java SDK:
AmazonSNS snsClient = ... /* initialise the client */;
Map<String, MessageAttributeValue> notificationAttributes = new HashMap<String, MessageAttributeValue>();
notificationAttributes.put("AWS.SNS.MOBILE.MPNS.Type",
new MessageAttributeValue()
.withDataType("String")
.withStringValue("token")); // or "toast" or "raw", depending on the payload
notificationAttributes.put("AWS.SNS.MOBILE.MPNS.NotificationClass",
new MessageAttributeValue()
.withDataType("String")
.withStringValue("realtime"));
PublishRequest request = new PublishRequest();
request.setMessageAttributes(notificationAttributes);
request.setMessageStructure("json");
request.setTargetArn(... /* topic or endpoint ARN */);
request.setMessage(... /* JSON payload */)
snsClient.publish(request);

How to authenticate with Chrome sync XMPP servers?

I need to get the currently opened tabs of a Google Chrome user in my Java application (not on the same machine). Chrome sync is enabled so the current tabs are synced with Google servers.
According to the documentation of Chrome sync it is done via XMPP. So I guess it should be possible to connect to the Google XMPP server (xmpp.google.com), e.g. via Smack (Java library for XMPP), authenticate and listen for protobuf messages that indicate a tab session change.
Of course the login credentials of the user or the "client_id" Chrome uses to identify clients are available.
But I'm having a hard time getting behind the authentication method that is used to connect to the XMPP server – I can't figure out how it's done in the Chromium source code and there's no documentation available besides the very low-level comments in the code.
The libjingle library Google uses for it's XMPP based services is only available for C++ and not well maintained/documented.
So is there anyone who has done something like that before and who can give any advice/hints on how the authentication process works?
I'm not sure chrome sync uses xmpp, at least on the level when it has to exchange info with client. It uses 'protocol buffers' Google technology. The protocol is given by using .proto protocol description files and you can convert it to your language's objects by using special compiler.
The sync server seems to rest at https://clients4.google.com/chrome-sync and client sends POST requests with the binary body where typed ClientToServerMessage message is placed.
Here's the output from when first connecting to sync server.
The first output Python object is a pprint of 'environ' WSGI variable where HTTP headers are placed too. The second object (after '====' ) is actual protocol message.
{'CONTENT_LENGTH': '54',
'CONTENT_TYPE': 'application/octet-stream',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTP_ACCEPT_CHARSET': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'HTTP_ACCEPT_ENCODING': 'gzip,deflate,sdch',
'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8',
'HTTP_AUTHORIZATION': 'GoogleLogin auth=MKhiqZsdz2RV4WrUJzPltxc2smTMcRnlfPALTOpf-Xdy9vsp6yUpS5cGuND0awqrYVUK4lhOJlh6OMsg093eBRghGGIgvWUTzU8PUvquy_c8Xn4sRiz_3tVJcke5eXi3q4qFDa6iVuEbT_0QhyPOjIQyeDOKRpZzMR3rpHsAs0ptFiTtUeTHsoIeUFT9nZPYzkET4-yHbDAp45_dxWdb-U6DPg24',
'HTTP_CONNECTION': 'keep-alive',
'HTTP_HOST': 'localhost:8080',
'HTTP_USER_AGENT': 'Chrome MAC 0.4.21.6 (130497)-devel',
'PATH_INFO': '/chrome-sync/dev/command/',
'QUERY_STRING': 'client_id=SOME_SPECIAL_STRING',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '59031',
'REQUEST_METHOD': 'POST',
'SCRIPT_NAME': '',
'SERVER_NAME': 'vian-bizon.local',
'SERVER_PORT': '8080',
'SERVER_PROTOCOL': 'HTTP/1.0',
'SERVER_SOFTWARE': 'gevent/1.0 Python/2.6',
'wsgi.errors': <open file '<stderr>', mode 'w' at 0x100416140>,
'wsgi.input': <gevent.pywsgi.Input object at 0x102a04250>,
'wsgi.multiprocess': False,
'wsgi.multithread': False,
'wsgi.run_once': False,
'wsgi.url_scheme': 'https',
'wsgi.version': (1, 0)}
'==================================='
share: "MY_EMAIL_WAS_HERE#gmail.com"
protocol_version: 30
message_contents: GET_UPDATES
get_updates {
caller_info {
source: NEW_CLIENT
notifications_enabled: false
}
fetch_folders: true
from_progress_marker {
data_type_id: 47745
token: ""
notification_hint: ""
}
}
debug_info {
events {
type: INITIALIZATION_COMPLETE
}
events_dropped: false
}
This happens for OAuth based authentication. You can see the OAuth token in HTTP_AUTHORIZATION field. The OAuth token is given to you when you interact with HTML dialog 'Google Account Login'. I'm not sure but seems like the API to get an access token for Google services is available publicly.
If you are looking for XMPP auth instead, please see the description of X-GOOGLE-TOKEN auth mechanism here:
Authenticate to Google Talk (XMPP, Smack) using an authToken
For the X-OAUTH2 authorization, you can access the info here: https://developers.google.com/talk/jep_extensions/oauth
And a sample here: http://pits.googlecode.com/svn/trunk/xmpp.c
Note that you can add XMPP stream flow to the Chrome log files populated on each run of the browser - chrome_debug.log. To enable this, run Chrome with following options: --enable-logging --v=2