node-red squeezebox

1,209 views
Skip to first unread message

Nic Garton

unread,
Apr 7, 2016, 5:09:16 AM4/7/16
to Node-RED
Like many, the "child in the sweet-shop" feeling of node-red (especially combined with esp8266) feeling persists for me.
But I'd really love to have a node that interfaces to squeezebox (logitech media server), so that I can control my household music.
Anyone knows of such a thing?

r...@ecliptiq.co.uk

unread,
Apr 7, 2016, 6:13:35 AM4/7/16
to node...@googlegroups.com
Hi,

On Thu, Apr 07, 2016 at 02:09:16AM -0700, Nic Garton wrote:
> But I'd really love to have a node that interfaces to squeezebox (logitech
> media server), so that I can control my household music.

SlimProto is documented(ish) here: http://wiki.slimdevices.com/index.php/SlimProto_TCP_protocol. I don't know of any Node.js bindings for it. You may also find http://wiki.slimdevices.com/index.php/SlimProtoDeveloperGuide useful.

If I remember correctly, if you're pretending to be a controller you can pretty much get away with sending HELO, IR and STAT packets to the server and responding to the server's strm pings. Figuring out the IR codes is a bit of a pain: if I remember correctly, when I played with slimproto, I just lifted the codes from SoftSqueeze's skin files (e.g. http://softsqueeze.cvs.sourceforge.net/viewvc/softsqueeze/softsqueeze3/resources/skin/woodgrain/common.xml).

I last played with this a very long time ago, so the above may be out of date!

Hope this is vaguely useful,

Rob

Dave C-J

unread,
Apr 7, 2016, 1:41:44 PM4/7/16
to node...@googlegroups.com
then there is this - that although mainly aimed at the squeezebox/spotify combo - does describe how to use it for normal local playback etc... - so may make the basis of a node.

r...@ecliptiq.co.uk

unread,
Apr 7, 2016, 5:01:24 PM4/7/16
to node...@googlegroups.com
On Thu, Apr 07, 2016 at 06:41:42PM +0100, Dave C-J wrote:
> https://www.npmjs.com/package/squeezenode

Whoa, that's useful. And an awful lot easier than trying to speak slimproto. I shall remember that exists: thanks!

Greg EVA

unread,
Apr 8, 2016, 8:28:11 AM4/8/16
to Node-RED
Another idea to consider is using NR to speak with another system/API which already supports LMS.  There is a lot of different functionality to handle in communication with an LMS which goes beyond just playing a song!  (sync players, unsync zones, volume& power control, etc.)

Nic Garton

unread,
Apr 10, 2016, 12:00:12 PM4/10/16
to Node-RED
>>https://github.com/piotrraczynski/squeezenode

The author has done a couple of updates in last few days, and it does just what I need.
Very simple to integrate into node-red, even for a non-programmer like myself.

Purpose of this was to send Watson generate (text to-) speech to all squeeze players in the house. Works perfectly.

Stuart Poulton

unread,
Apr 10, 2016, 12:03:05 PM4/10/16
to node...@googlegroups.com
Nic,

Would love to see the details of what you’ve accomplished been thinking about something similar myself.

Stuart

Dave C-J

unread,
Apr 10, 2016, 12:48:12 PM4/10/16
to node...@googlegroups.com
+1 for an example ;-)

Nic Garton

unread,
Apr 10, 2016, 3:08:59 PM4/10/16
to Node-RED
Ok - my code is not even close to be presentable, but here's an intro to get you started. Full control of your squeezebox players is trivial starting from here ...

https://github.com/piotrraczynski/squeezenode

Unzip squeezenode.zip (remove "-master"), so it's here:
    ~/.node-red/node_modules/squeezenode
Add this to the "functionGlobalContext: {" section of your settings.js:
    squeezebox:require('~/.node-red/node_modules/squeezenode')

Restart node-red

Most of the functions you need are in "squeezeplayer.js".
For example to toggle pause on your squeezebox player, the functions is:

    this.pause = function (callback) {
        this.request(playerId, ["pause"], callback);
    };

Here's the node-red importable code, that implements the toggled pause, and also code that returns a string showing name of current track.

[{"id":"8dbd6fd5.11bdc","type":"inject","z":"a451b65e.e3e48","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":1346.6666259765625,"y":731.6665859222412,"wires":[["23ed90d5.d73628"]]},{"id":"23ed90d5.d73628","type":"function","z":"a451b65e.e3e48","name":"play","func":"var SqueezeServer = global.get('squeezebox'); //require('~/.node-red/node_modules/squeezenode');\nvar squeeze = new SqueezeServer('http://localhost', 9000);\nsqueeze.on('register', function(){\n\tsqueeze.players[\"00:1f:1f:a9:a2:95\"].play();\n});\nreturn msg;","outputs":1,"noerr":0,"x":1499.4881591796875,"y":731.4046936035156,"wires":[[]]},{"id":"ee54bb1c.b04dd","type":"debug","z":"a451b65e.e3e48","name":"","active":true,"console":"false","complete":"true","x":1737.1547927856445,"y":776.666606426239,"wires":[]},{"id":"b02a9618.af7e9","type":"function","z":"a451b65e.e3e48","name":"get current track title","func":"var SqueezeServer = global.get('squeezebox'); //require('~/.node-red/node_modules/squeezenode');\nvar squeeze = new SqueezeServer('http://localhost', 9000);\nsqueeze.on('register', function(){\n\t    \tsqueeze.players[\"00:1f:1f:a9:a2:95\"].getCurrentTitle(function(response){\n\t \t    node.send(response.result);\n \t\t});\n});\n","outputs":1,"noerr":0,"x":1548.5831336975098,"y":777.1428852081299,"wires":[["ee54bb1c.b04dd"]]},{"id":"91436022.d771d","type":"inject","z":"a451b65e.e3e48","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":1343.3332977294922,"y":777.7619018554688,"wires":[["b02a9618.af7e9"]]}]

You'll need to change the squeeze.players ID to match yours (or create a node to choose one), and update the ip for your Logitechmediaserver - mine is on localhost.
My target functionality was to get all my squeezeboxes to play speech sent as text via MQTT (e.g. "doorbell pressed", or something silly like that).
The process flow is thus:

MQTT publish "doorbell pressed"
Read the relevant topic
Send the text to Watson text to speech
Received the speech data (FLAC), save to file
Clear the LMS playlist
Enqueue the file to the playlist
Play

Total timelag between publishing the required text to MQTT, and hearing it out of each of my squeezeboxes, can't be more than about a second, so it's very usable.
Many thanks to Piotr for the excellent but simple to use JS squeezenode interface. I can see that it does all I need and much more.
Reply all
Reply to author
Forward
0 new messages