RecordRTC upload video to node js server - node.js

I am using RecordRTC from recording webrtc meeting. After implementing recording, when I test this application if both client are on the same system then its working fine. When I test this application on different system it isn't working fine and meeting is not recorded.
Here this is my code from stop recording client side.
recordRTC.stopRecording(function (videoURL) {
console.log('recordRTC.stopRecording Function inside');
SelectedFile = recordRTC.getBlob();
$('#uploadForm').append('#attachmentFileId', recordRTC.getBlob());
StartUpload();
});
var FReader;
var Name = "Meeting" + "_" + Date.now() + ".webm";
function StartUpload()
{
FReader = new FileReader();
FReader.onload = function (evnt)
{
socket.emit('Upload', { 'Name': Name, Data: evnt.target.result });
}
socket.emit('Start', { 'Name': Name, 'Size': SelectedFile.size });
}
socket.on('MoreData', function (data)
{
var Place = data['Place'] * 524288; //The Next Blocks Starting Position
var NewFile; //The Variable that will hold the new Block of Data
if (SelectedFile.webkitSlice)
NewFile = SelectedFile.webkitSlice(Place, Place + Math.min(524288, (SelectedFile.size - Place)));
else
NewFile = SelectedFile.slice(Place, Place + Math.min(524288, (SelectedFile.size - Place)));
FReader.readAsBinaryString(NewFile);
});
Server Side Code
I get this from here.
socket.on('Start', function (data) { //data contains the variables that we passed through in the html file
var Name = data['Name'];
Files[Name] = { //Create a new Entry in The Files Variable
FileSize : data['Size'],
Data : "",
Downloaded : 0
}
var Place = 0;
try{
var Stat = fs.statSync('Temp/' + Name);
if(Stat.isFile())
{
Files[Name]['Downloaded'] = Stat.size;
Place = Stat.size / 524288;
}
}
catch(er){} //It's a New File
fs.open("Temp/" + Name, 'a', 0755, function(err, fd){
if(err)
{
console.log(err);
}
else
{
Files[Name]['Handler'] = fd; //We store the file handler so we can write to it later
socket.emit('MoreData', { 'Place' : Place, Percent : 0 });
}
});
});
socket.on('Upload', function (data){
var Name = data['Name'];
Files[Name]['Downloaded'] += data['Data'].length;
Files[Name]['Data'] += data['Data'];
if(Files[Name]['Downloaded'] == Files[Name]['FileSize']) //If File is Fully Uploaded
{
fs.write(Files[Name]['Handler'], Files[Name]['Data'], null, 'Binary', function(err, Writen){
var input = fs.createReadStream("Temp/" + Name);
var output = fs.createWriteStream("Video/" + Name);
//util.pump(readableStream, writableStream, [callback])
//Deprecated: Use readableStream.pipe(writableStream)
input.pipe(output);
input.on("end", function() {
console.log("end");
fs.unlink("Temp/" + Name, function ()
{ //This Deletes The Temporary File
console.log("unlink this file:",Name );
//socket.emit('Done', {'Image' : 'Video/' + Name + '.jpg'});
});
});
});
}
else if(Files[Name]['Data'].length > 10485760){ //If the Data Buffer reaches 10MB
fs.write(Files[Name]['Handler'], Files[Name]['Data'], null, 'Binary', function(err, Writen){
Files[Name]['Data'] = ""; //Reset The Buffer
var Place = Files[Name]['Downloaded'] / 524288;
var Percent = (Files[Name]['Downloaded'] / Files[Name]['FileSize']) * 100;
socket.emit('MoreData', { 'Place' : Place, 'Percent' : Percent});
});
}
else
{
var Place = Files[Name]['Downloaded'] / 524288;
var Percent = (Files[Name]['Downloaded'] / Files[Name]['FileSize']) * 100;
socket.emit('MoreData', { 'Place' : Place, 'Percent' : Percent});
}
});
If both clients are on same machine/system its working fine, but if both clients are on different system then meeting is not recorded.

