How can I connect mosquitto server between raspberry pi and windows7? - javascript

Hello I'm trying to use mosquitto server in Raspberry Pi using MQTT to send a json data from r-pi to window.
Before I use mosquitto server, I used "test.mosquitto.org" It worked well.
I mean It sended some json data to windows.
However, when I turned mosquitto server in r-pi on, the windows put some error message which is
opts.protocol = opts.protocol.replace, cannot read property 'replace' of null.
Would you mind telling me what it is going on and fix it?
this is javascript on windows code (I use python in raspberry pi)
console.log("start");
var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://test.mosquitto.org');
var client = mqtt.connect('192.168.1.2'); // IP of main-broker
client.on('connect', function () {
client.subscribe('sensor_A');
});
client.on('message', function (topic, message) {
console.log("Topic: " + topic);
var parsedData = JSON.parse(message);
var dataLen = parsedData.length
console.log('dataLen: ' + dataLen);
for (var i = 0; i < dataLen; i++) {
var data = JSON.parse(parsedData[i]);
console.log('data ' + i + ': ' + data.time + ' ' + data.tem + ' ' + data.hum + ' ' + data.gas);
}
});
I am using two r-pi which is sub-borker and main-broker.
sub-broker just send some sensor data as json and main-broker controls the json data and send again as json to windows.
I think my writing is quite complex to understand.
In short, I don't want to use "test.mosquitto.org" in r-pi so I turn mosquitto server on in r-pi to send data to window, however, there a error in window.

First you need to remove the line connecting to test.mosquitto.org as that will just confuse things.
Secondly you have missed out the mqtt:// from the URL for the local instance of mosquitto. The error is points out it can not find the protocol from the url.
console.log("start");
var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://192.168.1.2'); // IP of main-broker
client.on('connect', function () {
client.subscribe('sensor_A');
});
client.on('message', function (topic, message) {
console.log("Topic: " + topic);
var parsedData = JSON.parse(message);
var dataLen = parsedData.length
console.log('dataLen: ' + dataLen);
for (var i = 0; i < dataLen; i++) {
var data = JSON.parse(parsedData[i]);
console.log('data ' + i + ': ' + data.time + ' ' + data.tem + ' ' + data.hum + ' ' + data.gas);
}
});

Related

Write javascript array elements to file

