Xively and Node-Red - node.js

I'm fairly new at all this but have muddled my way to getting my Arduino to post values to a Xively stream I've named "Lux and Temp." Three values; count, lux, and temperature.
Now what I want to do is take those values and do something with them using Node-Red.
http://nodered.org
I have Node-Red up and running, but I'll be danged if I can figure out how to parse the data from the Xively API feed. https://api.xively.com/v2/feeds/1823833592
Sadly, I don't have enough reputation points to be able to actually post the data it returns to here, since it has more than 3 URLs embedded in the data. It's a LONG string of data too. ;)
I'm just stumped though as to how to write the function to extract the parts I want.
My initial want is to make a simple Twitter feed out of it. Something like;
"Count 40, Lux 30, Temp 78.3"
I'll eventually want to recycle the code for other things like making my RasPi do something; maybe a display or some LEDs. In either case I need to parse the data and build various messages with it.
Anybody have any experience with the Node-Red functions that can walk me through a solution? The Node-Red site is pretty awesome, but I think it assumes I'm a MUCH more experienced user than I really am. It gives hints, but frankly about all I know is fairly basic Arduino and trivial level Python.

OK, it shouldn't be too tricky, but try putting this in a function block:
var newPayload = "";
var count, lux, temp;
var data = msg.payload.datastreams;
for (var i = 0 ; i< data.length; i++) {
if (data[i].id === 'Count') {
count = data[i].current_value;
}else if (data[i].id === 'Lux') {
lux = data[i].current_value;
} else if (data[i].id === 'Temp') {
temp = data[i].current_value;
}
}
newPayload = util.format('Count: %s, Lux: %s, Temp: %s', count, lux, temp);
msg.payload = newPayload;
return msg;
You may need to add a msg.payload = JSON.parse(msg.payload); to the start if however your getting the feed from xively is not already considered to be json.
[edit]
You could also just run the flow through a JSON parse node. (I always forget the converter nodes)
You should be able to wire that to a twitter output node.

Related

web3js subscribe logs to fast for Javascript to handle

I am using web3js to subscribe to logs, I listening to swap events, the problem is that the .on(data) is so fast in giving data JavaScript can not keep up. lets say I add a variable let count = 0; each time I get a new log I increase the number ++count, sometimes the logs come so fast I get a double number.
The real problem is I need it to be in the exact order as it is coming in, that's why I give the number to each log, but that does not work.
How would I make sure that each data item I get from the log events that they are in order?
I tried to create a promise sequence
let sequence = Promise.resolve();
let count = 0;
web3.eth.subscribe('logs', {
fromBlock: block,
topics: [
[swapEvent]
]
}).on('data', (logData)=>{
sequence = sequence.then(()=>{
++count
processData(logData)
})
});
function processData(){
return new Promise(resolve=>{
// do some stuff
resolve();
})
};
In a simple test with a loop and random time to resolve this works fine, but in the actual code with socket it does not keep the order.
Anyone has some idea how I can make the socket data keep in order and process one by one?
Not sure why but my problem got solved with this.
sequence = sequence.then(()=>processData(logData))
before it was
sequence = sequence.then(()=>{
processData(logData)
})
Now its doing all in sequence.

Node.js, For loop

in node.js I am using for loop on server.js but it is not working and cause error
var myEasyrtcApp = function(err, appObj) {
for (i = 0; i < 10; i++) {
appObj.createRoom("room" + i ,null,function(err, roomObj){});
};
}
Please advice how can I use for loop to call appObj.createRoom several time to open different conference room
Sorry, but you almost not give any information... Asuming the last function is a Callback you need to make a Recursive "Loop" something like:
http://pastebin.com/LrKqLgyV
And to use it you can do this:
http://pastebin.com/L1bZZis0
To learn more about this, just google "recursive functions". (I can't post more than 2 links XD)
Hope It works for you ;)

How should I avoid out of memory using nodejs?