Related

How to zip a single file with Archiver

I am trying to zip a single file using the Archiver npm package located: https://www.npmjs.com/package/archiver
I have been able to use the following to zip a directory:
archive.directory(folderName, false);
But when I try to use either of these nothing seems to happen (ie: no zip is generated, file never finishes zipping):
archive.file(folderName, { name: 'file4.txt' });
archive.file(fs.createReadStream(path.resolve(file)), {name: 'File' + singleFileCheck});
Has anyone run into this issue before? Please let me know what I am doing wrong. Thank you in advance!
edit:
module.exports = async function zipper(user, pass, orgid, s4url, apiToken, newOrgName, file) {
const s4 = require('../testcli/s4');
const fs = require('fs');
const archiver = require('archiver');
const path = require('path');
var parentDirect;
if(file == "./"){
parentDirect = "..";
}else{
parentDirect = path.basename(path.dirname(file));
}
const newZipFile = parentDirect + '/s4.zip';
var folderName = file;
//Checks for existence of infinite loop
if(path.resolve(parentDirect).length > path.resolve(folderName).length){
console.log(folderName.search(parentDirect));
console.error('\x1b[36m%s\x1b[0m', 'ERROR!!!! : Please adjust where your console is pointed, this will result in an infinite loop. Exiting.');
return;
}
var P = ['\\', '|', '/', '-'];
var x = 0;
var output = fs.createWriteStream(newZipFile);
var archive = archiver('zip');
scansdisplayinterval = setInterval(function () {
twrl();
}, 250);
// listen for all archive data to be written
output.on('close', function () {
console.log('\x1b[36m%s\x1b[0m', archive.pointer() + ' total bytes');
console.log('\x1b[36m%s\x1b[0m', 'archiver has been finalized and the output file descriptor has closed.');
try {
process.stdout.write(newZipFile);
clearInterval(scansdisplayinterval);
s4(user, pass, newZipFile, orgid, s4url, apiToken, newOrgName);
} catch (e) {
console.log(e);
}
});
// good practice to catch this error explicitly
archive.on('error', function (err) {
throw err;
});
// good practice to catch warnings (ie stat failures and other non-blocking errors)
archive.on('warning', function(err) {
throw err;
});
// This event is fired when the data source is drained no matter what was the data source.
output.on('end', function() {
console.log('\x1b[36m%s\x1b[0m', 'Data has been drained');
});
// pipe archive data to the file
archive.pipe(output);
//Checks -f for file extension
let singleFileCheck = path.extname(file);
//If file has extension
if(singleFileCheck.length <= 4 && singleFileCheck != ''){
//Append single file
console.log('singleFile', path.resolve(file));
archive.file(path.resolve(file), { name: 'file4.txt' });
// archive.append(fs.createReadStream(path.resolve(file)), {name: 'File' + singleFileCheck});
//Else = folder
}else{
// append files from a sub-directory, putting its contents at the root of archive
archive.directory(folderName, false);
}
// archive.directory(folderName, false);
console.log('\x1b[36m%s\x1b[0m', "Zipping: " + folderName + " To: " + newZipFile);
console.log('\x1b[36m%s\x1b[0m', "Zipping To: " + path.resolve(newZipFile));
archive.finalize();
function twrl() {
process.stdout.write('\rZipping Folder ... ' + P[x++]);
x &= 3;
}
return(newZipFile);
};
The issue came from how I was defining the parentDirect var.
Solution:
let singleFileCheck = path.extname(file);
if(file == "./" || singleFileCheck.length <= 4 && singleFileCheck != ''){
parentDirect = "..";
}else{
parentDirect = path.basename(path.dirname(file));
}

mongoose .create statement not saving inside async.each loop

