A few useful Node.js scripts

I’ve more or less finished configuring Volumio 2 on a Raspberry Pi 3. I’ve added a generic IR receiver to control it with a remote, by mapping some buttons to specific actions. The “buttons” part is documented in the previous link and other places. The “actions” part needed some programming to get them do exactly what I wanted. I thought I’d share the scripts I have, in case someone finds them useful.

These are Node.js scripts intended to be run from the command line, so we need the “node” command and possibly some other packages/modules. I don’t remember exactly what I needed to install, but I think it was easy to find out when I tried running this kind of scripts. I don’t claim these are the best possible scripts, but they seem to do their job for me.

Toggle play/pause: If the current mode is “play”, it pauses, otherwise it plays.

[code]var io = require(‘socket.io-client’);
var socket = io.connect(‘http://localhost:3000’);
socket.emit(‘getState’, ‘’);
socket.on(‘pushState’, function(data) {
switch (data.status) {
case ‘play’:
socket.emit(‘pause’);
break;
default:
socket.emit(‘play’);
break;
}
socket.removeAllListeners(‘pushState’);
socket.on(‘pushState’, function() { socket.disconnect(); } );
} );

setTimeout(function() { socket.disconnect(); }, 3000);[/code]

Change volume: Takes one argument (i.e., run with "node "). A number sets the volume to that number, “+” and “-” increase or decrease the volume by 5%, “mute” toggles mute on/off.

[code]var io = require(‘socket.io-client’);
var socket = io.connect(‘http://localhost:3000’);
socket.emit(‘getState’, ‘’);
socket.on(‘pushState’, function(data) {
switch (process.argv[2]) {
case ‘+’:
socket.emit(‘volume’, Math.min(data.volume+5, 100));
break;
case ‘-’:
socket.emit(‘volume’, Math.max(data.volume-5, 0));
break;
case ‘mute’:
switch (data.mute) {
case true:
socket.emit(‘unmute’, true);
break;
case false:
socket.emit(‘mute’, true);
break;
}
break;
default:
socket.emit(‘volume’, Math.max(Math.min(Number(process.argv[2]), 100), 0));
}
process.exit();
} );

setTimeout(function() { socket.disconnect(); }, 3000);[/code]

Play custom webradio: Clears the playlist and plays the radio given as the argument

[code]var io = require(‘socket.io-client’);
var socket = io.connect(‘http://localhost:3000’);
socket.emit(‘clearQueue’);
var fs = require(‘fs’);
var content = fs.readFileSync(’/data/favourites/my-web-radio’);
var webradios = JSON.parse(content);
var radio = webradios.find(o => o.name === process.argv[2]);
if (radio == null) {
socket.disconnect();
} else {
socket.emit(‘addPlay’, {‘service’:radio.service,‘title’:radio.name,‘uri’:radio.uri});
socket.on(‘pushState’, function() { socket.disconnect(); } );
}

setTimeout(function() { socket.disconnect(); }, 3000);[/code]

Queue a random album: Clears the playlist and puts a random album from the library. (I use random.org to provide random numbers, use your own apiKey. It could be easily adapted to use a local random number generator.)

[code]var RandomOrg = require(‘random-org’);
var io = require(‘socket.io-client’);
var random = new RandomOrg({‘apiKey’:’#########################’});
var socket = io.connect(‘http://localhost:3000’);
socket.emit(‘browseLibrary’, {‘uri’:‘albums://’});
socket.on(‘pushBrowseLibrary’,function(data) {
var list = data.navigation.lists[0].items;
random.generateIntegers({‘min’:0, ‘max’:list.length-1, ‘n’:1})
.then(function(result) {
select = list[result.random.data[0]];
socket.emit(‘clearQueue’);
socket.emit(‘addToQueue’, {‘uri’:select.uri});
});
}
);
socket.on(‘pushQueue’, function(data) { if (data.length > 0) { socket.disconnect(); } } );

setTimeout(function() { socket.disconnect(); }, 5000);[/code]

Once I have these scripts I can assign them to the remote buttons in .lircrc

On a vanilla volumio installation, you need the npm package socket.io-client. You can easily install that package with:

npm install socket.io-client

Thanks for the scripts.

Hi,

this is exactly what i need. I have a external controller which sends commands using uart (AVR<-> Raspberry). The communication works, i can call the “node volume.js +” out of my bash script which listens to the uart.

But it takes about 2-3 seconds until the volume changes. Even when I call the volume.js directly from terminal it takes the same time.

How can i increase the speed the volume changes? Or is there another way to change it?

Thanks in advance

May 11 16:33:11 volumio-klein sendalive[1562]: VolUp May 11 16:33:13 volumio-klein sudo[1667]: pam_unix(sudo:session): session closed for user root May 11 16:33:13 volumio-klein volumio[944]: info: CoreCommandRouter::volumioGetState May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393836] CoreStateMachine::getState May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393839] CorePlayQueue::getTrack 0 May 11 16:33:13 volumio-klein volumio[944]: info: May 11 16:33:13 volumio-klein volumio[944]: [1494520393842] ---------------------------- Client requests Volumio state May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393848] InterfaceWebUI::pushState May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393880] ------------------------------ 48ms May 11 16:33:13 volumio-klein volumio[944]: info: May 11 16:33:13 volumio-klein volumio[944]: [1494520393903] ---------------------------- Client requests Volume 41 May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393905] VolumeController::SetAlsaVolume41 May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393931] ------------------------------ 28ms May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393955] VolumeController::Volume 41 May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393957] CoreStateMachine::pushState May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393958] CoreStateMachine::getState May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393960] CorePlayQueue::getTrack 0 May 11 16:33:13 volumio-klein volumio[944]: info: CoreCommandRouter::volumioPushState May 11 16:33:13 volumio-klein volumio[944]: info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393968] interfaceApi::pushState May 11 16:33:13 volumio-klein volumio[944]: info: [1494520393969] InterfaceWebUI::pushState May 11 16:33:14 volumio-klein volumio[944]: info: Pushing Favourites {"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=1503052","favourite May 11 16:33:14 volumio-klein sudo[1703]: volumio : TTY=pts/0 ; PWD=/home/volumio ; USER=root ; COMMAND=/bin/journalctl -n 40

VolUp is the function that calls the node script which itself runs the code given above

[code]var io = require(‘socket.io-client’);
var socket = io.connect(‘http://localhost:3000’);
socket.emit(‘getState’, ‘’);
socket.on(‘pushState’, function(data) {
switch (process.argv[2]) {
case ‘+’:
socket.emit(‘volume’, Math.min(data.volume+1, 100));
break;
case ‘-’:
socket.emit(‘volume’, Math.max(data.volume-1, 0));
break;
case ‘mute’:
switch (data.mute) {
case true:
socket.emit(‘unmute’, true);
break;
case false:
socket.emit(‘mute’, true);
break;
}
break;
default:
socket.emit(‘volume’, Math.max(Math.min(Number(process.argv[2]), 100), 0));
}
process.exit();
} );

setTimeout(function() { socket.disconnect(); }, 3000);
[/code]

We’re reworking the volumio command line to be quite a lot faster. The problem in .js script is that they need 3 seconds to start. Stay tuned we’ll release the new version with improved commands soon

Hi,

that sounds good. Im asking myself if it already happened cause in the 2.175 Changelog i read
“Updated command line client”
but i wasnt able to find a documentation if this means also “volume” changes via console

A easy, quite fast change of the volume would be nice. Even telnet would help me.

Thanks for your work on this

Edit - seems to work:
I found an entry which seems to be quite new
“volumio.local/api/v1/commands/?cmd=volume&volume=80”
github.com/volumio/docs/blob/ma … EST_API.md

For my “special” case i would like to change the volume from the console.
I tried send a request with curl and it works

sudo curl "volumio.local:3000/api/v1/commands/?cmd=play"

Thank you for these scripts

Many thanks for the scripts, I have modified the random album loader to load a number of random albums, or artists by altering the socket.emit('browseLibrary… Line but I can’t work out how to change it to load random tracks. Any ideas?

Many thanks in advance for any help given!