Remote Controlling / Monitoring - Azure IoT hub - raspberry-pi

I'm doing a small project where I'm using a Raspberry PI to monitor temperature and controlling a LED using Azure IOT Hub. The temperature is visualized through a dashboard portal, where you also can control the LED. I've read the documentation thoroughly but it I'm still unsure about a couple of things:
Remote Monitoring:
The Raspberry PI currently sends temperature to my IoT Hub (Device2Cloud), everything looks fine on that part. In order to display the values sent from the Raspberry PI I'm reading off the Event bus from my NodeJS backend, in the same manner as they do in this sample:
https://github.com/Azure-Samples/web-apps-node-iot-hub-data-visualization/blob/master/IoThub/iot-hub.js
Is this correct way to read device to cloud messages?
Remote Controlling
This is the part I'm very unsure about, I would like to control the LED that's connected to the Raspberry PI through Cloud2Device communication in my dashboard page. I'm not quite sure how to implement this in my Node JS backend, and I really cant find any good examples where this has been done. Any advice would be appreciated.

Regarding the remote monitoring question: yes this will work although i want to point out that the event hubs SDK for Node is still preview (and might change a bit in the future) so you should expect some quirks.
Regarding "remote controlling": in order to send cloud-to-device messages you should use the Azure IoT Hub Service SDK for Node, and here is an example of how to send a cloud to device message (copied from here)
'use strict';
var Client = require('azure-iothub').Client;
var Message = require('azure-iot-common').Message;
var connectionString = '[IoT Hub Connection String]';
var targetDevice = '[Target device that will receive the message]';
var client = Client.fromConnectionString(connectionString);
client.open(function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
} else {
console.log('Client connected');
// Create a message and send it to the IoT Hub every second
var data = JSON.stringify({ text : 'foo' });
var message = new Message(data);
console.log('Sending message: ' + message.getData());
client.send(targetDevice, message, function (err) {
if (err) {
console.error('Could not send: ' + err.message);
} else {
console.log('Message sent');
}
});
}
});

