How to use bluetooth devices and FIWARE IoT Agent - iot

I would like to use my bluetooth device (for example I'm going to create an app to be installed in a tablet) to send data (set of attributes) in Orion Context Broker via IoT Agent.
I'm looking for the FIWARE IoT Agent and probably I've to use IoT Agent LWM2M. Is it correct?
Thanks in advance and regards.
Pasquale

Assuming you have freedom of choice, you probably don't need an IoT Agent for that, you just need a service acting as a bluetooth receiver which can receive your message and pass it on using a recognisable transport.
For example, you can receive data using the following Stack Overflow answer
You can then extract the necessary information to identify the device and the context to be updated.
You can programmatically send NGSI requests in any language capable of HTTP - just generate a library using the NGSI Swagger file - an example is shown in the tutorials
// Initialization - first require the NGSI v2 npm library and set
// the client instance
const NgsiV2 = require('ngsi_v2');
const defaultClient = NgsiV2.ApiClient.instance;
defaultClient.basePath = 'http://localhost:1026/v2';
// This is a promise to make an HTTP PATCH request to the /v2/entities/<entity-id>/attr end point
function updateExistingEntityAttributes(entityId, body, opts, headers = {}) {
return new Promise((resolve, reject) => {
defaultClient.defaultHeaders = headers;
const apiInstance = new NgsiV2.EntitiesApi();
apiInstance.updateExistingEntityAttributes(
entityId,
body,
opts,
(error, data, response) => {
return error ? reject(error) : resolve(data);
}
);
});
}
If you really want to do this with an IoT Agent, you can use the IoT Agent Node lib and and create your own IoT Agent

Related

How to retrieve messages from Alpakka Mqtt Streaming client?

I was following document for writing a Mqtt client subscriber using alpakka.
https://doc.akka.io/docs/alpakka/3.0.4/mqtt-streaming.html?_ga=2.247958340.274298740.1642514263-524322027.1627936487
After the code marked in bold, I’m not sure how could I retrieve/interact with subscribed messages. Any lead?
Pair<SourceQueueWithComplete<Command>, CompletionStage> run =
Source.<Command>queue(3, OverflowStrategy.fail())
.via(mqttFlow)
.collect(
new JavaPartialFunction<DecodeErrorOrEvent, Publish>() {
#Override
public Publish apply(DecodeErrorOrEvent x, boolean isCheck) {
if (x.getEvent().isPresent() && x.getEvent().get().event() instanceof Publish)
return (Publish) x.getEvent().get().event();
else throw noMatch();
}
})
.toMat(Sink.head(), Keep.both())
.run(system);
SourceQueueWithComplete<Command> commands = run.first();
commands.offer(new Command<>(new Connect(clientId, ConnectFlags.CleanSession())));
commands.offer(new Command<>(new Subscribe(topic)));
session.tell(
new Command<>(
new Publish(
ControlPacketFlags.RETAIN() | ControlPacketFlags.QoSAtLeastOnceDelivery(),
topic,
ByteString.fromString(“ohi”))));
// for shutting down properly
commands.complete();
commands.watchCompletion().thenAccept(done → session.shutdown());
Also, in the following example, it shows how to subscribe to the client but nothing about how to get messages after the subscription.
https://github.com/pbernet/akka_streams_tutorial/blob/master/src/main/scala/alpakka/mqtt/MqttEcho.scala
Will be grateful if anyone knows the solution or can point to any resource which uses the same connector as mqtt client and can retrieve messages.
The code to retrieve messages for the subscriber is hidden in the client method which is used for both publisher and subscriber:
...
//Only the Publish events are interesting for the subscriber
.collect { case Right(Event(p: Publish, _)) => p }
.wireTap(event => logger.info(s"Client: $connectionId received: ${event.payload.utf8String}"))
.toMat(Sink.ignore)(Keep.both)
.run()
https://github.com/pbernet/akka_streams_tutorial/blob/3e4484c5356e55522366e65e42e1741c18830a18/src/main/scala/alpakka/mqtt/MqttEcho.scala#L136
I was struggling with this connector and then tried an example with the one based on Eclipse Paho, which in the end looks better:
https://github.com/pbernet/akka_streams_tutorial/blob/3e4484c5356e55522366e65e42e1741c18830a18/src/main/scala/alpakka/mqtt/MqttPahoEcho.scala#L41
Paul

Ktor-websocket library do nothing when trying to receive data on client

I am currently trying to connect our Kotlin Multiplatform Project to websockets. I would like to use ktor-websockets library to receive some updates from our backend but onfortunately when I run this code, nothing happens:
client.webSocket(
port = 80,
method = HttpMethod.Get,
host = "https://uat-betws.sts.pl",
path = "/ticket?token=eyJzdWIiOiI0ZmY5Y2E1Mi02ZmEwLTRiYWYtODlhYS0wODM1NGE2MTU0YjYiLCJpYXQiOjE2MTk4MDAwNzgsImV4cCI6MTYxOTgwMzY3OH0.oIaXH-nFDpMklp4FSJWMtsM7ECSIfuNF99tTQxiEALM"
)
{
for (message in incoming) {
message as? Frame.Text ?: continue
val receivedText = message.readText()
println(receivedText)
}
// Consume all incoming websockets on this url
this.incoming.consumeAsFlow().collect {
logger.d("Received ticket status websocket of type ${it.frameType.name}")
if (it is Frame.Text) {
Json.decodeFromString<TicketStatusResponse>(it.readText())
}
}
}
Does somebody have any experience with ktor-websockets library? There is almost no documentation so maybe I am doing something wrong.
Thank you
As the documentation says
Ktor provides Websocket client support for the following engines: CIO, OkHttp, Js.
This means that it works only on JVM/JS, you're probably targeting iOS. It's not yet supported, you can follow issue KTOR-363 for updates
For sure the team is working on it, but for now you had to implement it by yourself using expect/actual, you can check out official example
An other possible problem in your code: host shouldn't include https://, if you're using ssl, you should add an other parameter:
request = {
url.protocol = URLProtocol.WSS
}
Or use client.wss(...) - which is just a short form for the same operation

SSPI negotiation failed WSTrustChannelFactory

This one has me for a while now, I am trying to build a console app that can call a .net web/wcf service SP, the first leg is to get a token from the idP (ADFS4.0) the pasted code was working fine for a whole day, at some point it stopped working with the following error:
SOAP security negotiation with 'https://adfs.domain.in/adfs/services/trust/13/windowsmixed' for target 'https://adfs.domain.in/adfs/services/trust/13/windowsmixed' failed. See inner exception for more details.
The inner error is:
The Security Support Provider Interface (SSPI) negotiation failed.
NativeErrorCode: 0x80090350 -> SEC_E_DOWNGRADE_DETECTED
I have tried /13/windows and /windowstransport as well as the endpoint.
private static GenericXmlSecurityToken RequestSecurityToken()
{
// set up the ws-trust channel factory
var factory = new Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannelFactory(new WindowsWSTrustBinding(
SecurityMode.TransportWithMessageCredential), new EndpointAddress(new Uri("https://adfs.domain.in/adfs/services/trust/13/windowsmixed"), EndpointIdentity.CreateSpnIdentity("adfs#domain.in")));
factory.TrustVersion = TrustVersion.WSTrust13;
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Bearer,
AppliesTo = new System.ServiceModel.EndpointAddress(endpoint_address)
};
// request token and return
return factory.CreateChannel().Issue(rst) as GenericXmlSecurityToken;
}
In my case, for some reason, the ADFS was available over VPN but the AD based authentication bits are not happening over VPN. That's why SEC_E_DOWNGRADE_DETECTED is coming. In a regular non VPN environment things are good.
Also, another observation is once SAML token is generated over a regular enterprise network. Subsequent calls to generate the SAML token are going through as expected even on VPN.
So, if you see this error just check if the network you are in is part of the domain (and not public or private network), for SSPI negotiation.

