Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# AmpliPi Software Releases

# Future Release
* System
* Upgrade from Logitech Media Server 8.5.2 to Lyrion Music Server 9.0.3


# 0.4.11
Expand Down
10 changes: 5 additions & 5 deletions amplipi/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,22 +238,22 @@ def shutdown():
}
)
def lms_mode(ctrl: Api = Depends(get_ctrl)):
""" Toggles Logitech Media Server mode on or off. """
""" Toggles Lyrion Music Server mode on or off. """
new_config: models.Status
if ctrl.lms_mode:
logging.info("turning LMS mode off...")
try:
os.remove(pathlib.Path(defaults.USER_CONFIG_DIR, "lms_mode"))
except FileNotFoundError:
pass
Popen('sudo systemctl stop logitechmediaserver', shell=True)
Popen('sudo systemctl disable logitechmediaserver', shell=True)
Popen('sudo systemctl stop lyrionmusicserver', shell=True)
Popen('sudo systemctl disable lyrionmusicserver', shell=True)
new_config = models.Status(**defaults.default_config(is_streamer=ctrl.is_streamer, lms_mode=False))
else:
logging.info("turning LMS mode on...")
pathlib.Path(defaults.USER_CONFIG_DIR, "lms_mode").touch()
Popen('sudo systemctl start logitechmediaserver', shell=True)
Popen('sudo systemctl enable logitechmediaserver', shell=True)
Popen('sudo systemctl start lyrionmusicserver', shell=True)
Popen('sudo systemctl enable lyrionmusicserver', shell=True)
new_config = models.Status(**defaults.default_config(is_streamer=ctrl.is_streamer, lms_mode=True))
load_config(new_config, ctrl)

Expand Down
3 changes: 3 additions & 0 deletions bin/arm64/find_lms_server
Git LFS file not shown
2 changes: 1 addition & 1 deletion docs/amplipi_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2680,7 +2680,7 @@ paths:
tags:
- config
summary: Lms Mode
description: Toggles Logitech Media Server mode on or off.
description: Toggles Lyrion Music Server mode on or off.
operationId: lms_mode_api_lms_mode_post
responses:
'200':
Expand Down
14 changes: 6 additions & 8 deletions scripts/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,15 @@
]
},
'lms': {
'apt': ['libcrypt-openssl-rsa-perl', 'libio-socket-ssl-perl', 'libopusfile0'],
'apt': ['libcrypt-openssl-rsa-perl', 'libio-socket-ssl-perl', 'libopusfile0', 'squeezelite'],
'copy': [{'from': 'bin/ARCH/find_lms_server', 'to': 'streams/find_lms_server'}],
'script': [
'if [ ! $(dpkg-query --show --showformat=\'${Status}\' logitechmediaserver | grep -q installed) ]; then '
' wget -nv https://storage.googleapis.com/amplipi-deb/pool/main/l/logitechmediaserver/logitechmediaserver_8.5.2_all.deb -O /tmp/logitechmediaserver_8.5.2.deb',
' sudo dpkg -i /tmp/logitechmediaserver_8.5.2.deb',
' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl disable logitechmediaserver; fi',
' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl stop logitechmediaserver; fi',
'if [ ! $(dpkg-query --show --showformat=\'${Status}\' lyrionmusicserver | grep -q installed) ]; then '
' wget -nv https://downloads.lms-community.org/LyrionMusicServer_v9.0.3/lyrionmusicserver_9.0.3_arm.deb -O /tmp/lyrionmusicserver_9.0.3.deb',
' sudo dpkg -i /tmp/lyrionmusicserver_9.0.3.deb',
' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl disable lyrionmusicserver; fi',
' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl stop lyrionmusicserver; fi',
'fi',
'wget -nv https://storage.googleapis.com/amplipi-deb/pool/main/s/squeezelite/squeezelite_2.0.0-1488+git20240509.0e85ddf-1.1_armhf.deb -O /tmp/squeezelite_2.0.0-1488+git20240509.0e85ddf-1.1_armhf.deb',
'sudo dpkg -i /tmp/squeezelite_2.0.0-1488+git20240509.0e85ddf-1.1_armhf.deb',
'sudo systemctl stop squeezelite',
'sudo systemctl disable squeezelite',

Expand Down
10 changes: 5 additions & 5 deletions scripts/edit_media_directories.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@


def check_lms_mode():
try:
status_output = subprocess.check_output('systemctl is-active logitechmediaserver', shell=True).decode().strip()
return status_output == 'active'
except subprocess.CalledProcessError:
return False
try:
status_output = subprocess.check_output('systemctl is-active lyrionmusicserver', shell=True).decode().strip()
return status_output == 'active'
except subprocess.CalledProcessError:
return False


def get_usb_drives(logger: logging.Logger):
Expand Down
45 changes: 21 additions & 24 deletions streams/find_lms_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*
*/

/* from https://github.com/ralph-irving/squeezelite/blob/master/tools/find_servers.c */
#include <assert.h>
#include <ctype.h>
#include <signal.h>
Expand Down Expand Up @@ -60,7 +61,7 @@
#define packC(ptr, off, v) \
{ ptr[off] = v & 0xFF; }
#define packA4(ptr, off, v) \
{ strncpy((char *)(&ptr[off]), v, 4); }
{ strncpy((char*)(&ptr[off]), v, 4); }

#define unpackN4(ptr, off) \
((ptr[off] << 24) | (ptr[off + 1] << 16) | (ptr[off + 2] << 8) | ptr[off + 3])
Expand All @@ -74,18 +75,18 @@
#define DISCOVERY_PKTSIZE 1516
#define SLIMPROTO_DISCOVERY "eNAME\0JSON\0"

int slimproto_discover(char *server_addr, int server_addr_len, int port,
unsigned int *jsonport, bool scan) {
int slimproto_discover(char* server_addr, int server_addr_len, int port, unsigned int* jsonport,
bool scan) {
int sockfd;
int try;
char *packet;
char* packet;
int pktlen;
int pktidx;
char *t;
char* t;
unsigned int l;
char *v;
char *server_name;
char *server_json;
char* v;
char* server_name;
char* server_json;
struct pollfd pollfd;
struct sockaddr_in sendaddr;
struct sockaddr_in recvaddr;
Expand Down Expand Up @@ -117,8 +118,8 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port,
pollfd.fd = sockfd;
pollfd.events = POLLIN;

if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const void *)&broadcast,
sizeof broadcast)) == -1) {
if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const void*)&broadcast, sizeof broadcast)) ==
-1) {
perror("setsockopt - SO_BROADCAST");
return -1;
}
Expand All @@ -128,7 +129,7 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port,
sendaddr.sin_addr.s_addr = INADDR_ANY;
memset(sendaddr.sin_zero, '\0', sizeof sendaddr.sin_zero);

