I need to implement Notifications in my Ionic Application for Android. For that we have set up Azure IOT Hub where the device should get registered and from there, we can send messages to the device and vice versa (from the device to the cloud).
Now, I have gone through lots of links in the google regarding plugins for azure in Ionic, i tried them but in vain. I need to do two things
Register the device ID with the Azure IOT Hub
Send Notification in the Azure IOT Hub using that device ID, so that I can receive it in the device.
I have gone through
https://github.com/Azure/azure-iot-sdk-node
https://github.com/derek82511/cordova-azure-notification-hubs
None of them helped me to register device to the IOT Hub. Can some one guide me in the right direction. I need to know the process how to connect the Azure IOT Hub with my Ionic mobile app for Android.
Code:
var iothub = require('azure-iothub');
var connectionString = config.hubConnectionString;
var registry = iothub.Registry.fromConnectionString(connectionString);
// Create a new device
var device = {
deviceId: uuid
};
registry.create(device, function(err, deviceInfo, res) {
if (err) {
console.log( ' error: ' + err.toString());
this.showAlert('Create Device Error',err.toString());
}
if (res) {
console.log(' status: ' + res.statusCode + ' ' + res.statusMessage);
this.showAlert('Create Device Success Response',`status: ${res.statusCode} ${res.statusMessage}`);
}
if (deviceInfo) {
console.log(' device info: ' + JSON.stringify(deviceInfo));
this.showAlert('Device Info',JSON.stringify(deviceInfo));
}
});
//var clientFromConnectionString = require('azure-iot-device-http').clientFromConnectionString;
//var Message = require('azure-iot-device').Message;
var connectionString = config.hubConnectionString;
var client = clientFromConnectionString(connectionString);
var connectCallback = function (err) {
if (err) {
console.error('Could not connect: ' + err);
this.showAlert('HTTP Connection Error',err.toString());
} else {
console.log('Client connected');
var message = new Message('some data from my device');
client.sendEvent(message, function (err) {
if (err) {
console.log(err.toString());
this.showAlert('HTTP Send IOT Message Error',err.toString());
}
});
client.on('message', function (msg) {
console.log(msg);
this.showAlert('IOT Received Message',msg);
client.complete(msg, function () {
console.log('completed');
});
});
}
};
client.open(connectCallback);
You need to use the IoT Hub Service SDK: https://www.npmjs.com/package/azure-iothub
This example is from that link and shows how to use the device registry to create a new device.
var iothub = require('azure-iothub');
var connectionString = '[IoT Connection String]';
var registry = iothub.Registry.fromConnectionString(connectionString);
// Create a new device
var device = {
deviceId: 'sample-device-' + Date.now()
};
registry.create(device, function(err, deviceInfo, res) {
if (err) console.log('error: ' + err.toString());
if (res) console.log('status: ' + res.statusCode + ' ' + res.statusMessage);
if (deviceInfo) console.log('device info: ' + JSON.stringify(deviceInfo));
});
Related
Azure Notification Hub Exception: not able to register device entries.. the request could not be completed. we are using node js to register
You can use below code to register device entries.
Related posts and documents:
1. Issue with notification hub
2. createRegistrationId(callback)
/**
* Creates a registration identifier.
*
* #param {Function(error, response)} callback `error` will contain information
* if an error occurs; otherwise, `response`
* will contain information related to this operation.
*/
NotificationHubService.prototype.createRegistrationId = function (callback) {
validateCallback(callback);
var webResource = WebResource.post(this.hubName + '/registrationids');
webResource.headers = {
'content-length': null,
'content-type': null
};
this._executeRequest(webResource, null, null, null, function (err, rsp) {
var registrationId = null;
if (!err) {
var parsedLocationParts = url.parse(rsp.headers.location).pathname.split('/');
registrationId = parsedLocationParts[parsedLocationParts.length - 1];
}
callback(err, registrationId, rsp);
});
};
Using the azure-sb node.js module, you should be able to register a device and send to it directly. This requires a connection string and hub, as well as a device token, depending on the platform such as APNS.
import { NotificationHubService } from 'azure-sb';
const CONNECTION_STRING = ''; // Full Access Connection String
const HUB_NAME = ''; // Notification Hub Name
const APNS_TOKEN = ''; //APNS Token
const APNS_MESSAGE = {
aps: {
alert: "Notification Hub test notification"
}
};
service.apns.createNativeRegistration(APNS_REGISTRATION_ID, SAMPLE_TAG, (err, response) => {
if (err) {
console.log(err);
return;
}
console.log('Registration success');
console.log(JSON.stringify(response));
service.apns.send(SAMPLE_TAG, APNS_MESSAGE, (error, res) => {
if (error) {
console.log(error);
return;
}
console.log('Message sent');
console.log(JSON.stringify(res));
});
});
When this runs, it should register the device and send to it. I have run this very recently and works without a hitch. The older azure module might be tied to earlier TLS 1.0/1.1, which has since been deprecated for usage on Azure.
I am new to IOT and X509 Authentication provisioning.
I am able to register device using node.js in Azure IOT hub (Self Assigned X509 Device type).
The pipeline is,
1. Download certificate of the registered device type.
2. convert into key and cert pem files
3. pass register id as device id
register_X509.js
'use strict';
var fs = require('fs');
var Client = require('azure-iot-device').Client;
var Message = require('azure-iot-device').Message;
var X509AuthenticationProvider = require('azure-iot-device').X509AuthenticationProvider;
var Protocol = require('azure-iot-device-mqtt').Mqtt;
var Transport = require('azure-iot-provisioning-device-mqtt').Mqtt;
var X509Security = require('azure-iot-security-x509').X509Security;
var ProvisioningDeviceClient = require('azure-iot-provisioning-device').ProvisioningDeviceClient;
var provisioningHost = 'my-provisioning-host';
var idScope = 'id-scope';
var registrationId = 'registration-id';
var deviceCert = {
cert: fs.readFileSync('cert.pem').toString(),
key: fs.readFileSync('key.pem').toString()
};
var transport = new Transport();
var securityClient = new X509Security(registrationId, deviceCert);
var deviceClient = ProvisioningDeviceClient.create(provisioningHost, idScope, transport, securityClient);
// Register the device. Do not force a re-registration.
deviceClient.register(function(err, result) {
if (err) {
console.log("error registering device: " + err);
} else {
console.log('registration succeeded');
console.log('assigned hub=' + result.assignedHub);
console.log('deviceId=' + result.deviceId);
var client = Client.fromAuthenticationProvider(X509AuthenticationProvider.fromX509Options(
result.deviceId, result.assignedHub, deviceCert
), Protocol);
var connectCallback = function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
} else {
console.log('Client connected');
// Create device Twin
client.getTwin(function (err, twin) {
if (err) {
console.error('could not get twin');
} else {
console.log('twin created');
console.log('twin contents:');
console.log(twin.properties);
// Send Event message
setTimeout(function () {
var data = JSON.stringify({
'did': result.deviceId,
'dts': new Date().toISOString(),
'desiredStatus': 'Activated',
'reportedStatus': 'Activating',
'msg': []
});
var message = new Message(data);
console.log('Sending message: ' + message.getData());
client.sendEvent(message, printResultFor('send'));
}, 1000);
}
});
client.on('error', function (err) {
console.error(err.message);
});
client.on('message', function (msg) {
console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
// When using MQTT the following line is a no-op.
client.complete(msg, printResultFor('completed'));
// The AMQP and HTTP transports also have the notion of completing, rejecting or abandoning the message.
// When completing a message, the service that sent the C2D message is notified that the message has been processed.
// When rejecting a message, the service that sent the C2D message is notified that the message won't be processed by the device. the method to use is client.reject(msg, callback).
// When abandoning the message, IoT Hub will immediately try to resend it. The method to use is client.abandon(msg, callback).
// MQTT is simpler: it accepts the message by default, and doesn't support rejecting or abandoning a message.
});
}
};
client.open(connectCallback);
}
});
// Helper function to print results in the console
function printResultFor(op) {
return function printResult(err, res) {
if (err) console.log(op + ' error: ' + err.toString());
if (res) console.log(op + ' status: ' + res.constructor.name);
};
}
At the end of this output, my device is registed under IOT hub and I am able to make connection as well using following code.
The output of the above script is,
registration succeeded
assigned hub=my-end-point.net
deviceId=my-device-id
Client connected
twin created
twin contents:null: Object {reported: Object, desired: Object}
Sending message: {"did":"my-device-id","dts":"2020-01-30T07:18:38.471Z","desiredStatus":"Activated","reportedStatus":"Activating","msg":[]}
send status: MessageEnqueued
it says messages is in queue but I am unable to activate the device.
I'm stuck at this stage, Can anyone help me to get rid of this?
any idea why it's not working or Am I going in the right approach would be welcome.
I have a existing script from Microsoft that generates data for an IoT hub. Script works like a charm and generates telemetry data every second. Now I want to add an Id to the output of the code. Nothing fancy just starting at 1 and progress with every message up to 1000000
I search for the for loop and found an easy example on W3 schools. But when I use this piece of code the way I think it should be used, it does not generate code every second anymore, but continuously. and the Id field starts at 1000000 and does not add up.
The sample code from Microsoft:
'''var connectionString = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
// Using the Node.js Device SDK for IoT Hub:
// https://github.com/Azure/azure-iot-sdk-node
// The sample connects to a device-specific MQTT endpoint on your IoT Hub.
var Mqtt = require('azure-iot-device-mqtt').Mqtt;
var DeviceClient = require('azure-iot-device').Client
var Message = require('azure-iot-device').Message;
var client = DeviceClient.fromConnectionString(connectionString, Mqtt);
// Create a message and send it to the IoT hub every second
setInterval(function(){
// Simulate telemetry.
var temperature = 20 + (Math.random() * 15);
var message = new Message(JSON.stringify({
temperature: temperature,
humidity: 60 + (Math.random() * 20)
}));
// Add a custom application property to the message.
// An IoT hub can filter on these properties without access to the message body.
message.properties.add('temperatureAlert', (temperature > 30) ? 'true' : 'false');
console.log('Sending message: ' + message.getData());
// Send the message.
client.sendEvent(message, function (err) {
if (err) {
console.error('send error: ' + err.toString());
} else {
console.log('message sent');
}
});
}, 1000);
'''
The way I used the for-loop:
'''
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
'use strict';
// The device connection string to authenticate the device with your IoT hub.
//
// NOTE:
// For simplicity, this sample sets the connection string in code.
// In a production environment, the recommended approach is to use
// an environment variable to make it available to your application
// or use an HSM or an x509 certificate.
// https://learn.microsoft.com/azure/iot-hub/iot-hub-devguide-security
//
// Using the Azure CLI:
// az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id MyNodeDevice --output table
var connectionString = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
// Using the Node.js Device SDK for IoT Hub:
// https://github.com/Azure/azure-iot-sdk-node
// The sample connects to a device-specific MQTT endpoint on your IoT Hub.
var Mqtt = require('azure-iot-device-mqtt').Mqtt;
var DeviceClient = require('azure-iot-device').Client
var Message = require('azure-iot-device').Message;
var client = DeviceClient.fromConnectionString(connectionString, Mqtt);
**var id
for (id = 0; id < 1000000; id++) {**
// Create a message and send it to the IoT hub every second
setInterval(function(){
// Simulate telemetry.
var temperature = 20 + (Math.random() * 15);
var message = new Message(JSON.stringify({
id: id,
temperature: temperature,
humidity: 60 + (Math.random() * 20)
}));
// Add a custom application property to the message.
// An IoT hub can filter on these properties without access to the message body.
message.properties.add('temperatureAlert', (temperature > 30) ? 'true' : 'false');
console.log('Sending message: ' + message.getData());
// Send the message.
client.sendEvent(message, function (err) {
if (err) {
console.error('send error: ' + err.toString());
} else {
console.log('message sent');
}
});
}, 1000);
**};**
'''
How to use the for loop in the existing script so I can Add an ID to the output that starts at 1 progresses with 1 every single record up to 1000000
Remove the for loop, just ad id var outside the setInterval in increase it each fire:
// Using the Node.js Device SDK for IoT Hub:
// https://github.com/Azure/azure-iot-sdk-node
// The sample connects to a device-specific MQTT endpoint on your IoT Hub.
var Mqtt = require('azure-iot-device-mqtt').Mqtt;
var DeviceClient = require('azure-iot-device').Client
var Message = require('azure-iot-device').Message;
var client = DeviceClient.fromConnectionString(connectionString, Mqtt);
**var id
var id = 0;
// Create a message and send it to the IoT hub every second
setInterval(function(){
id++;
// Simulate telemetry.
var temperature = 20 + (Math.random() * 15);
var message = new Message(JSON.stringify({
id: id,
temperature: temperature,
humidity: 60 + (Math.random() * 20)
}));
// Add a custom application property to the message.
// An IoT hub can filter on these properties without access to the message body.
message.properties.add('temperatureAlert', (temperature > 30) ? 'true' : 'false');
console.log('Sending message: ' + message.getData());
// Send the message.
client.sendEvent(message, function (err) {
if (err) {
console.error('send error: ' + err.toString());
} else {
console.log('message sent');
}
});
}, 1000);
'''
I'm trying to use Azure IoT Hub Device SDK for Node to listen to new blob in storage account events (or whatever that's called officialy). I'm following this sample.
I have receive notifications turned on:
However, the client SDK gets nothing when i add a file to that container.
client.on('message', function (msg) {
// message event does not fire
console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
}
If i send a cloud-to-device message (also from the Portal blade) it goes through just fine and i can read it in console.log().
Am i listening for the completely wrong event — message?
It looks like you're expecting to receive file upload notifications on the cloud-to-device message channel. that's not where these notifications are surfaced.
There are 2 types of SDKs for Azure IoT Hub: Device SDKs, and Service SDKs.
The capability to upload a file is in the Device SDK (azure-iot-device package).
The capability to monitor file upload notifications (from all devices) is in the Service SDK (azure-iothub package).
In the Device SDK When the upload is complete, the callback to the uploadToBlob method is called.
source from example
var Protocol = require('azure-iot-device-mqtt').Mqtt;
var Client = require('azure-iot-device').Client;
var fs = require('fs');
var filePath = '[path/to/file]';
var client = Client.fromConnectionString(deviceConnectionString, Protocol);
fs.stat(filePath, function (err, fileStats) {
var fileStream = fs.createReadStream(filePath);
client.uploadToBlob('testblob.txt', fileStream, fileStats.size, function (err, result) {
if (err) {
console.error('error uploading file: ' + err.constructor.name + ': ' + err.message);
} else {
console.log('Upload successful - ' + result);
}
fileStream.destroy();
});
});
If you want to listen for notification when a file is uploaded to a blob by a device, you need to use the Service SDK . Use the client to get a "file notification receiver" and then listen on this object's "message" event.
source for the example
var Client = require('azure-iothub').Client;
var client = Client.fromConnectionString(connectionString);
client.open(function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
} else {
console.log('Client connected');
client.getFileNotificationReceiver(function(err, receiver) {
if(err) {
console.error('Could not get file notification receiver: ' + err.message);
} else {
receiver.on('message', function(msg) {
console.log('File uploaded: ');
console.log(msg.data.toString());
receiver.complete(msg, function(err) {
if (err) {
console.error('Could not complete the message: ' + err.message);
} else {
console.log('Message completed');
}
});
});
}
});
}
});
In addition to #pierreca-MSFT, there is also another option for upload file notifications such as using an Azure Event Grid (today in the preview). In this case, your files are uploaded into the event-driven blob storage, which automatically it will publish an event message to the Event Grid. These event messages can be distributed (pushed) to the subscribers in the reliable manner based on the Event Grid Subscriptions. This is an event-driven push model.
More details about the Azure Event Grid is here and for event-driven blob storage here.
The following screen snippet shows an example of the event message in my subscriber (Azure Function) after when the file has been uploaded from the device. Note, that for this example (for demonstration purpose), the device used a REST Api calls for handling an upload file, see more details here.
//THIS IS THE CODE TO READ SERIAL NUMBER AND SEND DATA TO AZURE IOT HUB
var rc522=require("rc522/build/Release/rc522");
var Async = require('async');
var Protocol = require('azure-iot-device-http').Http;
var Client = require('azure-iot-device').Client;
var ConnectionString = require('azure-iot-device').ConnectionString;
var Message = require('azure-iot-device').Message;
// Enter Device Connection String: AZURE--> IOTHub --> Devices--> select Device--> Connection String.
var connectionString = '';
var deviceId = ConnectionString.parse(connectionString).DeviceId;
var client = Client.fromConnectionString(connectionString, Protocol);
var connectCallback=function(err){
if(err){
console.error('could not open connection' +err);
}
else{
console.log('client connected');
rc522(function(serial){
console.log(serial);
});
var readings = { Id:serial};
var message = new Message(JSON.stringify(readings));
client.sendEvent(message, function (error) {
if (error)
{
console.log(error.toString());
}
else
{
console.log("Data sent on %s...", new Date());
}
});
}
}
client.open(connectCallback);
I cannot send rfid rc522 serial number to Azure IOT hub with Nodejs.I am able to connect to client and display serial number on console but cannot see any received messages in azure iot hub.I wrote function app and sent iothub message to tablestorage.
Below is my code and output
iothub and table storage output,
console output for rfid nodejs,
Can somepone please explain me how to send serial number to azure IOT hub.
I have searched for resources about this but could not find any in nodejs.
Many Thanks in advance
What happens when you log JSON.stringify(readings) to the console? I am not a node.js expert but I think serial is undefined there since it is used outside the scope of rc522(function(serial){ ..} where it is defined
try
rc522(function(serial){
console.log(serial);
var readings = { Id:serial};
var message = new Message(JSON.stringify(readings));
client.sendEvent(message, function (error) {
// code here
});
});