Squeezebox Player WIP (Help Appreciated)

image

This widget has been developed for Squeezebox, but should work with any media control. You will need to update the PREVIOUS command in the widget code to suit your binding.

Pre-requisites:

  • For the album art to work with Squeezebox you’ll need to update your binding to the 2.3.0 snapshot version. I built the jar file based on OH Github. Once I sort out my home server I will link to it from here.
  • To get Spotify stations working with the Spotty plugin on Squeezebox, make sure you’re using a recent release. I used 7.9.1 from the nightly build server.
  • You will need to create an audio.rules file (actually, any .rules file is fine, I just like to keep things separate)

In the rules file you create your stations. URLs and Squeezebox MAC addresses need to be Encoded using something like https://www.urlencoder.org/ and added to the appropriate variables

import org.openhab.core.library.types.*
import org.openhab.model.script.actions.*
import org.openhab.action.squeezebox.*

var squeezeServer = "http://192.168.3.11:9000/status.html?p0=playlist&p1=play&p2="
var String kitchenPlaylist
var string squeezeplayer = "b8%3A27%3Aeb%3Ab1%3A54%3Af6"
var String station1 = "randomplay%3A%2F%2Ftrack"
var String station2 = "http%3A%2F%2Fopml.radiotime.com%2FTune.ashx%3Fid%3Ds24939%26formats%3Daac%2Cogg%2Cmp3%2Cwmpro%2Cwma%2Cwmvoice%26partnerId%3D16%26serial%3D1aecf10be8fd71e50285a088058a7a49"
var String station3 = "spotify%3Auser%3Aspotify%3Aplaylist%3A37i9dQZF1DXeby79pVadGa"
var String station4 = "spotify%3Auser%3Aspotify%3Aplaylist%3A37i9dQZF1DWXF8Nf1uycDZ"

rule "Kitchen Playlist"
when
	Item KitchenMusicPlaylist received update
then
	switch (KitchenMusicPlaylist.state) {
		case 0 :
			kitchenPlaylist = "off"
		case 1 :
			kitchenPlaylist = station1
		case 2 :
			kitchenPlaylist = station2
		case 3 :
			kitchenPlaylist = station3
		case 4 :
			kitchenPlaylist = station4
	}
	logInfo("squeezeplaylist.rules",kitchenPlaylist)
	if (kitchenPlaylist == "off") {
		logInfo("squeezeplaylist.rules","Playlist Off")
		KitchenMusicPower.sendCommand(OFF)
	}
	else {
		if(KitchenMusicPower.state = OFF){
			KitchenMusicPower.sendCommand(ON)
		}
		var playlistURL = squeezeServer + kitchenPlaylist + "&player=" + squeezeplayer
		logInfo("squeezeplaylist.rules",playlistURL)
		sendHttpGetRequest(playlistURL)
	}
end

Then load in the widget and configure with your items.

Although it seems to render well (ok, acceptably) on my laptop, it’s not so good on my Nexus 7. I’m a bit of a hack when it comes to CSS so I need to work (or have assistance on) the centering of the play/skip icons and making the circles round. I’m also not overly happy with the volume control or stations so will work on making that look a little bit better.
SqueezePlayer.widget.json (6.3 KB)

Enjoy!

1 Like

Took a quick look at your widget and found some errors you might want to fix:

    .glyphicon-pause {
        font-size: xx-large;
        vertical-align: middle;
         !important
    }

all of your !important are outside the semi-colon

That’s because you’re using static/explicit dimensions: px. Use responsive techniques: em/rem/%/etc

2 Likes

Nice posting. Some comments about the Rules (since I don’t know anything about HABPanel widgets I can’t comment there).

  • If you are on OH 2 you should not import anything from org.openhab. Remove all of your imports.

  • sqeezeServer, squeezeplayer, station1, station2, station3, and station4 are all constants, use val instead of var to declare them.

  • you should add a default case and set kitchenPlaylist to “off” or to some other value that you test for later and report an error for unknown values of KitchenMusicPlaylist. This will save your butt in the long run when you add a new station but forget to update the switch.

The Rule is nice and short. I like it. I do have some advanced things you might consider to make it even shorter and flexible. These are not necessarily mutually compatible nor necessary, they just might be something people wouldn’t consider trying.

  • Design Pattern: Human Readable Names in Messages - put the mapping between your KitchenMusicPlaylist.state and station into a .map file. You can then replace all of the stationx constants as well as your switch statement with

    kitchenPlaylist = transform("MAP", "stations.map", KitchenMusicPlaylist.state)
    This will also let you add or change stations in the future without needing to touch your Rules file.

  • Design Pattern: Encoding and Accessing Values in Rules combined with Design Pattern: Associated Items - Create a Group for the stations and an Item for each stations using a name that can be constructed from the value of KitchenMusicPlaylist.state. Set the state of these station Items to the values in your global vars. You can then replace your global station variables and your switch statement with

kitchenPlaylist = Stations.members.findFirst[station | station.name = "Station_" + KitchenMusicPlaylist.state.toString].state.toString
You can add/remove/change stations by adding new Items following the DPs above to initialize them to the proper value without needing to modify this Rule.

Keep up the good work!

2 Likes