if (bind(sockfd, (struct sockaddr *)&sendaddr, sizeof sendaddr) == -1) {
if (bind(sockfd, (struct sockaddr*)&sendaddr, sizeof sendaddr) == -1) {
perror("bind");
return -1;
}
Expand All @@ -152,7 +153,7 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port,

for (try = 0; try < 5; try++) {
if (sendto(sockfd, SLIMPROTO_DISCOVERY, sizeof(SLIMPROTO_DISCOVERY), 0,
(struct sockaddr *)&recvaddr, sizeof(recvaddr)) == -1) {
(struct sockaddr*)&recvaddr, sizeof(recvaddr)) == -1) {
CLOSESOCKET(sockfd);
perror("sendto");
return -1;
Expand All @@ -165,7 +166,7 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port,
memset(packet, 0, sizeof(packet));

pktlen = recvfrom(sockfd, packet, DISCOVERY_PKTSIZE, MSG_DONTWAIT,
(struct sockaddr *)&sendaddr, &sockaddr_len);
(struct sockaddr*)&sendaddr, &sockaddr_len);

if (pktlen == -1)
continue;
Expand Down Expand Up @@ -198,17 +199,14 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port,
server_json[l] = '\0';
}

VDEBUGF("slimproto_discover: key: %s len: %d value: %s pktidx: %d\n", t,
l, v, pktidx);
VDEBUGF("slimproto_discover: key: %s len: %d value: %s pktidx: %d\n", t, l, v, pktidx);
}

inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr, server_addr,
server_addr_len);
inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr, server_addr, server_addr_len);

*jsonport = (unsigned int)strtoul(server_json, NULL, 10);

DEBUGF("slimproto_discover: discovered %s:%u (%s)\n", server_name,
*jsonport, server_addr);
DEBUGF("slimproto_discover: discovered %s:%u (%s)\n", server_name, *jsonport, server_addr);

serveraddr_len = strlen(server_addr);

Expand Down Expand Up @@ -271,7 +269,7 @@ static void license(void) {
"https://github.com/ralph-irving/squeezelite\n");
}

int main(int argc, char **argv) {
int main(int argc, char** argv) {
char slimserver_address[256] = "127.0.0.1";
int port = 3483;
unsigned int json;
Expand All @@ -283,11 +281,10 @@ int main(int argc, char **argv) {
}

/* Scan */
len = slimproto_discover(slimserver_address, sizeof(slimserver_address), port,
&json, true);
len = slimproto_discover(slimserver_address, sizeof(slimserver_address), port, &json, true);

VDEBUGF("main: slimproto_discover_scan: address:%s len:%d json:%u\n",
slimserver_address, len, json);
VDEBUGF("main: slimproto_discover_scan: address:%s len:%d json:%u\n", slimserver_address, len,
json);

return 0;
}
7 changes: 5 additions & 2 deletions streams/lms_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def save_file(self, folder):


class LMSMetadataReader:
"""A class for getting metadata from a Logitech Media Server."""
"""A class for getting metadata from a Lyrion Music Server."""

# meta_ref is probably an unneccessary variable to pass as an arg since it's obscured from the user, but we can eventually make it an optional setting for the user
def __init__(self, name: str, vsrc: int, server: Optional[str] = None, port: Optional[int] = 9000, meta_ref: Optional[int] = 2):
Expand Down Expand Up @@ -167,15 +167,18 @@ def connect(self):
find_lms_server = "bin/x64/find_lms_server"
elif machine == "armv7l":
find_lms_server = "bin/arm/find_lms_server"
elif machine == "aarch64":
find_lms_server = "bin/arm64/find_lms_server"
else:
self.meta.artist = "Unsupported CPU architecture for LMS MetaData"
self.meta.album = "Please set 'server' in LMS config to an IP"
self.meta.track = "or contact AmpliPi Support:support@micro-nova.com"
self.logger.warning("LMS metadata reader has detected an unsupported chipset")
self.logger.warning("Aborting LMS metadata search")
break
find_lms_server = "bin/arm64/find_lms_server"

# Much faster method of connecting to the metadata server using code from: https://github.com/ralph-irving/squeezelite/blob/master/tools/find_server.c
# Much faster method of connecting to the metadata server using code from: https://github.com/ralph-irving/squeezelite/blob/master/tools/find_servers.c
# faster relative to the original method, using NMAP to go door to door (ip to ip) and ask if self.name is home
ip_find = subprocess.run([find_lms_server], check=True, capture_output=True, text=True)
ip_output = ip_find.stdout.splitlines()
Expand Down
Loading