I am trying to have a node js script write some coordinates to a csv file for use in a Newman CLI script. I have the following:
const axios = require('axios');
var move_decimal = require('move-decimal-point');
var sLat = 45.029830;
var sLon = -93.400891;
var eLat = 45.069523;
var eLon = -94.286001;
var arrLatLon = []
axios.get('http://router.project-osrm.org/route/v1/driving/' + sLon + ',' + sLat + ';' + eLon + ',' + eLat + '?steps=true')
.then(function (response) {
for (let i = 0; i < response.data.routes[0].legs.length; i++) {
//console.log(response.data)
for (let ii = 0; ii < response.data.routes[0].legs[i].steps.length; ii++) {
//console.log('leg ' + i + " - step " + ii + ": " + response.data.routes[0].legs[i].steps[ii].maneuver.location[1] + "," + response.data.routes[0].legs[i].steps[ii].maneuver.location[0]);
// Declaring Latitude as 'n' & Longitude as 'nn' for decimal calculations
var n = response.data.routes[0].legs[i].steps[ii].maneuver.location[1]
var nn = response.data.routes[0].legs[i].steps[ii].maneuver.location[0]
// Latitude calculatiuons to make 'lat' values API friendly
var y = move_decimal(n, 6)
var p = Math.trunc(y);
// Longitude calculations to make 'lon' values API friendly
var yy = move_decimal(nn, 6)
var pp = Math.trunc(yy);
arrLatLon.push(p + "," + pp);
}
console.log(arrLatLon)
}
})
I have been looking through and trying numerous different tutorials/code snippets regarding writing the array elements from arrLatLon to an output file on my local machine, but none have been successful. The current code outputs the lat,lon correctly, console.log(arrLatLon) outputs:
[ '45029830,-93400894',
'44982812,-93400740',
'44977444,-93400530',
'44973116,-93410884',
'44971101,-93450400',
'45035514,-93766885',
'45035610,-93766886',
'45081631,-94286752',
'45070849,-94282026' ]
any help would be greatly appreciated. Thanks.
With nodejs you can easily write files using the fs module
const fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
in your case you can simply do something like
const fs = require('fs');
// I'm converting your array in a string on which every value is
// separated by a new line character
const output = arrLatLon.join("\n");
// write the output at /tmp/test
fs.writeFile("/tmp/test", output, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
Let me forward you to this question for more information Writing files in Node.js

Zapier Code (JS) + Twitter API - POST statuses/update (in_reply_to_status_id)

What I'm trying to achieve is a Zapier Code (JS) action to preform a Twitter reply to a given status ID with a given text .
I'm already using the functioning Zapier (JS) Code action offered by #KayCee which preform a POST favorites/create and would like to modify it so it would preform a reply action to any given status_id using the POST statuses/update (in_reply_to_status_id) as instructed by Twitter API.
Here is #KayCee's code with the modifications I made to preform a reply:
// This code requires that you set the ID of the tweet that you want to reply to as an input variable called "reply_to_id" and the text you wish to reply as an input variable called "status_text". Learn more at https://zapier.com/help/code/#data-variables
// INSTUCTIONS FOR SETTING THESE REQUIRED VARIABLES: After you create a new app at https://apps.twitter.com/, click on the name of the app to open it. Then, select the "Keys and Access Tokens" tab.
var twitterApplicationConsumerKey = 'CONSUMERKEY';
var twitterApplicationConsumerSecret = 'CONSUMERSECRET';
var twitterApplicationAccessToken = 'ACCESSTOKEN';
var twitterApplicationAccessTokenSecret = 'ACCESSTOKENSECRET';
// That's it. No need to edit anything below.
function b64_hmac_sha1(k,d,_p,_z){
if(!_p){_p='=';}if(!_z){_z=8;}function _f(t,b,c,d){if(t<20){return(b&c)|((~b)&d);}if(t<40){return b^c^d;}if(t<60){return(b&c)|(b&d)|(c&d);}return b^c^d;}function _k(t){return(t<20)?1518500249:(t<40)?1859775393:(t<60)?-1894007588:-899497514;}function _s(x,y){var l=(x&0xFFFF)+(y&0xFFFF),m=(x>>16)+(y>>16)+(l>>16);return(m<<16)|(l&0xFFFF);}function _r(n,c){return(n<<c)|(n>>>(32-c));}function _c(x,l){x[l>>5]|=0x80<<(24-l%32);x[((l+64>>9)<<4)+15]=l;var w=[80],a=1732584193,b=-271733879,c=-1732584194,d=271733878,e=-1009589776;for(var i=0;i<x.length;i+=16){var o=a,p=b,q=c,r=d,s=e;for(var j=0;j<80;j++){if(j<16){w[j]=x[i+j];}else{w[j]=_r(w[j-3]^w[j-8]^w[j-14]^w[j-16],1);}var t=_s(_s(_r(a,5),_f(j,b,c,d)),_s(_s(e,w[j]),_k(j)));e=d;d=c;c=_r(b,30);b=a;a=t;}a=_s(a,o);b=_s(b,p);c=_s(c,q);d=_s(d,r);e=_s(e,s);}return[a,b,c,d,e];}function _b(s){var b=[],m=(1<<_z)-1;for(var i=0;i<s.length*_z;i+=_z){b[i>>5]|=(s.charCodeAt(i/8)&m)<<(32-_z-i%32);}return b;}function _h(k,d){var b=_b(k);if(b.length>16){b=_c(b,k.length*_z);}var p=[16],o=[16];for(var i=0;i<16;i++){p[i]=b[i]^0x36363636;o[i]=b[i]^0x5C5C5C5C;}var h=_c(p.concat(_b(d)),512+d.length*_z);return _c(o.concat(h),512+160);}function _n(b){var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s='';for(var i=0;i<b.length*4;i+=3){var r=(((b[i>>2]>>8*(3-i%4))&0xFF)<<16)|(((b[i+1>>2]>>8*(3-(i+1)%4))&0xFF)<<8)|((b[i+2>>2]>>8*(3-(i+2)%4))&0xFF);for(var j=0;j<4;j++){if(i*8+j*6>b.length*32){s+=_p;}else{s+=t.charAt((r>>6*(3-j))&0x3F);}}}return s;}function _x(k,d){return _n(_h(k,d));}return _x(k,d);
}
var replyToId = input.reply_to_id;
var status = input.status_text;
//create nonce
function generateRandomString(desiredLengthOfRandomString) {
var result = '';
var possibleCharactersForRandomString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < desiredLengthOfRandomString; i++ )
result += possibleCharactersForRandomString.charAt(Math.floor(Math.random() * possibleCharactersForRandomString.length));
return result;
}
var randomString = generateRandomString(32);
var nonce = new Buffer(randomString).toString('base64');
//create timestamp
var timestamp = Math.floor(new Date() / 1000);
//create the signature
var signatureParameterString = 'in_reply_to_status_id=' + replyToId + '&status=' + status + '&oauth_consumer_key=' + twitterApplicationConsumerKey + '&oauth_nonce=' + encodeURIComponent(nonce) + '&oauth_signature_method=HMAC-SHA1&oauth_timestamp=' + timestamp + '&oauth_token=' + twitterApplicationAccessToken + '&oauth_version=1.0';
var signatureBaseString = 'POST&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fupdate.json&' + encodeURIComponent(signatureParameterString);
var signingKey = encodeURIComponent(twitterApplicationConsumerSecret) + '&' + encodeURIComponent(twitterApplicationAccessTokenSecret);
var signature = b64_hmac_sha1(signingKey, signatureBaseString);
var apiUrl = 'https://api.twitter.com/1.1/statuses/update.json?in_reply_to_status_id=' + replyToId + '&status=' + status;
var oauthString = 'OAuth oauth_consumer_key="' + twitterApplicationConsumerKey + '", oauth_nonce="' + encodeURIComponent(nonce) + '", oauth_signature="' + encodeURIComponent(signature) + '", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' + timestamp + '", oauth_token="' + twitterApplicationAccessToken + '", oauth_version="1.0"';
fetch(apiUrl, {
method: 'POST',
headers: {
'Authorization': oauthString
}
})
.then(function(res) {
return res.json();
})
.then(function(body) {
var output = body;
callback(null, output);
})
.catch(callback);
For some reason, I keep on getting error message: "Could not authenticate you" although the same code worked for performing a "like".
Not sure what am I doing wrong?

