Squeezebox and Smarthings

This looks pretty good- good starting point for me. I think i’d like to make a smartapp that lets you configure those ‘slots’ on the player with LMS urls of your choosing- to include spotify, etc.

And actually now that they’ve added a Music Player capability…time to look at using that.
http://docs.smartthings.com/en/latest/capabilities-reference.html#music-player

1 Like

Hi

Well I got round to modifying Mike’s code as requested by HENDRE so now it’s all a bit more usable. Still with the 5 player update.

If it is off use to anybody please consider donating to my favourite charity: https://www.nowdonate.com/checkout/pv0j03m4s1o1x60o6bh2

New functions are:

  • sqVS: volume control and on/off status refresh.
  • sqeezeSwitch: 3 player sync groups, 5 playlist slots, playlist and player select and on/off status refresh.

The Smart App has been updated also.

To support the status refresh I have added a bridge program that runs on the Linux box you run your SBS and a JSON Slurper device handler to receive commands back from the bridge.

Its not a simple install so there are some instructions and all the files on GitHub:
https://github.com/LeeC77/SmartThings-and-Squeezebox-Controller
sqVS:


squeezeSwitch:

Hope this works for you

2 Likes

Not sure where anyone is with this. I have coded the media player device type to control LMS via http and receive status replies from the server. It is only for one player right now… Need to tear it apart to split into the server, which handles the calls and players which would issue the controls, allowing for multiple players. Need to figure out parent child devices to really make it work.

This was initially done just to see if I could, but now
I am thinking about using it for announcements, so it needs polish.

Any advice or suggestions?
Screenshot_20180113-190900

2 Likes

Hi Lee I was trying to get this going on a raspberry pi 3 running max2play and I am confused about a couple parts of the install. I’m not sure if I screwed something up with the hexidecimal part and the telnet port or CLI port… I’m wondering if I didnt infact screw up the install at all but if it has something to do with the passord protection I setup on my logitech media server? I cant find anywhere where this app would handle a password protected LMS

I think the password was causing issues cause I disabled it and then I had some control… I notice my virtual switches do turn on and off my players but they get stuck in ilmbo stating turning off or turning on but don’t actually change state. The volume seems to work too except volume up and down both increased the volume. Any ideas?

Hi
If the virtual switch buttons are not following the squeezebox it could be because the bridge is not connected, check the Slurper activity, if you do not see a reply after pressing a virtual switch there is some issue, perrhaps with the bridge or the Slurper. Are you able to confirm the bridge is running on your RasPi.
Not sure why the volume is not working for you it can take a short while for the command to reach your squeezebox.
Have a look in the live logging.
I’ll try to look at it at the weekend

Hi

So I have been thinking of progressing this for announcements also, but have put it on pause as there is a DLNA integration going on that may be better. See posts above. The DLNA integration doesn’t work with squeezebox yet and the developer like us all has many other things going on. So I have started to adapt his code and have got as far as creating child devices. I am now trying to debug them.
Happy to share if you can help out on DLNA or this project.

Thanks for the hard work and quick reply. I can send you my logs the live logging if it helps. The log shows activities as well as some json parsing messages and such when I hit a button. The Json slurper shows no activities however. For the json slurper all you have to do is copy paste the code as a device type and then create a device with that type right? Seems like I couldn’t have screwed up that part if there was nothing I needed to change. The python code I had set to autorun like you did with the shell script. However for testing I ran it manually in a terminal window to make sure it was running with
$python SBBridge.py
When I run this my command prompt disappears as I would expect when running a program. I might not have gotten the settings right for it though I suppose. For my setup I’m running max2play on a pi3 that is my server. I installed the python script on the same pi that is my server not sure if there is any issue with doing this. I was able to manually telnet port 9090. What should the settings of the top of my .py file look like for my max2play is 192.168.1.22 and my smartthings is 192.168.1.3

I decided to not use the DLNA route since the LMS integration of that seemed flaky. So, I have coded using the REST commands with the status.html format. I have all the buttons on the media player functional and am getting a response to parse to update song title and player status. I poll the player every minute to update status since I want to keep it in sync with activity outside Smartthings like song changes and starting/stopping the player.

This works great for one player. As everyone has said the DNI and ip address issues mess with multiple players because of how LMS is set up. I have ideas on how to address this, just haven’t had time to play with it yet. This week I hope.