You have a couple of options for remotely controlling your device. You should review this article (https://learn.microsoft.com/azure/iot-hub/iot-hub-devguide-c2d-guidance) to determine which option is most appropriate for your scenario.
You can find a cloud-to-device messages tutorial here: https://learn.microsoft.com/azure/iot-hub/iot-hub-node-node-c2d
You can find a direct methods tutorial here: https://learn.microsoft.com/azure/iot-hub/iot-hub-node-node-direct-methods

Related

Notifications not received on Android device via Azure Notifications hub, but on firebase console they deliver as expected

I have recently updated my app to flutter for cross platform availability but I am having trouble receiving push notifications.
When I send an "alert" to the backend, users should be notified that someone sent out an alert.
Right now when I call the SendFCMNativeNotificationsAsync method, I always get an enqueued response (when I only had an Android version they always said successful).
private async Task sendNotifAsync(Alert alert)
{
Microsoft.Azure.NotificationHubs.NotificationOutcome outcome = null;
HttpStatusCode ret = HttpStatusCode.InternalServerError;
var cafe = cafeRepository.GetById(alert.CafeId);
var message = alert.UserName + " needs help in " + cafe.Name;
var notif = "{ \"notification\":{\"title\":\"Somebody needs help\",\"body\":\""+message+"\"},\"data\" : {\"message\":\"" + "From " + alert.UserName + ": " + message + "\"}}";
outcome = await Notifications.Instance.Hub.SendFcmNativeNotificationAsync(notif);
}
This is the code I use to call the notificationhub in my backend.
The weird thing is that when I try to send a test notification via firebase console, it works as expected, so I don't really know where to look right now to fix this issue.
To send push notification to a Flutter application targeting Android and iOS, first we need to handle device registration for the client using the latest and best Installation approach using an ASP.NET Core Web API backend. Check this Registration management document more further details.
There can be many reasons why you are facing this issue, it may be due to Notification Hubs misconfiguration or may be for Application issue due to invalid registration and Push notification service could also be the issues.
Since you are getting notification from firebase console, push notification service should not be an issue. Still you can use the EnableTestSend property while you initialize NotificationHubClient to get a detailed status about push notification service errors that occur if any when the notification is sent.
bool enableTestSend = true;
NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString(connString, hubName, enableTestSend);
var outcome = await hub.SendWindowsNativeNotificationAsync(toast);
Console.WriteLine(outcome.State);
foreach (RegistrationResult result in outcome.Results)
{
Console.WriteLine(result.ApplicationPlatform + "\n" + result.RegistrationId + "\n" + result.Outcome);
}
I would suggest to read the Diagnose dropped notifications in Azure Notification Hubs document from Microsoft to do some self-diagnosis and solve the problem you are facing. Also read the Send push notifications to Flutter apps using Azure Notification Hubs via a backend service document for more information.

IBM Connections Cloud custom contextual data

I followed the official documentation and created a minor community app for my website.
What I'd like to know is if there's a way "to shim" custom data to IBM Connections Cloud when uploading my app as a JSON and then retrieve it inside the message handler after my app loads:
window.addEventListener('message', function(event) {
if (event.origin === "https://apps.collabservnext.com"){
// event.data contains the full context
console.log("Running in community named " + event.data.source.resourceId);
}
}, false);
parent.postMessage("appReady", "*");
So far I'm only getting the extraContent, source and user JSON keys in event.data. It would be awesome if there was a way to retrieve say hello: world.
Thanks.

Sending mail from Firebase webapp

var express = require('express');
var app = express();
var nodemailer=require('nodemailer');
var transporter = nodemailer.createTransport('smtps://username#gmail.com:password#smtp.gmail.com');
app.get('/sendMail', function(req,res){
var mailOptions={
to: 'receiver#gmail.com',
subject: 'Test Mail',
html: 'Testing the Mail'
}
transporter.sendMail(mailOptions,function(err,response){
if(err){
res.end('Mail not sent');
}
else{
res.end('Mail sent');
}
});
}).listen(9091);
console.log('This is running');
I am developing a firebase web app. I need to send an email via my web app. I saw some tutorials and found some code. Using the above code I am able to send emails. It runs in the port 9091. The message will be sent when the address bar has www.mywebsite.com/sendMail. But when I host this page to Firebase what changes to be done in this code, whether there must be a change in the port number?. Please help to implement this code in my web app.
Update 2019: Alternatively, you can use the new Trigger Email Firebase Extension (currently in beta).
As I mentioned on my comment, the problem is: your web app was built with NodeJS and you're trying to host it on a static host environment (Firebase Hosting). But Firebase also has Cloud Functions - a service that let's you run functions on a NodeJS environment. So you should deploy your app to that service instead.
It's really easy to Get Started with Cloud Functions. And since you have already set up Firebase hosting, you can simply go to that directory and set up Cloud Functions by using this command:
firebase init functions
A new folder named "functions" will be created and an index.js file will be automatically added to that folder. Now that's the file where you're going to write your functions (we're actually just gonna need 1 function triggered by HTTP to send the email).
So in order to create this function, you would no longer need Express. you can remove that and then change a bit your index.js file to add firebase-functions, so it would become:
//var express = require('express'); No longer needed
//var app = express(); No longer needed
var nodemailer=require('nodemailer');
const functions = require('firebase-functions');
var transporter = nodemailer.createTransport('smtps://username#gmail.com:password#smtp.gmail.com');
exports.sendMail = functions.https.onRequest((req, res) =>{
var mailOptions={
to: 'receiver#gmail.com',
subject: 'Test Mail',
html: 'Testing the Mail'
}
transporter.sendMail(mailOptions,function(err,response){
if(err){
res.end('Mail not sent');
}
else{
res.end('Mail sent');
}
});
});
Now when you want to send a message, you can use this url: https://us-central1-<project-id>.cloudfunctions.net/sendMail
Replace <project-id> with your Firebase Project ID.

How to build a simple smart home app to connect IOT?

I want to create a smart home app Google Home using Actions SDK. As it is now, I have a cloud server and its OAuth 2.0 API and some real IOT devices, all the cloud environment is prepared. When I 've browsed the document of Smart Home, I feel confused, I edit a json file and upload it to my google project with gaction, and isn't done? If it is, How to handle the response json of SNYC,QUERY and EXECUTE? Thanks a lot.
In the Actions on Google console for your project, there should be a webhook field. You put the URL that the HomeGraph will call. In your webhook, you'll receive a JSON payload that contains the intent and other parameters for you to handle.
let reqdata = request.body;
let input = reqdata.inputs[0];
let intent = input.intent;
switch (intent) {
case "action.devices.SYNC":
console.log('post /ha SYNC');
// Do sync
break;
case "action.devices.QUERY":
console.log('post /ha QUERY');
// Do query
break;
case "action.devices.EXECUTE":
console.log('post /ha EXECUTE');
// Do execute
break;
default:
response.status(401).set({
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
}).json({error: "missing intent"});
break;
}
You should return a JSON payload as a response.
The actual way to adjust your IoT device is entirely dependent on your server and device implementation.
You can check out the sample project to figure out a bit more.

Phonegap/Cordova and Couchbase Mobile/server

I'm creating my mobile app using phonegap.
I decided to use Couchbase to store datas; but I can't figure out if I must have to use Couchbase mobile or I can connect my app (javascript) directly with couchbase server, and how to 'query' my .net app.
I have downloaded the couchbase server on my system, but how to connect it with my app?
Can I use N1QL to 'query' the server with .NET also using phonegap? (because couchbase mobile doesn't support n1ql).
I could just call a rest web service done with .NET or maybe JAVA but so is it needed to add couchbase mobile to the app?
This is the query of C# couchbase mobile documentation:
var document = database.CreateDocument();
var properties = new Dictionary<string, object>()
{
{"type", "list"},
{"title", "title"},
{"created_at", DateTime.UtcNow.ToString ("o")},
{"owner", "profile:" + userId},
{"members", new List<string>()}
};
var rev = document.PutProperties(properties);
Debug.Assert(rev != null);
how i Call it?
This is a query in Server documentation (the previous was in mobile):
var doc = new Document<dynamic>{ Id = "document_id", Content = new {Some="value"} };
var result = bucket.Insert(doc);
Console.WriteLine(JsonConvert.SerializeObject(result.Document));
why they are different?
This is the function to connect the server to phonegap:
var DB_NAME = 'todo';
function initRESTClient(url) {
var client = new SwaggerClient({
spec: window.spec,
usePromise: true,
})
.then(function (client) {
client.setHost(url);
if (device.platform == 'android') {
var encodedCredentials = "Basic " + window.btoa(url.split('/')[1].split('#')[0]);
client.clientAuthorizations.add("auth", new SwaggerClient.ApiKeyAuthorization('Authorization', encodedCredentials, 'header'));
}
client.server.get_all_dbs()
.then(function (res) {
var dbs = res.obj;
if (dbs.indexOf(DB_NAME) == -1) {
return client.database.put_db({db: DB_NAME});
}
return client.database.get_db({db: DB_NAME});
})
.then(function (res) {
return client.document.post({db: DB_NAME, body: {title: 'Couchbase Mobile', sdk: 'PhoneGap'}});
})
.then(function (res) {
console.log('Document ID :: ' + res.obj.id);
})
.catch(function (err) {
console.log(err);
});
});
}
sorry if I'm a bit confused but I need some high level clarify to get started coding.
At a high level: you need Couchbase mobile on the device and Couchbase Server on server (cloud or on premise). To push/pull data between mobile and server you need the Couchbase Sync Gateway running (cloud or on premise). More information is available over at the Couchbase Mobile Portal for Developers.
With regards to your question as to why the .Net version of mobile and server queries are different-
The Mobile version calls into Couchbase Lite which is the embedded NoSQL database for mobile client platforms. The database is embedded in your mobile/desktop client and it syncs periodically with the Couchbase Server in the cloud via the sync gateway. So you would typically implement this in your Windows mobile app. You can also implement this in your desktop client application.
The server version - In this case, you would use the .Net SDK that queries against the Couchbase Server. You would implement this in your .Net web service app in your backend. You can implement your backend web service in any supported language including Java.
If you are considering Phonegap, you may want to refer to this tutorial. This integrates with Couchbase Lite using a swagger client- there isn't a native JS API hence the swagger based client. The Couchbase Lite syncs with the Couchbase Server via the Sync Gateway.