How to: Build a LMS based whole house audio system

This is take 2. Back in March I posted build out instruction for Mopidy. It worked well, and I liked the iris interface plugin for Mopidy. Sadly Spodify discontinued supporting connections via libspotify which is used by mopidy. As Spodify is the main music/podcast source in our house I had to find another approach. On the mopidy build out thread people recommend I check out Logitect Media Server (LMS). I figured I’d give it a try. My requirements and basic setup remained the same and are repeated here.

My main requirement for the whole house audio system

  1. Has to be accessible from my cell phone and my computer
  2. It has to play multiple music streams at the same time.
  3. I want no limit on the number of speakers that can be connected
  4. Any speaker has to be easily connected to any music stream
  5. The system must allow playing locally stored music. I have a lot of music CDs that I’ve ripped.
  6. Needs to allow playing of music from Spotify
  7. Play back of pod cast and other sources would be nice, but not required
  8. Anyone living in the house has to be able to start a stream on any speaker (NO IT SKILLS required)
  9. The implementation has to be build on all open source software
  10. I was not looking to run LMS directly on my HA hardware.
  11. The controller and the media players had to work on linux.
  12. HA is to only provide access to the audio system User Interface

This is a simple picture of what these instruction build.

Most of the speakers connect to the network/LMS via WiFi through a PI media player. My HA, music server and one media player are hardwired. At this point I don’t use bluetooth to connect any of the speakers. All outputs are connect through the audio output of the PIs, each running a media player.


  1. Raspberry PI 3 for the mopidy music server.
  2. A Raspberry PI 3 for each speaker
  3. A very old stereo system (optional) in living room
  4. A AV amplifier (optional) in basement
  5. USB Wifi, while the PI 3 has built in WiFi it’s not very good and it results in the music stream dropping out. I used two of these.
  6. Ground loop noise isolator. If you power the speaker off the PI USB port you’ll need these. Alternatively you can use a separate power source for the speaker and the PI.
  7. You should also use a good power supply as to not over tax your PIs

Prepare items at the OS level in preparation for the LMS install
I have to say there was very little work required beyond adding a few additional packages to the Rasberry PIs OS to get this thing up and running. On the PI that acts as the LMS server I needed to add the following:

apt -y install libio-socket-ssl-perl libcrypt-openssl-rsa-perl

I did reuse the same OS load that had previously been used for mopidy, so there may be some other packages required that I’d previously load with Mopidy. I’ll update this in the future if I do a build from scratch again and find I’ve missed packages.

The hostname for each PI is used to identify the media player when it connects to the LMS server, so make sure you set the hostname in /etc/hostname and /etc/hosts and reboot before doing the LMS component install.

Building the LMS server
You need to go here and pull down the latest LogicalMediaServer .deb file. At this time it’s v8.2.0. At the command prompt on the LMS PI, while sitting in the directory where the .deb file is located, run the following to install the package:

dpkg -i logitechmediaserver_*_all.deb

At this point your media server is set up with a web server listening on port 9000. The first time you connect to port 9000 you get prompted for information like where is you music library and where do you want to store play list. LMS runs as user squeezeboxserver, so if you have music on the box you need to make sure it’s readable by the squeezeboxserver user. The play list folder needs to be read/write by user squeezeboxserver. It also ask you about your account. I added an account, but there is a skip button so you can just skip this.

Once you’ve accessed the LMS web interface you should add the following 3rd party plugins

  • Group Players – allows you to establish virtual players that synchronize play to multiple players
  • Material Skin – Provides a mobile friendly alternative web interface
  • Spotify for Squeezebox, Still Spotty – enables connectivity to spotify

In the event you have a firewall blocking outbound traffic you’ll need to allow outbound port 4070 traffic if you use spotify.

Connecting LMS to Spotify
When you’re ready to connect the spotty plugin to spotify it’s pretty easy. You go back to the plugin page, find Spotty under the Active Plugins. At the end of the Spotty line there is a Settings link. Click that. It’ll give you the instructions to connect to spotify. In summery you fire up spotify on your phone and play some music. Down at the bottom of the interface there is a player icon next to a heart icon. You tap the player icon and look for an authorization request that’s tied to your media player. Give it a little time to pop up. You might have to go in and out a couple of times, but it should pop up. You click on it and now your LMS player is good to access spotify.

Building the Squeezelite media players

The easiest way to way to get your speakers connected is by using the squeezelite media player. You install it on any PI that is going to be connected to a speaker/amplifier. You can run a copy on the PI that is also running LMS if desired. The install process is simply

apt install squeezelite

Squeezelite is a headless media server. So it has no user interface. Once installed it’ll start queezelite and squeezelite automatically connects to your LMS device using the hostname to identify itself.

Here’s a shot of the ugly LMS web interface:

Notice the available media players show on the pull down at top right. You get to the screen to enables plugins and create your synchronized groups using the setting gear at the bottom right.

HA configuration
The first thing you need to do is add the Logitech Squeezebox integration.