Following on from my question last week, I got the async loop working, but I have run into a new issue. It appears the documents being created by the loop are not being saved to the db. They are however being pushed into the parent record (plan incode below), and that is saving the push successfully. I've included the full route code below:
// Auto-populate entries
router.post( "/populate", middlewareObj.isLoggedIn, function(req, res){
var orgList=[]
console.log( req.body.orgs);
if (typeof req.body.orgs == 'string') {
orgList = [req.body.orgs]
} else {
orgList = req.body.orgs
};
orgList.save
console.log( orgList)
//lookup Plan using ID
Plan.findById( req.params.id, function(err, foundPlan){
if(err){
console.log( err);
res.redirect("/plans");
} else {
BaseData.find({
"contributingRegion": foundPlan.contributingRegion,
"org": { $in: orgList}
}, function( err, baseData) {
if (err) {
console.log( err)
} else {
console.log( baseData.length);
//Create entries & push into plan
async.each( baseData, function(data, next) {
Entry.create(data, function(err, entry) { /*Create entry*/
if(err) {
next (err);
} else {
// Create other entry variables
entry.author.id = req.user._id;
entry.author.username = req.user.username;
entry.save();
entry.adjHC = entry.initHC;
entry.adjResRate = entry.initResRate;
entry.yr1Resignations = Math.round(entry.adjHC * entry.adjResRate);
entry.yr1Supply = entry.adjHC - entry.yr1Resignations;
entry.yr2Resignations = Math.round(entry.yr1Supply * entry.adjResRate);
entry.yr2Supply = entry.yr1Supply - entry.yr2Resignations;
entry.yr3Resignations = Math.round(entry.yr2Supply * entry.adjResRate);
entry.yr3Supply = entry.yr2Supply - entry.yr3Resignations;
entry.yr4Resignations = Math.round(entry.yr3Supply * entry.adjResRate);
entry.yr4Supply = entry.yr3Supply - entry.yr4Resignations;
entry.yr5Resignations = Math.round(entry.yr4Supply * entry.adjResRate);
entry.yr5Supply = entry.yr4Supply- entry.yr5Resignations;
entry.demandYr0 = entry.adjHC;
entry.demandYr1 = entry.adjHC;
entry.demandYr2 = entry.adjHC;
entry.demandYr3 = entry.adjHC;
entry.demandYr4 = entry.adjHC;
entry.demandYr5 = entry.adjHC;
entry.gapYr1 = entry.yr1Supply - entry.demandYr1;
entry.gapYr2 = entry.yr2Supply - entry.demandYr2;
entry.gapYr3 = entry.yr3Supply - entry.demandYr3;
entry.gapYr4 = entry.yr4Supply - entry.demandYr4;
entry.gapYr5 = entry.yr5Supply - entry.demandYr5;
entry.save();
console.log(entry._id + ' saved')
foundPlan.planEntries.push(entry);
foundPlan.save();
// next iteration
next();
}
}); /*entry Create*/
}, function(err) {
// This function runs when all iterations are done
if (err) throw err;
res.redirect('/plans/' + foundPlan._id);
} ); /*End of Async Loop*/
};
}); /*End of BaseDate.find*/
}
}); /*End of Plan.findById*/
});
From the various console.logs in the code, that I've been using to troubleshoot, I know the code is finding the right number of entries in baseData (42 records).
I should add the same Entry.create code is used in a separate route where Entries are added manually one-by-one by the user.
When I look at the mongodb itself to look at the size of the planEntries array in the plan I get:
// 1) Manually added entry
{ "_id" : ObjectId("5a6f00421046d90019e2c6e8"), "name" : "test", "numEntries" : 1 }
// 2) After First populate route
{ "_id" : ObjectId("5a6f00421046d90019e2c6e8"), "name" : "test", "numEntries" : 46 }
// 3) After a second populate route (same selections)
{ "_id" : ObjectId("5a6f00421046d90019e2c6e8"), "name" : "test", "numEntries" : 239 }
The manually added entry saves correctly, but the others don't seem to be saving the document.
What is also unexpected, is after each auto-populate, I would expect numEmtries to increase by 42, but it seems to be growing by much greater numbers
So managed to work it out. There were 2 things going on.
Firstly, Entry.create creates the object but doesn't allow it to save to the DB for some reason. If i swap my code to be var entry = new ENTRY(), then it saved them to the database.
Once I got this working, I ran into an issue of each entry being passed into the plan multiple times (the same number of times as there were entries to add so i ended up with 42 * 42 entries). This was resolved by clearing out the entry object before the next() function is called. I also switched to async.eachSeries. I will test is async.each later and see if that works.
UPDATE: async.each reverts back to the duplication of results, it appears async.eachSeries is needed to prevent this duplication.
Complete final code for completeness:
// Auto-populate entries
router.post( "/populate", middlewareObj.isLoggedIn, function( req, res) {
// Ensure req.body.orgs is an array
var orgList=[]
if (typeof req.body.orgs == 'string') {
orgList = [req.body.orgs]
} else {
orgList = req.body.orgs
};
orgList.save
//lookup Plan using ID
Plan.findById( req.params.id, function(err, foundPlan){
if(err){
console.log( err);
res.redirect("/plans");
} else {
BaseData.find({
"contributingRegion": foundPlan.contributingRegion,
"org": { $in: orgList}
}, function( err, baseData) {
if (err) {
console.log( err)
} else {
// console.log( baseData.length);
//Loop through baseData to create entries & push into plan
async.eachSeries( baseData, function(data, next) {
console.log(data);
// Create new entry record
var entry = new Entry({
author: {
id: req.user._id,
username: req.user.username
},
org: data.org,
jobFamily: data.jobFamily,
globalGrade: data.globalGrade,
location: data.location,
initHC: data.initHC,
initResRate: data.initResRate.toFixed(3)
});
// Derive calculated variables for entry
entry.adjHC = entry.initHC;
entry.adjResRate = entry.initResRate;
entry.yr1Resignations = Math.round(entry.adjHC * entry.adjResRate);
entry.yr1Supply = entry.adjHC - entry.yr1Resignations;
entry.yr2Resignations = Math.round(entry.yr1Supply * entry.adjResRate);
entry.yr2Supply = entry.yr1Supply - entry.yr2Resignations;
entry.yr3Resignations = Math.round(entry.yr2Supply * entry.adjResRate);
entry.yr3Supply = entry.yr2Supply - entry.yr3Resignations;
entry.yr4Resignations = Math.round(entry.yr3Supply * entry.adjResRate);
entry.yr4Supply = entry.yr3Supply - entry.yr4Resignations;
entry.yr5Resignations = Math.round(entry.yr4Supply * entry.adjResRate);
entry.yr5Supply = entry.yr4Supply- entry.yr5Resignations;
entry.demandYr0 = entry.adjHC;
entry.demandYr1 = entry.adjHC;
entry.demandYr2 = entry.adjHC;
entry.demandYr3 = entry.adjHC;
entry.demandYr4 = entry.adjHC;
entry.demandYr5 = entry.adjHC;
entry.gapYr1 = entry.yr1Supply - entry.demandYr1;
entry.gapYr2 = entry.yr2Supply - entry.demandYr2;
entry.gapYr3 = entry.yr3Supply - entry.demandYr3;
entry.gapYr4 = entry.yr4Supply - entry.demandYr4;
entry.gapYr5 = entry.yr5Supply - entry.demandYr5;
entry.save();
// Push entry into plan
foundPlan.planEntries.push(entry);
foundPlan.save(function(err){
if (err) {
console.log(err)
} else{
entry = {}
// next iteration
next()
};
});
}, function(err) {
// This function runs when all iterations are done
if (err) throw err;
res.redirect('/plans/' + foundPlan._id);
} ); /*End of Async Loop*/
};
}); /*End of BaseDate.find*/
}
}); /*End of Plan.findById*/
});
// =====================================================
// ======UPDATE ENTRIES FROM SUPPLY/DEMAND SCREENS======
// =====================================================
// Entry Update (from Supply Screen)
router.put("/:entryId", middlewareObj.isLoggedIn, function(req, res){
// console.log(req.body)
var adjHC = req.body.entry.adjHC;
var adjResRate = req.body.entry.adjResRate / 100;
var yr1Resignations = Math.round(adjHC * adjResRate);
var yr1Supply = adjHC - yr1Resignations;
var yr2Resignations = Math.round(yr1Supply * adjResRate);
var yr2Supply = yr1Supply - yr2Resignations;
var yr3Resignations = Math.round(yr2Supply * adjResRate);
var yr3Supply = yr2Supply - yr3Resignations;
var yr4Resignations = Math.round(yr3Supply * adjResRate);
var yr4Supply = yr3Supply - yr4Resignations;
var yr5Resignations = Math.round(yr4Supply * adjResRate);
var yr5Supply = yr4Supply- yr5Resignations;
var demandYr0 = adjHC;
var demandYr1 = adjHC;
var demandYr2 = adjHC;
var demandYr3 = adjHC;
var demandYr4 = adjHC;
var demandYr5 = adjHC;
var gapYr1 = yr1Supply - demandYr1;
var gapYr2 = yr2Supply - demandYr2;
var gapYr3 = yr3Supply - demandYr3;
var gapYr4 = yr4Supply - demandYr4;
var gapYr5 = yr5Supply - demandYr5;
var updatedEntry = {adjHC : adjHC,
adjResRate : adjResRate,
yr1Resignations : yr1Resignations,
yr2Resignations : yr2Resignations,
yr3Resignations : yr3Resignations,
yr4Resignations : yr4Resignations,
yr5Resignations : yr5Resignations,
yr1Supply : yr1Supply,
yr2Supply : yr2Supply,
yr3Supply : yr3Supply,
yr4Supply : yr4Supply,
yr5Supply : yr5Supply,
demandYr0 : demandYr0,
demandYr1 : demandYr1,
demandYr2 : demandYr2,
demandYr3 : demandYr3,
demandYr4 : demandYr4,
demandYr5 : demandYr5,
gapYr1 : gapYr1,
gapYr2 : gapYr2,
gapYr3 : gapYr3,
gapYr4 : gapYr4,
gapYr5 : gapYr5 };
//lookup Entry using ID
Entry.findByIdAndUpdate(req.params.entryId, updatedEntry, {new: true}, function(err, foundEntry){
if(err){
console.log(err);
res.redirect("/plans");
} else {
res.json(foundEntry);
}
});
});