Is the JSON slurper receiving async replies from the server or do you poll regularly? I need to look at your code.

The other thing I inadvertently did was allow a smart app to send any valid call to the LMS so playlists and such can work as well. I also have a few virtual buttons working for Google Home control.

I would be happy to share and help if we are indeed going in the same direction.

Looks like I forgot to add that the Slurper DNI should be your RasPi mac.
Try it and let me know. I’ll update the instructions

You need a device created in SmartThings to represent the Raspberry Pi. The device should have a Device Network Id (DNI) that matches the MAC address of the Raspberry Pi. It should be all uppercase and without any octet separators (e.g.000A959D6816).

Okay thaks for the update. I got this edited the JSON sluper in the IDE to have a DNI of the Raspberry PI mac address with no colons all caps. I still do not see events in my json slurper. I think at this point I’ve got to be misunderstanding or having one thing set wrong. I have included the first few lines of my SBBridge.py file in case I mixed up or misunderstood the intent of the different IP address settings. My pi with LMS and the bridge is 192.168.1.22 and my smartthings hub is 192.168.1.3

import socket
import threading
import subprocess

myIP = '192.168.1.22'

telnetPort = 9090 #these need numbers
telnetIP = '192.168.1.22'

httpPort = 39500
httpIP = '192.168.1.22' #raspi ip

SmartHubIP = '192.168.1.3'

also there is this line in your instructions that states…
"NOTE: The bridge expects to receive on port 39500, so this has to be HEX encoded as the device ID for squeezeSwitch."
this seems conflicting with the thread saying it should match the hex ip and port of your telnet server???
so my network id for my squeezewitch is currently c0a80116:2382
I understand how 192.168.1.22 becomes c0a80116 but Im completely lost about why 9090 becomes 2382 Im not sure if this is set right at all but it seems when I tinker with it to try other stuff I lose all functionality so I think I had that portion right…

Hopefully Ive included enough information to figure out my problem… On a sidenote how difficult would this be to include support for password protected servers as I’ve had to disable that to get it to work?

In this case the telnet server is the SBS, but the bridge is translating back and forth to SmartThings so you need to use the IP and port of the bridge program not the SBS.
The bridge is set to bind to port 39500 and the IP of your RasPi '192.168.1.22’
So set the squeezeSwitch Network ID to C0A80116:9A4C. Here 9A4C is Hex for 39500 (the port the bridge is listening on).

2382 is Hex for 9090, so when you used this ‘c0a80116:2382’ you are saying RasPi port 9090, which is likely to be your SBS (unless you changed it) therefore you are sending commands directly to the SBS and not the bridge, the bridge cannot then receive the replies to send to SmartThings. This is why you only had connectivity in one direction.

On password protection you would need to adapt the bridge program to send the user and password as part of opening the telnet connection. Try a live telnet (e.g. putty) and get that to work then adapt the bridge at lines 81,82.

I don’t see this as very useful as you will have stored the password in the clear on the seme device as the server.

that did the trick :slight_smile:

Okay so all is working for me now so thank you for you help. I realize that it wouldn’t be the highest level of security or anything putting a password in that file but at least some deterrent could be good since I have some ports forwarded for control of my lms I’d hate to take that password down. I am able to login via telnet fine but I cant figure out for the life of me what I would put in lines 81 and 82 in the code to make that happen. Sorry for the lame questions I’m such a newbie to coding and IM trying to learn and figure out how some of this works and expand it for my needs… Here is the telnet commands that worked

$telnet localhost 9090
then this brings up the command cursor in telnet and if I type...

login myusernamehere mypasswordhere

I am then in and can send the server commands

Looks like you are looking for something like:
http://www.xaxxon.com/oculus/docs/view?f=script_example_react_to_loud_noise.
Failing that you might need to rewrite the bridge somewhat using functions from the Python telnetlib rather than the socket module try:
http://www.pythonforbeginners.com/code-snippets-source-code/python-using-telnet.
or Google telnetlib or python telnet password.
If you mange to get it working don’t forget to post back.

Best of luck

1 Like