Once selected it pop’s up a menu that should have your LMS IP and port number 9000, with the option to provide an LMS username and password, which you just leave blank and click the submit button. This integration will automatically discover the media players connected to LMS and create associated HA entities.

The interface I put in place was inspired by Mey in this post. Here’s what mine looks like:

I have a dashboard with three tabs. The PLAY IT tab is the normal way I expect other users in the house to access LMS. The box on the left in this tab is provided by the material plugin you install on LMS. The individual volume and player controls are provided by the HA HACS mini media player card. The MATERIAL tab just gives more space and thus a less need to clicking to the LMS MATERIAL interface. It’s redundant.

The last tab give access to the standard LMS user interface. I include this to get access to the setting menu and for on the fly speaker synchronization off the media player pull down.

To get the exact layout in the PLAY IT tab you need to add a couple of customer cards from HACS. Select the HACS dashboard. Select “Explore & Download Repositories”. The two card repositories you want to add are “Mini Media Player” and “Stack in Card”.

Now create a dashboard named Music, using the icon mdi:music, with Show in sidebar enabled.

Select the Music dashboard. It will be filled with a lot of stuff. Use the triple dot menu to Edit the Dashboard. Move the slider “Start with an empty dashboard” and select “Take Control”. The dashboard has one primary view named HOME, edit this and change it to the title you like. The first tab should be a Masonry view. Add two more view tab that are of type Panel card, titled Material and LMS default.