WebRTC: Sound not muting - can anyone see an error?

I have inserted a mute button into my WebRTC Video chat page but I cannot get it to work. If I click it in the browser I get a console message that the sound has been muted but there is still sound.
The Constraints variables:
var constraints = {
video: true,
audio: true,
};
If I change audio to false here there will be no sound.
Code on Mute Button:
function muteVideoBtnClick() {
if(constraints.audio == true) {
constraints.audio = false;
console.log('Audio: ' + constraints.audio);
} else {
constraints.audio = true;
console.log('Audio: ' + constraints.audio);
}
}
The Only other place where the constraints variables are used:
function pageReady() {
uuid = uuid(); //CB Universal Unique Identifier
//CB Create the variables for local and remote video
localVideo = document.getElementById('localVideo');
remoteVideo = document.getElementById('remoteVideo');
//CB Create the connection using websocket (443 as it is a secure connection)
serverConnection = new WebSocket('wss://' + window.location.hostname + ':443');
serverConnection.onmessage = gotMessageFromServer;
// CB Checks thats getUserMedia works and then runs getUserMedia if it works and displays an error
//if it doesnt work
if(navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(constraints).then(getUserMediaSuccess).catch(errorHandler);
} else {
alert('Your browser does not support getUserMedia API');
}
}
I would be very grateful if anyone has any suggestions.
Kind regards,
Claire
The Full code:
var localVideo;
var remoteVideo;
var peerConnection;
var uuid;
var rooms = [];//CB 31/07
var constraints = {
video: true,
audio: true,
};
var peerConnectionConfig = {
'iceServers': [
{'urls': 'stun:stun.services.mozilla.com'},
{'urls': 'stun:stun.l.google.com:19302'},
]
};
function pageReady() {
uuid = uuid(); //CB Universal Unique Identifier
//CB Create the variables for local and remote video
localVideo = document.getElementById('localVideo');
remoteVideo = document.getElementById('remoteVideo');
//CB Create the connection using websocket (443 as it is a secure connection)
serverConnection = new WebSocket('wss://' + window.location.hostname + ':443');
serverConnection.onmessage = gotMessageFromServer;
// CB Checks thats getUserMedia works and then runs getUserMedia if it works and displays an error
//if it doesnt work
if(navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(constraints).then(getUserMediaSuccess).catch(errorHandler);
} else {
alert('Your browser does not support getUserMedia API');
}
}
//CB if it is possible to run gerUserMedia then gets the local video stream
function getUserMediaSuccess(stream) {
localStream = stream;
localVideo.src = window.URL.createObjectURL(stream); //Depreciated!!!!!
//localVideo.srcObject = stream;
}
//CB this function starts the call
function start(isCaller) {
peerConnection = new RTCPeerConnection(peerConnectionConfig);
peerConnection.onicecandidate = gotIceCandidate;
peerConnection.onaddstream = gotRemoteStream;
//peerConnection.ontrack = gotRemoteStream;
peerConnection.addStream(localStream);
if(isCaller) {
peerConnection.createOffer().then(createdDescription).catch(errorHandler);
}
}
//Added by CB for Pause Button 20/07
function pauseVideoBtnClick() {
var btn = document.getElementById("pause_video_btn");
if (isVideoPaused()) {
pauseVideo(false);
btn.innerHTML = "Pause Video";
} else {
pauseVideo(true);
btn.innerHTML = "Resume Video";
}
}
//Added by CB for Pause Button 20/07
function isVideoPaused() {
return !(localStream.getVideoTracks()[0].enabled);
}
//Added by CB for Pause Button 20/07
function pauseVideo (pause) {
localStream.getVideoTracks()[0].enabled = !pause;
};
//Added by CB for mute button 29/07 - DOESNT WORK YET
function muteVideoBtnClick() {
if(constraints.audio == true) {
constraints.audio = false;
console.log('Audio: ' + constraints.audio);
} else {
constraints.audio = true;
console.log('Audio: ' + constraints.audio);
}
}
//End of added code
function gotMessageFromServer(message) {
if(!peerConnection) start(false);
var signal = JSON.parse(message.data);
// Ignore messages from ourself
if(signal.uuid == uuid) return;
if(signal.sdp) {
peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp)).then(function() {
// Only create answers in response to offers
if(signal.sdp.type == 'offer') {
peerConnection.createAnswer().then(createdDescription).catch(errorHandler);
}
}).catch(errorHandler);
} else if(signal.ice) {
peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice)).catch(errorHandler);
}
}
function gotIceCandidate(event) {
if(event.candidate != null) {
serverConnection.send(JSON.stringify({'ice': event.candidate, 'uuid': uuid}));
}
}
function createdDescription(description) {
console.log('got description');
peerConnection.setLocalDescription(description).then(function() {
serverConnection.send(JSON.stringify({'sdp': peerConnection.localDescription, 'uuid': uuid}));
}).catch(errorHandler);
}
function gotRemoteStream(event) {
console.log('got remote stream');
remoteVideo.src = window.URL.createObjectURL(event.stream);
//remoteVideo.src = event.stream;
}
function errorHandler(error) {
console.log(error);
}
// CB A UUID (Universal Unique Identifier) is a 128-bit number used to uniquely identify some object or entity on the Internet.
// Taken from http://stackoverflow.com/a/105074/515584
// Strictly speaking, it's not a real UUID, but it gets the job done here
function uuid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
You are changing the constraints to the getUserMedia call (after doing the call). You are not changing the resulting stream which is stored in the localStream variable. Try this:
localStream.getAudioTracks()[0].enabled = false;

