send data from Rfid rc522 to azure iot hub using nodejs - node.js

//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
});
});

Related

How to get activate device in X509 self assigned Device type in Azure IOT hub?

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.

How to integrate Azure IOT Hub with Ionic Mobile app?

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));
});

where to place the for-loop in existing node.js scrtip

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);
'''

Azure IOT Hub MQTT Messages Lost on Internet drop

We are using azure-iot-device-mqtt node package to connect a debian computer to the Azure IOT Hub. We have noticed that when the Internet drops (i.e. we disconnect it) Device Explorer thinks the device is still connected (for about 10 seconds) and messages being fired in this period do not reach the device (or get queued). After 10 seconds they appear in the Device Explorer queue. Also the device still thinks it's connected and does not recover the connection.
We have tried package versions 1.1.17 and 1.2.1 and have the same symptoms on both.
var clientFromConnectionString = require('azure-iot-device-mqtt').clientFromConnectionString;
var Message = require('azure-iot-device').Message;
var connectionString = 'xxx';
var client = clientFromConnectionString(connectionString);
var connectCallback = function (err) {
if (err) {
console.error('Could not connect: ' + err);
} 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());
});
client.on('message', function (msg) {
console.log(msg);
client.complete(msg, function () {
console.log('completed');
});
});
client.on('disconnect', function () {
console.log("disconnect");
});
}
};
client.open(connectCallback);
N.b We require MQTT as we are using direct-method functionality.
With the AMQP package as soon as any disconnection the messages from the cloud instantly go into the queue.
Summary of issues:
MQTT messages lost for first 10-15 seconds of disconnection (After this they are queued cloud side).
MQTT+AMQP clients does not detect disconnects.
Any advice would be greatly appreciated.
Thanks,
David

APN Feedback service does not send tokens

I implemented a node.js script that queries the APN Feedback service to retrieve the list of invalid tokens. Unfortunately, I did not manage to get any invalid token. I followed these steps:
Install the ios app with push notifications in sandbox mode.
Send some notifications to the app (done successfully).
Uninstall the app (I read that if the app that I uninstall is the only one with push notifications, it will cause the disconnection from the APN Service and make impossible to notify it that the app was uninstalled; but this is not my case, the iPad has many push notification apps installed!!).
Send many other notifications with the same token, about ten or twenty, just to prove that the application token is not valid anymore (obviously the notifications are not delivered because the app has just been uninstalled).
Query the Feedback service to finally get the invalid token. The
Feedback service does not send anything, it just closes the connection without any kind of data.
This is the script I use to query the feedback service:
function pollAPNFeedback() {
var certPem = fs.readFileSync('apns-prod-cert.pem', encoding='ascii');
var keyPem = fs.readFileSync('apns-prod-key-noenc.pem', encoding='ascii');
var options = { key: keyPem, cert: certPem };
console.log("Connecting APN feedback service");
var stream = tls.connect(2196, 'feedback.sandbox.push.apple.com', options, function() {
if (stream.authorized == false) {
return console.log('not connected')
} else {
console.log('connected');
};
var bufferlist = [];
stream.on('data', function(data) {
// APN feedback starts sending data immediately on successful connect
console.log('-->Data: ', data);
//bufferlist.push(data);
});
stream.on('readable', function(){
console.log('we have incoming data');
});
stream.on('error', function(err){
console.log('error: ', err);
});
stream.on('close', function(){
console.log('closed');
console.log('stream.data = ', stream.data);
});
});
}
As you can see, I put some listeners on the stream variable. The callback function on the 'data' listener is never invoked, only the 'close' event triggers its callback. I am sure that the connection is up because stream.authorized is true.
What am I doing wrong?
Is it possible that you are using a production certificate to contact the sandbox environment?
From your code :
var certPem = fs.readFileSync('apns-prod-cert.pem', encoding='ascii');
var keyPem = fs.readFileSync('apns-prod-key-noenc.pem', encoding='ascii');
And :
var stream = tls.connect(2196, 'feedback.sandbox.push.apple.com', options, function()
If that's the case, that's why it doesn't work.

Resources