Thanks Lee for the above and beyond help. I was able to get this working with the server being on a password after reading the example codes you linked. I couldn’t find the encrypted version on my pi anywhere like that robot example you posted had but I was able to get it to work with a plain text version. Here is the changes to the SBBridge.py. I basically added a variable to store the username and one for the password too. I added the time library so I could add a sleep in the code after the first connect to give it a second to connect before I shoot off the password. I then added the send string to send the username and password. All my additions are surrounded with ** obviously the stars have to be deleted for it to work but I couldn’t figure out how to make them bold on here to accentuate my changes. Now if I can figure out how the player syncs work in the app I’ll be set. Seems like one of my groups worked and another one said null for some reason in the slurper after I tried to activate a “group” maybe its cause I don’t have any playlists or something and that expected behavior? but Ill probably just have to play with it more to figure it all out. Would anyone else be interested in a next song previous song and play stop buttons? Seems it would be useful to add those features but at least most importantly as it is I can easily turn on and off players.

## Bridge program between smart things and the raspberry PI
##
##                       |  RASPBERRY PI INTERNAL
##                       |
##   S                   |                       S
##   T                   |  B                    B 
##       ---- HTTP --->  |  R  ---- TELNET --->  
##   S                   |  I                    S
##   E                   |  D                    E
##   R                   |  G                    R
##   V   <--- JSON ----  |  E  <--- TELNET ----  V
##   E                   |                       E
##   R                   |                       R
##                       |
##
## the Json will be sent via a line of shell code and TELNET treated as raw
## packets as far as possible

import socket
import threading
import subprocess
**import time**

myIP = ''

telnetPort = 9090 #these need numbers
telnetIP = '192.168.1.85'

httpPort = 39500
httpIP = '' #raspi ip

SmartHubIP = '192.168.1.119'
**username = 'usernamehere'**
**password = 'passwordhere'**

def sendJSON(message):
    ##complie and send a JSON msg by shell script
    subprocess.call('curl -H \"Content-Type: application/json\" -X POST -d \'{\"SBSResponse\":\"' + message + '\"}\' http://' + SmartHubIP + ':' + str(httpPort), shell = True)

    

def telnetHandler():
    ##recvs and deals with telnet msgs, will use sendJSON funct
    while True:       
        msg = telSocket.recv(1024)

##        with lock:
##            print('recved on telnet: ' + msg.decode().strip())
            
        sendJSON(msg.decode())


def httpHandler():
    ##recvs and deals with HTTP msgs, will use sendTEL funct
    while True:
 
        con, addr = httpSocket.accept()

        SmartHubIP = addr[0]
	SmartHubPort = addr[1]
        
        requ = con.recv(1024)
            
##        with lock:
##            print('recved on http: ' + requ.decode().strip())
##            print('resolved IP: ' + SmartHubIP + '\n resolved Port: ' + str(SmartHubPort))

        con.close()

        telSocket.send(requ)
        


lock = threading.Lock() #allows threads to print


httpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#creates the socket for recveing HTTP msgs (server type)
httpSocket.bind((httpIP, httpPort))
httpSocket.listen(3)


telSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#creates the telnet socket (client type)
telSocket.connect((telnetIP, telnetPort))
**time.sleep(5)**
**telSocket.sendall("login "+username+" "+password+"\r\n" )**
        

telnetDaemon = threading.Thread(target = telnetHandler, args = ()) #creates threads
httpDaemon = threading.Thread(target = httpHandler, args = ())
telnetDaemon.isDaemon() #sets threads to daemons
httpDaemon.isDaemon()

telnetDaemon.start() #begins threads 
httpDaemon.start()


while True:
    pass

Just an update from my end. Had surgery, so am just now having a chance to work on my idea. This past week I’ve succeeded in getting server and player device handlers written and functioning with two players being controlled independently. I do get server responses back without a bridge, but only with polling, no lan aysnc yet that I know of. Need to do a bit more testing and clean up my code. Will try to share something soon. Glad thereis still interest in this.

I would love to see what you have

I have finally gotten my code posted. I’ve started a new topic so that I can attempt to keep the feedback about it findable and not continue to clutter up this conversation. Thanks for your interest.

Announcements from your Squeezebox players.

  • Generic Media Render (DLNA Speakers) reworked to work with Squeezebox.

  • Use Big Talker to make your announcements

If it is of use to anybody please consider donating to my favourite charity: https://www.nowdonate.com/checkout/pv0j03m4s1o1x60o6bh2

Its not perfect, but works, your welcome to feedback problems, but I’m not promising to fix it.

1 Like