Start with the LMS default tab and select the “add card” button. Select a webpage card and give it the URL of the web interface for your LMS server (i.e This will give you access to the full LMS interface through HA.

Next select the center Material tab and add a card. Once again pick the webpage card and this time use the LMS URL with the added material location (i.e This gives you a better interface for selecting your content and playing it. This same interface will be available in the PLAY IT tab, but only in less screen area.

The Final tab, PLAY IT, is designed to give you the ability to access your content and play it, while having easier access to volume control of all players at the same time. Start by adding a webpag card with the material URL (i.e Set the Aspect Ratio to 100% (or greater) and save the card. Next we’re going to add a vertical stack card to control each player. I used the stack-in-card to remove boarders. The stack-in-card doesn’t have a visual interface for building the vertical stack. As such, I think the easiest way to build this interface is to start by using a standard “Vertical Stack” card to build the screen area. Once you’ve added the Vertical Stack you’ll need to add a Mini Media Player card for each player. The only item you have to update in the mini media player is the Entity. I also prefer the look of “material” for the Artwork pull down. Once you’ve created the stack and verified it works as desirer you can change the vertical stack to a stack-in-card. You do this by getting into edit mode for the vertical stack card and select “Show Code Editor”. Here you change the top two lines from:

type: vertical-stack


type: custom:stack-in-card
mode: vertical

I think that’s about it. You now have a full house audio system. I have to admit that this was a lot easier to get going than the mopidy setup I previously built. The LMS spotty plugin also gives access to your spotify podcast. By default LMS also includes access to a lot of internet radio channels. Nice. There also additional plugins for most of the alternatives to Spotify.

Players dropping out
I had an issue where players would first connect the mac address 00:00:00:00:00:00. When multiple players were in this situation then a player would appear to drop out. Turns out LMS uses the MAC address to track individual players. Some people fix this by ensuring the network is fully up before allowing squeezelite to start. I prefer the alternative of just setting the MAC address in /etc/default/squeezelite. At the bottom of the file you uncomment the following line and add the -m argument with the MAC address for your interface. In reality it can be anything that looks like a MAC address as long as it’s unique between players. Here’s an example of the modified line on one of my squeezelite players.

SB_EXTRA_ARGS="-m b4:4b:d6:2d:6c:7b"

Other useful LMS plugin

  • Chromcast Bridge - This allows any chromcast to act as a LMS connected media player. It works pretty well. In the short time I’ve used it I only had one time where It LMS couldn’t communicate with the chromcast after turning the TV on, that also powers the chromcast. In general it works great and makes it easy to play music from LMS (controlled by HA) through the TV speakers.
  • Multiple streaming Radio plugins - With the default install you get direct access to a few hundred streaming radio stations without any additional action on your part.
  • Pandora, TIDAL and Deezer - I have not used these plugin but they are installed by default giving access to other streaming music services.

Related configuration Items
Using a universal media player card to add amplifier volume control
Adding IR transmission to control AV equipment


well done!
I have also recently switched from volumio to LMS and I have to say there is no turning back
there are also two more easy options which may fit to your deployment:

Thanks for the suggestions. While I think the HA add-on might be good for some, I don’t like the idea of adding none critical Home Automation or Home Security items on my HA controller. As for piCorePlayer I normally don’t like the product specific distros because they normally lock too much down. That said, I didn’t want to lose all my mopidy work incase I decided to switch back when they get spotify worked out again or if the LMS stuff didn’t work well. At this point I can run either LMS or modify. If it wasn’t for concern about maybe moving back, I might have given piCorePlayer a try. Are they any feature that come with piCorePlayer that you really like?

1 Like

I don’t know if it is a unique piCorePlayer feature, but I love the option to add bluetooth speakers and treat them like media players

1 Like

I just viewed the Let’s get loud video that goes over the Music Assistant included in the 2022.7 release. It’s looking to be the media controller for your full house audio system. It looks interesting, but I believe it’ll be a while before it really competes with LMS. HA should also thing about how to have a distributed install. I’m not crazy about the though of the music controller running on Smart house controller competing for resource.

1 Like

It looks like Music Assistant is close to getting a good implementation of a way to stream YouTube Music which there is no native ability in LMS right now. Seems like they can work togethor to some extent. MA to stream YT Music, LMS to sync the players

Still testing, but just installed LMS + 3 Squeezelites to Rpi3b and convolver for each used audio device.

When you’re done I’d love to hear had you feel about convolver’s impact on the audio output.

I’ve been using convolvers since -11 so they are nothing new to me. I have one Fiio headphone amp for Sennheiser HD595 and Sennheiser RS-180 wireless headphones with full digital audio path. Speakers have amp connected with s/pdif and s/pdif-usb conversion done by Asus Xonar U7 MkII sound card.

With ladspa_dsp you can also skip the convolver and create your own parametric equalizer.

There are operating systems specifically for LMS such as Max2Play which should make installation even easier. I use HifiBerry hats on the Raspberry Pis connected to the speakers. These are inexpensive but high quality amps. We don’t bother with controlling the speakers through HA and use the Squeezer app on our android phones but you can use iPeng for iphones or even the Material skin on a browser.
I do want to use HA for text to speech messages over my speakers, however.
The problem is that a message will stop the connection to the LMS and I have to manually connect after the message has finished.

There are scripts on the forum to resume the previous media once tts is done.

Thanks for replying. I dived into the forums and found things which were too complicated for me and didn’t even seem satisfactory to the people who knew what they were doing. However I came across the JSONRPC Squeezebox API which lets you send URLs to the LMS server to control it. If you install the HA Squeezebox integration you can not only use more geeky ways of sending the URLs (http-request using RESTful etc.), there is already a built in visual interface for thickos like me. You still have to spend time finding out what commands and parameters are available and then how to format your commands. I have LMS on a separate Raspberry Pi and a another Pi controlling each pair of speakers. There is supposed to be a security feature of the API which prevents software other than your browser from sending commands without a special code in the URL but it didn’t seem to stop me. I don’t care; it works! There are tons of commands. The one which seemed to regain control of my speakers once the TTS had used them was"clear playlist". So far I’ve only managed to get our usual radio station to play after regaining control, but resuming where you left off before the TTS seems possible (“save playlist” possibly) but I can’t save or manipulate playlists at the moment and don’t know why.

I use this intergration for notifications. I just have to see how this can be combined with the new voice assistant in the May 2023 version of homeassistant.

If you’re using ssl for HA then the link for LMS must also use SSL. I did not include instructions for setting up the SSL proxy on the LMS server, but I do indeed use SSL with an nginx proxy. I use a wildcard domainname so I only have to generate one certificate for all the services on my network that I integrate with HA. My router resolves the domainname. My nginx configuration in sites-enabled for the lms server looks like this:

server {
        listen 9001 ssl;

        # Set to "_" to listen to all domains

        # Update the following to reflect your certificate and key location
        #ssl on;
        ssl_certificate /home/cert-usr/certs/;
        ssl_certificate_key /home/cert-usr/certs/;
        ssl_prefer_server_ciphers on;

        proxy_http_version 1.1;
        proxy_read_timeout 600s;
#        location = / {
#                return 301 /iris/;
#        }

        location / {
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $http_connection;

So then in the HA iframe I don’'t connect to the lms http port 9000 as that doesn’t work in an iframe when HA is using ssl. I connect to So the proxy provides https access to lms on port 9001, which can then be used as the url in HA.

1 Like

This is great, thanks so much for sharing it as I’ve been looking for a good multi-room option for quite some time now. I’ve got everything working for the most part, but when I stop playing a channel the album artwork from the previous channel stays on the mini-player. Is there a setting in LMS or somewhere else to clear this out once a channel stops playing?

Interesting question. I’m not aware of an LMS option to clear the playlist upon completion of play.

Easy to do with an ha automation.

Good idea. Here’s what I’ve come up with. Is there a way to “loop” through this for the 8 different media_player entities (speakers) that I have without having to copy/paste the same code 8 times?

  - alias: 'Clear media player playlists if inactive'
      platform: time_pattern
      minutes: '/10'
      - condition: template
        value_template: '{{ states.media_player.kitchen_speakers.state != "playing"}}' 
      - service: media_player.clear_playlist
        data: {}
          entity_id: media_player.kitchen_speakers

Instead of using a time pattern trigger, why not use a trigger on the state of the player i.e. from playing to idle or off?

You can then list all your players under the entity_id key within the state trigger, and use the trigger.entity_id in your condition and entity templates to target the correct player (although the condition would probably be redundant actually).

You would probably need to set the automation mode to parallel in case it was triggered simultaneously by more than one player.

1 Like