var pass = require('./pass.js');
var fs = require('fs');
var path = "password.txt";
var name ="admin";
var
remaining = "",
lineFeed = "\r\n",
lineNr = 0;
var log =
fs.createReadStream(path, { encoding: 'utf-8' })
.on('data', function (chunk) {
// store the actual chunk into the remaining
remaining = remaining.concat(chunk);
// look that we have a linefeed
var lastLineFeed = remaining.lastIndexOf(lineFeed);
// if we don't have any we can continue the reading
if (lastLineFeed === -1) return;
var
current = remaining.substring(0, lastLineFeed),
lines = current.split(lineFeed);
// store from the last linefeed or empty it out
remaining = (lastLineFeed > remaining.length)
? remaining.substring(lastLineFeed + 1, remaining.length)
: "";
for (var i = 0, length = lines.length; i < length; i++) {
// process the actual line
var account={
username:name,
password:lines[i],
};
pass.test(account);
}
})
.on('end', function (close) {
// TODO I'm not sure this is needed, it depends on your data
// process the reamining data if needed
if (remaining.length > 0) {
var account={
username:name,
password:remaining,
};
pass.test(account);
};
});
I tried to do something like test password of account "admin", pass.test is a function to test the password, I download a weak password dictionary with a large number of lines,so I search for way to read that many lines of weak password,but with code above, the lines array became too large ,and run out of memory,what should I do?
Insofar as my limited understanding goes, you need to watch a 1GB limit, which I believe is imposed by the V8 engine, actually. (Here's a link, actually saying the limit is 1.4 GB, currently, and lists the different params used to change this manually.) Depending on where you host your node app(s), you can increase this limit, by a param set on the command line when node is started. Again, see the linked article for a few ways to do this.
Also, you might want to make sure that, whenever possible, you use buffers, instead of converting things like data streams (from a DB or other things, for instance) to arrays/whatever, as this will then load the entire dataset into memory. As long as it lives in a buffer, it doesn't contribute to the total memory footprint of your app.
And actually, one thing that doesn't make sense, and that seems to be very inefficient in your app, is that, on reading each chunk of data in, you then check your username against EVERY username you've amassed so far, in your lines array, instead of the LAST one. What your app should do is keep track of the last username and password combo you've read in, and then delete all data before this user, in your remaining variable, so you keep your memory down. And since it's not a hold all repository for every line of your password file anymore, you should probably retitle it something like buffer or something. This means that you'd remove your for loop, since you're already "looping" through the data in your password file, by reading it in, chunk by chunk.

cannot emit sIo.sockets.clients()

It seems that socket.io cannot send the list of connected users, like this:
socket.emit('users', sIo.sockets.clients());
It gives me the following error:
/Users/enrico/Desktop/helloExpress/node_modules/socket.io/lib/parser.js:75
data = JSON.stringify(ev);
^
TypeError: Converting circular structure to JSON
Apparently it cannot stringify the returned value from sIo.sockets.clients() Any ideas on how to fix this? Thanks in advance.
Since the problem is a circular reference there no real 'fixing it'. Circular reference means that some object in the structure points to another part of the object, making an infinite loop. What you can do is something like this.
var returnList = [];
var clients = sIo.sockets.clients(); // grab list of clients, assuming its an array
for(var i = 0; i < clients.length; i++) {
var client = clients[i]; // next client in array
// push values into return list
returnList.push({
name: client.name,
someOther: client.value,
another: client.thing
});
}
// emit cleaned up list
socket.emit('users', returnList);
With this code you can cherry pick the values you want and send only those. This is good for several other reasons. Since this clients list is likely an internal implementation is might also send information about other clients connection.
This is all also pretty speculative as I'm not 100% what libraries you're using, looks like Socket.IO but I cannot find any socket.clients() method.

spotify models.Track object

is the spotify models.Track object restricted to non-local tracks only?
I've built a little spotify app that will calculate the total play time of some random assortment of tracks that are dropped into the sidebar, but it seems like the Track object doesn't get any information from local files.
Here's what I got so far:
models.application.observe(models.EVENT.LINKSCHANGED, function () {
totalTime = 0;
var links = models.application.links;
if (links.length) {
for (var i = 0; i < links.length; i++) {
var track = models.Track.fromURI(links[i], function(t) {
totalTime = totalTime + t.duration;
});
}
}
document.getElementById("time").innerHTML = secondsToString(Math.round(totalTime/1000)) ;
});
Everything is firing correctly and working great on spotify tracks, but the whole reason i wrote this little app was so that I could calculate the total time of some of my really long audiobook files. Anyone know of a solution?
Link to the documentation page.
If this is indeed the case, I think you've found a bug/oversight.
However, local file URIs look like this: spotify:local:Coldplay:Mylo+Xyloto:Paradise:277
That last parameter is the length of the track, in integral seconds. It's a hacky workaround, but you could parse the URI and use the figure from that instead of models.Track.

Resources