Nodejs generating duplicate http-requests

Hope some can help with my issue. i'm using below nodejs code from this SAP Tutorial to read Sensor values post them per HTTP. All works pretty fine, but for the fact that every record is posted twice(see Screenshot). i'm not versed with server-side JS and don't know why the duplicates.Agreed, the values not aways the same, but for further processing i'd like to have single datasets per timestamp. Could someone please help me locate the issue and if possible, provide a solution/workaround?
Also the script reads and transmits the data every 10s. Am looking for a way to set the interval to maybe 3mins. I would appreciate every bit of help here as well
/* sensorTag IR Temperature sensor example
* Craig Cmehil, SAP SE (c) 2015
*/
/* Choose the proper HTTP or HTTPS, SAP Cloud Platformrequires HTTPS */
var http = require('https');
var SensorTag = require('sensortag');
var lv_temp;
var lv_humid;
var lv_deviceid = "";
var DEBUG_VALUE = true;
var xtimestamp;
var date = new Date();
var time = date.getTime ();
// SAP Cloud Platform connection details
var portIoT = 443;
var pathIoT = '/com.sap.iotservices.mms/v1/api/http/data/';
var hostIoT = 'iotmmsXXXXXXXXXXtrial.hanatrial.ondemand.com';
var authStrIoT = 'Bearer XXXXXXXXXXXX';
var deviceId = 'XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX';
var messageTypeID = 'XXXXXXXXXXXX';
var options = {
host: hostIoT,
port: portIoT,
path: pathIoT + deviceId,
agent: false,
headers: {
'Authorization': authStrIoT,
'Content-Type': 'application/json;charset=utf-8',
'Accept': '*/*'
},
method: 'POST',
};
/***************************************************************/
/* Coding to access TI SensorTag and values of various sensors */
/***************************************************************/
console.log("If not yet activated, then press the power button.");
SensorTag.discover(function(tag) {
tag.on('disconnect', function() {
console.log('disconnected!');
process.exit(0);
});
function connectExecute() {
console.log('Connect Device and Execute Sensors');
tag.connectAndSetUp(enableSensors);
}
function enableSensors() {
/* Read device specifics */
tag.readDeviceName(function(error, deviceName) {
console.log('Device Name = ' + deviceName);
});
tag.readSystemId(function(error, systemId) {
console.log('System ID = ' + systemId);
lv_deviceid = systemId;
});
tag.readSerialNumber(function(error, serialNumber) {
console.log('Serial Number = ' + serialNumber);
});
tag.readFirmwareRevision(function(error, firmwareRevision) {
console.log('Firmware Rev = ' + firmwareRevision);
});
tag.readHardwareRevision(function(error, hardwareRevision) {
console.log('Hardware Rev = ' + hardwareRevision);
});
tag.readHardwareRevision(function(error, softwareRevision) {
console.log('Software Revision = ' + softwareRevision);
});
tag.readManufacturerName(function(error, manufacturerName) {
console.log('Manufacturer = ' + manufacturerName);
});
/* Enable Sensors */
console.log("Enabling sensors:");
console.log('\tenableIRTemperatureSensor');
tag.enableIrTemperature(notifyMe);
console.log('\tenableHumidity');
tag.enableHumidity(notifyMe);
console.log("*********************************************");
console.log(" To stop press both buttons on the SensorTag ");
console.log("*********************************************");
}
function notifyMe() {
tag.notifySimpleKey(listenForButton);
setImmediate(function loop () {
tag.readIrTemperature(function(error, objectTemperature, ambientTemperature){
lv_obj = objectTemperature.toFixed(1);
lv_ambient = ambientTemperature.toFixed(1);
});
tag.readHumidity(function(error, temperature, humidity) {
lv_temp = temperature.toFixed(1);
lv_humid = humidity.toFixed(1);
});
if(DEBUG_VALUE)
console.log("Sending Data: " + lv_deviceid + " " + lv_temp + " " + lv_humid);
setSensorData(lv_temp, lv_humid);
setTimeout(loop, 10000);
});
}
function listenForButton() {
tag.on('simpleKeyChange', function(left, right) {
if (left && right) {
tag.disconnect();
}
});
}
connectExecute();
});
/******************************************************************/
/* FUNCTION to get Temperature from the Sensor & update into HANA */
/******************************************************************/
function setSensorData(lv_temp,lv_humid){
date = new Date();
time =date.getTime();
var data = {
"mode":"sync",
"messageType": messageTypeID,
"messages": [{
"timestamp": time,
"temperature": lv_temp,
"humidity": lv_humid
}]
};
var strData = JSON.stringify(data);
if(DEBUG_VALUE)
console.log("Data: " + strData);
if(strData.length > 46){
if(DEBUG_VALUE)
console.log("Sending Data to server");
/* Process HTTP or HTTPS request */
options.agent = new http.Agent(options);
var request_callback = function(response) {
var body = '';
response.on('data', function (data) {
body += data;
});
response.on('end', function () {
if(DEBUG_VALUE)
console.log("REQUEST END:", response.statusCode);
});
response.on('error', function(e) {
console.error(e);
});
}
var request = http.request(options, request_callback);
request.on('error', function(e) {
console.error(e);
});
request.write(strData);
request.end();
}else{
if(DEBUG_VALUE)
console.log("Incomplete Data");
}
}
It should only be posting once to the system but twice to the screen.
In the function notifyMe you need to change the line
setTimeout(loop, 10000);
Change the number to the interval you want it to delay before posting again.