Is there an API method in Slack-Api to set (change) Events API Request URLs so I can do this in code?

To use Events API for Slack App development, there is a setting for "Events API Request URLs" as described in doc:
In the Events API, your Events API Request URL is the target location
where all the events your application is subscribed to will be
delivered, regardless of the team or event type.
There is a UI for changing the URL "manually" at api.slack.com under
"Event Subscriptions" section in settings. There is also url_verification event after changing the Request URL described here.
My question - Is there an API call (method) so I can update the endpoint (Request URL) from my server code?
For example, in Facebook API there is a call named subscriptions where I can change webhook URL after initial setup - link
Making a POST request with the callback_url, verify_token, and object
fields will reactivate the subscription.
PS. To give a background, this is needed for development using outbound tunnel with dynamic endpoint URL, e.g. ngrok free subscription. By the way, ngrok is referenced in sample "onboarding" app by slack here
Update. I checked Microsoft Bot Framework, and they seems to use RTM (Real Time Messaging) for slack which doesn't require Request URL setup, and not Events API. Same time, e.g. for Facebook they (MS Bot) instruct me to manually put their generated URL to webhook settings of a FB app, so there is no automation on that.
Since this question was originally asked, Slack has introduced app manifests, which enable API calls to change app configurations. This can be used to update URLs and other parameters, or create/delete apps.
At the time of writing, the manifest / manifest API is in beta:
Beta API — this API is in beta, and is subject to change without the usual notice period for changes.
so the this answer might not exactly fit the latest syntax as they make changes.
A programatic workflow might look as follows:
Pull a 'template' manifest from an existing version of the application, with most of the settings as intended (scopes, name, etc.)
Change parts of the manifest to meet the needs of development
Verify the manifest
Update a slack app or create a new one for testing
API List
Basic API list
Export a manifest as JSON: apps.manifest.export
Validate a manifest JSON: apps.manifest.validate
Update an existing app: apps.manifest.update
Create a new app from manifest: apps.manifest.create
Delete an app: apps.manifest.delete
Most of these API requests are Tier 1 requests, so only on the order of 1+ per minute.
API Access
You'll need to create and maintain "App Configuration Tokens". They're created in the "Your Apps" dashboard. More info about them here.
Example NodeJS Code
const axios = require('axios');
// Change these values:
const TEMPLATE_APP_ID = 'ABC1234XYZ';
const PUBLIC_URL = 'https://www.example.com/my/endpoint';
let access = {
slackConfigToken: "xoxe.xoxp-1-MYTOKEN",
slackConfigRefreshToken: "xoxe-1-MYREFRESHTOKEN",
slackConfigTokenExp: 1648550283
};
// Helpers ------------------------------------------------------------------------------------------------------
// Get a new access token with the refresh token
async function refreshTokens() {
let response = await axios.get(`https://slack.com/api/tooling.tokens.rotate?refresh_token=${access.slackConfigRefreshToken}`);
if (response.data.ok === true) {
access.slackConfigToken = response.data.token;
access.slackConfigRefreshToken = response.data.refresh_token;
access.slackConfigTokenExp = response.data.exp;
console.log(access);
} else {
console.error('> [error] The token could not be refreshed. Visit https://api.slack.com/apps and generate tokens.');
process.exit(1);
}
}
// Get an app manifest from an existing slack app
async function getManifest(applicationID) {
const config = {headers: { Authorization: `Bearer ${access.slackConfigToken}` }};
let response = await axios.get(`https://slack.com/api/apps.manifest.export?app_id=${applicationID}`, config);
if (response.data.ok === true) return response.data.manifest;
else {
console.error('> [error] Invalid could not get manifest:', response.data.error);
process.exit(1);
}
}
// Create a slack application with the given manifest
async function createDevApp(manifest) {
const config = {headers: { Authorization: `Bearer ${access.slackConfigToken}` }};
let response = await axios.get(`https://slack.com/api/apps.manifest.create?manifest=${encodeURIComponent(JSON.stringify(manifest))}`, config);
if (response.data.ok === true) return response.data;
else {
console.error('> [error] Invalid could not create app:', response.data.error);
process.exit(1);
}
}
// Verify that a manifest is valid
async function verifyManifest(manifest) {
const config = {headers: { Authorization: `Bearer ${access.slackConfigToken}` }};
let response = await axios.get(`https://slack.com/api/apps.manifest.validate?manifest=${encodeURIComponent(JSON.stringify(manifest))}`, config);
if (response.data.ok !== true) {
console.error('> [error] Manifest did not verify:', response.data.error);
process.exit(1);
}
}
// Main ---------------------------------------------------------------------------------------------------------
async function main() {
// [1] Check token expiration time ------------
if (access.slackConfigTokenExp < Math.floor(new Date().getTime() / 1000))
// Token has expired. Refresh it.
await refreshTokens();
// [2] Load a manifest from an existing slack app to use as a template ------------
const templateManifest = await getManifest(TEMPLATE_APP_ID);
// [3] Update URLS and data in the template ------------
let devApp = { name: 'Review App', slashCommand: '/myslashcommand' };
templateManifest.settings.interactivity.request_url = `${PUBLIC_URL}/slack/events`;
templateManifest.settings.interactivity.message_menu_options_url = `${PUBLIC_URL}/slack/events`;
templateManifest.features.slash_commands[0].url = `${PUBLIC_URL}/slack/events`;
templateManifest.oauth_config.redirect_urls[0] = `${PUBLIC_URL}/slack/oauth_redirect`;
templateManifest.settings.event_subscriptions.request_url = `${PUBLIC_URL}/slack/events`;
templateManifest.display_information.name = devApp.name;
templateManifest.features.bot_user.display_name = devApp.name;
templateManifest.features.slash_commands[0].command = devApp.slashCommand;
// [5] Verify that the manifest is still valid ------------
await verifyManifest(templateManifest);
// [6] Create our new slack dev application ------------
devApp.data = await createDevApp(templateManifest);
console.log(devApp);
}
main();
Hope this helps anyone else looking to update Slack applications programatically.
No, such a method does not exist in the official documentation. There might be an unofficial method - there are quite a few of them actually - but personally I doubt it.
But you don't need this feature for developing Slack apps. Just simulate the POST calls from Slack on your local dev machine with a script and then do a final test together with Slack on your webserver on the Internet.