AWS IoT: Subscribe to Topic in Browser

I'm currently developing a Serverless App with AWS.
I want to subscribe to a topic using plain JavaScript (No Node.js, React, Angular etc.)
The IoT and IoTData SDK's doesn't support a "subscribe to topic" function.
To achieve this, i need to implement the aws-iot-device sdk, via require('aws-iot-device') (which i can't use in plain JS).
Unfortunatly this SDK only works with runtimes like Node.js or Browserify.
So how can someone subscribe to a topic from browser? Is there a way to implement the SDK into plain JS?
Thanks in advance
This is how its done, works perfectly fine:
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core-min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/hmac-min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/sha256-min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
cp this libaries into your html.
function SigV4Utils(){}
SigV4Utils.sign = function(key, msg) {
var hash = CryptoJS.HmacSHA256(msg, key);
return hash.toString(CryptoJS.enc.Hex);
};
SigV4Utils.sha256 = function(msg) {
var hash = CryptoJS.SHA256(msg);
return hash.toString(CryptoJS.enc.Hex);
};
SigV4Utils.getSignatureKey = function(key, dateStamp, regionName, serviceName) {
var kDate = CryptoJS.HmacSHA256(dateStamp, 'AWS4' + key);
var kRegion = CryptoJS.HmacSHA256(regionName, kDate);
var kService = CryptoJS.HmacSHA256(serviceName, kRegion);
var kSigning = CryptoJS.HmacSHA256('aws4_request', kService);
return kSigning;
};
function createEndpoint(regionName, awsIotEndpoint, accessKey, secretKey) {
var time = moment.utc();
var dateStamp = time.format('YYYYMMDD');
var amzdate = dateStamp + 'T' + time.format('HHmmss') + 'Z';
var service = 'iotdevicegateway';
var region = regionName;
var secretKey = secretKey;
var accessKey = accessKey;
var algorithm = 'AWS4-HMAC-SHA256';
var method = 'GET';
var canonicalUri = '/mqtt';
var host = awsIotEndpoint;
var credentialScope = dateStamp + '/' + region + '/' + service + '/' + 'aws4_request';
var canonicalQuerystring = 'X-Amz-Algorithm=AWS4-HMAC-SHA256';
canonicalQuerystring += '&X-Amz-Credential=' + encodeURIComponent(accessKey + '/' + credentialScope);
canonicalQuerystring += '&X-Amz-Date=' + amzdate;
canonicalQuerystring += '&X-Amz-SignedHeaders=host';
var canonicalHeaders = 'host:' + host + '\n';
var payloadHash = SigV4Utils.sha256('');
var canonicalRequest = method + '\n' + canonicalUri + '\n' + canonicalQuerystring + '\n' + canonicalHeaders + '\nhost\n' + payloadHash;
var stringToSign = algorithm + '\n' + amzdate + '\n' + credentialScope + '\n' + SigV4Utils.sha256(canonicalRequest);
var signingKey = SigV4Utils.getSignatureKey(secretKey, dateStamp, region, service);
var signature = SigV4Utils.sign(signingKey, stringToSign);
canonicalQuerystring += '&X-Amz-Signature=' + signature;
canonicalQuerystring += '&X-Amz-Security-Token=' + encodeURIComponent(AWS.config.credentials.sessionToken);
return 'wss://' + host + canonicalUri + '?' + canonicalQuerystring;
}
var endpoint = createEndpoint(
'eu-central-1', // YOUR REGION
'xxxxxx.iot.eu-central-1.amazonaws.com', // YOUR IoT ENDPOINT
accesskey, // YOUR ACCESS KEY
secretkey); // YOUR SECRET ACCESS KEY
var clientId = Math.random().toString(36).substring(7);
var client = new Paho.MQTT.Client(endpoint, clientId);
var connectOptions = {
useSSL: true,
timeout: 3,
mqttVersion: 4,
onSuccess: subscribe
};
client.connect(connectOptions);
client.onMessageArrived = onMessage;
client.onConnectionLost = function(e) {
console.log(e)
};
function subscribe() {
client.subscribe("my/things/something");
console.log("subscribed");
}
function onMessage(message) {
var status = JSON.parse(message.payloadString);
}
With this code, you can subscribe to IoT Topics in plain client side JavaScript. No Node.js, React.js or similar is needed!
You can use paho js or mqttjs in the browser. The aws-iot-device sdk for javascript is a wrapper around mqttjs.

Send massage based on some interval in Node JS Websocket

I'm new to Node JS. I wrote NodeJs code it is working fine. But is sending when send a message from a client but I want to send message repeated manner.
Send response when client send any message:
var webSocketServer = require('ws').Server;
var http = require('http');
var fs = require('fs');
var webSocketServerObject = new webSocketServer({ port: 9060 });
webSocketServerObject.on('connection', function (socketObject) {
socketObject.on('message', function (message) {
console.log('The' + message + 'Message Received from \n from IP ' + socketObject.upgradeReq.connection.remoteAddress);
socketObject.send("Received " + message);
});
socketObject.on('close', function (c, d) {
console.log('Disconnect ' + c + ' -- ' + d);
});
});
Above code is working fine(reference ) same code I modified based on interval but it not working.
Below modification:
webSocketServerObject.on('connection', function (socketObject) {
setInterval(function(){
socketObject.send("Hello...");
}, 10000);
socketObject.on('close', function (c, d) {
console.log('Disconnect ' + c + ' -- ' + d);
});
});
How I can make it in sever to keep sending messages.

Socket.IO transmitting a array per emit(...)

I am trying to build a array in my socket io server and sending it to the client.
var roomList = io.sockets.manager.rooms;
// new Array to save the clients per room
var clientsPerRoom = new Array();
//for (var i = 0; i < roomList.length; i++) {
for (var room in roomList) {
room = room.replace("/", "");
// get the clients per room
var clients = io.sockets.clients(room).length;
// saving it in the array at the name of the room
clientsPerRoom[room] = clients;
}
// transmit it to the client
io.sockets.emit('roomList', roomList, clientsPerRoom);
On the client side
var clients = 1;
for (room in roomList) {
if (room.length > 0) {
room = room.replace("/", "");
clients = clientsPerRoom[room];
console.log("ROOM: '" + room + "' has '" + clients + "' CLIENTS");
}
}
At the client, "clientsPerRoom" is "[]" (empty?), and so "clients" is "undeined".
What am I doing wrong?
At the console log from the server are the values 1 if a user is connectet. If more users are online then its still 1 but at least it should send this value to the client.
Thanks
Finaly I solved it:
var clients = io.sockets.clients(room).length;
// has to look like this:
//clientsPerRoom = {"test" : 3, "xyz" : 4};
clientString = '"' + room + '" : "' + clients + '",' + clientString;
console.log("clientsPerRoom[" + room + "] : " + clientsPerRoom[room]);
console.log("__END OF LOOP__");
}
}
//cut the "," et the end of the string (else: ERROR!)
clientString = clientString.substr(0, clientString.length-1);
// parse it with JSON to pretend beeing a object
clientsPerRoom = JSON.parse('{' + clientString + '}');
// now send it to the client
io.sockets.emit('roomList', roomList, clientsPerRoom, totalClients);
Now another problem is, that
var clients = io.sockets.clients(room).length;
is always 1...
Even solved yet.
Problem was: io.sockets.clients(room) only counts users who accepted webcam access, otherwise the are not "really" in the room yet.
Greetings

Categories

Resources