Handling byte streams in node.js

For education purposes I am creating a little chat with node.js using TCP.
I am using the windows console to connect with my node server but when I am typing all the characters are streamed one by one. They don't arive as strings. How can I manage to handle those streams so my users don't can write complete words.
My Code:
var net = require("net");
Array.prototype.remove = function(e) {
for (var i = 0; i < this.length; i++) {
if (e == this[i]) { return this.splice(i, 1); }
}
};
function Chatter(stream) {
this.name = null;
this.stream = stream;
}
var chatters = [];
var server = net.createServer(function(stream) {
var chatter = new Chatter(stream);
chatters.push(chatter);
stream.setTimeout(0);
stream.setEncoding("utf8");
stream.addListener("connect", function(){
stream.write("Hallo, wer bist du?:\n");
});
stream.addListener("data", function (data) {
if(chatter.name == null) {
chatter.name = data.match(/\S+/);
stream.write("....................\n");
chatters.forEach(function(c){
if (c != chatter) {
c.stream.write(chatter.name + " ist dem Chat beigetreten!\n");
}
});
return;
}
var command = data.match(/^\/(.*)/);
if (command) {
if (command[1] == 'users') {
chatters.forEach(function(c) {
stream.write("- " + c.name + "\n");
});
}
else if (command[1] == 'quit') {
stream.end();
}
}
chatters.forEach(function(c) {
if(c != chatter) {
c.stream.write(chatter.name + ": " + data);
}
});
});
stream.addListener("end", function(){
chatters.remove(chatter);
chatters.forEach(function(c) {
c.stream.write(chatter.name + " hat den Chat verlassen.\n");
});
stream.end();
});
});
server.listen(8000);
For the record that code is from this site
ADDITION:
setEncoding('utf8') is supposed to change the emiting of data, but it doesn't work for me :-(
The solution to your problem is to store all received characters in a buffer and when an END_OF_NICK character is encountered (say, \n), use the buffer as the name.
var buffer = ""; // stores received characters
stream.addListener("data", function (data) {
if(chatter.name == null) { // still receiving characters for the name
buffer += data; // append received characters to the buffer
if (buffer.indexOf('\n') == -1) return; // if there's no END_OF_NICK character, keep waiting for it
chatter.name = buffer.match(/\S+/); // use the name in the buffer
// ...
}

Resources