Test Webhook at localhost in braintree

I am working on braintree and I want to send custom email notifications to my customers as I am working with recurring billing, so every month these custom notifications should be send to all users. For this I have to use webhooks to retrieve currently ocuured event and then send email notification according to webhook's response. (I think this is only solution in this case, If anyone know another possible solution please suggest). I want to test webhooks at my localhost first, And I have tried to create a new webhook and specified the localhost path as destination to retrieve webhooks. But this shows a error "Destination is not verified"..........
My path is : "http://127.0.0.1:81/webhook/Accept"
These are some of the tools that can be used during development of webhooks :
1) PostCatcher,
2) RequestBin,
3) ngrok,
4) PageKite and
5) LocalTunnel
http://telerivet.com/help/api/webhook/testing
https://www.twilio.com/blog/2013/10/test-your-webhooks-locally-with-ngrok.html
Well Another way to test it is by creating a WebAPI and POSTing Data to your POST method via Postman. To do this, just create a WebAPI in Visual Studio. In the API controller, create a POST method.
/// <summary>
/// Web API POST method for Braintree Webhook request
/// The data is passed through HTTP POST request.
/// A sample data set is present in POSTMAN HTTP Body
/// /api/webhook
/// </summary>
/// <param name="BTRequest">Data from HTTP request body</param>
/// <returns>Webhook notification object</returns>
public WebhookNotification Post([FromBody]Dictionary<String, String> BTRequest)
{
WebhookNotification webhook = gateway.WebhookNotification.Parse(BTRequest["bt_signature"], BTRequest["bt_payload"]);
return webhook;
}
In Postman, Post the following data in the Body as raw JSON.
{
"bt_signature":"Generated Data",
"bt_payload":"Very long generated data"
}
The data for the above Json dictionary has been generated through the below code:
Dictionary<String, String> sampleNotification = gateway.WebhookTesting.SampleNotification(WebhookKind.DISPUTE_OPENED, "my_Test_id");
// Your Webhook kind and your test ID
Just pick the data from sample notification and place it above in the JSON. Run your WebAPI, place debuggers. Add the localhost URL in Postman, select POST, and click on Send.
Your POST method should be hit.
Also, don't forget to add your gateway details:
private BraintreeGateway gateway = new BraintreeGateway
{
Environment = Braintree.Environment.SANDBOX,
MerchantId = "Your Merchant Key",
PublicKey = "Your Public Key",
PrivateKey = "Your Private Key"
};
I hope this helps!
I work at Braintree. If you need more help, please get in touch with our support team.
In order to test webhooks, your app needs to be able to be reached by the Braintree Gateway. A localhost address isn't. Try using your external IP address and make sure the port on the correct computer can be reached from the internet.
Take a look at the Braintree webhook guide for more info on setting up webhooks.
You can use PutsReq to simulate the response you want and do your end-to-end test in development.
For quick 'n dirty testing:
http://requestb.in/
For more formal testing (e.g. continuous integration):
https://www.runscope.com/
If you have a online server you may forward port from your computer to that server.
ssh -nNT -R 9090:localhost:3000 root#yourvds.com
And then specify webhook as http://yourvds.com:9090/webhook
all requests will be forwarded to you machine, you will be able to see logs
I know this is an old question, but according to the docs, you can use this code to test your webhook code:
Dictionary<String, String> sampleNotification = gateway.WebhookTesting.SampleNotification(
WebhookKind.SUBSCRIPTION_WENT_PAST_DUE, "my_id"
);
WebhookNotification webhookNotification = gateway.WebhookNotification.Parse(
sampleNotification["bt_signature"],
sampleNotification["bt_payload"]
);
webhookNotification.Subscription.Id;
// "my_id"
You can use the Svix CLI Listener: https://github.com/svix/svix-cli#using-the-listen-command
This will allow you to easily channel requests to your public endpoint to a local port where you can run your logic against and debug it on your localhost.

Resources