From 596f1152b489b4f3a8b8558820aaffbd7380facd Mon Sep 17 00:00:00 2001 From: RalfAlbers <44479345+RalfAlbers@users.noreply.github.com> Date: Mon, 25 May 2020 20:12:29 +0200 Subject: [PATCH 001/106] Update buster-install-default-with-autohotspot.sh (#976) Fix request an answer when installing via apt-get autohotspot packages --- .../installscripts/buster-install-default-with-autohotspot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/installscripts/buster-install-default-with-autohotspot.sh b/scripts/installscripts/buster-install-default-with-autohotspot.sh index d1b28584f..ce5f4c894 100755 --- a/scripts/installscripts/buster-install-default-with-autohotspot.sh +++ b/scripts/installscripts/buster-install-default-with-autohotspot.sh @@ -1041,7 +1041,7 @@ autohotspot() { # adapted from https://www.raspberryconnect.com/projects/65-raspberrypi-hotspot-accesspoints/158-raspberry-pi-auto-wifi-hotspot-switch-direct-connection # required packages - sudo apt-get install dnsmasq hostapd + ${apt_get} install dnsmasq hostapd sudo systemctl unmask hostapd sudo systemctl disable hostapd sudo systemctl disable dnsmasq From afa3990dd2cb9178f30c32f12735c609ad40fcd9 Mon Sep 17 00:00:00 2001 From: RalfAlbers <44479345+RalfAlbers@users.noreply.github.com> Date: Tue, 26 May 2020 12:38:28 +0200 Subject: [PATCH 002/106] Update Reader.py.experimental (#977) * Update Reader.py.experimental If you run bash /home/pi/RPi-Jukebox-RFID/components/rfid-reader/RC522/setup_rc522.sh the the import of Lib pirc522 will fail and you can not register the RFID Reader RC522 * Added comment for workaround Co-authored-by: s-martin --- scripts/Reader.py.experimental | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/Reader.py.experimental b/scripts/Reader.py.experimental index c6fcc151c..1db4af167 100755 --- a/scripts/Reader.py.experimental +++ b/scripts/Reader.py.experimental @@ -13,9 +13,13 @@ import RPi.GPIO as GPIO import logging from evdev import InputDevice, categorize, ecodes, list_devices -import pirc522 -from py532lib.i2c import * -from py532lib.mifare import * +# Workaround: when using RC522 reader with pirc522 pkg the py532lib pkg may not be installed and vice-versa +try: + import pirc522 + from py532lib.i2c import * + from py532lib.mifare import * +except ImportError: + pass logger = logging.getLogger(__name__) From b0bde25aa2e5bb05b3abe0b77aeefb7868b37605 Mon Sep 17 00:00:00 2001 From: s-martin Date: Tue, 26 May 2020 21:36:29 +0200 Subject: [PATCH 003/106] * fixed indentation * fixed formatting --- components/displays/HD44780-i2c/i2c_lcd.py | 582 +++++++++--------- components/gpio_control/gpio_control.py | 2 +- .../installscripts/buster-install-default.sh | 12 +- 3 files changed, 303 insertions(+), 293 deletions(-) diff --git a/components/displays/HD44780-i2c/i2c_lcd.py b/components/displays/HD44780-i2c/i2c_lcd.py index 95231e46a..b764542ec 100755 --- a/components/displays/HD44780-i2c/i2c_lcd.py +++ b/components/displays/HD44780-i2c/i2c_lcd.py @@ -1,28 +1,28 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 # -*- coding: utf-8 -*- import i2c_lcd_driver from time import * import time import subprocess import numpy -#import datetime +# import datetime from mpd import MPDClient -### constants +# constants mylcd = i2c_lcd_driver.lcd() -info_at_lines_play = [" "]*4 -info_at_lines_pause = [" "]*4 -info_at_lines_stop = [" "]*4 -info_at_lines_mpd_not_running = [" "]*4 +info_at_lines_play = [" "] * 4 +info_at_lines_pause = [" "] * 4 +info_at_lines_stop = [" "] * 4 +info_at_lines_mpd_not_running = [" "] * 4 ################# CHANGE YOUR SETTINGS HERE!!! ########################################### ## Display settings ## n_cols = 20 # EDIT!!! <-- number of cols your display has ## n_rows = 4 # EDIT!!! <-- number of rows your display has ## val_delay = 0.4 # EDIT!!! <-- speed of the scolling text ## -start_stop_sc_delay=4 ## -use_state_icons="yes" #choose "yes" if you want to use this ## -blinking_icons="no" #its an add-on for "use_state_icons", so "use_state_icons" must be "yes" ## -backlight_off_while_waiting="yes" #not active in state "play" and "pause" ## -backlight_off_delay= 10 # Delay in seconds ## +start_stop_sc_delay = 4 ## +use_state_icons = "yes" # choose "yes" if you want to use this ## +blinking_icons = "no" # its an add-on for "use_state_icons", so "use_state_icons" must be "yes" ## +backlight_off_while_waiting = "yes" # not active in state "play" and "pause" ## +backlight_off_delay = 10 # Delay in seconds ## #### change the following strings to give your box a personal style ## mpd_not_running_string = "MPD not running" ## music_stopped_string = "Music stopped!" ## @@ -39,31 +39,31 @@ ## ## ## Choose infos while state is "play" ## ## ## -info_at_lines_play [0] = 'date_and_time' # <-- Choose your favorite ## -info_at_lines_play [1] = 'artist' # <-- Choose your favorite ## -info_at_lines_play [2] = 'title' # <-- Choose your favorite ## -info_at_lines_play [3] = 'track_time_and_number' # <-- Choose your favorite ## +info_at_lines_play[0] = 'date_and_time' # <-- Choose your favorite ## +info_at_lines_play[1] = 'artist' # <-- Choose your favorite ## +info_at_lines_play[2] = 'title' # <-- Choose your favorite ## +info_at_lines_play[3] = 'track_time_and_number' # <-- Choose your favorite ## ## ## ## Choose infos while state is "pause" ## ## ## -info_at_lines_pause [0] = 'date_and_time' # <-- Choose your favorite ## -info_at_lines_pause [1] = 'artist' # <-- Choose your favorite ## -info_at_lines_pause [2] = 'title' # <-- Choose your favorite ## -info_at_lines_pause [3] = 'pause_string' # <-- Choose your favorite ## +info_at_lines_pause[0] = 'date_and_time' # <-- Choose your favorite ## +info_at_lines_pause[1] = 'artist' # <-- Choose your favorite ## +info_at_lines_pause[2] = 'title' # <-- Choose your favorite ## +info_at_lines_pause[3] = 'pause_string' # <-- Choose your favorite ## ## ## ## Choose infos while state is "stop" ## ## ## -info_at_lines_stop [0] = 'date_and_time' # <-- Choose your favorite ## -info_at_lines_stop [1] = 'nothing' # <-- Choose your favorite ## -info_at_lines_stop [2] = 'nothing' # <-- Choose your favorite ## -info_at_lines_stop [3] = 'stop_string' # <-- Choose your favorite ## +info_at_lines_stop[0] = 'date_and_time' # <-- Choose your favorite ## +info_at_lines_stop[1] = 'nothing' # <-- Choose your favorite ## +info_at_lines_stop[2] = 'nothing' # <-- Choose your favorite ## +info_at_lines_stop[3] = 'stop_string' # <-- Choose your favorite ## ## ## ## Choose infos while state is "not_running" ## ## ## -info_at_lines_mpd_not_running [0] = 'date_and_time' # <-- Choose your favorite ## -info_at_lines_mpd_not_running [1] = 'nothing' # <-- Choose your favorite ## -info_at_lines_mpd_not_running [2] = 'nothing' # <-- Choose your favorite ## -info_at_lines_mpd_not_running [3] = 'mpd_not_running_string' # <-- Choose your favorite## +info_at_lines_mpd_not_running[0] = 'date_and_time' # <-- Choose your favorite ## +info_at_lines_mpd_not_running[1] = 'nothing' # <-- Choose your favorite ## +info_at_lines_mpd_not_running[2] = 'nothing' # <-- Choose your favorite ## +info_at_lines_mpd_not_running[3] = 'mpd_not_running_string' # <-- Choose your favorite ## ## ## ########################################################################################## @@ -74,7 +74,7 @@ string_date_time = " " track_number = " " title = " " -playlist_length=" " +playlist_length = " " last_title = " " i_counter = 0 state = " " @@ -82,18 +82,18 @@ track_time = " " current_time = time.time() last_time = time.time() -if n_cols >16: # select date_string dependent on how many columns the display has (usually either 16 or 20 rows) - date_string="%d.%m.%Y %H:%M" +if n_cols > 16: # select date_string dependent on how many columns the display has (usually either 16 or 20 rows) + date_string = "%d.%m.%Y %H:%M" else: - date_string = "%d.%m.%y %H:%M" # save two character spaces for displays showing only 16 characters per row + date_string = "%d.%m.%y %H:%M" # save two character spaces for displays showing only 16 characters per row # lines that got to show -lines = [" "*n_cols]*n_rows -last_lines = [" "*n_cols]*n_rows +lines = [" " * n_cols] * n_rows +last_lines = [" " * n_cols] * n_rows # User icons user_icons = [ - [0b10000, # Play + [0b10000, # Play 0b11000, 0b11100, 0b11110, @@ -101,7 +101,7 @@ 0b11000, 0b10000, 0b00000], - [0b00000, # Pause + [0b00000, # Pause 0b11011, 0b11011, 0b11011, @@ -109,7 +109,7 @@ 0b11011, 0b11011, 0b00000], - [0b00000, # Stop + [0b00000, # Stop 0b11111, 0b11111, 0b11111, @@ -117,7 +117,7 @@ 0b11111, 0b00000, 0b00000], - [0b00000, # Offline + [0b00000, # Offline 0b00000, 0b01010, 0b00000, @@ -126,285 +126,303 @@ 0b00000, 0b00000]] -def print_changes (string_new,string_old,row): - for pos in range(len(string_new)): - if string_new[pos] != string_old[pos]: - mylcd.lcd_display_string(string_new[pos], row, pos) +def print_changes(string_new, string_old, row): + for pos in range(len(string_new)): + if string_new[pos] != string_old[pos]: + mylcd.lcd_display_string(string_new[pos], row, pos) + + +def fill_with_spaces(string1, length): + if len(string1) <= length: + return (string1 + " " * (length - len(string1))) + else: + return string1 -def fill_with_spaces(string1,length): - if len(string1) <= length: - return (string1 + " " * (length - len(string1))) - else: - return string1 def loop_string(string1, string2): - my_long_string = string2 - title_max_length = n_cols - len(string1) #max_len is dependent by len (track_number) - position = numpy.clip((i_counter % (len(string2)-(title_max_length-1)+2*start_stop_sc_delay))-start_stop_sc_delay,0,len(string2)-(title_max_length)) - scroll_text = my_long_string[position:(position+title_max_length)] - return (string1+scroll_text) + my_long_string = string2 + title_max_length = n_cols - len(string1) # max_len is dependent by len (track_number) + position = numpy.clip((i_counter % (len(string2) - (title_max_length - 1) + 2 * start_stop_sc_delay)) - start_stop_sc_delay, 0, len(string2) - (title_max_length)) + scroll_text = my_long_string[position:(position + title_max_length)] + return (string1 + scroll_text) + def print_nothing(): - return clearline + return clearline + def print_pause_string(): - return (fill_with_spaces(music_paused_string,n_cols)) + return (fill_with_spaces(music_paused_string, n_cols)) + + def print_stop_string(): - return (fill_with_spaces(music_stopped_string,n_cols)) + return (fill_with_spaces(music_stopped_string, n_cols)) + def print_mpd_not_running_string(): - return (fill_with_spaces(mpd_not_running_string,n_cols)) + return (fill_with_spaces(mpd_not_running_string, n_cols)) + def print_artist(): - if len(artist)<=n_cols: - return fill_with_spaces(artist,n_cols) - else: - return loop_string("", artist) ### SC version + if len(artist) <= n_cols: + return fill_with_spaces(artist, n_cols) + else: + return loop_string("", artist) # SC version + def print_track_title(): - ## Write Track number & Title into the row of the display - string_track_title = track_number + ":" + title - if len(string_track_title)<=n_cols: - return fill_with_spaces(string_track_title,n_cols) - else: - return loop_string(track_number + ":", title) ### SC version + # Write Track number & Title into the row of the display + string_track_title = track_number + ":" + title + if len(string_track_title) <= n_cols: + return fill_with_spaces(string_track_title, n_cols) + else: + return loop_string(track_number + ":", title) # SC version + + def print_title(): - ## Write Title into the row of the display - if len(title)<=n_cols: - return fill_with_spaces(title,n_cols) - else: - return loop_string("",title) ### SC version + # Write Title into the row of the display + if len(title) <= n_cols: + return fill_with_spaces(title, n_cols) + else: + return loop_string("", title) # SC version + def print_track_artist_title(): - string_track_artist_title = track_number + ":" + artist + " - "+ title - if len(string_track_artist_title)<=n_cols: - return fill_with_spaces(string_track_artist_title,n_cols) - else: - return loop_string(track_number+":", artist + " - " + title) ### SC version + string_track_artist_title = track_number + ":" + artist + " - " + title + if len(string_track_artist_title) <= n_cols: + return fill_with_spaces(string_track_artist_title, n_cols) + else: + return loop_string(track_number + ":", artist + " - " + title) # SC version + + def print_artist_title(): - string_artist_title = artist + " - "+ title - if len(string_artist_title)<=n_cols: - return fill_with_spaces(string_artist_title,n_cols) - else: - return loop_string("", artist + " - " + title) ### SC version + string_artist_title = artist + " - " + title + if len(string_artist_title) <= n_cols: + return fill_with_spaces(string_artist_title, n_cols) + else: + return loop_string("", artist + " - " + title) # SC version + + def print_track_time(): - return fill_with_spaces(track_time,n_cols) + return fill_with_spaces(track_time, n_cols) + def print_track_time_and_number(): - song_of_playlist = track_number + "/" + playlist_length - return (fill_with_spaces(track_time,n_cols))[:(n_cols-len(song_of_playlist))] + song_of_playlist + song_of_playlist = track_number + "/" + playlist_length + return (fill_with_spaces(track_time, n_cols))[:(n_cols - len(song_of_playlist))] + song_of_playlist + def print_date_time(): - return fill_with_spaces(time.strftime(date_string),n_cols) + return fill_with_spaces(time.strftime(date_string), n_cols) + def choose_line(info_text): - switcher = { - 'pause_string': print_pause_string(), - 'stop_string': print_stop_string(), - 'mpd_not_running_string': print_mpd_not_running_string(), - 'track_title': print_track_title(), - 'track_artist_title': print_track_artist_title(), - 'artist_title': print_artist_title(), - 'artist': print_artist(), - 'title': print_title(), - 'date_and_time': print_date_time(), - 'nothing': print_nothing(), - 'track_time': print_track_time(), - 'track_time_and_number': print_track_time_and_number() - } - return switcher.get(info_text, fill_with_spaces("ERROR",n_cols)) + switcher = { + 'pause_string': print_pause_string(), + 'stop_string': print_stop_string(), + 'mpd_not_running_string': print_mpd_not_running_string(), + 'track_title': print_track_title(), + 'track_artist_title': print_track_artist_title(), + 'artist_title': print_artist_title(), + 'artist': print_artist(), + 'title': print_title(), + 'date_and_time': print_date_time(), + 'nothing': print_nothing(), + 'track_time': print_track_time(), + 'track_time_and_number': print_track_time_and_number() + } + return switcher.get(info_text, fill_with_spaces("ERROR", n_cols)) + def choose_icon(state): - switcher = { - 'play': "\x00", - 'pause': "\x01", - 'stop': "\x02", - 'not_running': "\x03", - } - return switcher.get(state, " ") + switcher = { + 'play': "\x00", + 'pause': "\x01", + 'stop': "\x02", + 'not_running': "\x03", + } + return switcher.get(state, " ") + def sec_to_min_and_sec(seconds): - return (str('%d'%(int(seconds) / 60))+":"+str('%0.2d'%(int(seconds) % 60))) + return (str('%d' % (int(seconds) / 60)) + ":" + str('%0.2d' % (int(seconds) % 60))) + ######### BEGIN OF CODE ################################ ## init mpd-client try: - client = MPDClient() - client.timeout=0.3 - client.connect("localhost", 6600) # -except Exception: # if reconnect isn't possible, client is not running # - print("mpd not avalible") -if use_state_icons=="yes": - mylcd.lcd_load_custom_chars(user_icons) + client = MPDClient() + client.timeout = 0.3 + client.connect("localhost", 6600) # +except Exception: # if reconnect isn't possible, client is not running # + print("mpd not avalible") +if use_state_icons == "yes": + mylcd.lcd_load_custom_chars(user_icons) try: - while True: - ##################### RESET ALL VALUES ########################################## - mpd_info = " " # - track_number = "0" # - title = " " # - album = " " # - artist = " " # - track_time = "0.0/0.0" # - ################################################################################# - - ########################## GET STATE ############################################ - try: # - client.ping() # test if client is up # - status=client.status() # - state=status['state'] # - current_song_infos=client.currentsong() # - except Exception: # - try: # if client is not connected, try to reconnect # - client = MPDClient() # - client.timeout=0.3 # - client.connect("localhost", 6600) # - status=client.status() # - state=status['state'] # - current_song_infos=client.currentsong() # - except Exception: # if reconnect isn't possible, client is not running # - state="not_running" # - # it is running, get more details # - ################################################################################# - ########### RESTART COUNTER, IF STATE CHANGED#################################### - # - if last_state != state: # if state changed, the scrolltext starts at position 0 # - i_counter = 0 # - mylcd.backlight (1) - ################################################################################# - - ########### GET INFOS, IF STATE IS "NOT_RUNNING" ################################ - if state == "not_running": # - for row in range(n_rows): # - lines[row] = choose_line(info_at_lines_mpd_not_running [row]) # - ################################################################################# - - ########### GET INFOS, IF STATE IS "STOP" ####################################### - elif state == "stop": # - for row in range(n_rows): # - lines[row] = choose_line(info_at_lines_stop [row]) # - ################################################################################# - - - else: - ########## GET MORE SONG-INFOS #################################################### - # This section reads in certain album informations # - # # - ## read in track number # - try: # - track_number = current_song_infos['track'] # - except KeyError: # - track_number = "1" # - ## read in playlistlength # - try: # - playlist_length = status['playlistlength'] # - except KeyError: # - playlist_length = "1" # - ## read in track title # - try: # - title = current_song_infos['title'] # - title = title.replace("\n", "").replace("ä", "\341").replace("ö", "\357").replace("ü", "\365").replace("ß", "\342").replace("Ä", "\341").replace("Ö", "\357").replace("Ü", "\365") # weitere codes siehe https://www.mikrocontroller.net/topic/293125 # - except KeyError: # - title = "" # - ## read in album title # - try: # - album = current_song_infos['album'] # - album = album.replace("\n", "").replace("ä", "\341").replace("ö", "\357").replace("ü", "\365").replace("ß", "\342").replace("Ä", "\341").replace("Ö", "\357").replace("Ü", "\365") # weitere codes siehe https://www.mikrocontroller.net/topic/293125 # - except KeyError: # - album = "" # - ## read in artist info # - try: # - artist = current_song_infos['artist'] # - artist = artist.replace("\n", "").replace("ä", "\341").replace("ö", "\357").replace("ü", "\365").replace("ß", "\342").replace("Ä", "\341").replace("Ö", "\357").replace("Ü", "\365") # weitere codes siehe https://www.mikrocontroller.net/topic/293125 # - except KeyError: # - artist = "" # - if (client.mpd_version) >= "0.20": - try: # - elapsed=status['elapsed'].split(".")[0] # - duration=status['duration'].split(".")[0] # - track_time = sec_to_min_and_sec(elapsed)+"/"+sec_to_min_and_sec(duration) # - except KeyError: # - track_time = "" # - else: # - track_time = subprocess.check_output('mpc | head -n2 | tail -n1 | sed "s/ \+/ /g" | cut -d" " -f3', shell=True) - track_time = track_time.replace("\n", "") # - ########################################################################################### - - ############# RESET GLOBAL COUNTER, IF TITLE CHANGED ############################ - if last_title != title: # if title changed, the scrolltext starts at position 0 # - i_counter = 0 # - ################################################################################# - - ########### GET INFOS, IF STATE IS "PAUSE" ###################################### - if state == "pause": # - for row in range(n_rows): # - lines[row] = choose_line(info_at_lines_pause [row]) # - ################################################################################# - - ########### GET INFOS, IF STATE IS "PLAY" ####################################### - if state == "play": # - for row in range(n_rows): # - lines[row] = choose_line(info_at_lines_play [row]) # - ################################################################################# - - - ################## EXACT CYCLE TIME ################################################## - current_time=time.time() # - # calculate real sleep-time - if cycle to long, use 0.0 # - extra_sleep=(max(val_delay-(current_time-last_time),0.0)) # calculate real sleep # - time.sleep(extra_sleep) # time the display stays as is before re-running the loop # - current_time=time.time() # get current time after sleep # - # print ("Cycle-time:"+str(current_time-last_time)) #only for debugging # - last_time=current_time # save time for next cycle # - ###################################################################################### - - ######################## ADD STATE ICONS ############################################# - ## add blinking state icon in first row # - if use_state_icons=="yes": # - if blinking_icons =="yes": # - if i_counter%2==0: # - icon=choose_icon(state) # - else: # - icon=" " # - else: # - icon=choose_icon(state) # - lines[0]= lines[0][:n_cols-2]+" "+icon # - ###################################################################################### - - ######################## DISPLAY OFF AFTER A WHILE ################################ - if (i_counter*val_delay)>=backlight_off_delay and backlight_off_while_waiting == "yes" and (state != "play" and state != "pause"): - mylcd.backlight (0) - else: - ###################################################################################### - ######################## PRINT ALL CHANGES ON DISPLAY ################################ - for row in range(n_rows): # - print_changes (lines[row],last_lines[row],row+1) # - ###################################################################################### - - - ####################### UPDATE COUNTER ############################################### - i_counter += 1 # - if i_counter >= 65000: # - i_counter = 1000 #<-- not 0, cause the display could be off # - ###################################################################################### - - - ####################### REMIND STUFF FOR NEXT CYCLE ################################# - last_state=state # - last_title=title # - for row in range(n_rows): # - last_lines[row]=lines[row] # - ###################################################################################### + while True: + ##################### RESET ALL VALUES ########################################## + mpd_info = " " # + track_number = "0" # + title = " " # + album = " " # + artist = " " # + track_time = "0.0/0.0" # + ################################################################################# + + ########################## GET STATE ############################################ + try: # + client.ping() # test if client is up # + status = client.status() # + state = status['state'] # + current_song_infos = client.currentsong() # + except Exception: # + try: # if client is not connected, try to reconnect # + client = MPDClient() # + client.timeout = 0.3 # + client.connect("localhost", 6600) # + status = client.status() # + state = status['state'] # + current_song_infos = client.currentsong() # + except Exception: # if reconnect isn't possible, client is not running # + state = "not_running" # + # it is running, get more details # + ################################################################################# + ########### RESTART COUNTER, IF STATE CHANGED#################################### + + if last_state != state: # if state changed, the scrolltext starts at position 0 # + i_counter = 0 # + mylcd.backlight(1) + ################################################################################# + + ########### GET INFOS, IF STATE IS "NOT_RUNNING" ################################ + if state == "not_running": # + for row in range(n_rows): # + lines[row] = choose_line(info_at_lines_mpd_not_running[row]) # + ################################################################################# + + ########### GET INFOS, IF STATE IS "STOP" ####################################### + elif state == "stop": # + for row in range(n_rows): # + lines[row] = choose_line(info_at_lines_stop[row]) # + ################################################################################# + + else: + ########## GET MORE SONG-INFOS #################################################### + # This section reads in certain album informations # + # # + ## read in track number # + try: # + track_number = current_song_infos['track'] # + except KeyError: # + track_number = "1" # + ## read in playlistlength # + try: # + playlist_length = status['playlistlength'] # + except KeyError: # + playlist_length = "1" # + ## read in track title # + try: # + title = current_song_infos['title'] # + title = title.replace("\n", "").replace("ä", "\341").replace("ö", "\357").replace("ü", "\365").replace("ß", "\342").replace("Ä", "\341").replace("Ö", "\357").replace("Ü", "\365") # weitere codes siehe https://www.mikrocontroller.net/topic/293125 # + except KeyError: # + title = "" # + ## read in album title # + try: # + album = current_song_infos['album'] # + album = album.replace("\n", "").replace("ä", "\341").replace("ö", "\357").replace("ü", "\365").replace("ß", "\342").replace("Ä", "\341").replace("Ö", "\357").replace("Ü", "\365") # weitere codes siehe https://www.mikrocontroller.net/topic/293125 # + except KeyError: # + album = "" # + ## read in artist info # + try: # + artist = current_song_infos['artist'] # + artist = artist.replace("\n", "").replace("ä", "\341").replace("ö", "\357").replace("ü", "\365").replace("ß", "\342").replace("Ä", "\341").replace("Ö", "\357").replace("Ü", "\365") # weitere codes siehe https://www.mikrocontroller.net/topic/293125 # + except KeyError: # + artist = "" # + if (client.mpd_version) >= "0.20": + try: # + elapsed = status['elapsed'].split(".")[0] # + duration = status['duration'].split(".")[0] # + track_time = sec_to_min_and_sec(elapsed) + "/" + sec_to_min_and_sec(duration) # + except KeyError: # + track_time = "" # + else: # + track_time = subprocess.check_output('mpc | head -n2 | tail -n1 | sed "s/ \+/ /g" | cut -d" " -f3', shell=True) + track_time = track_time.replace("\n", "") # + ########################################################################################### + + ############# RESET GLOBAL COUNTER, IF TITLE CHANGED ############################ + if last_title != title: # if title changed, the scrolltext starts at position 0 # + i_counter = 0 # + ################################################################################# + + ########### GET INFOS, IF STATE IS "PAUSE" ###################################### + if state == "pause": # + for row in range(n_rows): # + lines[row] = choose_line(info_at_lines_pause[row]) # + ################################################################################# + + ########### GET INFOS, IF STATE IS "PLAY" ####################################### + if state == "play": # + for row in range(n_rows): # + lines[row] = choose_line(info_at_lines_play[row]) # + ################################################################################# + + ################## EXACT CYCLE TIME ################################################## + current_time = time.time() # + # calculate real sleep-time - if cycle to long, use 0.0 # + extra_sleep = (max(val_delay - (current_time - last_time), 0.0)) # calculate real sleep # + time.sleep(extra_sleep) # time the display stays as is before re-running the loop # + current_time = time.time() # get current time after sleep # + # print ("Cycle-time:"+str(current_time-last_time)) #only for debugging # + last_time = current_time # save time for next cycle # + ###################################################################################### + + ######################## ADD STATE ICONS ############################################# + ## add blinking state icon in first row # + if use_state_icons == "yes": # + if blinking_icons == "yes": # + if i_counter % 2 == 0: # + icon = choose_icon(state) # + else: # + icon = " " # + else: # + icon = choose_icon(state) # + lines[0] = lines[0][:n_cols - 2] + " " + icon # + ###################################################################################### + + ######################## DISPLAY OFF AFTER A WHILE ################################ + if (i_counter * val_delay) >= backlight_off_delay and backlight_off_while_waiting == "yes" and (state != "play" and state != "pause"): + mylcd.backlight(0) + else: + ###################################################################################### + ######################## PRINT ALL CHANGES ON DISPLAY ################################ + for row in range(n_rows): # + print_changes(lines[row], last_lines[row], row + 1) # + ###################################################################################### + + ####################### UPDATE COUNTER ############################################### + i_counter += 1 # + if i_counter >= 65000: # + i_counter = 1000 # <-- not 0, cause the display could be off # + ###################################################################################### + + ####################### REMIND STUFF FOR NEXT CYCLE ################################# + last_state = state # + last_title = title # + for row in range(n_rows): # + last_lines[row] = lines[row] # + ###################################################################################### except KeyboardInterrupt: - lines[0]=print_date_time() - lines[1]=print_nothing() - if n_rows >= 3: - lines[2]=print_nothing() - if n_rows >= 4: - lines[3]=print_nothing() - for row in range(n_rows): - print_changes (lines[row],last_lines[row],row+1) - client.close() # send the close command - client.disconnect() # disconnect from the server + lines[0] = print_date_time() + lines[1] = print_nothing() + if n_rows >= 3: + lines[2] = print_nothing() + if n_rows >= 4: + lines[3] = print_nothing() + for row in range(n_rows): + print_changes(lines[row], last_lines[row], row + 1) + client.close() # send the close command + client.disconnect() # disconnect from the server diff --git a/components/gpio_control/gpio_control.py b/components/gpio_control/gpio_control.py index 837afb95a..c3e051542 100755 --- a/components/gpio_control/gpio_control.py +++ b/components/gpio_control/gpio_control.py @@ -1,4 +1,4 @@ -#! /usr/bin/python3 +#!/usr/bin/env python3 import configparser import os import logging diff --git a/scripts/installscripts/buster-install-default.sh b/scripts/installscripts/buster-install-default.sh index 72e94ca31..d8720cee6 100755 --- a/scripts/installscripts/buster-install-default.sh +++ b/scripts/installscripts/buster-install-default.sh @@ -726,14 +726,6 @@ install_main() { sudo python3 -m pip install -q -r "${jukebox_dir}"/requirements-spotify.txt fi - local raw_github="https://raw.githubusercontent.com/MiczFlor/RPi-Jukebox-RFID" - # I comment the following lines out for now. I think they come from splitti when he applied a hotfix in Feb 2020? - # Back then the master install script needed develop branch files. I think this is from that time...? - #sudo rm "${jukebox_dir}"/misc/sampleconfigs/phoniebox-rfid-reader.service.stretch-default.sample - #wget -P "${jukebox_dir}"/misc/sampleconfigs/ "${raw_github}"/develop/misc/sampleconfigs/phoniebox-rfid-reader.service.stretch-default.sample - #sudo rm "${jukebox_dir}"/scripts/RegisterDevice.py - #wget -P "${jukebox_dir}"/scripts/ "${raw_github}"/develop/scripts/RegisterDevice.py - # Install more required packages echo "Installing additional Python packages..." sudo python3 -m pip install -q -r "${jukebox_dir}"/requirements.txt @@ -755,11 +747,11 @@ install_main() { echo "RESTART" > "${jukebox_dir}"/settings/Second_Swipe echo "${jukebox_dir}/playlists" > "${jukebox_dir}"/settings/Playlists_Folders_Path echo "ON" > "${jukebox_dir}"/settings/ShowCover - + # sample file for debugging with all options set to FALSE sudo cp "${jukebox_dir}"/settings/debugLogging.conf.sample "${jukebox_dir}"/settings/debugLogging.conf sudo chmod 777 "${jukebox_dir}"/settings/debugLogging.conf - + # The new way of making the bash daemon is using the helperscripts # creating the shortcuts and script from a CSV file. # see scripts/helperscripts/AssignIDs4Shortcuts.php From 873038fe02f8fe9c0d18c02d4bb0aea15b79e93a Mon Sep 17 00:00:00 2001 From: s-martin Date: Tue, 26 May 2020 22:43:38 +0200 Subject: [PATCH 004/106] Fix bug in csv import --- htdocs/cardRegisterNew.php | 78 +++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/htdocs/cardRegisterNew.php b/htdocs/cardRegisterNew.php index e7397e7f7..56aefd626 100755 --- a/htdocs/cardRegisterNew.php +++ b/htdocs/cardRegisterNew.php @@ -23,7 +23,7 @@ ?>
- + "; - print $conf['upload_abs']; + print "
";
+        print $conf['upload_abs'];
         print "\n";
-        print $uploadFileType; 
+        print $uploadFileType;
         print "\n";
         print "
"; } // check if csv if($uploadFileType == "csv") { - if(move_uploaded_file($_FILES['importFileUpload']['tmp_name'], $conf['upload_abs'] . "/rfidImport.csv")) { + if(move_uploaded_file($_FILES['importFileUpload']['tmp_name'], $conf['upload_abs'] . "./rfidImport.csv")) { $messageSuccess .= "

" . $lang['cardImportFileSuccessUpload'] . basename( $_FILES['importFileUpload']['name']). "

"; /* * read RFID into array */ $rfidPostedAudio = array(); $rfidPostedCommands = array(); - $fn = fopen($conf['upload_abs'] . "/rfidImport.csv","r"); + $fn = fopen($conf['upload_abs'] . "./rfidImport.csv","r"); while(! feof($fn)) { $pair = explode("\",\"", fgets($fn)); // ignore header and empty lines @@ -83,10 +83,10 @@ } fclose($fn); if($debug == "true") { - print "
rfidPostedCommands: \n"; 
+                print "
rfidPostedCommands: \n";
                 print_r($rfidPostedCommands);
                 print "\nrfidPostedAudio: \n";
-                print_r($rfidPostedAudio); 
+                print_r($rfidPostedAudio);
                 print "\nshortcuts: \n";
                 print_r($shortcuts);
                 print "
"; @@ -97,11 +97,11 @@ */ if($_POST['importFileDelete'] == "all" || $_POST['importFileDelete'] == "commands") { // delete commands => create array of available commands with not array of used commands - $fillRfidArrAvailWithUsed = fillRfidArrAvailWithUsed($rfidAvailArr); + $fillRfidArrAvailWithUsed = fillRfidArrAvailWithUsed($rfidAvailArr); if($debug == "true") { print "
delete commands - fillRfidArrAvailWithUsed:\n"; print_r($fillRfidArrAvailWithUsed); print "
"; } - $messageSuccess .= $lang['cardImportFileDeleteMessageCommands']; + $messageSuccess .= $lang['cardImportFileDeleteMessageCommands']; } else { // keep commands if($debug == "true") { @@ -119,9 +119,9 @@ $result = exec($exec); } } - $messageSuccess .= $lang['cardImportFileDeleteMessageAudio']; + $messageSuccess .= $lang['cardImportFileDeleteMessageAudio']; } - + // which files to replace? if($_POST['importFileOverwrite'] != "audio") { // create commands @@ -132,7 +132,7 @@ } $fillRfidArrAvailWithUsed[trim($value, '%')] = $key; } - + /****************************************** * Create new conf file based on posted values */ @@ -145,7 +145,7 @@ exec("sed -i 's/%".$key."%/".$val."/' '../settings/rfid_trigger_play.conf'"); } } - $messageSuccess .= $lang['cardImportFileOverwriteMessageCommands']; + $messageSuccess .= $lang['cardImportFileOverwriteMessageCommands']; } if($_POST['importFileOverwrite'] != "commands") { // create audio files @@ -154,14 +154,14 @@ exec($exec); } exec("chmod 777 ../shared/shortcuts/*"); - $messageSuccess .= $lang['cardImportFileOverwriteMessageAudio']; + $messageSuccess .= $lang['cardImportFileOverwriteMessageAudio']; } } else{ $messageError .= $lang['cardImportFileErrorUpload']; } } else { $messageError .= $lang['cardImportFileErrorFiletype']; - } + } } else { if($debug == "true") { print "no file upload"; @@ -181,7 +181,7 @@ | - +

@@ -202,7 +202,7 @@ */ if ($messageAction == "" && $messageError == "") { $messageAction = $lang['cardRegisterMessageDefault'].$lang['cardRegisterManualLinks']; -} +} if(isset($messageSuccess) && $messageSuccess != "") { print '
'.$messageSuccess.'

'.$lang['cardRegisterMessageSwipeNew'].'

'; unset($post); @@ -253,8 +253,8 @@ - - + +
@@ -275,7 +275,7 @@
- +
@@ -287,21 +287,21 @@
-
+
'> -
+
- +
- +
-
- +
+
@@ -311,10 +311,10 @@ - -
-
- + +
+
+
@@ -325,11 +325,11 @@ - -
+ +
- - + +
@@ -338,15 +338,15 @@

- + - - + + + From b457bf94a4d899f010335912100d5e161c2d6475 Mon Sep 17 00:00:00 2001 From: Micz Flor Date: Wed, 27 May 2020 15:04:10 +0200 Subject: [PATCH 005/106] change owner when creating settings files #980 --- .../installscripts/buster-install-default.sh | 73 +++++++++++++++++-- scripts/playout_controls.sh | 1 + scripts/rfid_trigger_play.sh | 1 + 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/scripts/installscripts/buster-install-default.sh b/scripts/installscripts/buster-install-default.sh index 72e94ca31..a3ab8f637 100755 --- a/scripts/installscripts/buster-install-default.sh +++ b/scripts/installscripts/buster-install-default.sh @@ -125,10 +125,11 @@ reset_install_config_file() { # from such a config file with no user input. # Remove existing config file - rm "${HOME_DIR}/PhonieboxInstall.conf" + #rm "${HOME_DIR}/PhonieboxInstall.conf" # Create empty config file - touch "${HOME_DIR}/PhonieboxInstall.conf" - echo "# Phoniebox config" > "${HOME_DIR}/PhonieboxInstall.conf" + #touch "${HOME_DIR}/PhonieboxInstall.conf" + #echo "# Phoniebox config" > "${HOME_DIR}/PhonieboxInstall.conf" + echo "# Phoniebox config" } config_wifi() { @@ -202,6 +203,7 @@ read -rp "Hit ENTER to proceed to the next step." INPUT check_existing() { local jukebox_dir="$1" local backup_dir="$2" + local home_dir="$3" ##################################################### # Check for existing Phoniebox @@ -230,10 +232,44 @@ check_existing() { # get the current short commit hash of the repo CURRENT_REMOTE_COMMIT="$(git ls-remote https://github.com/MiczFlor/RPi-Jukebox-RFID.git ${GIT_BRANCH} | cut -c1-7)" fi - echo "IMPORTANT: you can use the existing content and configuration files for your new install." + echo "IMPORTANT: you can use the existing content and configuration" + echo "files for your new install." echo "Whatever you chose to keep will be moved to the new install." echo "Everything else will remain in a folder called 'BACKUP'. " + + ### + # See if we find the PhonieboxInstall.conf file + # We need to do this first, because if we re-use the .conf file, we need to append + # the variables regarding the found content to the also found configuration file. + # That way, reading the configuration file for the (potentially) non-interactive + # install procedure will: + # a) overwrite whatever variables regarding re-cycling existing content which might + # be stored in the config file + # b) if there are no variables for dealing with re-cycled context, we will append + # them - to have them for this install + if [ -f "${jukebox_dir}"/settings/PhonieboxInstall.conf ]; then + # ask for re-using the found configuration file + echo "The configuration of your last Phoniebox install was found." + read -rp "Use existing configuration for this installation? [Y/n] " response + case "$response" in + [nN][oO]|[nN]) + EXISTINGusePhonieboxInstall=NO + ;; + *) + EXISTINGusePhonieboxInstall=YES + # Copy PhonieboxInstall.conf configuration file to settings folder + sudo cp "${jukebox_dir}"/settings/PhonieboxInstall.conf "${home_dir}"/PhonieboxInstall.conf + sudo chown pi:www-data "${home_dir}"/PhonieboxInstall.conf + sudo chmod 775 "${home_dir}"/PhonieboxInstall.conf + echo "The existing configuration will be used." + echo "Just a few more questions to answer." + read -rp "Hit ENTER to proceed to the next step." INPUT + clear + ;; + esac + fi + # Delete or use existing installation? read -rp "Re-use config, audio and RFID codes for the new install? [Y/n] " response case "$response" in @@ -331,6 +367,25 @@ check_existing() { fi # append variables to config file echo "EXISTINGuse=$EXISTINGuse" >> "${HOME_DIR}/PhonieboxInstall.conf" + + # Check if we found a Phoniebox install configuration earlier and ask if to run this now + if [ "${EXISTINGusePhonieboxInstall}" == "YES" ]; then + clear + echo "Using the existing configuration, you can run a non-interactive install." + echo "This will re-cycle found content (specified just now) as well as the" + echo "system information from last time (wifi, audio interface, spotify, etc.)." + read -rp "Do you want to run a non-interactive installation? [Y/n] " response + case "$response" in + [nN][oO]|[nN]) + ;; + *) + cd "${home_dir}" + clear + ./buster-install-default.sh -a + exit + ;; + esac + fi } config_audio_interface() { @@ -1089,9 +1144,9 @@ finish_installation() { main() { if [[ ${INTERACTIVE} == "true" ]]; then welcome - reset_install_config_file + #reset_install_config_file config_wifi - check_existing "${JUKEBOX_HOME_DIR}" "${JUKEBOX_BACKUP_DIR}" + check_existing "${JUKEBOX_HOME_DIR}" "${JUKEBOX_BACKUP_DIR}" "${HOME_DIR}" config_audio_interface config_spotify config_mpd @@ -1106,6 +1161,12 @@ main() { wifi_settings "${JUKEBOX_HOME_DIR}/misc/sampleconfigs" "/etc/dhcpcd.conf" "/etc/wpa_supplicant/wpa_supplicant.conf" existing_assets "${JUKEBOX_HOME_DIR}" "${JUKEBOX_BACKUP_DIR}" folder_access "${JUKEBOX_HOME_DIR}" "pi:www-data" 775 + + # Copy PhonieboxInstall.conf configuration file to settings folder + sudo cp "${HOME_DIR}/PhonieboxInstall.conf" "${JUKEBOX_HOME_DIR}/settings/" + sudo chown pi:www-data "${JUKEBOX_HOME_DIR}/settings/PhonieboxInstall.conf" + sudo chmod 775 "${JUKEBOX_HOME_DIR}/settings/PhonieboxInstall.conf" + if [[ ${INTERACTIVE} == "true" ]]; then finish_installation "${JUKEBOX_HOME_DIR}" else diff --git a/scripts/playout_controls.sh b/scripts/playout_controls.sh index 3f1964eaf..6252a2655 100755 --- a/scripts/playout_controls.sh +++ b/scripts/playout_controls.sh @@ -570,6 +570,7 @@ case $COMMAND in # write latest folder played to settings file sudo echo ${FOLDER} > ${PATHDATA}/../settings/Latest_Folder_Played + sudo chown pi:www-data ${PATHDATA}/../settings/Latest_Folder_Played sudo chmod 777 ${PATHDATA}/../settings/Latest_Folder_Played if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " echo ${FOLDER} > ${PATHDATA}/../settings/Latest_Folder_Played" >> ${PATHDATA}/../logs/debug.log; fi if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " VAR Latest_Folder_Played: ${FOLDER}" >> ${PATHDATA}/../logs/debug.log; fi diff --git a/scripts/rfid_trigger_play.sh b/scripts/rfid_trigger_play.sh index 3b638328e..47eac6d44 100755 --- a/scripts/rfid_trigger_play.sh +++ b/scripts/rfid_trigger_play.sh @@ -466,6 +466,7 @@ if [ ! -z "$FOLDER" -a ! -z ${FOLDER+x} -a -d "${AUDIOFOLDERSPATH}/${FOLDER}" ]; if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Command: $PATHDATA/playout_controls.sh -c=playlistaddplay -v=\"${PLAYLISTNAME}\" -d=\"${FOLDER}\"" >> $PATHDATA/../logs/debug.log; fi # save latest playlist not to file sudo echo ${PLAYLISTNAME} > $PATHDATA/../settings/Latest_Playlist_Played + sudo chown pi:www-data $PATHDATA/../settings/Latest_Playlist_Played sudo chmod 777 $PATHDATA/../settings/Latest_Playlist_Played fi if [ "$PLAYPLAYLIST" == "skipnext" ] From 03e63de6669c49548c9246185f36554f245f7347 Mon Sep 17 00:00:00 2001 From: RalfAlbers <44479345+RalfAlbers@users.noreply.github.com> Date: Sat, 30 May 2020 14:17:40 +0200 Subject: [PATCH 006/106] Update buster-install-default-with-autohotspot.sh (#984) fix missing variable set it local inside function --- .../installscripts/buster-install-default-with-autohotspot.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/installscripts/buster-install-default-with-autohotspot.sh b/scripts/installscripts/buster-install-default-with-autohotspot.sh index ce5f4c894..c4b00b299 100755 --- a/scripts/installscripts/buster-install-default-with-autohotspot.sh +++ b/scripts/installscripts/buster-install-default-with-autohotspot.sh @@ -1037,6 +1037,7 @@ folder_access() { autohotspot() { local jukebox_dir="$1" + local apt_get="sudo apt-get -qq --yes" # adapted from https://www.raspberryconnect.com/projects/65-raspberrypi-hotspot-accesspoints/158-raspberry-pi-auto-wifi-hotspot-switch-direct-connection From 3216927b39e0f70f14009d4debd837798bf09642 Mon Sep 17 00:00:00 2001 From: s-martin Date: Sun, 31 May 2020 16:43:49 +0200 Subject: [PATCH 007/106] Reduce bounce time of buttons --- misc/sampleconfigs/gpio-buttons.py.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/sampleconfigs/gpio-buttons.py.sample b/misc/sampleconfigs/gpio-buttons.py.sample index a37d23b14..9d8deaa04 100644 --- a/misc/sampleconfigs/gpio-buttons.py.sample +++ b/misc/sampleconfigs/gpio-buttons.py.sample @@ -141,7 +141,7 @@ led_power = 12 # Set GPIO numbering to BCM instead of board numbering GPIO.setmode(GPIO.BCM) # Bounce tolerance time for buttons -bouncetime = 500 +bouncetime = 200 # Milliseconds? volumeHoldTime = 0.3 # Seconds shutdownHoldTime = 2 # Seconds PledBlinkTime = 0.3 # Seconds From a0d38fd5dc3bd0b6389e3c9df2af3cc4bf0516a4 Mon Sep 17 00:00:00 2001 From: s-martin Date: Sun, 31 May 2020 20:14:16 +0200 Subject: [PATCH 008/106] Fix permissions for mpd.log --- scripts/installscripts/buster-install-default.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/installscripts/buster-install-default.sh b/scripts/installscripts/buster-install-default.sh index 5a30de8e7..e0dac835a 100755 --- a/scripts/installscripts/buster-install-default.sh +++ b/scripts/installscripts/buster-install-default.sh @@ -893,6 +893,8 @@ install_main() { if [ "${MPDconfig}" == "YES" ]; then local mpd_conf="/etc/mpd.conf" + local mpd_log="/var/log/mpd/mpd.log" + echo "Configuring MPD..." # MPD configuration # -rw-r----- 1 mpd audio 14043 Jul 17 20:16 /etc/mpd.conf @@ -903,6 +905,8 @@ install_main() { sudo sed -i 's|%DIRaudioFolders%|'"$DIRaudioFolders"'|' "${mpd_conf}" sudo chown mpd:audio "${mpd_conf}" sudo chmod 640 "${mpd_conf}" + + sudo chown mpd:audio "${mpd_log}" fi # set which version has been installed From e837971e3d86681ab564138d955ba23fbf784d69 Mon Sep 17 00:00:00 2001 From: s-martin Date: Mon, 1 Jun 2020 15:23:11 +0200 Subject: [PATCH 009/106] Fix warning in usort --- htdocs/inc.viewFolderTree.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/inc.viewFolderTree.php b/htdocs/inc.viewFolderTree.php index 1f1268ea3..30478c09c 100755 --- a/htdocs/inc.viewFolderTree.php +++ b/htdocs/inc.viewFolderTree.php @@ -178,7 +178,7 @@ $temp['count_subdirs'] = count($containingfolders); $temp['count_files'] = count($containingfiles); $temp['count_audioFiles'] = count($containingaudiofiles); - usort($containingfolders); + usort($containingfolders, 'strnatcasecmp'); $temp['subdirs'] = $containingfolders; usort($containingfiles, 'strnatcasecmp'); $temp['files'] = $containingfiles; From c35c4badaf9172bedb45a12903c9323a16bea5ca Mon Sep 17 00:00:00 2001 From: Micz Flor Date: Tue, 2 Jun 2020 11:42:12 +0200 Subject: [PATCH 010/106] change audio iFace default in install script #973 --- .../buster-install-default-with-autohotspot.sh | 16 +++++++--------- scripts/installscripts/buster-install-default.sh | 16 +++++++--------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/scripts/installscripts/buster-install-default-with-autohotspot.sh b/scripts/installscripts/buster-install-default-with-autohotspot.sh index c4b00b299..28fae4b8d 100755 --- a/scripts/installscripts/buster-install-default-with-autohotspot.sh +++ b/scripts/installscripts/buster-install-default-with-autohotspot.sh @@ -343,20 +343,19 @@ config_audio_interface() { # # CONFIGURE AUDIO INTERFACE (iFace) # -# By default for the RPi the audio interface would be 'PCM'. -# But this does not work for every setup, alternatives are -# 'Master' or 'Speaker'. Other external sound cards might -# use different interface names. -# To list all available iFace names, type 'amixer scontrols' -# in the terminal. +# The default RPi audio interface is 'Headphone'. +# But this does not work for every setup. Here a list of +# available iFace names: " - read -rp "Use PCM as iFace? [Y/n] " response + amixer scontrols + echo " " + read -rp "Use Headphone as iFace? [Y/n] " response case "$response" in [nN][oO]|[nN]) read -rp "Type the iFace name you want to use:" AUDIOiFace ;; *) - AUDIOiFace="PCM" + AUDIOiFace="Headphone" ;; esac # append variables to config file @@ -746,7 +745,6 @@ install_main() { cp "${jukebox_dir}"/settings/rfid_trigger_play.conf.sample "${jukebox_dir}"/settings/rfid_trigger_play.conf # creating files containing editable values for configuration - # DISCONTINUED: now done by MPD? echo "PCM" > /home/pi/RPi-Jukebox-RFID/settings/Audio_iFace_Name echo "$AUDIOiFace" > "${jukebox_dir}"/settings/Audio_iFace_Name echo "$DIRaudioFolders" > "${jukebox_dir}"/settings/Audio_Folders_Path echo "3" > "${jukebox_dir}"/settings/Audio_Volume_Change_Step diff --git a/scripts/installscripts/buster-install-default.sh b/scripts/installscripts/buster-install-default.sh index e0dac835a..cf5c79f9e 100755 --- a/scripts/installscripts/buster-install-default.sh +++ b/scripts/installscripts/buster-install-default.sh @@ -398,20 +398,19 @@ config_audio_interface() { # # CONFIGURE AUDIO INTERFACE (iFace) # -# By default for the RPi the audio interface would be 'PCM'. -# But this does not work for every setup, alternatives are -# 'Master' or 'Speaker'. Other external sound cards might -# use different interface names. -# To list all available iFace names, type 'amixer scontrols' -# in the terminal. +# The default RPi audio interface is 'Headphone'. +# But this does not work for every setup. Here a list of +# available iFace names: " - read -rp "Use PCM as iFace? [Y/n] " response + amixer scontrols + echo " " + read -rp "Use Headphone as iFace? [Y/n] " response case "$response" in [nN][oO]|[nN]) read -rp "Type the iFace name you want to use:" AUDIOiFace ;; *) - AUDIOiFace="PCM" + AUDIOiFace="Headphone" ;; esac # append variables to config file @@ -793,7 +792,6 @@ install_main() { cp "${jukebox_dir}"/settings/rfid_trigger_play.conf.sample "${jukebox_dir}"/settings/rfid_trigger_play.conf # creating files containing editable values for configuration - # DISCONTINUED: now done by MPD? echo "PCM" > /home/pi/RPi-Jukebox-RFID/settings/Audio_iFace_Name echo "$AUDIOiFace" > "${jukebox_dir}"/settings/Audio_iFace_Name echo "$DIRaudioFolders" > "${jukebox_dir}"/settings/Audio_Folders_Path echo "3" > "${jukebox_dir}"/settings/Audio_Volume_Change_Step From 3e57328f2898a24e71311e2b51e0d54b3e3ba2d7 Mon Sep 17 00:00:00 2001 From: Micz Flor Date: Tue, 2 Jun 2020 22:50:59 +0200 Subject: [PATCH 011/106] adding mpc rescan to update mpd DB on startup. fresh install does not work with web app otherwise. --- scripts/startup-scripts.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/startup-scripts.sh b/scripts/startup-scripts.sh index 16335718f..9c0dc7bc4 100755 --- a/scripts/startup-scripts.sh +++ b/scripts/startup-scripts.sh @@ -28,6 +28,10 @@ echo ${AUDIOVOLSTARTUP} /bin/sleep 2 /usr/bin/mpg123 /home/pi/RPi-Jukebox-RFID/shared/startupsound.mp3 +####################### +# re-scan music library +mpc rescan + ####################### # read out wifi config? if [ "${READWLANIPYN}" == "ON" ]; then From 6eb6c5d1db880051b5778844ee0984c63ad87e2e Mon Sep 17 00:00:00 2001 From: Micz Flor Date: Tue, 2 Jun 2020 23:10:56 +0200 Subject: [PATCH 012/106] web app adding hover for player list of files and folders --- htdocs/_assets/bootstrap-3/css/bootstrap.darkly.css | 8 +++++++- htdocs/func.php | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/htdocs/_assets/bootstrap-3/css/bootstrap.darkly.css b/htdocs/_assets/bootstrap-3/css/bootstrap.darkly.css index 9a5498d96..8498e966c 100755 --- a/htdocs/_assets/bootstrap-3/css/bootstrap.darkly.css +++ b/htdocs/_assets/bootstrap-3/css/bootstrap.darkly.css @@ -58,7 +58,13 @@ font-weight: 700; src: url("../../fonts/Source_Sans_Pro/SourceSansPro-SemiBoldItalic.ttf"); } - +/* hover effects for list of files and folders on player page */ +.pb-plist-play:hover, +.pb-plist-play:active, +.playlist_headline:hover, +.playlist_headline:active { + color: #E74C3C; +} /*@import url("https://fonts.googleapis.com/css?family=Lato:400,700,400italic");*/ /*! * bootswatch v3.3.7 diff --git a/htdocs/func.php b/htdocs/func.php index 8ed47b886..cd776a288 100755 --- a/htdocs/func.php +++ b/htdocs/func.php @@ -326,11 +326,11 @@ function index_folders_print($item, $key) */ if($contentTree[$key]['count_files'] > 0) { print " - "; + "; } if($contentTree[$key]['count_subdirs'] > 0) { print " - "; + "; } if (!in_array($contentTree[$key]['path_abs']."/livestream.txt", $contentTree[$key]['files']) && !in_array($contentTree[$key]['path_abs']."/spotify.txt", $contentTree[$key]['files']) && !in_array($contentTree[$key]['path_abs']."/podcast.txt", $contentTree[$key]['files']) ) { @@ -339,7 +339,7 @@ function index_folders_print($item, $key) print " "; print $contentTree[$key]['basename']; //print "\n "; - print "\n "; + print "\n "; if($contentTree[$key]['count_subdirs'] > 0) { print " ".$contentTree[$key]['count_subdirs'].""; From cf48eb1a6b881a9b251d435e44db69b52061bb6d Mon Sep 17 00:00:00 2001 From: s-martin Date: Wed, 3 Jun 2020 15:49:42 +0200 Subject: [PATCH 013/106] Improve MPD logging configuration; reverts PR #989 --- .../mpd.conf.buster-default.sample | 4 ++-- .../installscripts/buster-install-default.sh | 17 +++++++---------- .../tests/run_installation_tests.sh | 2 +- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/misc/sampleconfigs/mpd.conf.buster-default.sample b/misc/sampleconfigs/mpd.conf.buster-default.sample index f219492ee..3e228bf01 100755 --- a/misc/sampleconfigs/mpd.conf.buster-default.sample +++ b/misc/sampleconfigs/mpd.conf.buster-default.sample @@ -37,7 +37,7 @@ db_file "/var/lib/mpd/tag_cache" # setting defaults to logging to syslog, or to journal if mpd was started as # a systemd service. # -log_file "/var/log/mpd/mpd.log" +log_file "syslog" # # This setting sets the location of the file which stores the process ID # for use of mpd --kill and some init scripts. This setting is disabled by @@ -98,7 +98,7 @@ bind_to_address "localhost" # argument is recommended for troubleshooting, though can quickly stretch # available resources on limited hardware storage. # -#log_level "default" +log_level "default" # # Setting "restore_paused" to "yes" puts MPD into pause mode instead # of starting playback after startup. diff --git a/scripts/installscripts/buster-install-default.sh b/scripts/installscripts/buster-install-default.sh index cf5c79f9e..6647a148c 100755 --- a/scripts/installscripts/buster-install-default.sh +++ b/scripts/installscripts/buster-install-default.sh @@ -244,9 +244,9 @@ check_existing() { # the variables regarding the found content to the also found configuration file. # That way, reading the configuration file for the (potentially) non-interactive # install procedure will: - # a) overwrite whatever variables regarding re-cycling existing content which might + # a) overwrite whatever variables regarding re-cycling existing content which might # be stored in the config file - # b) if there are no variables for dealing with re-cycled context, we will append + # b) if there are no variables for dealing with re-cycled context, we will append # them - to have them for this install if [ -f "${jukebox_dir}"/settings/PhonieboxInstall.conf ]; then # ask for re-using the found configuration file @@ -367,7 +367,7 @@ check_existing() { fi # append variables to config file echo "EXISTINGuse=$EXISTINGuse" >> "${HOME_DIR}/PhonieboxInstall.conf" - + # Check if we found a Phoniebox install configuration earlier and ask if to run this now if [ "${EXISTINGusePhonieboxInstall}" == "YES" ]; then clear @@ -399,7 +399,7 @@ config_audio_interface() { # CONFIGURE AUDIO INTERFACE (iFace) # # The default RPi audio interface is 'Headphone'. -# But this does not work for every setup. Here a list of +# But this does not work for every setup. Here a list of # available iFace names: " amixer scontrols @@ -891,8 +891,7 @@ install_main() { if [ "${MPDconfig}" == "YES" ]; then local mpd_conf="/etc/mpd.conf" - local mpd_log="/var/log/mpd/mpd.log" - + echo "Configuring MPD..." # MPD configuration # -rw-r----- 1 mpd audio 14043 Jul 17 20:16 /etc/mpd.conf @@ -903,8 +902,6 @@ install_main() { sudo sed -i 's|%DIRaudioFolders%|'"$DIRaudioFolders"'|' "${mpd_conf}" sudo chown mpd:audio "${mpd_conf}" sudo chmod 640 "${mpd_conf}" - - sudo chown mpd:audio "${mpd_log}" fi # set which version has been installed @@ -1155,12 +1152,12 @@ main() { wifi_settings "${JUKEBOX_HOME_DIR}/misc/sampleconfigs" "/etc/dhcpcd.conf" "/etc/wpa_supplicant/wpa_supplicant.conf" existing_assets "${JUKEBOX_HOME_DIR}" "${JUKEBOX_BACKUP_DIR}" folder_access "${JUKEBOX_HOME_DIR}" "pi:www-data" 775 - + # Copy PhonieboxInstall.conf configuration file to settings folder sudo cp "${HOME_DIR}/PhonieboxInstall.conf" "${JUKEBOX_HOME_DIR}/settings/" sudo chown pi:www-data "${JUKEBOX_HOME_DIR}/settings/PhonieboxInstall.conf" sudo chmod 775 "${JUKEBOX_HOME_DIR}/settings/PhonieboxInstall.conf" - + if [[ ${INTERACTIVE} == "true" ]]; then finish_installation "${JUKEBOX_HOME_DIR}" else diff --git a/scripts/installscripts/tests/run_installation_tests.sh b/scripts/installscripts/tests/run_installation_tests.sh index f4fbbf774..b1f4ddcba 100644 --- a/scripts/installscripts/tests/run_installation_tests.sh +++ b/scripts/installscripts/tests/run_installation_tests.sh @@ -15,7 +15,7 @@ export DEBIAN_FRONTEND=noninteractive # Run installation (in interactive mode) # y confirm interactive # n dont configure wifi -# y PCM as iface +# y Headphone as iface # n no spotify # y configure mpd # y audio default location From 6d52f2741b9e2a4c8daad06500684bce1c07f94c Mon Sep 17 00:00:00 2001 From: s-martin Date: Fri, 5 Jun 2020 21:43:17 +0200 Subject: [PATCH 014/106] Change used type to existing (#997) * Change used type to existing * use of ; for commenting, should fix errors related to in line comments --- .../gpio_control/example_configs/gpio_settings.ini | 8 ++++---- .../gpio_settings_rotary_and_led.ini | 8 ++++---- .../example_configs/gpio_settings_test.ini | 14 +++++++------- .../gpio_control/test/gpio_settings_test.ini | 14 +++++++------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/components/gpio_control/example_configs/gpio_settings.ini b/components/gpio_control/example_configs/gpio_settings.ini index a42926215..065d326db 100644 --- a/components/gpio_control/example_configs/gpio_settings.ini +++ b/components/gpio_control/example_configs/gpio_settings.ini @@ -2,17 +2,17 @@ enabled: True [VolumeControl] enabled: False -Type: RotaryEncoderClickable +Type: RotaryEncoder PinUp: 16 PinDown: 19 pull_up: True hold_time: 0.3 hold_repeat: True -timeBase: 0.1 # only for rotary encoder +timeBase: 0.1 ; only for rotary encoder functionCallDown: functionCallVolD functionCallUp: functionCallVolU -functionCallTwoButtons: functionCallVol0 #only for TwoButtonControl -functionCallButton: functionCallPlayerPause # only for RotaryEncoderClickable +functionCallTwoButtons: functionCallVol0 ;only for TwoButtonControl +functionCallButton: functionCallPlayerPause ; only for RotaryEncoderClickable [PrevNextControl] Type: TwoButtonControl diff --git a/components/gpio_control/example_configs/gpio_settings_rotary_and_led.ini b/components/gpio_control/example_configs/gpio_settings_rotary_and_led.ini index 560ccd914..206fc4b0d 100644 --- a/components/gpio_control/example_configs/gpio_settings_rotary_and_led.ini +++ b/components/gpio_control/example_configs/gpio_settings_rotary_and_led.ini @@ -11,13 +11,13 @@ pull_up: True hold_time: 0.3 hold_repeat: True timeBase: 0.2 -# only for rotary encoder +; only for rotary encoder functionCallDown: functionCallVolD functionCallUp: functionCallVolU functionCallTwoButtons: functionCallStop -#only for TwoButtonControl -functionCallButton: functionCallPlayerPause -# only for RotaryEncoderClickable +; only for TwoButtonControl +functionCallButton: functionCallPlayerPause +; only for RotaryEncoderClickable [PrevNextControl] enabled: True diff --git a/components/gpio_control/example_configs/gpio_settings_test.ini b/components/gpio_control/example_configs/gpio_settings_test.ini index 91659e03a..78b859287 100644 --- a/components/gpio_control/example_configs/gpio_settings_test.ini +++ b/components/gpio_control/example_configs/gpio_settings_test.ini @@ -1,10 +1,10 @@ [DEFAULT] enabled: True -#The following Types exist: -# RotaryEncoder -# TwoButtonControl -# SimpleButton = Button +; The following Types exist: +; RotaryEncoder +; TwoButtonControl +; SimpleButton = Button [VolumeControl] enabled: True Type: RotaryEncoder @@ -14,12 +14,12 @@ pull_up: True hold_time: 0.3 hold_repeat: True timeBase: 0.1 -#timeBase only for rotary encoder +; timeBase only for rotary encoder functionCallDown: functionCallVolD functionCallUp: functionCallVolU functionCallTwoButtons: functionCallVol0 -# functionCallTwoButtons only for TwoButtonControl -#functionCallButton: functionCallPlayerPause ; only for RotaryEncoderClickable +; functionCallTwoButtons only for TwoButtonControl +; functionCallButton: functionCallPlayerPause ; only for RotaryEncoderClickable [PrevNextControl] Type: TwoButtonControl diff --git a/components/gpio_control/test/gpio_settings_test.ini b/components/gpio_control/test/gpio_settings_test.ini index 91659e03a..78b859287 100644 --- a/components/gpio_control/test/gpio_settings_test.ini +++ b/components/gpio_control/test/gpio_settings_test.ini @@ -1,10 +1,10 @@ [DEFAULT] enabled: True -#The following Types exist: -# RotaryEncoder -# TwoButtonControl -# SimpleButton = Button +; The following Types exist: +; RotaryEncoder +; TwoButtonControl +; SimpleButton = Button [VolumeControl] enabled: True Type: RotaryEncoder @@ -14,12 +14,12 @@ pull_up: True hold_time: 0.3 hold_repeat: True timeBase: 0.1 -#timeBase only for rotary encoder +; timeBase only for rotary encoder functionCallDown: functionCallVolD functionCallUp: functionCallVolU functionCallTwoButtons: functionCallVol0 -# functionCallTwoButtons only for TwoButtonControl -#functionCallButton: functionCallPlayerPause ; only for RotaryEncoderClickable +; functionCallTwoButtons only for TwoButtonControl +; functionCallButton: functionCallPlayerPause ; only for RotaryEncoderClickable [PrevNextControl] Type: TwoButtonControl From f8c2fe57fa3780a1380c09b5bd230f98a9098084 Mon Sep 17 00:00:00 2001 From: s-martin Date: Sat, 6 Jun 2020 10:02:55 +0100 Subject: [PATCH 015/106] integrated scripts to install RC522 and PN532 reader --- .../installscripts/buster-install-default.sh | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/scripts/installscripts/buster-install-default.sh b/scripts/installscripts/buster-install-default.sh index cf5c79f9e..76a8f1d2a 100755 --- a/scripts/installscripts/buster-install-default.sh +++ b/scripts/installscripts/buster-install-default.sh @@ -1096,19 +1096,42 @@ finish_installation() { ##################################################### # Register external device(s) - echo "If you are using an USB RFID reader, connect it to your RPi." + echo "If you are using an RFID reader, connect it to your RPi." echo "(In case your RFID reader required soldering, consult the manual.)" # Use -e to display response of user in the logfile - read -e -r -p "Have you connected your USB Reader? [Y/n] " response + read -e -r -p "Have you connected your RFID reader? [Y/n] " response case "$response" in [nN][oO]|[nN]) ;; *) - cd "${jukebox_dir}"/scripts/ || exit - python3 RegisterDevice.py - sudo chown pi:www-data "${jukebox_dir}"/scripts/deviceName.txt - sudo chmod 644 "${jukebox_dir}"/scripts/deviceName.txt - ;; + echo 'Please select the RFID reader you want to use' + options=("USB-Reader (e.g. Neuftech)" "RC522" "PN532" "Manual configuration") + select opt in "${options[@]}"; do + case $opt in + "USB-Reader (e.g. Neuftech)") + cd "${jukebox_dir}"/scripts/ || exit + python3 RegisterDevice.py + sudo chown pi:www-data "${jukebox_dir}"/scripts/deviceName.txt + sudo chmod 644 "${jukebox_dir}"/scripts/deviceName.txt + break + ;; + "RC522") + bash "${jukebox_dir}"/components/rfid-reader/RC522/setup_rc522.sh + break + ;; + "PN532") + bash "${jukebox_dir}"/components/rfid-reader/PN532/setup_pn532.sh + break + ;; + "Manual configuration") + echo "Please configure your reader manually." + break + ;; + *) + echo "This is not a number" + ;; + esac + done esac echo From 8a08d5d5d31a01b0e0aa72ba23a8f6b48196b1a0 Mon Sep 17 00:00:00 2001 From: s-martin Date: Sat, 6 Jun 2020 16:01:36 +0200 Subject: [PATCH 016/106] * Force installation of pyhton packages, even when older versions are already installed * Harmonized python package installation --- .../audio/PirateAudioHAT/requirements.txt | 7 +++++++ .../PirateAudioHAT/setup_pirateAudioHAT.sh | 5 ++++- components/gpio_control/install.sh | 4 ++-- components/gpio_control/requirements.txt | 2 ++ components/rfid-reader/PN532/requirements.txt | 4 ++-- components/rfid-reader/PN532/setup_pn532.sh | 2 +- components/rfid-reader/RC522/requirements.txt | 4 ++-- components/rfid-reader/RC522/setup_rc522.sh | 2 +- requirements-gmusic.txt | 2 +- requirements-spotify.txt | 2 +- requirements.txt | 3 +-- ...buster-install-default-with-autohotspot.sh | 10 +++++----- .../installscripts/buster-install-default.sh | 20 +++++++++---------- 13 files changed, 39 insertions(+), 28 deletions(-) create mode 100644 components/audio/PirateAudioHAT/requirements.txt diff --git a/components/audio/PirateAudioHAT/requirements.txt b/components/audio/PirateAudioHAT/requirements.txt new file mode 100644 index 000000000..0380e1855 --- /dev/null +++ b/components/audio/PirateAudioHAT/requirements.txt @@ -0,0 +1,7 @@ +# PirateAudioHAT related requirements +# You need to install these with `sudo python3 -m pip install --upgrade --force-reinstall -q -r requirements.txt` + +Mopidy-PiDi +pidi-display-pil +pidi-display-st7789 +mopidy-raspberry-gpio diff --git a/components/audio/PirateAudioHAT/setup_pirateAudioHAT.sh b/components/audio/PirateAudioHAT/setup_pirateAudioHAT.sh index 09119309a..add059670 100755 --- a/components/audio/PirateAudioHAT/setup_pirateAudioHAT.sh +++ b/components/audio/PirateAudioHAT/setup_pirateAudioHAT.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash +HOME_DIR="/home/pi" +JUKEBOX_HOME_DIR="${HOME_DIR}/RPi-Jukebox-RFID" + question() { local question=$1 read -p "${question} (y/n)? " choice @@ -90,7 +93,7 @@ printf "Installing Python dependencies...\n" sudo apt-get -y -qq install python3-pil python3-numpy printf "Installing mopidy plugins...\n" -sudo pip3 --quiet install Mopidy-PiDi pidi-display-pil pidi-display-st7789 mopidy-raspberry-gpio +sudo python3 -m pip install --upgrade --force-reinstall -q -r "${JUKEBOX_HOME_DIR}"/components/audio/PirateAudioHAT/requirements.txt # Only add, if it does not exist already printf "Editing mopidy configuration...\n" diff --git a/components/gpio_control/install.sh b/components/gpio_control/install.sh index cbd0c7ae0..f5733100d 100755 --- a/components/gpio_control/install.sh +++ b/components/gpio_control/install.sh @@ -1,11 +1,11 @@ #!/bin/bash if [[ $(id -u) = 0 ]]; then - echo "This script should be run as root/sudo, please run as normal 'pi' user" + echo "This script should be run as root/sudo, please run as normal 'pi' user" exit 1 fi echo 'Install all required python modules' -pip install -r requirements.txt +sudo python3 -m pip install --upgrade --force-reinstall -r requirements.txt echo 'Installing GPIO_Control service' echo diff --git a/components/gpio_control/requirements.txt b/components/gpio_control/requirements.txt index 949878fc9..5ea6d4f53 100644 --- a/components/gpio_control/requirements.txt +++ b/components/gpio_control/requirements.txt @@ -1,3 +1,5 @@ +# gipo_control related requirements +# You need to install these with `sudo python3 -m pip install --upgrade --force-reinstall -q -r requirements.txt` python-mpd2 mock diff --git a/components/rfid-reader/PN532/requirements.txt b/components/rfid-reader/PN532/requirements.txt index 2369f76e7..26f7bf884 100644 --- a/components/rfid-reader/PN532/requirements.txt +++ b/components/rfid-reader/PN532/requirements.txt @@ -1,3 +1,3 @@ # PN532 related requirements -# You need to install these with `sudo python3 -m pip install -q -r requirements.txt` -py532lib \ No newline at end of file +# You need to install these with `sudo python3 -m pip install --upgrade --force-reinstall -q -r requirements.txt` +py532lib diff --git a/components/rfid-reader/PN532/setup_pn532.sh b/components/rfid-reader/PN532/setup_pn532.sh index 2cbd2fddd..3b9ab1252 100755 --- a/components/rfid-reader/PN532/setup_pn532.sh +++ b/components/rfid-reader/PN532/setup_pn532.sh @@ -33,7 +33,7 @@ else fi printf "Installing Python requirements for PN532...\n" -sudo python3 -m pip install -q -r "${JUKEBOX_HOME_DIR}"/components/rfid-reader/PN532/requirements.txt +sudo python3 -m pip install --upgrade --force-reinstall -q -r "${JUKEBOX_HOME_DIR}"/components/rfid-reader/PN532/requirements.txt printf "Configure RFID reader in Phoniebox...\n" cp "${JUKEBOX_HOME_DIR}"/scripts/Reader.py.experimental "${JUKEBOX_HOME_DIR}"/scripts/Reader.py diff --git a/components/rfid-reader/RC522/requirements.txt b/components/rfid-reader/RC522/requirements.txt index d8586be80..775bee697 100644 --- a/components/rfid-reader/RC522/requirements.txt +++ b/components/rfid-reader/RC522/requirements.txt @@ -1,5 +1,5 @@ # RC522 related requirements -# You need to install these with `sudo python3 -m pip install -q -r requirements.txt` +# You need to install these with `sudo python3 -m pip install --upgrade --force-reinstall -q -r requirements.txt` # pi-rc522 use latest version from Github -git+git://github.com/ondryaso/pi-rc522.git#egg=pi-rc522 \ No newline at end of file +git+git://github.com/ondryaso/pi-rc522.git#egg=pi-rc522 diff --git a/components/rfid-reader/RC522/setup_rc522.sh b/components/rfid-reader/RC522/setup_rc522.sh index 04c01ff5c..b87147412 100644 --- a/components/rfid-reader/RC522/setup_rc522.sh +++ b/components/rfid-reader/RC522/setup_rc522.sh @@ -17,7 +17,7 @@ printf "Please make sure that the RC522 reader is wired up correctly to the GPIO question "Continue" printf "Installing Python requirements for RC522...\n" -sudo python3 -m pip install -q -r "${JUKEBOX_HOME_DIR}"/components/rfid-reader/RC522/requirements.txt +sudo python3 -m pip install --upgrade --force-reinstall -q -r "${JUKEBOX_HOME_DIR}"/components/rfid-reader/RC522/requirements.txt printf "Configure RFID reader in Phoniebox...\n" cp "${JUKEBOX_HOME_DIR}"/scripts/Reader.py.experimental "${JUKEBOX_HOME_DIR}"/scripts/Reader.py diff --git a/requirements-gmusic.txt b/requirements-gmusic.txt index ab04eb757..39e13ce36 100644 --- a/requirements-gmusic.txt +++ b/requirements-gmusic.txt @@ -1,3 +1,3 @@ # Google Music related requirements (in addition to requirements-spotify.txt) -# You need to install these with `sudo pip install -r requirements-gmusic.txt` +# You need to install these with `sudo pip install --upgrade --force-reinstall -r requirements-gmusic.txt` Mopidy-Gmusic diff --git a/requirements-spotify.txt b/requirements-spotify.txt index aa89ce1d6..fa82f0c3e 100644 --- a/requirements-spotify.txt +++ b/requirements-spotify.txt @@ -1,3 +1,3 @@ # Spotify related requirements - # You need to install these with `sudo pip install -r requirements-spotify.txt` + # You need to install these with `sudo pip install --upgrade --force-reinstall -r requirements-spotify.txt` Mopidy-Iris==3.45.0 diff --git a/requirements.txt b/requirements.txt index 585226deb..dfd2c27b3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Library dependencies for the python code. You need to install these with -# `sudo pip install -r requirements.txt` before you can run this. +# `sudo python3 -m pip install --upgrade --force-reinstall -r requirements.txt` before you can run this. #### ESSENTIAL LIBRARIES FOR MAIN FUNCTIONALITY #### @@ -8,7 +8,6 @@ evdev==0.7.0 git+git://github.com/lthiery/SPI-Py.git#egg=spi-py youtube_dl pyserial -# spidev - currently installed via apt-get RPi.GPIO # Type checking for python diff --git a/scripts/installscripts/buster-install-default-with-autohotspot.sh b/scripts/installscripts/buster-install-default-with-autohotspot.sh index 28fae4b8d..7bbb8071e 100755 --- a/scripts/installscripts/buster-install-default-with-autohotspot.sh +++ b/scripts/installscripts/buster-install-default-with-autohotspot.sh @@ -344,7 +344,7 @@ config_audio_interface() { # CONFIGURE AUDIO INTERFACE (iFace) # # The default RPi audio interface is 'Headphone'. -# But this does not work for every setup. Here a list of +# But this does not work for every setup. Here a list of # available iFace names: " amixer scontrols @@ -722,7 +722,7 @@ install_main() { ${apt_get} ${allow_downgrades} install libspotify12 python3-cffi python3-ply python3-pycparser python3-spotify # Install necessary Python packages - sudo python3 -m pip install -q -r "${jukebox_dir}"/requirements-spotify.txt + sudo python3 -m pip install --upgrade --force-reinstall -q -r "${jukebox_dir}"/requirements-spotify.txt fi local raw_github="https://raw.githubusercontent.com/MiczFlor/RPi-Jukebox-RFID" @@ -735,7 +735,7 @@ install_main() { # Install more required packages echo "Installing additional Python packages..." - sudo python3 -m pip install -q -r "${jukebox_dir}"/requirements.txt + sudo python3 -m pip install --upgrade --force-reinstall -q -r "${jukebox_dir}"/requirements.txt samba_config @@ -753,11 +753,11 @@ install_main() { echo "RESTART" > "${jukebox_dir}"/settings/Second_Swipe echo "${jukebox_dir}/playlists" > "${jukebox_dir}"/settings/Playlists_Folders_Path echo "ON" > "${jukebox_dir}"/settings/ShowCover - + # sample file for debugging with all options set to FALSE sudo cp "${jukebox_dir}"/settings/debugLogging.conf.sample "${jukebox_dir}"/settings/debugLogging.conf sudo chmod 777 "${jukebox_dir}"/settings/debugLogging.conf - + # The new way of making the bash daemon is using the helperscripts # creating the shortcuts and script from a CSV file. # see scripts/helperscripts/AssignIDs4Shortcuts.php diff --git a/scripts/installscripts/buster-install-default.sh b/scripts/installscripts/buster-install-default.sh index cf5c79f9e..8b1f6ad1b 100755 --- a/scripts/installscripts/buster-install-default.sh +++ b/scripts/installscripts/buster-install-default.sh @@ -244,9 +244,9 @@ check_existing() { # the variables regarding the found content to the also found configuration file. # That way, reading the configuration file for the (potentially) non-interactive # install procedure will: - # a) overwrite whatever variables regarding re-cycling existing content which might + # a) overwrite whatever variables regarding re-cycling existing content which might # be stored in the config file - # b) if there are no variables for dealing with re-cycled context, we will append + # b) if there are no variables for dealing with re-cycled context, we will append # them - to have them for this install if [ -f "${jukebox_dir}"/settings/PhonieboxInstall.conf ]; then # ask for re-using the found configuration file @@ -367,7 +367,7 @@ check_existing() { fi # append variables to config file echo "EXISTINGuse=$EXISTINGuse" >> "${HOME_DIR}/PhonieboxInstall.conf" - + # Check if we found a Phoniebox install configuration earlier and ask if to run this now if [ "${EXISTINGusePhonieboxInstall}" == "YES" ]; then clear @@ -399,7 +399,7 @@ config_audio_interface() { # CONFIGURE AUDIO INTERFACE (iFace) # # The default RPi audio interface is 'Headphone'. -# But this does not work for every setup. Here a list of +# But this does not work for every setup. Here a list of # available iFace names: " amixer scontrols @@ -777,12 +777,12 @@ install_main() { ${apt_get} ${allow_downgrades} install libspotify12 python3-cffi python3-ply python3-pycparser python3-spotify # Install necessary Python packages - sudo python3 -m pip install -q -r "${jukebox_dir}"/requirements-spotify.txt + sudo python3 -m pip install --upgrade --force-reinstall -q -r "${jukebox_dir}"/requirements-spotify.txt fi # Install more required packages echo "Installing additional Python packages..." - sudo python3 -m pip install -q -r "${jukebox_dir}"/requirements.txt + sudo python3 -m pip install --upgrade --force-reinstall -q -r "${jukebox_dir}"/requirements.txt samba_config @@ -892,7 +892,7 @@ install_main() { if [ "${MPDconfig}" == "YES" ]; then local mpd_conf="/etc/mpd.conf" local mpd_log="/var/log/mpd/mpd.log" - + echo "Configuring MPD..." # MPD configuration # -rw-r----- 1 mpd audio 14043 Jul 17 20:16 /etc/mpd.conf @@ -903,7 +903,7 @@ install_main() { sudo sed -i 's|%DIRaudioFolders%|'"$DIRaudioFolders"'|' "${mpd_conf}" sudo chown mpd:audio "${mpd_conf}" sudo chmod 640 "${mpd_conf}" - + sudo chown mpd:audio "${mpd_log}" fi @@ -1155,12 +1155,12 @@ main() { wifi_settings "${JUKEBOX_HOME_DIR}/misc/sampleconfigs" "/etc/dhcpcd.conf" "/etc/wpa_supplicant/wpa_supplicant.conf" existing_assets "${JUKEBOX_HOME_DIR}" "${JUKEBOX_BACKUP_DIR}" folder_access "${JUKEBOX_HOME_DIR}" "pi:www-data" 775 - + # Copy PhonieboxInstall.conf configuration file to settings folder sudo cp "${HOME_DIR}/PhonieboxInstall.conf" "${JUKEBOX_HOME_DIR}/settings/" sudo chown pi:www-data "${JUKEBOX_HOME_DIR}/settings/PhonieboxInstall.conf" sudo chmod 775 "${JUKEBOX_HOME_DIR}/settings/PhonieboxInstall.conf" - + if [[ ${INTERACTIVE} == "true" ]]; then finish_installation "${JUKEBOX_HOME_DIR}" else From 21f8dc5376830d3c275934b151b64344ca86c9db Mon Sep 17 00:00:00 2001 From: s-martin Date: Sat, 6 Jun 2020 15:23:37 +0100 Subject: [PATCH 017/106] test py packages depending on installed reader --- .../installscripts/tests/test_installation.sh | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/scripts/installscripts/tests/test_installation.sh b/scripts/installscripts/tests/test_installation.sh index 7d16be465..fe034e976 100755 --- a/scripts/installscripts/tests/test_installation.sh +++ b/scripts/installscripts/tests/test_installation.sh @@ -190,6 +190,7 @@ verify_pip_packages() { local modules_spotify="Mopidy-Iris" local modules_pn532="py532lib" local modules_rc522="pi-rc522" + local deviceName="${JUKEBOX_HOME_DIR}"/scripts/deviceName.txt printf "\nTESTING installed pip modules...\n\n" @@ -198,7 +199,17 @@ verify_pip_packages() { modules="${modules} ${modules_spotify}" fi - # modules="${modules} ${modules_pn532}" + # RC522 reader is used + if grep -Fxq "${deviceName}" MFRC522 + then + modules="${modules} ${modules_rc522}" + fi + + # PN532 reader is used + if grep -Fxq "${deviceName}" PN532 + then + modules="${modules} ${modules_pn532}" + fi for module in ${modules} do @@ -210,21 +221,6 @@ verify_pip_packages() { fi ((tests++)) done - - # workaround, because currently it's not known, if modules have been installed manually - # TODO integrate in above check (similar to spotify modules) - optional_modules="${modules_rc522} ${modules_pn532}" - - for module in ${optional_modules} - do - if [[ $(pip3 show "${module}") ]]; then - echo " ${module} is installed" - else - echo " WARNING: Optional pip module ${module} is not installed" - # doesnt count as error, because only manually installed or not - fi - ((tests++)) - done } verify_samba_config() { From 5bcb22bf4a00e78302552e22c39954b77fdcdf9f Mon Sep 17 00:00:00 2001 From: s-martin Date: Sat, 6 Jun 2020 15:31:55 +0100 Subject: [PATCH 018/106] pass entrypoint only in Github Action --- .github/workflows/dockerimage.yml | 2 +- ci/Dockerfile.buster.test_install.amd64 | 2 -- .../installscripts/tests/test_installation.sh | 20 ++++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 44b2f6fae..89d3e228f 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -13,4 +13,4 @@ jobs: - name: Build Docker image and run tests run: | docker build . --file ./ci/Dockerfile.buster.test_install.amd64 --tag rpi-jukebox-rfid-buster:latest - docker run --rm -i rpi-jukebox-rfid-buster:latest + docker run --rm -i rpi-jukebox-rfid-buster:latest --entrypoint /bin/bash /code/scripts/installscripts/tests/run_installation_tests.sh diff --git a/ci/Dockerfile.buster.test_install.amd64 b/ci/Dockerfile.buster.test_install.amd64 index 2aba010cd..fa81fded3 100644 --- a/ci/Dockerfile.buster.test_install.amd64 +++ b/ci/Dockerfile.buster.test_install.amd64 @@ -28,6 +28,4 @@ RUN export DEBIAN_FRONTEND=noninteractive ;\ touch /boot/cmdlinetxt ;\ rm -rf /var/cache/apt/* /var/lib/apt/lists/* -ENTRYPOINT /code/scripts/installscripts/tests/run_installation_tests.sh - USER pi diff --git a/scripts/installscripts/tests/test_installation.sh b/scripts/installscripts/tests/test_installation.sh index fe034e976..723647578 100755 --- a/scripts/installscripts/tests/test_installation.sh +++ b/scripts/installscripts/tests/test_installation.sh @@ -199,16 +199,18 @@ verify_pip_packages() { modules="${modules} ${modules_spotify}" fi - # RC522 reader is used - if grep -Fxq "${deviceName}" MFRC522 - then - modules="${modules} ${modules_rc522}" - fi + if [[ -f "${deviceName}" ]]; then + # RC522 reader is used + if grep -Fxq "${deviceName}" MFRC522 + then + modules="${modules} ${modules_rc522}" + fi - # PN532 reader is used - if grep -Fxq "${deviceName}" PN532 - then - modules="${modules} ${modules_pn532}" + # PN532 reader is used + if grep -Fxq "${deviceName}" PN532 + then + modules="${modules} ${modules_pn532}" + fi fi for module in ${modules} From d874ecf9641020f34332a27a66ea32bbab4665e6 Mon Sep 17 00:00:00 2001 From: s-martin Date: Sat, 6 Jun 2020 16:23:25 +0100 Subject: [PATCH 019/106] fix start of script on running docker image --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 89d3e228f..62b6b8a9a 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -13,4 +13,4 @@ jobs: - name: Build Docker image and run tests run: | docker build . --file ./ci/Dockerfile.buster.test_install.amd64 --tag rpi-jukebox-rfid-buster:latest - docker run --rm -i rpi-jukebox-rfid-buster:latest --entrypoint /bin/bash /code/scripts/installscripts/tests/run_installation_tests.sh + docker run --rm -i rpi-jukebox-rfid-buster:latest /code/scripts/installscripts/tests/run_installation_tests.sh From 87c49d2f3f30a1bf0f007098e816a924f4ec7f66 Mon Sep 17 00:00:00 2001 From: s-martin Date: Sat, 6 Jun 2020 16:37:47 +0100 Subject: [PATCH 020/106] add a test for installing an RFID reader --- .github/workflows/dockerimage.yml | 1 + .../tests/run_installation_tests.sh | 2 ++ .../tests/run_installation_tests2.sh | 33 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 scripts/installscripts/tests/run_installation_tests2.sh diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 62b6b8a9a..163360174 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -14,3 +14,4 @@ jobs: run: | docker build . --file ./ci/Dockerfile.buster.test_install.amd64 --tag rpi-jukebox-rfid-buster:latest docker run --rm -i rpi-jukebox-rfid-buster:latest /code/scripts/installscripts/tests/run_installation_tests.sh + docker run --rm -i rpi-jukebox-rfid-buster:latest /code/scripts/installscripts/tests/run_installation_tests2.sh diff --git a/scripts/installscripts/tests/run_installation_tests.sh b/scripts/installscripts/tests/run_installation_tests.sh index f4fbbf774..dadb62106 100644 --- a/scripts/installscripts/tests/run_installation_tests.sh +++ b/scripts/installscripts/tests/run_installation_tests.sh @@ -3,6 +3,8 @@ # Install Phoniebox and test it # Used e.g. for tests on Docker +# Objective: Test installation with script using a simple configuration + # Print current path echo $PWD diff --git a/scripts/installscripts/tests/run_installation_tests2.sh b/scripts/installscripts/tests/run_installation_tests2.sh new file mode 100644 index 000000000..874563015 --- /dev/null +++ b/scripts/installscripts/tests/run_installation_tests2.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# Install Phoniebox and test it +# Used e.g. for tests on Docker + +# Objective: Test installation with script using a RC522 reader + +# Print current path +echo $PWD + +# Preparations +# Skip interactive Samba WINS config dialog +echo "samba-common samba-common/dhcp boolean false" | sudo debconf-set-selections +# No interactive frontend +export DEBIAN_FRONTEND=noninteractive + +# Run installation (in interactive mode) +# y confirm interactive +# n dont configure wifi +# y PCM as iface +# n no spotify +# y configure mpd +# y audio default location +# y RFID registration +# 2 use RC522 reader +# yes, reader is connected +# n No reboot + +# TODO check, how this behaves on branches other than develop +GIT_BRANCH=develop bash ./scripts/installscripts/buster-install-default.sh <<< $'y\nn\n\ny\n\nn\n\ny\n\ny\n\ny\ny\n2\ny\nn\n' + +# Rest installation +./scripts/installscripts/tests/test_installation.sh From 337ac73c4a0a2dee137a9d0eb9d221fdda6edfb6 Mon Sep 17 00:00:00 2001 From: s-martin Date: Sat, 6 Jun 2020 16:40:30 +0100 Subject: [PATCH 021/106] make test script writable --- ci/Dockerfile.buster.test_install.amd64 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/Dockerfile.buster.test_install.amd64 b/ci/Dockerfile.buster.test_install.amd64 index fa81fded3..df9168fe9 100644 --- a/ci/Dockerfile.buster.test_install.amd64 +++ b/ci/Dockerfile.buster.test_install.amd64 @@ -7,7 +7,8 @@ RUN groupadd --gid 1000 pi ;\ useradd -u 1000 -g 1000 -G sudo -d /home/pi -m -s /bin/bash -p '$1$iV7TOwOe$6ojkJQXyEA9bHd/SqNLNj0' pi ;\ chown -R 1000:1000 /code /home/pi ;\ chmod +x /code/scripts/installscripts/buster-install-default.sh ;\ - chmod +x /code/scripts/installscripts/tests/run_installation_tests.sh + chmod +x /code/scripts/installscripts/tests/run_installation_tests.sh ;\ + chmod +x /code/scripts/installscripts/tests/run_installation_tests2.sh RUN export DEBIAN_FRONTEND=noninteractive ;\ apt-get update ;\ From c5fd2610b819ee741c447154a533d64b80f024d9 Mon Sep 17 00:00:00 2001 From: bernipi Date: Mon, 8 Jun 2020 22:12:44 +0200 Subject: [PATCH 022/106] Fix "Play single file" to play filenames containing single quotes --- htdocs/api/playlist/playsinglefile.php | 3 +-- htdocs/func.php | 14 +++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/htdocs/api/playlist/playsinglefile.php b/htdocs/api/playlist/playsinglefile.php index 6c55e7b82..af05b2f08 100755 --- a/htdocs/api/playlist/playsinglefile.php +++ b/htdocs/api/playlist/playsinglefile.php @@ -17,7 +17,7 @@ } if ($_SERVER['REQUEST_METHOD'] === 'PUT') { - $body = file_get_contents('php://input'); + $body = str_replace("'","''\''",file_get_contents('php://input')); if($debugLoggingConf['DEBUG_WebApp_API'] == "TRUE") { file_put_contents("../../../logs/debug.log", "\n # \$body: " . $body , FILE_APPEND | LOCK_EX); } @@ -34,4 +34,3 @@ } ?> - diff --git a/htdocs/func.php b/htdocs/func.php index cd776a288..df231550c 100755 --- a/htdocs/func.php +++ b/htdocs/func.php @@ -173,14 +173,14 @@ function html_bootstrap3_createHeader($lang="en",$title="Welcome",$url_absolute= margin-right: 1em } /* anchor behaviour */ - + /* flash briefly on click */ .panel-heading a.btn-panel-big:active { color: #fff!important; } .panel-heading a.btn-panel-big { cursor: pointer; - } + } \n"; @@ -191,7 +191,7 @@ function tailShell($filepath, $lines = 1) { passthru('tail -' . $lines . ' ' . escapeshellarg($filepath)); return trim(ob_get_clean()); } - + function arrayPregDiff($a, $p) { # added function to use regular expressions to remove multiple files # e.g. all of the same file type from the array forming the later playlist. @@ -539,12 +539,12 @@ function printPlaylistHtml($files) foreach($files as $file) { print "
  • ".$counter++." : - - - ".basename($file).""; + + + ".htmlspecialchars(basename($file),ENT_QUOTES).""; if(basename($file) != "livestream.txt" && basename($file) != "podcast.txt" && basename($file) != "spotify.txt") { print" -    ".$lang['globalEdit'].""; +    ".$lang['globalEdit'].""; } print "
  • "; From b8f13a584c3bd665830101cc6f163e4ab0a059c4 Mon Sep 17 00:00:00 2001 From: bernipi Date: Mon, 8 Jun 2020 22:39:30 +0200 Subject: [PATCH 023/106] Add stringreplace also to appendFileToPlaylist.php --- htdocs/api/playlist/appendFileToPlaylist.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/api/playlist/appendFileToPlaylist.php b/htdocs/api/playlist/appendFileToPlaylist.php index 8c105a35a..2d42f903f 100755 --- a/htdocs/api/playlist/appendFileToPlaylist.php +++ b/htdocs/api/playlist/appendFileToPlaylist.php @@ -17,7 +17,7 @@ } if ($_SERVER['REQUEST_METHOD'] === 'PUT') { - $body = file_get_contents('php://input'); + $body = str_replace("'","''\''",file_get_contents('php://input')); if($debugLoggingConf['DEBUG_WebApp_API'] == "TRUE") { file_put_contents("../../../logs/debug.log", "\n # \$body: " . $body , FILE_APPEND | LOCK_EX); } @@ -33,4 +33,3 @@ } ?> - From a5de23bcb727ee6393f1c4ed584ffd886dfcceff Mon Sep 17 00:00:00 2001 From: bernipi Date: Mon, 8 Jun 2020 23:01:54 +0200 Subject: [PATCH 024/106] Error becauseof autocomplete from Atom --- htdocs/api/playlist/appendFileToPlaylist.php | 2 +- htdocs/api/playlist/playsinglefile.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/api/playlist/appendFileToPlaylist.php b/htdocs/api/playlist/appendFileToPlaylist.php index 2d42f903f..3d2a43c0b 100755 --- a/htdocs/api/playlist/appendFileToPlaylist.php +++ b/htdocs/api/playlist/appendFileToPlaylist.php @@ -17,7 +17,7 @@ } if ($_SERVER['REQUEST_METHOD'] === 'PUT') { - $body = str_replace("'","''\''",file_get_contents('php://input')); + $body = str_replace("'","'\''",file_get_contents('php://input')); if($debugLoggingConf['DEBUG_WebApp_API'] == "TRUE") { file_put_contents("../../../logs/debug.log", "\n # \$body: " . $body , FILE_APPEND | LOCK_EX); } diff --git a/htdocs/api/playlist/playsinglefile.php b/htdocs/api/playlist/playsinglefile.php index af05b2f08..496bc88b2 100755 --- a/htdocs/api/playlist/playsinglefile.php +++ b/htdocs/api/playlist/playsinglefile.php @@ -17,7 +17,7 @@ } if ($_SERVER['REQUEST_METHOD'] === 'PUT') { - $body = str_replace("'","''\''",file_get_contents('php://input')); + $body = str_replace("'","'\''",file_get_contents('php://input')); if($debugLoggingConf['DEBUG_WebApp_API'] == "TRUE") { file_put_contents("../../../logs/debug.log", "\n # \$body: " . $body , FILE_APPEND | LOCK_EX); } From cb928f4b243dc41d0be0d47b345cb6a1e4c551ab Mon Sep 17 00:00:00 2001 From: bernipi Date: Mon, 8 Jun 2020 23:18:14 +0200 Subject: [PATCH 025/106] web app adding hover for playsinglefile and appendfiletoplaylist --- htdocs/func.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/func.php b/htdocs/func.php index df231550c..2cfde287b 100755 --- a/htdocs/func.php +++ b/htdocs/func.php @@ -539,8 +539,8 @@ function printPlaylistHtml($files) foreach($files as $file) { print "
  • ".$counter++." : - - + + ".htmlspecialchars(basename($file),ENT_QUOTES).""; if(basename($file) != "livestream.txt" && basename($file) != "podcast.txt" && basename($file) != "spotify.txt") { print" From db6730ca0fb1975f14eb819826e19ff40475714a Mon Sep 17 00:00:00 2001 From: bernipi Date: Mon, 8 Jun 2020 23:24:31 +0200 Subject: [PATCH 026/106] web app adding hover for fileedit --- htdocs/func.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/func.php b/htdocs/func.php index 2cfde287b..97fd92c7f 100755 --- a/htdocs/func.php +++ b/htdocs/func.php @@ -544,7 +544,7 @@ function printPlaylistHtml($files) ".htmlspecialchars(basename($file),ENT_QUOTES).""; if(basename($file) != "livestream.txt" && basename($file) != "podcast.txt" && basename($file) != "spotify.txt") { print" -    ".$lang['globalEdit'].""; +    ".$lang['globalEdit'].""; } print "
  • "; From 6261d405b0ea33fc0583d8e182b4edb63ae92007 Mon Sep 17 00:00:00 2001 From: bernipi Date: Mon, 8 Jun 2020 23:30:32 +0200 Subject: [PATCH 027/106] Fixed Uppercases. Append File to Playlist now works. --- htdocs/js/jukebox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/js/jukebox.js b/htdocs/js/jukebox.js index 020ad5bf9..c0eab1aef 100755 --- a/htdocs/js/jukebox.js +++ b/htdocs/js/jukebox.js @@ -109,7 +109,7 @@ function playSongInPlaylist(song) { function appendFileToPlaylist(file) { $.ajax({ - url: `api/playlist/appendfiletoplaylist.php`, + url: `api/playlist/appendFileToPlaylist.php`, method: 'PUT', data: file.toString() }).success(data => { From 92c666915d4ec178e40ac00bd0d03c4e416ff387 Mon Sep 17 00:00:00 2001 From: veloxidSchweiz <55716261+veloxidSchweiz@users.noreply.github.com> Date: Thu, 11 Jun 2020 16:18:27 +0200 Subject: [PATCH 028/106] add GIT_URL als variable to give the option to define the Git repository (#1009) Co-authored-by: Felix Bachmair --- scripts/installscripts/buster-install-default.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/installscripts/buster-install-default.sh b/scripts/installscripts/buster-install-default.sh index 8b1f6ad1b..1ad53d821 100755 --- a/scripts/installscripts/buster-install-default.sh +++ b/scripts/installscripts/buster-install-default.sh @@ -19,6 +19,9 @@ # The absolute path to the folder which contains this script PATHDATA="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" GIT_BRANCH=${GIT_BRANCH:-master} +GIT_URL=${GIT_URL:-https://github.com/MiczFlor/RPi-Jukebox-RFID.git} +echo GIT_BRANCH $GIT_BRANCH +echo GIT_URL $GIT_URL DATETIME=$(date +"%Y%m%d_%H%M%S") @@ -230,7 +233,7 @@ check_existing() { #echo "The version of your installation is: $(cat ${jukebox_dir}/settings/version)" # get the current short commit hash of the repo - CURRENT_REMOTE_COMMIT="$(git ls-remote https://github.com/MiczFlor/RPi-Jukebox-RFID.git ${GIT_BRANCH} | cut -c1-7)" + CURRENT_REMOTE_COMMIT="$(git ls-remote ${GIT_URL} ${GIT_BRANCH} | cut -c1-7)" fi echo "IMPORTANT: you can use the existing content and configuration" echo "files for your new install." @@ -747,7 +750,7 @@ install_main() { # Get github code cd "${HOME_DIR}" || exit - git clone https://github.com/MiczFlor/RPi-Jukebox-RFID.git --branch "${GIT_BRANCH}" + git clone ${GIT_URL} --branch "${GIT_BRANCH}" # VERSION of installation From 29d88e266e59774e736b9ec9036fe0ce07799ca2 Mon Sep 17 00:00:00 2001 From: veloxidSchweiz <55716261+veloxidSchweiz@users.noreply.github.com> Date: Thu, 11 Jun 2020 16:27:27 +0200 Subject: [PATCH 029/106] Bugfix/gpio control installscript (#1010) * make script work with rasbian lite * fixed ownership of config file as the script is now executed with sudo --- components/gpio_control/install.sh | 33 +++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/components/gpio_control/install.sh b/components/gpio_control/install.sh index f5733100d..f45137132 100755 --- a/components/gpio_control/install.sh +++ b/components/gpio_control/install.sh @@ -1,21 +1,31 @@ #!/bin/bash -if [[ $(id -u) = 0 ]]; then - echo "This script should be run as root/sudo, please run as normal 'pi' user" + +if [[ $(id -u) != 0 ]]; then + echo "This script should be run using sudo" exit 1 fi + +echo 'disable old services: phoniebox-gpio-buttons and phoniebox-rotary-encoder' +systemctl stop phoniebox-rotary-encoder.service +systemctl disable phoniebox-rotary-encoder.service +systemctl stop phoniebox-gpio-buttons.service +systemctl disable phoniebox-gpio-buttons.service + + echo 'Install all required python modules' -sudo python3 -m pip install --upgrade --force-reinstall -r requirements.txt +python3 -m pip install --upgrade --force-reinstall -r requirements.txt echo 'Installing GPIO_Control service' echo -CONFIG_PATH=$HOME/.config/phoniebox +USER_HOME=$(eval echo ~${SUDO_USER}) +CONFIG_PATH=$USER_HOME/.config/phoniebox +FILE=$CONFIG_PATH/gpio_settings.ini if [ ! -d $CONFIG_PATH ]; then - mkdir -p $HOME/.config/phoniebox/ ; + mkdir -p $USER_HOME/.config/phoniebox/ ; fi; -FILE=$CONFIG_PATH/gpio_settings.ini if test -f "$FILE"; then echo "$FILE exist" echo "Script will not install a configuration" @@ -34,6 +44,7 @@ else echo "Copy file to $FILE" echo cp -v $opt $FILE cp -v $opt $FILE + chown -R $(whoami) $FILE break ;; "Stop the script") @@ -47,12 +58,16 @@ else done fi +chown -R ${SUDO_USER}:${SUDO_USER} $FILE + echo echo 'Installing GPIO_Control service, this will require to enter your password up to 3 times to enable the service' read -p "Press enter to continue " -n 1 -r SERVICE_FILE=/etc/systemd/system/phoniebox_gpio_control.service if test -f "$SERVICE_FILE"; then echo "$SERVICE_FILE exists."; + echo 'systemctl daemon-reload' + systemctl daemon-reload echo 'restarting service' systemctl restart phoniebox_gpio_control.service read -p "Press enter to continue " -n 1 -r; @@ -60,8 +75,9 @@ if test -f "$SERVICE_FILE"; then #echo "systemctl daemon-reload" #systemctl daemon-reload else - sudo cp -v ./example_configs/phoniebox_gpio_control.service /etc/systemd/system/ + cp -v ./example_configs/phoniebox_gpio_control.service /etc/systemd/system/ echo "systemctl start phoniebox_gpio_control.service" + echo 'systemctl daemon-reload' systemctl start phoniebox_gpio_control.service echo "systemctl enable phoniebox_gpio_control.service" systemctl enable phoniebox_gpio_control.service @@ -86,6 +102,3 @@ fi #systemctl is-active --quiet phoniebox_gpio_control.service #systemctl status phoniebox_gpio_control.service - - - From 300fa3f2afd7fafdf379e202a4504a8013adebe9 Mon Sep 17 00:00:00 2001 From: Micz Flor Date: Fri, 12 Jun 2020 11:38:42 +0200 Subject: [PATCH 030/106] volume handling alternative with amixer not mpd #973 --- htdocs/api/common.php | 8 +- htdocs/api/player.php | 5 + htdocs/api/volume.php | 2 +- htdocs/inc.setInputDevices.php | 61 +++++++++++ htdocs/lang/lang-en-UK.php | 1 + scripts/inc.writeGlobalConfig.sh | 14 ++- scripts/playout_controls.sh | 170 +++++++++++++++++++++++++++---- 7 files changed, 236 insertions(+), 25 deletions(-) diff --git a/htdocs/api/common.php b/htdocs/api/common.php index 5f298941d..7955989c7 100755 --- a/htdocs/api/common.php +++ b/htdocs/api/common.php @@ -3,7 +3,11 @@ function execAndEcho($command) { $output = execScript($command); - echo(implode('\n', $output)); + $result = implode('\n', $output); + echo $result; + if($debugLoggingConf['DEBUG_WebApp_API'] == "TRUE") { + file_put_contents("../../logs/debug.log", "\n # function execAndEcho: " . $result , FILE_APPEND | LOCK_EX); + } } function execScript($command) { @@ -14,7 +18,7 @@ function execScript($command) { function execScriptWithoutCheck($command) { global $debugLoggingConf; if($debugLoggingConf['DEBUG_WebApp_API'] == "TRUE") { - file_put_contents("../../../logs/debug.log", "\n # function execScriptWithoutCheck: " . $command , FILE_APPEND | LOCK_EX); + file_put_contents("../../logs/debug.log", "\n # function execScriptWithoutCheck: " . $command , FILE_APPEND | LOCK_EX); } $absoluteCommand = realpath(dirname(__FILE__) .'/../../scripts') ."/{$command}"; exec("sudo ".$absoluteCommand); diff --git a/htdocs/api/player.php b/htdocs/api/player.php index bc8e45224..7ebd680c4 100755 --- a/htdocs/api/player.php +++ b/htdocs/api/player.php @@ -58,6 +58,11 @@ function handleGet() { $responseList[strtolower($match['key'])] = $match['value']; } } + // get volume separately from mpd, because we might use amixer to control volume + $command = "playout_controls.sh -c=getvolume"; + $output = execScript($command); + $responseList['volume'] = implode('\n', $output); + if($debugLoggingConf['DEBUG_WebApp_API'] == "TRUE") { file_put_contents("../../logs/debug.log", "\n # function handleGet() " , FILE_APPEND | LOCK_EX); file_put_contents("../../logs/debug.log", "\n\$responseList: " . json_encode($responseList) . $_SERVER['REQUEST_METHOD'] , FILE_APPEND | LOCK_EX); diff --git a/htdocs/api/volume.php b/htdocs/api/volume.php index 329a3d3e1..0ba69365c 100755 --- a/htdocs/api/volume.php +++ b/htdocs/api/volume.php @@ -12,7 +12,7 @@ */ $debugLoggingConf = parse_ini_file("../../settings/debugLogging.conf"); if($debugLoggingConf['DEBUG_WebApp_API'] == "TRUE") { - file_put_contents("../../logs/debug.log", "\n# WebApp API # " . __FILE__ , FILE_APPEND | LOCK_EX); + file_put_contents("../../logs/debug.log", "\n# WebApp API api/volume.php# " . __FILE__ , FILE_APPEND | LOCK_EX); file_put_contents("../../logs/debug.log", "\n # \$_SERVER['REQUEST_METHOD']: " . $_SERVER['REQUEST_METHOD'] , FILE_APPEND | LOCK_EX); } diff --git a/htdocs/inc.setInputDevices.php b/htdocs/inc.setInputDevices.php index d257a25b9..7eae6d2a0 100755 --- a/htdocs/inc.setInputDevices.php +++ b/htdocs/inc.setInputDevices.php @@ -64,4 +64,65 @@ + + '.$conf['settings_abs'].'/Volume_Manager'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['VolumeManager']) == "amixer") { + $VolumeManager = "amixer"; + $exec = 'echo "'.$VolumeManager.'" > '.$conf['settings_abs'].'/Volume_Manager'; + if($debug == "true") { + print $exec; + } + exec($exec); + } + // execute shell to create config file + exec("sudo ".$conf['scripts_abs']."/inc.writeGlobalConfig.sh"); +} +?> + + +
    +
    +

    +
    '> +
    + + + '/> + +
    +
    +
    + +
    + diff --git a/htdocs/lang/lang-en-UK.php b/htdocs/lang/lang-en-UK.php index 82096610d..999180706 100755 --- a/htdocs/lang/lang-en-UK.php +++ b/htdocs/lang/lang-en-UK.php @@ -229,6 +229,7 @@ $lang['settingsWlanSendON'] = "Yes, send email."; $lang['settingsWlanSendOFF'] = "No, do not send email."; +$lang['settingsVolumeManager'] = "Select volume manager"; $lang['settingsWlanReadNav'] = "Read Wlan IP"; $lang['settingsWlanReadInfo'] = "Read IP address of wlan (wifi) each time after booting? (useful if you hook your Phoniebox into a new wlan networt with dynamic IP)"; diff --git a/scripts/inc.writeGlobalConfig.sh b/scripts/inc.writeGlobalConfig.sh index 958eb4d61..75f3a618d 100755 --- a/scripts/inc.writeGlobalConfig.sh +++ b/scripts/inc.writeGlobalConfig.sh @@ -75,6 +75,16 @@ fi # 2. then|or read value from file AUDIOIFACENAME=`cat $PATHDATA/../settings/Audio_iFace_Name` +############################################## +# Volume_Manager (mpd or amixer) +# 1. create a default if file does not exist +if [ ! -f $PATHDATA/../settings/Volume_Manager ]; then + echo "mpd" > $PATHDATA/../settings/Volume_Manager + chmod 777 $PATHDATA/../settings/Volume_Manager +fi +# 2. then|or read value from file +VOLUMEMANAGER=`cat $PATHDATA/../settings/Volume_Manager` + ############################################## # Audio_Volume_Change_Step # 1. create a default if file does not exist @@ -164,7 +174,7 @@ if [ ! -f $PATHDATA/../settings/MailWlanIpYN ]; then chmod 777 $PATHDATA/../settings/MailWlanIpYN fi # 2. then|or read value from file -MAILWLANIPYN=`cat $PATHDATA/../settings/WlanIpMailYN` +MAILWLANIPYN=`cat $PATHDATA/../settings/MailWlanIpYN` ############################################## # Read IP address of Wlan after boot? @@ -213,6 +223,7 @@ VERSION=`cat $PATHDATA/../settings/version` # PLAYLISTSFOLDERPATH # SECONDSWIPE # AUDIOIFACENAME +# VOLUMEMANAGER # AUDIOVOLCHANGESTEP # AUDIOVOLMAXLIMIT # AUDIOVOLMINLIMIT @@ -234,6 +245,7 @@ echo "AUDIOFOLDERSPATH=\"${AUDIOFOLDERSPATH}\"" >> "${PATHDATA}/../settings/glob echo "PLAYLISTSFOLDERPATH=\"${PLAYLISTSFOLDERPATH}\"" >> "${PATHDATA}/../settings/global.conf" echo "SECONDSWIPE=\"${SECONDSWIPE}\"" >> "${PATHDATA}/../settings/global.conf" echo "AUDIOIFACENAME=\"${AUDIOIFACENAME}\"" >> "${PATHDATA}/../settings/global.conf" +echo "VOLUMEMANAGER=\"${VOLUMEMANAGER}\"" >> "${PATHDATA}/../settings/global.conf" echo "AUDIOVOLCHANGESTEP=\"${AUDIOVOLCHANGESTEP}\"" >> "${PATHDATA}/../settings/global.conf" echo "AUDIOVOLMAXLIMIT=\"${AUDIOVOLMAXLIMIT}\"" >> "${PATHDATA}/../settings/global.conf" echo "AUDIOVOLMINLIMIT=\"${AUDIOVOLMINLIMIT}\"" >> "${PATHDATA}/../settings/global.conf" diff --git a/scripts/playout_controls.sh b/scripts/playout_controls.sh index 6252a2655..7f07901db 100755 --- a/scripts/playout_controls.sh +++ b/scripts/playout_controls.sh @@ -178,38 +178,74 @@ case $COMMAND in sudo systemctl start mopidy ;; mute) - if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " ${COMMAND}" >> ${PATHDATA}/../logs/debug.log; fi + if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " ${COMMAND} | VOLUMEMANAGER:${VOLUMEMANAGER}" >> ${PATHDATA}/../logs/debug.log; fi if [ ! -f $VOLFILE ]; then # $VOLFILE does NOT exist == audio on # read volume in percent and write to $VOLFILE - echo -e status\\nclose | nc -w 1 localhost 6600 | grep -o -P '(?<=volume: ).*' > $VOLFILE + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sget \'$AUDIOIFACENAME\' | grep -Po -m 1 '(?<=\[)[^]]*(?=%])' > $VOLFILE + else + # manage volume with mpd + echo -e status\\nclose | nc -w 1 localhost 6600 | grep -o -P '(?<=volume: ).*' > $VOLFILE + fi # set volume to 0% - echo -e setvol 0\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' 0% + else + # manage volume with mpd + echo -e setvol 0\\nclose | nc -w 1 localhost 6600 + fi else # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent - echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% + else + # manage volume with mpd + echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + fi # delete $VOLFILE rm -f $VOLFILE fi ;; setvolume) - if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " ${COMMAND}" >> ${PATHDATA}/../logs/debug.log; fi + if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " ${COMMAND} | VOLUMEMANAGER:${VOLUMEMANAGER}" >> ${PATHDATA}/../logs/debug.log; fi #increase volume only if VOLPERCENT is below the max volume limit and above min volume limit if [ ${VALUE} -le $AUDIOVOLMAXLIMIT ] && [ ${VALUE} -ge $AUDIOVOLMINLIMIT ]; then # set volume level in percent - echo -e setvol $VALUE\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' $VALUE% + else + # manage volume with mpd + echo -e setvol $VALUE\\nclose | nc -w 1 localhost 6600 + fi else if [ ${VALUE} -gt $AUDIOVOLMAXLIMIT ]; then # if we are over the max volume limit, set the volume to maxvol - echo -e setvol $AUDIOVOLMAXLIMIT\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' $AUDIOVOLMAXLIMIT% + else + # manage volume with mpd + echo -e setvol $AUDIOVOLMAXLIMIT\\nclose | nc -w 1 localhost 6600 + fi fi if [ ${VALUE} -lt $AUDIOVOLMINLIMIT ]; then # if we are unter the min volume limit, set the volume to minvol - echo -e setvol $AUDIOVOLMINLIMIT\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' $AUDIOVOLMINLIMIT% + else + # manage volume with mpd + echo -e setvol $AUDIOVOLMINLIMIT\\nclose | nc -w 1 localhost 6600 + fi fi fi ;; @@ -231,22 +267,47 @@ case $COMMAND in fi # $VOLFILE does NOT exist == audio on # read volume in percent - VOLPERCENT=$(echo -e status\\nclose | nc -w 1 localhost 6600 | grep -o -P '(?<=volume: ).*') + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + VOLPERCENT=`amixer sget \'$AUDIOIFACENAME\' | grep -Po -m 1 '(?<=\[)[^]]*(?=%])'` + else + # manage volume with mpd + VOLPERCENT=$(echo -e status\\nclose | nc -w 1 localhost 6600 | grep -o -P '(?<=volume: ).*') + fi # increase by $AUDIOVOLCHANGESTEP VOLPERCENT=`expr ${VOLPERCENT} + \( ${AUDIOVOLCHANGESTEP} \* ${VALUE} \)` + if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " VOLPERCENT:${VOLPERCENT} | VOLUMEMANAGER:${VOLUMEMANAGER}" >> ${PATHDATA}/../logs/debug.log; fi #increase volume only if VOLPERCENT is below the max volume limit if [ $VOLPERCENT -le $AUDIOVOLMAXLIMIT ]; then # set volume level in percent - echo -e setvol +$VOLPERCENT\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' ${VOLPERCENT}% + else + # manage volume with mpd + echo -e setvol +$VOLPERCENT\\nclose | nc -w 1 localhost 6600 + fi else # if we are over the max volume limit, set the volume to maxvol - echo -e setvol $AUDIOVOLMAXLIMIT\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' ${AUDIOVOLMAXLIMIT}% + else + # manage volume with mpd + echo -e setvol $AUDIOVOLMAXLIMIT\\nclose | nc -w 1 localhost 6600 + fi fi else # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent - echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% + else + # manage volume with mpd + echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + fi # delete $VOLFILE rm -f $VOLFILE fi @@ -269,40 +330,84 @@ case $COMMAND in fi # $VOLFILE does NOT exist == audio on # read volume in percent - VOLPERCENT=$(echo -e status\\nclose | nc -w 1 localhost 6600 | grep -o -P '(?<=volume: ).*') + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + VOLPERCENT=`amixer sget \'$AUDIOIFACENAME\' | grep -Po -m 1 '(?<=\[)[^]]*(?=%])'` + else + # manage volume with mpd + VOLPERCENT=$(echo -e status\\nclose | nc -w 1 localhost 6600 | grep -o -P '(?<=volume: ).*') + fi # decrease by $AUDIOVOLCHANGESTEP VOLPERCENT=`expr ${VOLPERCENT} - \( ${AUDIOVOLCHANGESTEP} \* ${VALUE} \)` + if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " VOLPERCENT:${VOLPERCENT} | VOLUMEMANAGER:${VOLUMEMANAGER}" >> ${PATHDATA}/../logs/debug.log; fi #decrease volume only if VOLPERCENT is above the min volume limit if [ $VOLPERCENT -ge $AUDIOVOLMINLIMIT ]; then # set volume level in percent - echo -e setvol +$VOLPERCENT\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' ${VOLPERCENT}% + else + # manage volume with mpd + echo -e setvol +$VOLPERCENT\\nclose | nc -w 1 localhost 6600 + fi else # if we are below the min volume limit, set the volume to minvol - echo -e setvol $AUDIOVOLMINLIMIT\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' ${AUDIOVOLMINLIMIT}% + else + # manage volume with mpd + echo -e setvol $AUDIOVOLMINLIMIT\\nclose | nc -w 1 localhost 6600 + fi fi else # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent - echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% + else + # manage volume with mpd + echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + fi # delete $VOLFILE rm -f $VOLFILE fi ;; getvolume) # read volume in percent - if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " ${COMMAND}" >> ${PATHDATA}/../logs/debug.log; fi - VOLPERCENT=$(echo -e status\\nclose | nc -w 1 localhost 6600 | grep -o -P '(?<=volume: ).*') + if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo "# ${COMMAND}" >> ${PATHDATA}/../logs/debug.log; fi + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + VOLPERCENT=`amixer sget \'$AUDIOIFACENAME\' | grep -Po -m 1 '(?<=\[)[^]]*(?=%])'` + else + # manage volume with mpd + VOLPERCENT=$(echo -e status\\nclose | nc -w 1 localhost 6600 | grep -o -P '(?<=volume: ).*') + fi + if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " VOLPERCENT:${VOLPERCENT} | VOLUMEMANAGER:${VOLUMEMANAGER}" >> ${PATHDATA}/../logs/debug.log; fi echo $VOLPERCENT ;; setmaxvolume) if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " ${COMMAND}" >> ${PATHDATA}/../logs/debug.log; fi # read volume in percent - VOLPERCENT=$(echo -e status\\nclose | nc -w 1 localhost 6600 | grep -o -P '(?<=volume: ).*') + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + VOLPERCENT=`amixer sget \'$AUDIOIFACENAME\' | grep -Po -m 1 '(?<=\[)[^]]*(?=%])'` + else + # manage volume with mpd + VOLPERCENT=$(echo -e status\\nclose | nc -w 1 localhost 6600 | grep -o -P '(?<=volume: ).*') + fi # if volume of the box is greater than wanted maxvolume, set volume to maxvolume if [ $VOLPERCENT -gt ${VALUE} ]; then - echo -e setvol ${VALUE} | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' ${VALUE}% + else + # manage volume with mpd + echo -e setvol ${VALUE} | nc -w 1 localhost 6600 + fi fi # if startupvolume is greater than wanted maxvolume, set startupvolume to maxvolume if [ ${AUDIOVOLSTARTUP} -gt ${VALUE} ]; @@ -353,7 +458,14 @@ case $COMMAND in exit 1 else # set volume level in percent - echo -e setvol ${AUDIOVOLSTARTUP}\\nclose | nc -w 1 localhost 6600 + if [ "${VOLUMEMANAGER}" == "amixer" ]; then + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + amixer sset \'$AUDIOIFACENAME\' ${AUDIOVOLSTARTUP}% + else + # manage volume with mpd + echo -e setvol ${AUDIOVOLSTARTUP}\\nclose | nc -w 1 localhost 6600 + fi + fi ;; playerstop) @@ -383,6 +495,8 @@ case $COMMAND in # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + # amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% # delete $VOLFILE rm -f $VOLFILE fi @@ -396,6 +510,8 @@ case $COMMAND in # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + # amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% # delete $VOLFILE rm -f $VOLFILE fi @@ -409,6 +525,8 @@ case $COMMAND in # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + # amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% # delete $VOLFILE rm -f $VOLFILE fi @@ -425,6 +543,8 @@ case $COMMAND in # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + # amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% # delete $VOLFILE rm -f $VOLFILE fi @@ -454,6 +574,8 @@ case $COMMAND in # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + # amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% # delete $VOLFILE rm -f $VOLFILE fi @@ -480,6 +602,8 @@ case $COMMAND in # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + # amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% # delete $VOLFILE rm -f $VOLFILE fi @@ -492,6 +616,8 @@ case $COMMAND in # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + # amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% # delete $VOLFILE rm -f $VOLFILE fi @@ -560,6 +686,8 @@ case $COMMAND in # $VOLFILE DOES exist == audio off # read volume level from $VOLFILE and set as percent echo -e setvol `<$VOLFILE`\\nclose | nc -w 1 localhost 6600 + # volume handling alternative with amixer not mpd (2020-06-12 related to ticket #973) + # amixer sset \'$AUDIOIFACENAME\' `<$VOLFILE`% # delete $VOLFILE rm -f $VOLFILE fi From 78bb4ce8d2e01b627be17393a73f9a40b8af4826 Mon Sep 17 00:00:00 2001 From: Micz Flor Date: Fri, 12 Jun 2020 12:38:50 +0200 Subject: [PATCH 031/106] # --- htdocs/inc.header.php | 4 ++-- htdocs/manageFilesFolders.php | 6 +++--- scripts/startup-scripts.sh | 6 ++++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/htdocs/inc.header.php b/htdocs/inc.header.php index 6d1bc812c..a623c67a7 100755 --- a/htdocs/inc.header.php +++ b/htdocs/inc.header.php @@ -152,7 +152,9 @@ function fileGetContentOrDefault($filename, $defaultValue) // assign the values from the global conf file to the vars in PHP $Audio_Folders_Path = $globalConf['AUDIOFOLDERSPATH']; +$Playlists_Folders_Path = $globalConf['PLAYLISTSFOLDERPATH']; $Second_Swipe = $globalConf['SECONDSWIPE']; +$VolumeManager = $globalConf['VOLUMEMANAGER']; $ShowCover = $globalConf['SHOWCOVER']; $WlanIpReadYN = $globalConf['READWLANIPYN']; $WlanIpMailYN = $globalConf['MAILWLANIPYN']; @@ -173,7 +175,6 @@ function fileGetContentOrDefault($filename, $defaultValue) */ include("inc.langLoad.php"); -//<<<<<<< HEAD /*======= $Second_Swipe = trim(file_get_contents($conf['settings_abs'].'/Second_Swipe')); $ShowCover = fileGetContentOrDefault($conf['settings_abs'].'/ShowCover', "ON"); @@ -183,7 +184,6 @@ function fileGetContentOrDefault($filename, $defaultValue) * load language strings */ //$conf['settings_lang'] = fileGetContentOrDefault($conf['settings_abs'].'/Lang', "en-UK"); -//>>>>>>> 7ef4a568abfc0e0c97cd0ffd954fa3e5ce54b240 /******************************************* * URLPARAMETERS diff --git a/htdocs/manageFilesFolders.php b/htdocs/manageFilesFolders.php index d74d42f87..0664704fa 100755 --- a/htdocs/manageFilesFolders.php +++ b/htdocs/manageFilesFolders.php @@ -111,7 +111,7 @@ // hang on, does that folder exist already? if(!file_exists($Audio_Folders_Path . "/" . $moveFolder)) { // no, so create the folder - $exec = 'mkdir "' . $moveFolder . '"; chown -R pi:www-data "' . $moveFolder . '"; chmod 777 "' . $moveFolder . '"'; + $exec = 'mkdir "' . $moveFolder . '"; chown -R pi:www-data "' . $moveFolder . '"; sudo chmod -R 777 "' . $moveFolder . '"'; exec($exec); $messageAction .= "Will create new folder and move files to: '" . $moveFolder . "'"; } else { @@ -132,7 +132,7 @@ // move files to folder foreach ($uFiles['ufile'] as $key => $values) { $targetName = $moveFolder . '/' . $values['name']; - $exec = 'mv "' . $values['tmp_name'] . '" "' . $targetName . '"; chown -R pi:www-data "' . $targetName . '"; chmod 777 "' . $targetName . '"'; + $exec = 'mv "' . $values['tmp_name'] . '" "' . $targetName . '"; chown -R pi:www-data "' . $targetName . '"; sudo chmod -R 777 "' . $targetName . '"'; exec($exec); } $messageSuccess = "

    Files were successfully uploaded.

    "; @@ -162,7 +162,7 @@ /* * create folder */ - $exec = 'mkdir "'.$Audio_Folders_Path.'/'.$newDirPathRel.'"; chmod 777 "'.$Audio_Folders_Path.'/'.$newDirPathRel.'"; chown -R pi:www-data "' . $Audio_Folders_Path.'/'.$newDirPathRel . '"'; + $exec = 'mkdir "'.$Audio_Folders_Path.'/'.$newDirPathRel.'"; sudo chmod -R 777 "'.$Audio_Folders_Path.'/'.$newDirPathRel.'"; chown -R pi:www-data "' . $Audio_Folders_Path.'/'.$newDirPathRel . '"'; exec($exec); $messageSuccess = "

    ".$lang['manageFilesFoldersSuccessNewFolder']." '".$newDirPathRel."'

    "; diff --git a/scripts/startup-scripts.sh b/scripts/startup-scripts.sh index 9c0dc7bc4..2538e968c 100755 --- a/scripts/startup-scripts.sh +++ b/scripts/startup-scripts.sh @@ -18,6 +18,12 @@ cat $PATHDATA/../settings/global.conf echo echo ${AUDIOVOLSTARTUP} +#################################### +# make playists, files and folders +# readable and writable to all +sudo chmod -R 777 ${AUDIOFOLDERSPATH} +sudo chmod -R 777 ${PLAYLISTSFOLDERPATH} + #################################### # check if and set volume on startup /home/pi/RPi-Jukebox-RFID/scripts/playout_controls.sh -c=setvolumetostartup From 04ad7fc6758c91061b4bc18ca9ba36e8b11c05bf Mon Sep 17 00:00:00 2001 From: Micz Flor Date: Fri, 12 Jun 2020 12:39:39 +0200 Subject: [PATCH 032/106] on boot make playlists and files chmod 777 #998 --- htdocs/inc.header.php | 10 ---------- scripts/startup-scripts.sh | 3 +-- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/htdocs/inc.header.php b/htdocs/inc.header.php index a623c67a7..e14f2a0d8 100755 --- a/htdocs/inc.header.php +++ b/htdocs/inc.header.php @@ -175,16 +175,6 @@ function fileGetContentOrDefault($filename, $defaultValue) */ include("inc.langLoad.php"); -/*======= -$Second_Swipe = trim(file_get_contents($conf['settings_abs'].'/Second_Swipe')); -$ShowCover = fileGetContentOrDefault($conf['settings_abs'].'/ShowCover', "ON"); -$version = trim(file_get_contents($conf['settings_abs'].'/version')); -$edition = fileGetContentOrDefault(dirname(__FILE__).'/../settings/edition', "classic"); -/* -* load language strings -*/ -//$conf['settings_lang'] = fileGetContentOrDefault($conf['settings_abs'].'/Lang', "en-UK"); - /******************************************* * URLPARAMETERS *******************************************/ diff --git a/scripts/startup-scripts.sh b/scripts/startup-scripts.sh index 2538e968c..f26a96261 100755 --- a/scripts/startup-scripts.sh +++ b/scripts/startup-scripts.sh @@ -19,8 +19,7 @@ echo echo ${AUDIOVOLSTARTUP} #################################### -# make playists, files and folders -# readable and writable to all +# make playists, files and folders readable and writable to all sudo chmod -R 777 ${AUDIOFOLDERSPATH} sudo chmod -R 777 ${PLAYLISTSFOLDERPATH} From 7bb4a634f39c9d3856317b1de1ef393ddeee8e25 Mon Sep 17 00:00:00 2001 From: Micz Flor Date: Fri, 12 Jun 2020 12:45:31 +0200 Subject: [PATCH 033/106] make shortcuts on reboot chmod 777 --- scripts/startup-scripts.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/startup-scripts.sh b/scripts/startup-scripts.sh index f26a96261..43c0020e2 100755 --- a/scripts/startup-scripts.sh +++ b/scripts/startup-scripts.sh @@ -19,9 +19,12 @@ echo echo ${AUDIOVOLSTARTUP} #################################### -# make playists, files and folders readable and writable to all +# make playists, files and folders +# and shortcuts +# readable and writable to all sudo chmod -R 777 ${AUDIOFOLDERSPATH} sudo chmod -R 777 ${PLAYLISTSFOLDERPATH} +sudo chmod -R 777 $PATHDATA/../shared/shortcuts #################################### # check if and set volume on startup From e59526cbd7bf4276031c2b56b1de1a170f0082d6 Mon Sep 17 00:00:00 2001 From: Micz Flor Date: Sat, 13 Jun 2020 21:31:54 +0200 Subject: [PATCH 034/106] update shopping list in README --- README.md | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7f815d74d..557ed8ab1 100755 --- a/README.md +++ b/README.md @@ -206,16 +206,35 @@ If you like your Phoniebox, consider to [buy me a coffee](https://www.buymeacoff ## Shopping list -Here is a list of equipment needed. Chances are that you will find most of it in the back of your drawers or at the bottom of some shoe box. Well, most of it, possibly not the RFID reader itself. **Note: depending on individual projects, the hardware requirements vary.** +Here is a list of equipment needed. You can find a lot second hand online (save money and the planet). The links below lead to amazon, not at all because I want to support them, but because their PartnerNet program helps to support the Phoniebox maintenance (a little bit...). **Note: depending on individual projects, the hardware requirements vary.** + +### Raspberry Pi + +* [Raspberry Pi 4 Modell B](https://amzn.to/2Yuei04) +* [Raspberry Pi 3 Model B](https://amzn.to/3fqp8ef) +* [Raspberry Pi Zero WH](https://amzn.to/3fkfKc5) +* Note: You might be surprised how easy and affordable you can get an RPi second hand. Think about the planet before you buy a new one. + +### RFID Reader and cards / fobs + +* RFID Card Reader (USB): [Neuftech USB RFID Reader ID](https://amzn.to/2RrqScm) using 125 kHz - make sure to buy compatible cards, RFID stickers or key fobs working with the same frequency as the reader. **Important notice:** the hardware of the reader that I had linked here for a long times seems to have changed and suddenly created problems with the Phoniebox installation. The reader listed now has worked and was recommended by two Phoniebox makers (2018 Oct 4). I can not guarantee that this will not change and invite you to give [RFID Reader feedback in this thread](https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/231). + * RFID cards: [125 KHz EM4100](https://amzn.to/37pjy9q) make sure the frequency matches the RFID card reader !!! + * RFID fobs / key rings: [EM4100 RFID-Transponder-Schlüsselring, 125 KHz](https://amzn.to/3hsuvLO) make sure the frequency matches the RFID card reader !!! + +* RFID Kit RC522: [RC522 Reader, Chip, Card for Raspberry Pi 13.56MHz] (https://amzn.to/2C7YZCZ) + * RFID sticker / tags: [MIFARE RFID NFC Tags](https://amzn.to/30GfLDg) untested by me personally, but reported to work with work with RC522 and PN532 card readers. + +### Speakers / amps -* [Raspberry Pi 3 Model B ](https://amzn.to/2GEUjWK) | You might be surprised how easy and affordable you can get an RPi second hand. Think about the planet before you buy a new one. -* [Raspberry Pi Zero W Starter Set ](http://amzn.to/2ku0PU7) | You might be surprised how easy and affordable you can get an RPi second hand. Think about the planet before you buy a new one. -* RFID Card Reader (USB): [Neuftech USB RFID Reader ID](https://amzn.to/2RrqScm) using 125 kHz - make sure to buy compatible cards, RFID stickers or key fobs working with the same frequency as the reader. **Important notice:** the hardware of the reader that I had linked here for a long times seems to have changed and suddenly created problems with the Phoniebox installation. The reader listed now has worked and was recommended by two Phoniebox makers (2018 Oct 4). I can not guarantee that this will not change and invite you to give [RFID Reader feedback in this thread](https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/231). * [USB Stereo Speaker Set (6 Watt, 3,5mm jack, USB-powered) black](http://amzn.to/2kXrard) | This USB powered speaker set sounds good for its size, is good value for money and keeps this RPi project clean and without the need of a soldering iron :) * [USB A Male to Female Extenstion Cable with Switch On/Off](http://amzn.to/2hHrvkG) | I placed this USB extension between the USB power adapter and the Phoniebox. This will allow you to switch the Phoniebox on and off easily. * [USB 2.0 Hub 4-port bus powered USB Adapter](http://amzn.to/2kXeErv) | Depending on your setup, you will need none, one or two of these. If you are using the external USB powered speakers, you need one to make sure the speakers get enough power. If you want to use the additional USB soundcard and have an older RPi, you might need a second one to make sure you can connect enough devices with the RPi. -* Arcade Buttons / Tasten / Schalter (one of these might suit you) - * [Arcade Buttons / Tasten / Schalter ](https://amzn.to/2QMxe9r) if you want buttons for the GPIO control. + +### Arcade Buttons + +* Arcade Buttons / Sensors (one of these might suit you) + * [Arcade Buttons / Schalter in various colours](https://amzn.to/2QMxe9r) if you want buttons for the GPIO control. + * [Arcade Buttons wit LED and custom icons](https://amzn.to/2MWQ6hq) as used by [@splitti](https://splittscheid.de/selfmade-phoniebox/#3C). * [Set: Arcade Buttons / Tasten / Schalter ](https://amzn.to/2T81JTZ) GPIO Extension Board Starter Kit including cables and breadboard. * [Touch Sensor / Kapazitive Touch Tasten ](https://amzn.to/2Vc4ntx) these are not buttons to press but to touch as GPIO controls. @@ -224,7 +243,7 @@ Here is a list of equipment needed. Chances are that you will find most of it in These are links to additional items, which will add an individual flavour to your Phoniebox setup. Consult the issue threads to see if your idea has been realised already. * [Ground Loop Isolator / Entstörfilter Audio](https://amzn.to/2Kseo0L) this seems to [get rid off crackles in the audio out (a typical RPi problem)](https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/341) -* [Meachnical audio switch](https://amzn.to/35oOSCS) if you want to connect differen audio devices, this is the easiest way (in connection with the *Ground Loop Isolator* you will get good results) +* [Mechanical audio switch](https://amzn.to/35oOSCS) if you want to connect differen audio devices, this is the easiest way (in connection with the *Ground Loop Isolator* you will get good results) * [Rotary Encoder / Drehregler / Dial](https://amzn.to/2J34guF) for volume control. Read here for more information on how to [integrate the rotary dial](https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/267) * [HiFiBerry DAC+ Soundcard](https://amzn.to/2J36cU9) Read here for more information on how to [HifiBerry Soundcard integration](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/MANUAL#hifiberry-dac-soundcard-details) * [HDMI zu HDMI + Optisches SPDIF mit 3,5-mm-Stereo-HDMI Audio-Extractor | HDMI zu SPDIF Konverter](https://amzn.to/2N8KP8C) If you plan to use video, this might be the better solution than a USB soundcard or the hifiberry. If takes up some space, but will work with the HDMI audio out and split the signal to deliver audio through 3.5mm jack. From c94448c6313cdc3e61aaea4b34e9a1de5a1eccdb Mon Sep 17 00:00:00 2001 From: Micz Flor Date: Sat, 13 Jun 2020 21:33:18 +0200 Subject: [PATCH 035/106] version 2.1rc1 --- settings/version-number | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings/version-number b/settings/version-number index cd5ac039d..b20058860 100755 --- a/settings/version-number +++ b/settings/version-number @@ -1 +1 @@ -2.0 +2.1rc1 From 9145cae4c53ca042b501a5099e1b1e9c40d5f3b3 Mon Sep 17 00:00:00 2001 From: Markus Prochaska <–3446968+ProchaskaMarkus@users.noreply.github.com> Date: Sat, 13 Jun 2020 22:16:11 +0200 Subject: [PATCH 036/106] Added option for multiple RFID Readers #760 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To use it, the two files Reader.py and RegisterDevice.py must be replaced with the *py..Multi files. If you activate multiple RFID readers it´s e.g. possible to read Card and "Figure" RFID parallel. --- scripts/Reader.py.Multi | 73 +++++++++++++++++++++++++++++++++ scripts/RegisterDevice.py.Multi | 31 ++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 scripts/Reader.py.Multi create mode 100644 scripts/RegisterDevice.py.Multi diff --git a/scripts/Reader.py.Multi b/scripts/Reader.py.Multi new file mode 100644 index 000000000..752c34b9e --- /dev/null +++ b/scripts/Reader.py.Multi @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# There are a variety of RFID readers out there, USB and non-USB variants. +# This might create problems in recognizing the reader you are using. +# We haven't found the silver bullet yet. If you can contribute to this +# quest, please comment in the issue thread or create pull requests. +# ALTERNATIVE SCRIPTS: +# If you encounter problems with this script Reader.py +# consider and test one of the alternatives in the same scripts folder. +# Replace the Reader.py file with one of the following files: +# * Reader.py.experimental +# This alternative Reader.py script was meant to cover not only USB readers but more. +# It can be used to replace Reader.py if you have readers such as +# MFRC522, RDM6300 or PN532. +# * Reader.py.kkmoonRFIDreader +# KKMOON RFID Reader which appears twice in the devices list as HID 413d:2107 +# and this required to check "if" the device is a keyboard. + +# import string +# import csv +import os.path +import sys + +from evdev import InputDevice, ecodes, list_devices +from select import select + + +def get_devices(): + return [InputDevice(fn) for fn in list_devices()] + + +class Reader: + reader = None + + def __init__(self): + self.reader = self + devs = list() + path = os.path.dirname(os.path.realpath(__file__)) + self.keys = "X^1234567890XXXXqwertzuiopXXXXasdfghjklXXXXXyxcvbnmXXXXXXXXXXXXXXXXXXXXXXX" + if not os.path.isfile(path + '/deviceName.txt'): + sys.exit('Please run RegisterDevice.py first') + else: + with open(path + '/deviceName.txt', 'r') as f: + device_keys = f.readlines() + devices = get_devices() + for device in devices: + for dev_key in device_keys: + dev_name, dev_phys = dev_key.rstrip().split(';', 1) + if device.name == dev_name and device.phys == dev_phys: + devs.append(device) + break + for dev in devs: + try: + dev + except: + sys.exit('Could not find the device %s\n. Make sure is connected' % dev.name) + + str_devs = ','.join([str(x) for x in devs]) + #print("Devs: " + str_devs) + self.devices = map(InputDevice, str_devs) + self.devices = {dev.fd: dev for dev in devs} + + def readCard(self): + stri = '' + key = '' + while key != 'KEY_ENTER': + r, w, x = select(self.devices, [], []) + for fd in r: + for event in self.devices[fd].read(): + if event.type == 1 and event.value == 1: + stri += self.keys[event.code] + # print( keys[ event.code ] ) + key = ecodes.KEY[event.code] + return stri[:-1] diff --git a/scripts/RegisterDevice.py.Multi b/scripts/RegisterDevice.py.Multi new file mode 100644 index 000000000..08cf2a3e5 --- /dev/null +++ b/scripts/RegisterDevice.py.Multi @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 + +import os.path +from Reader import get_devices + +list_dev_ids = list() +devices = get_devices() + +def addDevice(): + i = 0 + print("Choose the reader from list") + for dev in devices: + print(i, dev.name + str(dev.phys)) + i += 1 + dev_id = int(input('Device Number: ')) + if dev_id not in list_dev_ids: + list_dev_ids.append(dev_id) + + +addDevice() +while True: + answer = input('Do you want to add another device: [Y/n]') + if not answer or answer[0] != 'Y': + break + addDevice() + +path = os.path.dirname(os.path.realpath(__file__)) +with open(path + '/deviceName.txt', 'w') as f: + for sel_dev_id in list_dev_ids: + f.write(devices[sel_dev_id].name + ";" + devices[sel_dev_id].phys + '\n') + f.close() From 4e16606743e19743e9e9ef59bd89e3d72d973cdd Mon Sep 17 00:00:00 2001 From: Markus Prochaska <–3446968+ProchaskaMarkus@users.noreply.github.com> Date: Sun, 14 Jun 2020 12:56:46 +0200 Subject: [PATCH 037/106] Added multi-reader support for experimental reader --- scripts/Reader.py.experimental.Multi | 191 +++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 scripts/Reader.py.experimental.Multi diff --git a/scripts/Reader.py.experimental.Multi b/scripts/Reader.py.experimental.Multi new file mode 100644 index 000000000..db8ae85de --- /dev/null +++ b/scripts/Reader.py.experimental.Multi @@ -0,0 +1,191 @@ +#!/usr/bin/env python3 +# This alternative Reader.py script was meant to cover not only USB readers but more. +# It can be used to replace Reader.py if you have readers such as +# MFRC522, RDM6300 or PN532. +# Please use the github issue threads to share bugs and improvements +# or create pull requests. + +import os.path +import sys +import serial +import string +import RPi.GPIO as GPIO +import logging +from queue import Queue +from threading import Thread + +from evdev import InputDevice, categorize, ecodes, list_devices +# Workaround: when using RC522 reader with pirc522 pkg the py532lib pkg may not be installed and vice-versa +try: + import pirc522 + from py532lib.i2c import * + from py532lib.mifare import * +except ImportError: + pass + +logger = logging.getLogger(__name__) + + +def get_devices(): + devices = [InputDevice(fn) for fn in list_devices()] + devices.append(NonUsbDevice('MFRC522')) + devices.append(NonUsbDevice('RDM6300')) + devices.append(NonUsbDevice('PN532')) + return devices + + +class NonUsbDevice(object): + name = None + + def __init__(self, name): + self.name = name + + +class UsbReader(object): + def __init__(self, device): + self.keys = "X^1234567890XXXXqwertzuiopXXXXasdfghjklXXXXXyxcvbnmXXXXXXXXXXXXXXXXXXXXXXX" + self.dev = device + + def readCard(self): + from select import select + stri = '' + key = '' + while key != 'KEY_ENTER': + select([self.dev], [], []) + for event in self.dev.read(): + if event.type == 1 and event.value == 1: + stri += self.keys[event.code] + key = ecodes.KEY[event.code] + return stri[:-1] + + +class Mfrc522Reader(object): + def __init__(self): + self.device = pirc522.RFID() + + def readCard(self): + # Scan for cards + self.device.wait_for_tag() + (error, tag_type) = self.device.request() + + if not error: + logger.info("Card detected.") + # Perform anti-collision detection to find card uid + (error, uid) = self.device.anticoll() + if not error: + card_id = ''.join((str(x) for x in uid)) + logger.info(card_id) + return card_id + logger.debug("No Device ID found.") + return None + + @staticmethod + def cleanup(): + GPIO.cleanup() + + +class Rdm6300Reader: + def __init__(self): + device = '/dev/ttyS0' + baudrate = 9600 + ser_timeout = 0.1 + self.last_card_id = '' + try: + self.rfid_serial = serial.Serial(device, baudrate, timeout=ser_timeout) + except serial.SerialException as e: + logger.error(e) + exit(1) + + def readCard(self): + byte_card_id = b'' + + try: + while True: + try: + read_byte = self.rfid_serial.read() + + if read_byte == b'\x02': # start byte + while read_byte != b'\x03': # end bye + read_byte = self.rfid_serial.read() + byte_card_id += read_byte + + card_id = byte_card_id.decode('utf-8') + byte_card_id = '' + card_id = ''.join(x for x in card_id if x in string.printable) + + # Only return UUIDs with correct length + if len(card_id) == 12 and card_id != self.last_card_id: + self.last_card_id = card_id + self.rfid_serial.reset_input_buffer() + return self.last_card_id + + else: # wrong UUID length or already send that UUID last time + self.rfid_serial.reset_input_buffer() + + except ValueError as ve: + logger.errror(ve) + + except serial.SerialException as se: + logger.error(se) + + def cleanup(self): + self.rfid_serial.close() + + +class Pn532Reader: + def __init__(self): + pn532 = Pn532_i2c() + self.device = Mifare() + self.device.SAMconfigure() + self.device.set_max_retries(MIFARE_WAIT_FOR_ENTRY) + + def readCard(self): + return str(+int('0x' + self.device.scan_field().hex(), 0)) + + def cleanup(self): + # Not sure if something needs to be done here. + logger.debug("PN532Reader clean up.") + + +class Reader(object): + def __init__(self): + self.reader = self + self.devs = list() + path = os.path.dirname(os.path.realpath(__file__)) + if not os.path.isfile(path + '/deviceName.txt'): + sys.exit('Please run RegisterDevice.py first') + else: + with open(path + '/deviceName.txt', 'r') as f: + device_keys = f.readlines() + devices = get_devices() + for device in devices: + for dev_key in device_keys: + dev_name, dev_phys = dev_key.rstrip().split(';', 1) + if device.name == dev_name and device.phys == dev_phys: + if dev_name == 'MFRC522': + self.devs.append(Mfrc522Reader()) + elif dev_name == 'RDM6300': + self.devs.append(Rdm6300Reader()) + elif dev_name == 'PN532': + self.devs.append(Pn532Reader()) + else: + try: + usb_reader = UsbReader(device) + self.devs.append(usb_reader) + except IndexError: + sys.exit('Could not find the device %s.\n Make sure it is connected' % dev_name) + break + + def readCard(self): + que = Queue.Queue() + threads_list = list() + for dev in self.devs: + t = Thread(target=lambda q, arg1: q.put(dev.readCard(arg1)), args=(que,)) + t.start() + threads_list.append(t) + for t in threads_list: + t.join() + while not que.empty(): + result = que.get() + print(result) + return result From f5f2736fd793e5359216e332f10dd676a04a49a5 Mon Sep 17 00:00:00 2001 From: Markus Prochaska <–3446968+ProchaskaMarkus@users.noreply.github.com> Date: Sun, 14 Jun 2020 13:20:30 +0200 Subject: [PATCH 038/106] Fixed waiting for Reader result --- scripts/Reader.py.experimental.Multi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/Reader.py.experimental.Multi b/scripts/Reader.py.experimental.Multi index db8ae85de..8c5bef1f2 100644 --- a/scripts/Reader.py.experimental.Multi +++ b/scripts/Reader.py.experimental.Multi @@ -177,15 +177,15 @@ class Reader(object): break def readCard(self): - que = Queue.Queue() + que = Queue() threads_list = list() for dev in self.devs: - t = Thread(target=lambda q, arg1: q.put(dev.readCard(arg1)), args=(que,)) + t = Thread(target=lambda q: q.put(dev.readCard()), args=(que,)) t.start() threads_list.append(t) - for t in threads_list: - t.join() - while not que.empty(): - result = que.get() - print(result) - return result + #for t in threads_list: + # t.join() + while True: + for read_thread in threads_list: + if not read_thread.is_alive() and not que.empty(): + return que.get() From 860402382433559d55b4d7d6c9366810059a60e9 Mon Sep 17 00:00:00 2001 From: Markus Prochaska <–3446968+ProchaskaMarkus@users.noreply.github.com> Date: Sun, 14 Jun 2020 13:33:07 +0200 Subject: [PATCH 039/106] Added terminating processes --- scripts/Reader.py.experimental.Multi | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/scripts/Reader.py.experimental.Multi b/scripts/Reader.py.experimental.Multi index 8c5bef1f2..2f9de547b 100644 --- a/scripts/Reader.py.experimental.Multi +++ b/scripts/Reader.py.experimental.Multi @@ -4,7 +4,7 @@ # MFRC522, RDM6300 or PN532. # Please use the github issue threads to share bugs and improvements # or create pull requests. - +import multiprocessing import os.path import sys import serial @@ -12,7 +12,6 @@ import string import RPi.GPIO as GPIO import logging from queue import Queue -from threading import Thread from evdev import InputDevice, categorize, ecodes, list_devices # Workaround: when using RC522 reader with pirc522 pkg the py532lib pkg may not be installed and vice-versa @@ -180,12 +179,15 @@ class Reader(object): que = Queue() threads_list = list() for dev in self.devs: - t = Thread(target=lambda q: q.put(dev.readCard()), args=(que,)) + t = multiprocessing.Process(target=lambda q: q.put(dev.readCard()), args=(que,)) t.start() threads_list.append(t) - #for t in threads_list: - # t.join() - while True: + + while que.empty(): for read_thread in threads_list: - if not read_thread.is_alive() and not que.empty(): - return que.get() + if not read_thread.is_alive(): + break + + for process in threads_list: + process.terminate() + return que.get() From 2aeb6570f3a0633c19047798db54c5b34300bd44 Mon Sep 17 00:00:00 2001 From: Markus Prochaska <–3446968+ProchaskaMarkus@users.noreply.github.com> Date: Sun, 14 Jun 2020 21:31:00 +0200 Subject: [PATCH 040/106] Added multiple USB reader support for Reader.py.experimental (see file Reader.py.experimental.Multi) Added Register NonUSB Devices with RegisterDevice (see RegisterDevice.py.Multi) --- scripts/Reader.py.experimental.Multi | 29 ++++++++++++++------ scripts/RegisterDevice.py.Multi | 41 ++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/scripts/Reader.py.experimental.Multi b/scripts/Reader.py.experimental.Multi index 2f9de547b..e2543132f 100644 --- a/scripts/Reader.py.experimental.Multi +++ b/scripts/Reader.py.experimental.Multi @@ -5,15 +5,18 @@ # Please use the github issue threads to share bugs and improvements # or create pull requests. import multiprocessing +try: + from multiprocessing import SimpleQueue +except ImportError: + from multiprocessing.queues import SimpleQueue import os.path import sys import serial import string import RPi.GPIO as GPIO import logging -from queue import Queue -from evdev import InputDevice, categorize, ecodes, list_devices +from evdev import InputDevice, ecodes, list_devices # Workaround: when using RC522 reader with pirc522 pkg the py532lib pkg may not be installed and vice-versa try: import pirc522 @@ -36,8 +39,9 @@ def get_devices(): class NonUsbDevice(object): name = None - def __init__(self, name): + def __init__(self, name, phys=''): self.name = name + self.phys = phys class UsbReader(object): @@ -159,7 +163,11 @@ class Reader(object): devices = get_devices() for device in devices: for dev_key in device_keys: - dev_name, dev_phys = dev_key.rstrip().split(';', 1) + dev_name_phys = dev_key.rstrip().split(';', 1) + dev_name = dev_name_phys[0] + dev_phys = '' + if len(dev_name) > 1: + dev_phys = dev_name_phys[0] if device.name == dev_name and device.phys == dev_phys: if dev_name == 'MFRC522': self.devs.append(Mfrc522Reader()) @@ -176,18 +184,23 @@ class Reader(object): break def readCard(self): - que = Queue() + que = SimpleQueue() threads_list = list() + for dev in self.devs: t = multiprocessing.Process(target=lambda q: q.put(dev.readCard()), args=(que,)) t.start() threads_list.append(t) - while que.empty(): - for read_thread in threads_list: - if not read_thread.is_alive(): + found_result = False + while not found_result: + for process in threads_list: + process.join(0.001) + if not process.is_alive(): + found_result = True break for process in threads_list: process.terminate() + return que.get() diff --git a/scripts/RegisterDevice.py.Multi b/scripts/RegisterDevice.py.Multi index 08cf2a3e5..9a41fb564 100644 --- a/scripts/RegisterDevice.py.Multi +++ b/scripts/RegisterDevice.py.Multi @@ -1,28 +1,51 @@ #!/usr/bin/env python3 import os.path -from Reader import get_devices +from evdev import InputDevice, list_devices + + +class NonUsbDevice(object): + name = None + + def __init__(self, name, phys=''): + self.name = name + self.phys = phys + + +def get_devices(): + devs = [InputDevice(fn) for fn in list_devices()] + devs.append(NonUsbDevice('MFRC522')) + devs.append(NonUsbDevice('RDM6300')) + devs.append(NonUsbDevice('PN532')) + return devs + list_dev_ids = list() devices = get_devices() -def addDevice(): + +def addUsbDevice(): i = 0 print("Choose the reader from list") for dev in devices: - print(i, dev.name + str(dev.phys)) + if i not in list_dev_ids: + print(i, dev.name + str(dev.phys)) i += 1 dev_id = int(input('Device Number: ')) if dev_id not in list_dev_ids: list_dev_ids.append(dev_id) -addDevice() -while True: - answer = input('Do you want to add another device: [Y/n]') - if not answer or answer[0] != 'Y': - break - addDevice() +def configureDevices(): + addUsbDevice() + while True: + answer = input('Do you want to add another device: [Y/n]') + if not answer or answer[0] != 'Y': + break + addUsbDevice() + + +configureDevices() path = os.path.dirname(os.path.realpath(__file__)) with open(path + '/deviceName.txt', 'w') as f: From 0ba32724bb6f4ada371ab26e57b87ba3ac39987a Mon Sep 17 00:00:00 2001 From: Markus Prochaska <–3446968+ProchaskaMarkus@users.noreply.github.com> Date: Sun, 14 Jun 2020 21:39:47 +0200 Subject: [PATCH 041/106] Fixed bug when adding devices to read --- scripts/Reader.py.experimental.Multi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/Reader.py.experimental.Multi b/scripts/Reader.py.experimental.Multi index e2543132f..17e9ea3c7 100644 --- a/scripts/Reader.py.experimental.Multi +++ b/scripts/Reader.py.experimental.Multi @@ -166,8 +166,8 @@ class Reader(object): dev_name_phys = dev_key.rstrip().split(';', 1) dev_name = dev_name_phys[0] dev_phys = '' - if len(dev_name) > 1: - dev_phys = dev_name_phys[0] + if len(dev_name_phys) > 1: + dev_phys = dev_name_phys[1] if device.name == dev_name and device.phys == dev_phys: if dev_name == 'MFRC522': self.devs.append(Mfrc522Reader()) From bc1d675d591a23cbef1cd7087eeedc712d13aa2b Mon Sep 17 00:00:00 2001 From: Markus Prochaska <–3446968+ProchaskaMarkus@users.noreply.github.com> Date: Mon, 15 Jun 2020 20:14:16 +0200 Subject: [PATCH 042/106] Removed duplicate of get_devices() --- scripts/RegisterDevice.py.Multi | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/scripts/RegisterDevice.py.Multi b/scripts/RegisterDevice.py.Multi index 9a41fb564..d087a6191 100644 --- a/scripts/RegisterDevice.py.Multi +++ b/scripts/RegisterDevice.py.Multi @@ -1,23 +1,7 @@ #!/usr/bin/env python3 import os.path -from evdev import InputDevice, list_devices - - -class NonUsbDevice(object): - name = None - - def __init__(self, name, phys=''): - self.name = name - self.phys = phys - - -def get_devices(): - devs = [InputDevice(fn) for fn in list_devices()] - devs.append(NonUsbDevice('MFRC522')) - devs.append(NonUsbDevice('RDM6300')) - devs.append(NonUsbDevice('PN532')) - return devs +from Reader import get_devices list_dev_ids = list() From a5f781f89f8fd2dc204176a397e095c1509abbb9 Mon Sep 17 00:00:00 2001 From: s-martin Date: Wed, 17 Jun 2020 08:09:15 +0200 Subject: [PATCH 043/106] Enable volume normalization See #685, thanks to @belinea4071 --- misc/sampleconfigs/mpd.conf.buster-default.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/sampleconfigs/mpd.conf.buster-default.sample b/misc/sampleconfigs/mpd.conf.buster-default.sample index f219492ee..59079af0d 100755 --- a/misc/sampleconfigs/mpd.conf.buster-default.sample +++ b/misc/sampleconfigs/mpd.conf.buster-default.sample @@ -395,7 +395,7 @@ audio_output { # result in the volume of all playing audio to be adjusted so the output has # equal "loudness". This setting is disabled by default. # -#volume_normalization "no" +volume_normalization "yes" # ############################################################################### From 19a4e8dc9c5b6e2b91250d10958ab221b3bc64b3 Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 22:41:17 +0200 Subject: [PATCH 044/106] Update inc.writeGlobalConfig.sh Add some options to the global.conf for handling second swipe pause + control cards --- scripts/inc.writeGlobalConfig.sh | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/scripts/inc.writeGlobalConfig.sh b/scripts/inc.writeGlobalConfig.sh index 75f3a618d..dcf8995de 100755 --- a/scripts/inc.writeGlobalConfig.sh +++ b/scripts/inc.writeGlobalConfig.sh @@ -65,6 +65,26 @@ fi # 2. then|or read value from file SECONDSWIPE=`cat $PATHDATA/../settings/Second_Swipe` +############################################## +# Second swipe Pause +# 1. create a default if file does not exist +if [ ! -f $PATHDATA/../settings/Second_Swipe_Pause ]; then + echo "2" > $PATHDATA/../settings/Second_Swipe_Pause + chmod 777 $PATHDATA/../settings/Second_Swipe_Pause +fi +# 2. then|or read value from file +SECONDSWIPEPAUSE=`cat $PATHDATA/../settings/Second_Swipe_Pause` + +############################################## +# Second swipe Pause Controls +# 1. create a default if file does not exist +if [ ! -f $PATHDATA/../settings/Second_Swipe_Pause_Controls ]; then + echo "ON" > $PATHDATA/../settings/Second_Swipe_Pause_Controls + chmod 777 $PATHDATA/../settings/Second_Swipe_Pause_Controls +fi +# 2. then|or read value from file +SECONDSWIPEPAUSECONTROLS=`cat $PATHDATA/../settings/Second_Swipe_Pause_Controls` + ############################################## # Audio_iFace_Name # 1. create a default if file does not exist @@ -219,9 +239,22 @@ fi # 2. then|or read value from file VERSION=`cat $PATHDATA/../settings/version` +############################################## +# read control card ids +# 1. read all values from file +CMDVOLUP=`grep 'CMDVOLUP' $PATHDATA/../settings/rfid_trigger_play.conf|tail -1|sed 's/CMDVOLUP=//g'|sed 's/"//g'|tr -d "\n"|grep -o '[0-9]*'` +CMDVOLDOWN=`grep 'CMDVOLDOWN' $PATHDATA/../settings/rfid_trigger_play.conf|tail -1|sed 's/CMDVOLDOWN=//g'|sed 's/"//g'|tr -d "\n"|grep -o '[0-9]*'` +CMDNEXT=`grep 'CMDNEXT' $PATHDATA/../settings/rfid_trigger_play.conf|tail -1|sed 's/CMDNEXT=//g'|sed 's/"//g'|tr -d "\n"|grep -o '[0-9]*'` +CMDPREV=`grep 'CMDPREV' $PATHDATA/../settings/rfid_trigger_play.conf|tail -1|sed 's/CMDPREV=//g'|sed 's/"//g'|tr -d "\n"|grep -o '[0-9]*'` +CMDREWIND=`grep 'CMDREWIND' $PATHDATA/../settings/rfid_trigger_play.conf|tail -1|sed 's/CMDREWIND=//g'|sed 's/"//g'|tr -d "\n"|grep -o '[0-9]*'` +CMDSEEKFORW=`grep 'CMDSEEKFORW' $PATHDATA/../settings/rfid_trigger_play.conf|tail -1|sed 's/CMDSEEKFORW=//g'|sed 's/"//g'|tr -d "\n"|grep -o '[0-9]*'` +CMDSEEKBACK=`grep 'CMDSEEKBACK' $PATHDATA/../settings/rfid_trigger_play.conf|tail -1|sed 's/CMDSEEKBACK=//g'|sed 's/"//g'|tr -d "\n"|grep -o '[0-9]*'` + # AUDIOFOLDERSPATH # PLAYLISTSFOLDERPATH # SECONDSWIPE +# SECONDSWIPEPAUSE +# SECONDSWIPEPAUSECONTROLS # AUDIOIFACENAME # VOLUMEMANAGER # AUDIOVOLCHANGESTEP @@ -237,6 +270,13 @@ VERSION=`cat $PATHDATA/../settings/version` # EDITION # LANG # VERSION +# CMDVOLUP +# CMDVOLDOWN +# CMDNEXT +# CMDPREV +# CMDREWIND +# CMDSEEKFORW +# CMDSEEKBACK ######################################################### # WRITE CONFIG FILE @@ -244,6 +284,8 @@ rm "${PATHDATA}/../settings/global.conf" echo "AUDIOFOLDERSPATH=\"${AUDIOFOLDERSPATH}\"" >> "${PATHDATA}/../settings/global.conf" echo "PLAYLISTSFOLDERPATH=\"${PLAYLISTSFOLDERPATH}\"" >> "${PATHDATA}/../settings/global.conf" echo "SECONDSWIPE=\"${SECONDSWIPE}\"" >> "${PATHDATA}/../settings/global.conf" +echo "SECONDSWIPEPAUSE=\"${SECONDSWIPEPAUSE}\"" >> "${PATHDATA}/../settings/global.conf" +echo "SECONDSWIPEPAUSECONTROLS=\"${SECONDSWIPEPAUSECONTROLS}\"" >> "${PATHDATA}/../settings/global.conf" echo "AUDIOIFACENAME=\"${AUDIOIFACENAME}\"" >> "${PATHDATA}/../settings/global.conf" echo "VOLUMEMANAGER=\"${VOLUMEMANAGER}\"" >> "${PATHDATA}/../settings/global.conf" echo "AUDIOVOLCHANGESTEP=\"${AUDIOVOLCHANGESTEP}\"" >> "${PATHDATA}/../settings/global.conf" @@ -257,6 +299,14 @@ echo "READWLANIPYN=\"${READWLANIPYN}\"" >> "${PATHDATA}/../settings/global.conf" echo "EDITION=\"${EDITION}\"" >> "${PATHDATA}/../settings/global.conf" echo "LANG=\"${LANG}\"" >> "${PATHDATA}/../settings/global.conf" echo "VERSION=\"${VERSION}\"" >> "${PATHDATA}/../settings/global.conf" +echo "CMDVOLUP=\"${CMDVOLUP}\"" >> "${PATHDATA}/../settings/global.conf" +echo "CMDVOLDOWN=\"${CMDVOLDOWN}\"" >> "${PATHDATA}/../settings/global.conf" +echo "CMDNEXT=\"${CMDNEXT}\"" >> "${PATHDATA}/../settings/global.conf" +echo "CMDPREV=\"${CMDPREV}\"" >> "${PATHDATA}/../settings/global.conf" +echo "CMDREWIND=\"${CMDREWIND}\"" >> "${PATHDATA}/../settings/global.conf" +echo "CMDSEEKFORW=\"${CMDSEEKFORW}\"" >> "${PATHDATA}/../settings/global.conf" +echo "CMDSEEKBACK=\"${CMDSEEKBACK}\"" >> "${PATHDATA}/../settings/global.conf" + # Work in progress: #echo "MAILWLANIPYN=\"${MAILWLANIPYN}\"" >> "${PATHDATA}/../settings/global.conf" #echo "MAILWLANIPADDR=\"${MAILWLANIPADDR}\"" >> "${PATHDATA}/../settings/global.conf" From dcb33a5ebf8ead0466be2c292acae978c3d1c163 Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 22:43:03 +0200 Subject: [PATCH 045/106] Update daemon_rfid_reader.py add setable same_id_delay, can be changed from settings tab. add option, to ignore controls cards for the time delay --- scripts/daemon_rfid_reader.py | 38 ++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/scripts/daemon_rfid_reader.py b/scripts/daemon_rfid_reader.py index 2747eb674..87634fe85 100755 --- a/scripts/daemon_rfid_reader.py +++ b/scripts/daemon_rfid_reader.py @@ -4,6 +4,7 @@ import os import subprocess import time +import re from Reader import Reader @@ -21,11 +22,40 @@ dir_path = os.path.dirname(os.path.realpath(__file__)) logger.info('Dir_PATH: {dir_path}'.format(dir_path=dir_path)) +# get control card ids +file_path = os.path.dirname(__file__) +if file_path != "": + os.chdir(file_path) + # vars for ensuring delay between same-card-swipes -same_id_delay = 0 +ssp = open('../settings/Second_Swipe_Pause', 'r') +same_id_delay = ssp.read().strip() +sspc = open('../settings/Second_Swipe_Pause_Controls', 'r') +sspc_nodelay = sspc.readline().strip() previous_id = "" previous_time = time.time() +#create array for control card ids +cards = [] + +# open file and read the content in a list +with open('../settings/global.conf', 'r') as filehandle: + filecontents = filehandle.readlines() + + for line in filecontents: + current_place = line[:-1] + cards.append(current_place) + + +extract = [s for s in cards if s.startswith('CMD')] +string = ''.join(extract) + +# if controlcards delay is deactivated, let the cards pass, otherwise, they have to wait... +if sspc_nodelay == "ON": + ids = re.findall("(\d+)", string) +else: + ids = "" + while True: # reading the card id # NOTE: it's been reported that KKMOON Reader might need the following line altered. @@ -40,16 +70,18 @@ # start the player script and pass on the cardid (but only if new card or otherwise # "same_id_delay" seconds have passed) if cardid is not None: - if cardid != previous_id or (time.time() - previous_time) >= same_id_delay: + if cardid != previous_id or (time.time() - previous_time) >= float(same_id_delay) or cardid in str(ids): logger.info('Trigger Play Cardid={cardid}'.format(cardid=cardid)) subprocess.call([dir_path + '/rfid_trigger_play.sh --cardid=' + cardid], shell=True) previous_id = cardid - previous_time = time.time() + else: logger.debug('Ignoring Card id {cardid} due to same-card-delay, delay: {same_id_delay}'.format( cardid=cardid, same_id_delay=same_id_delay )) + previous_time = time.time() + except OSError as e: logger.error('Execution failed: {e}'.format(e=e)) From 4d58e36d830a1a98cddf0c3895c34ae884c4ccbc Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 22:44:43 +0200 Subject: [PATCH 046/106] Update lang-de-DE.php --- htdocs/lang/lang-de-DE.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/htdocs/lang/lang-de-DE.php b/htdocs/lang/lang-de-DE.php index d7d7d0fbb..2a10711df 100755 --- a/htdocs/lang/lang-de-DE.php +++ b/htdocs/lang/lang-de-DE.php @@ -147,7 +147,7 @@ $lang['cardFormStreamLegend'] = "Stream verlinken / erstellen"; $lang['cardFormStreamLabel'] = "Stream URL (benötigt immer einen neuen Ordner - s.o.)"; $lang['cardFormStreamPlaceholderClassic'] = "http(...).mp3 / .m3u / .ogg / .rss / .xml / ..."; -$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:(user:username:)album/track/playlist:#### / Livestream: http(....).mp3 / .m3u / .ogg / ...."; +$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:album/artist/playlist/track:#### / Livestream: http(....).mp3 / .m3u / .ogg / ...."; $lang['cardFormStreamHelp'] = "Füge die URL für spotify, Podcast, Webradio, Stream oder andere Online-Medien hinzu"; $lang['cardFormStreamTypeSelectDefault'] = "Wähle den Typ"; $lang['cardFormStreamTypeHelp'] = "Wähle die Art des Streams, den du hinzufügen möchtest"; @@ -217,6 +217,12 @@ $lang['settingsSecondSwipePause'] = "Pause / Wiedergabe umschalten"; $lang['settingsSecondSwipePlay'] = "Wiedergabe fortsetzen"; $lang['settingsSecondSwipeNoAudioPlay'] = "Nur Systembefehle mehrfach ausführen"; +$lang['settingsSecondSwipePauseInfo'] = "Ignoriere das erneute Scannen derselben Karte für:"; +$lang['second'] = "Sekunde"; +$lang['seconds'] = "Sekunden"; +$lang['settingsSecondSwipePauseControlsInfo'] = "Bestimmte Funktionskarten (z.B. Lautstärke hoch/runter, Nächster/Voriger Titel, Vor-/Zurückspulen) sollen keine Verzögerung (wie in der Einstellung zuvor eingestellt) haben:"; +$lang['settingsSecondSwipePauseControlsOn'] = "Funktionskarten ohne Verzögerung"; +$lang['settingsSecondSwipePauseControlsOff'] = "Funktionskarten mit Verzögerung (Sekunden wie zuvor)"; $lang['settingsWebInterface'] = "Web-Oberfläche"; $lang['settingsCoverInfo'] = "Willst du Cover neben den Alben und Playlisten auf der Hauptseite anzeigen?"; $lang['settingsShowCoverON'] = "Cover anzeigen"; @@ -278,4 +284,14 @@ $lang['searchExample'] = "z.B. Moonlight"; $lang['searchSend'] = "Suchen"; $lang['searchResult'] = "Suchergebnisse:"; + +/* +* Filter +*/ +$lang['filterall'] = "Zeige alle"; +$lang['filterfile'] = "Dateien"; +$lang['filterlivestream'] = "Livestream"; +$lang['filterpodcast'] = "Podcast"; +$lang['filterspotify'] = "Spotify"; +$lang['filteryoutube'] = "YouTube"; ?> From 4868376cdd8fbf37f3b4f97f17559997db001377 Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 22:45:00 +0200 Subject: [PATCH 047/106] Update lang-en-UK.php --- htdocs/lang/lang-en-UK.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/htdocs/lang/lang-en-UK.php b/htdocs/lang/lang-en-UK.php index 999180706..c55fbc167 100755 --- a/htdocs/lang/lang-en-UK.php +++ b/htdocs/lang/lang-en-UK.php @@ -147,7 +147,7 @@ $lang['cardFormStreamLegend'] = "Link Stream"; $lang['cardFormStreamLabel'] = "Stream URL (always requires new folder above)"; $lang['cardFormStreamPlaceholderClassic'] = "http(...).mp3 / .m3u / .ogg / .rss / .xml / ..."; -$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:(user:username:)album/track/playlist:### / Stream/Podcast like http....mp3 .xml .rss .ogg"; +$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:album/artist/playlist/track/:### / Stream/Podcast like http....mp3 .xml .rss .ogg"; $lang['cardFormStreamHelp'] = "Add the URL for spotify, podcast, web radio, stream or other online media"; $lang['cardFormStreamTypeSelectDefault'] = "Select type"; $lang['cardFormStreamTypeHelp'] = "Select the type you are adding"; @@ -217,6 +217,12 @@ $lang['settingsSecondSwipePause'] = "Toggle pause / play"; $lang['settingsSecondSwipePlay'] = "Resume playback"; $lang['settingsSecondSwipeNoAudioPlay'] = "Ignore audio playout triggers, only system commands"; +$lang['settingsSecondSwipePauseInfo'] = "Ignore rescanning of the same card for:"; +$lang['second'] = "second"; +$lang['seconds'] = "seconds"; +$lang['settingsSecondSwipePauseControlsInfo'] = "Certain function cards (e.g. volume up / down, next / previous track, forward / rewind) should not have a delay (as set in the setting previously):"; +$lang['settingsSecondSwipePauseControlsOn'] = "Function cards without delay"; +$lang['settingsSecondSwipePauseControlsOff'] = "Function cards with delay (seconds as before)"; $lang['settingsWebInterface'] = "Web Interface"; $lang['settingsCoverInfo'] = "Do you want to show covers beside the albums and playlists on the main page?"; $lang['settingsShowCoverON'] = "Show cover"; @@ -279,4 +285,14 @@ $lang['searchExample'] = "z.B. Moonlight"; $lang['searchSend'] = "Search"; $lang['searchResult'] = "Search-Results:"; + +/* +* Filter +*/ +$lang['filterall'] = "Show all"; +$lang['filterfile'] = "Files"; +$lang['filterlivestream'] = "Livestream"; +$lang['filterpodcast'] = "Podcast"; +$lang['filterspotify'] = "Spotify"; +$lang['filteryoutube'] = "YouTube"; ?> From 22fa034c3dd8b41bd7f8cb247d09a7d770430ac8 Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 22:45:18 +0200 Subject: [PATCH 048/106] Update lang-nl-NL.php --- htdocs/lang/lang-nl-NL.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/htdocs/lang/lang-nl-NL.php b/htdocs/lang/lang-nl-NL.php index 87041b66b..f70c32e64 100755 --- a/htdocs/lang/lang-nl-NL.php +++ b/htdocs/lang/lang-nl-NL.php @@ -119,7 +119,7 @@ $lang['cardFormFolderSelectDefault'] = "Geen (Pulldown om een ​​map te selecteren)"; $lang['cardFormStreamLabel'] = "b) ... of maak verbinding met de Stream-URL"; $lang['cardFormStreamPlaceholderClassic'] = "Livestream: http(...).mp3 / .m3u / .ogg / ..."; -$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:(user:username:)album/track/playlist:### / Livestream: http(...).mp3 / .m3u / .ogg / ..."; +$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:album/artist/playlist/track:### / Livestream: http(...).mp3 / .m3u / .ogg / ..."; $lang['cardFormStreamHelp'] = "Voeg de URL toe voor spotify, podcast, webradio, stream of andere online media"; $lang['cardFormStreamTypeSelectDefault'] = "Selecteer type"; $lang['cardFormStreamTypeHelp'] = "Selecteer het type dat u toevoegt"; @@ -163,6 +163,12 @@ $lang['settingsSecondSwipeSkipnext'] = "Ga naar het volgende nummer"; $lang['settingsSecondSwipePause'] = "Schakelen tussen pauze / afspelen"; $lang['settingsSecondSwipeNoAudioPlay'] = "Negeer audio playout-triggers, alleen systeemopdrachten"; +$lang['settingsSecondSwipePauseInfo'] = "Negeer het opnieuw scannen van dezelfde kaart voor:"; +$lang['second'] = "Seconde"; +$lang['seconds'] = "Seconden"; +$lang['settingsSecondSwipePauseControlsInfo'] = "Bepaalde functiekaarten (bijv. Volume omhoog / omlaag, volgende / vorige track, snel vooruit / terugspoelen) mogen geen vertraging hebben (zoals eerder ingesteld in de instelling):"; +$lang['settingsSecondSwipePauseControlsOn'] = "Functiekaarten zonder vertraging"; +$lang['settingsSecondSwipePauseControlsOff'] = "Functiekaarten met vertraging (seconden als voorheen)"; $lang['settingsWebInterface'] = "Web Interface"; $lang['settingsCoverInfo'] = "Wil je albumhoezen naast de albums en afspeellijsten op de hoofdpagina weergeven?"; $lang['settingsShowCoverON'] = "Albumhoes laten zien"; @@ -205,5 +211,15 @@ $lang['searchExample'] = "z.B. Moonlight"; $lang['searchSend'] = "Zoeken"; $lang['searchResult'] = "Zoekresultaten:"; + +/* +* Filter +*/ +$lang['filterall'] = "Toon alles"; +$lang['filterfile'] = "Bestanden"; +$lang['filterlivestream'] = "Livestream"; +$lang['filterpodcast'] = "Podcast"; +$lang['filterspotify'] = "Spotify"; +$lang['filteryoutube'] = "YouTube"; ?> From fe3239af297f7e7218a4be337d227f9c28dc3b16 Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 22:47:35 +0200 Subject: [PATCH 049/106] Update settings.php add second swipe pause add second swipe pause (control card handling) --- htdocs/settings.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/settings.php b/htdocs/settings.php index 2aa981e11..51a0fa4a2 100755 --- a/htdocs/settings.php +++ b/htdocs/settings.php @@ -222,6 +222,8 @@
    From eb5a93a09d1cd01b485df7c04de1f9f4e254d3d0 Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 22:48:45 +0200 Subject: [PATCH 050/106] Update inc.header.php add second swipe pause add second swipe pause (control cards handling) --- htdocs/inc.header.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/inc.header.php b/htdocs/inc.header.php index e14f2a0d8..543778a22 100755 --- a/htdocs/inc.header.php +++ b/htdocs/inc.header.php @@ -154,6 +154,8 @@ function fileGetContentOrDefault($filename, $defaultValue) $Audio_Folders_Path = $globalConf['AUDIOFOLDERSPATH']; $Playlists_Folders_Path = $globalConf['PLAYLISTSFOLDERPATH']; $Second_Swipe = $globalConf['SECONDSWIPE']; +$Second_Swipe_Pause = $globalConf['SECONDSWIPEPAUSE']; +$Second_Swipe_Pause_Controls = $globalConf['SECONDSWIPEPAUSECONTROLS']; $VolumeManager = $globalConf['VOLUMEMANAGER']; $ShowCover = $globalConf['SHOWCOVER']; $WlanIpReadYN = $globalConf['READWLANIPYN']; From 133ac8b34ac9dc3e1ad30ae2337d4fcfee77c1c4 Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 22:49:45 +0200 Subject: [PATCH 051/106] Add files via upload add second swipe pause add second swipe pause (control cards handling) --- htdocs/inc.setSecondSwipePause.php | 186 +++++++++++++++++++++ htdocs/inc.setSecondSwipePauseControls.php | 61 +++++++ 2 files changed, 247 insertions(+) create mode 100644 htdocs/inc.setSecondSwipePause.php create mode 100644 htdocs/inc.setSecondSwipePauseControls.php diff --git a/htdocs/inc.setSecondSwipePause.php b/htdocs/inc.setSecondSwipePause.php new file mode 100644 index 000000000..c2b350749 --- /dev/null +++ b/htdocs/inc.setSecondSwipePause.php @@ -0,0 +1,186 @@ + + '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePause']) == "1") { + $Second_Swipe_Pause = "1"; + $exec = 'echo "'.$Second_Swipe_Pause.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePause']) == "2") { + $Second_Swipe_Pause = "2"; + $exec = 'echo "'.$Second_Swipe_Pause.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePause']) == "3") { + $Second_Swipe_Pause = "3"; + $exec = 'echo "'.$Second_Swipe_Pause.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePause']) == "4") { + $Second_Swipe_Pause = "4"; + $exec = 'echo "'.$Second_Swipe_Pause.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePause']) == "5") { + $Second_Swipe_Pause = "5"; + $exec = 'echo "'.$Second_Swipe_Pause.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePause']) == "6") { + $Second_Swipe_Pause = "6"; + $exec = 'echo "'.$Second_Swipe_Pause.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePause']) == "7") { + $Second_Swipe_Pause = "7"; + $exec = 'echo "'.$Second_Swipe_Pause.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePause']) == "8") { + $Second_Swipe_Pause = "8"; + $exec = 'echo "'.$Second_Swipe_Pause.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePause']) == "9") { + $Second_Swipe_Pause = "9"; + $exec = 'echo "'.$Second_Swipe_Pause.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePause']) == "10") { + $Second_Swipe_Pause = "10"; + $exec = 'echo "'.$Second_Swipe_Pause.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause'; + if($debug == "true") { + print $exec; + } + exec($exec); + } + // execute shell to create config file + exec("sudo ".$conf['scripts_abs']."/inc.writeGlobalConfig.sh"); +} +?> + +
    +
    +

    +
    '> +
    + + + '/> + +
    +
    +
    + +
    + diff --git a/htdocs/inc.setSecondSwipePauseControls.php b/htdocs/inc.setSecondSwipePauseControls.php new file mode 100644 index 000000000..befe9cc95 --- /dev/null +++ b/htdocs/inc.setSecondSwipePauseControls.php @@ -0,0 +1,61 @@ + + '.$conf['settings_abs'].'/Second_Swipe_Pause_Controls'; + if($debug == "true") { + print $exec; + } + exec($exec); + } elseif(trim($_POST['secondSwipePauseControls']) == "OFF") { + $Second_Swipe_Pause_Controls = "OFF"; + $exec = 'echo "'.$Second_Swipe_Pause_Controls.'" > '.$conf['settings_abs'].'/Second_Swipe_Pause_Controls'; + if($debug == "true") { + print $exec; + } + exec($exec); + } + // execute shell to create config file + exec("sudo ".$conf['scripts_abs']."/inc.writeGlobalConfig.sh"); +} +?> + +
    +
    +

    +
    '> +
    + + + '/> + +
    +
    +
    + +
    + From 944c0b3aa7f630d245afdb5c56404d342225ed15 Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 23:25:00 +0200 Subject: [PATCH 052/106] Update daemon_rfid_reader.py --- scripts/daemon_rfid_reader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/daemon_rfid_reader.py b/scripts/daemon_rfid_reader.py index 87634fe85..83e0e9d94 100755 --- a/scripts/daemon_rfid_reader.py +++ b/scripts/daemon_rfid_reader.py @@ -43,8 +43,8 @@ filecontents = filehandle.readlines() for line in filecontents: - current_place = line[:-1] - cards.append(current_place) + cids = line[:-1] + cards.append(cids) extract = [s for s in cards if s.startswith('CMD')] From 5e27fd09f15f9c9693d1bc9c89ef1930e4ae4a3e Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 23:28:47 +0200 Subject: [PATCH 053/106] Wait until server is running (#1026) * Update startup-scripts.sh Adding a while-loop for checking the mopidy/MPD server status. The startup-script continues when server is up and running. So, now the startup-sound indicates that the box and all packages are ready to use. * Update ajax.loadMopidyStatus.php in the information tab you can still see, the mopidy server status. But this is only the status of the service. I added seperate informations about service and server. --- htdocs/ajax.loadMopidyStatus.php | 7 ++++++- scripts/startup-scripts.sh | 7 +++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/htdocs/ajax.loadMopidyStatus.php b/htdocs/ajax.loadMopidyStatus.php index 3ffb3f420..7c740e80d 100755 --- a/htdocs/ajax.loadMopidyStatus.php +++ b/htdocs/ajax.loadMopidyStatus.php @@ -1,4 +1,9 @@ Mopidy.Service: " . exec("systemctl status mopidy | grep 'Active: '| sed 's/Active: //g'"); +} else { +$mopidystatus = "Mopidy.Server: Disconnected!
    Mopidy.Service: " . exec("systemctl status mopidy | grep 'Active: '| sed 's/Active: //g'"); +} ?>
    diff --git a/scripts/startup-scripts.sh b/scripts/startup-scripts.sh index 43c0020e2..92e37ad5f 100755 --- a/scripts/startup-scripts.sh +++ b/scripts/startup-scripts.sh @@ -26,14 +26,17 @@ sudo chmod -R 777 ${AUDIOFOLDERSPATH} sudo chmod -R 777 ${PLAYLISTSFOLDERPATH} sudo chmod -R 777 $PATHDATA/../shared/shortcuts +######################################### +# wait until mopidy/MPD server is running +STATUS=0 +while [ "$STATUS" != "ACTIVE" ]; do STATUS=$(echo -e status\\nclose | nc -w 1 localhost 6600 | grep 'OK MPD'| sed 's/^.*$/ACTIVE/'); done + #################################### # check if and set volume on startup /home/pi/RPi-Jukebox-RFID/scripts/playout_controls.sh -c=setvolumetostartup #################### # play startup sound -# after some sleep -/bin/sleep 2 /usr/bin/mpg123 /home/pi/RPi-Jukebox-RFID/shared/startupsound.mp3 ####################### From ccbe92c2cc6aa5a99664f8e9469298a93d5a07a2 Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sun, 28 Jun 2020 23:29:35 +0200 Subject: [PATCH 054/106] Fix for getting infos from Spotify (now supporting album + artist URLs) (#1025) * Update inc.viewFolderTree.php The mediatypes "track" and "playlist" were integrated, but "artist" and "album" are missing. There is no way to get this information from the mopidy.core.api, so we get the infos (including cover) from spotify web UI. Following informations are written to "title.txt" for the mediatypes: artist: artistname album: albumname track: trackname playlist: playlistname * Update inc.viewFolderTree.php Removed deprecated code --- htdocs/inc.viewFolderTree.php | 64 +++++++++++------------------------ 1 file changed, 20 insertions(+), 44 deletions(-) diff --git a/htdocs/inc.viewFolderTree.php b/htdocs/inc.viewFolderTree.php index 30478c09c..2ed928ddf 100755 --- a/htdocs/inc.viewFolderTree.php +++ b/htdocs/inc.viewFolderTree.php @@ -112,53 +112,29 @@ $temp['type'] = "spotify"; $titlefile = $subfolder."/title.txt"; $coverfile = $subfolder."/cover.jpg"; - - // get title from Spotify if wasn't previously stored - if (!file_exists($titlefile)) { - $uri = file_get_contents($subfolder."/spotify.txt"); - - // check for mediatype ("track" / "playlist") because following Mopidy API request needs differing parameters - $mediatype = explode(':' , $uri)[1]; - - if ($mediatype == "playlist"){ - // request media info via Mopidy's API - $method = 'core.playlists.lookup'; - $params = '{ - "uri": "'.trim($uri).'" - }'; - $json = mopidyApiCall($method, $params); - - $title = $json["result"]["name"]; - - } elseif ($mediatype == "track") { - // request media info via Mopidy's API - $method = 'core.library.lookup'; - $params = '{ - "uris": ["'.trim($uri).'"] - }'; - $json = mopidyApiCall($method, $params); - - $title = $json["result"][trim($uri)][0]["name"]; - } - file_put_contents($titlefile, $title); + + // this is a new and easier way for loading spotify informations! + $uri = file_get_contents($subfolder."/spotify.txt"); + $url = "https://open.spotify.com/oembed/?url=".trim($uri)."&format=json"; + + if (!file_exists($coverfile)) { + $str = file_get_contents($url); + $json = json_decode($str, true); + + $cover = $json['thumbnail_url']; + $coverdl = file_get_contents($cover); + file_put_contents($coverfile, $coverdl); } + + if (!file_exists($titlefile)) { + $str = file_get_contents($url); + $json = json_decode($str, true); - // get cover from Spotify if wasn't previously stored - if (!file_exists($coverfile)) { - $uri = file_get_contents($subfolder."/spotify.txt"); - - // request media-related images via Mopidy's API - $method = 'core.library.get_images'; - $params = '{ - "uris": ["'.trim($uri).'"] - }'; - $json = mopidyApiCall($method, $params); - - $coveruri = $json["result"][trim($uri)][0]["uri"]; - $cover = file_get_contents($coveruri); - - file_put_contents($coverfile, $cover); + $title = $json['title']; + file_put_contents($titlefile, $title); } + + } else { $temp['type'] = "generic"; } From dc2a864936a53adfc214b1490fe6ee3f16b4173d Mon Sep 17 00:00:00 2001 From: Markus Prochaska <–3446968+ProchaskaMarkus@users.noreply.github.com> Date: Thu, 2 Jul 2020 20:59:49 +0200 Subject: [PATCH 055/106] Update of Multi reader and install script -Added Multi Reader registration to buster-install-default.sh as extra option -Changed the installscripts/buster-install-default.sh to use new RegisterDevice.py.Multi -Added requirement for PN532 and RC522 installation direct to RegisterDevice.py.Multi if the user chooses it. --- scripts/Reader.py.experimental.Multi | 13 +++- scripts/RegisterDevice.py.Multi | 75 +++++++++++++++++-- .../installscripts/buster-install-default.sh | 7 +- 3 files changed, 85 insertions(+), 10 deletions(-) diff --git a/scripts/Reader.py.experimental.Multi b/scripts/Reader.py.experimental.Multi index 17e9ea3c7..326a5bd86 100644 --- a/scripts/Reader.py.experimental.Multi +++ b/scripts/Reader.py.experimental.Multi @@ -15,7 +15,7 @@ import serial import string import RPi.GPIO as GPIO import logging - +from enum import Enum from evdev import InputDevice, ecodes, list_devices # Workaround: when using RC522 reader with pirc522 pkg the py532lib pkg may not be installed and vice-versa try: @@ -27,12 +27,17 @@ except ImportError: logger = logging.getLogger(__name__) +class EDevices(Enum): + MFRC522 = 0 + RDM6300 = 1 + PN532 = 2 + def get_devices(): devices = [InputDevice(fn) for fn in list_devices()] - devices.append(NonUsbDevice('MFRC522')) - devices.append(NonUsbDevice('RDM6300')) - devices.append(NonUsbDevice('PN532')) + devices.append(NonUsbDevice(EDevices.MFRC522.name)) + devices.append(NonUsbDevice(EDevices.RDM6300.name)) + devices.append(NonUsbDevice(EDevices.PN532.name)) return devices diff --git a/scripts/RegisterDevice.py.Multi b/scripts/RegisterDevice.py.Multi index d087a6191..9974ca875 100644 --- a/scripts/RegisterDevice.py.Multi +++ b/scripts/RegisterDevice.py.Multi @@ -1,14 +1,59 @@ #!/usr/bin/env python3 import os.path -from Reader import get_devices +import subprocess +JUKEBOX_HOME_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +def runCmd(cmd, wait=True): + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) + (output, err) = p.communicate() + if wait: + p.wait() + return output + +def setupPN532(): + answer = input('Please make sure that the PN532 reader is wired up correctly ' + 'to the GPIO ports before continuing...\n Continue?: [Y/n]') + if not answer or answer[0] != 'Y': + return False + print("Activating I2C interface...\n") + runCmd("sudo raspi-config nonint do_i2c 0") + print("Installing i2c-tools...\n") + runCmd("sudo apt-get -qq -y install i2c-tools") + print("Checking if PN532 RFID reader is found through I2C...\n") + output = runCmd("sudo i2cdetect -y 1") + if "24" in str(output): + print(" PN532 was found.\n") + else: + print(" ERROR: PN532 was not found.\n") + print(str(output)) + return False + print("Installing Python requirements for PN532...\n") + runCmd("sudo python3 -m pip install --upgrade --force-reinstall " + "-q -r {}/components/rfid-reader/PN532/requirements.txt".format(JUKEBOX_HOME_DIR)) + print("Done") + return True + + +def setupMFRC522(): + answer = input('Please make sure that the RC522 reader is wired up correctly ' + 'to the GPIO ports before continuing...\n Continue?: [Y/n]') + if not answer or answer[0] != 'Y': + return False + print("Installing Python requirements for RC522...\n") + runCmd("sudo python3 -m pip install --upgrade --force-reinstall " + "-q -r {}/components/rfid-reader/RC522/requirements.txt".format(JUKEBOX_HOME_DIR)) + print("Done") + return True + + +runCmd("cp {0}/scripts/Reader.py.experimental.Multi {1}/scripts/Reader.py".format(JUKEBOX_HOME_DIR, JUKEBOX_HOME_DIR)) +from Reader import get_devices, EDevices list_dev_ids = list() devices = get_devices() - -def addUsbDevice(): +def addDevice(): i = 0 print("Choose the reader from list") for dev in devices: @@ -17,17 +62,26 @@ def addUsbDevice(): i += 1 dev_id = int(input('Device Number: ')) if dev_id not in list_dev_ids: + if devices[dev_id].name == EDevices.PN532.name: + if not setupPN532(): + return + if devices[dev_id].name == EDevices.MFRC522.name: + if not setupMFRC522(): + return list_dev_ids.append(dev_id) def configureDevices(): - addUsbDevice() + addDevice() while True: answer = input('Do you want to add another device: [Y/n]') if not answer or answer[0] != 'Y': break - addUsbDevice() + addDevice() + +print("Stopping phoniebox-rfid-reader service...\n") +runCmd("sudo systemctl stop phoniebox-rfid-reader.service") configureDevices() @@ -36,3 +90,14 @@ with open(path + '/deviceName.txt', 'w') as f: for sel_dev_id in list_dev_ids: f.write(devices[sel_dev_id].name + ";" + devices[sel_dev_id].phys + '\n') f.close() + +print("Restarting phoniebox-rfid-reader service...\n") +runCmd("sudo systemctl start phoniebox-rfid-reader.service") + +runCmd("sudo chown pi:www-data {}/scripts/deviceName.txt".format(JUKEBOX_HOME_DIR)) +runCmd("sudo chmod 644 {}/scripts/deviceName.txt".format(JUKEBOX_HOME_DIR)) + +print("Register Device(s) Done!") + + + diff --git a/scripts/installscripts/buster-install-default.sh b/scripts/installscripts/buster-install-default.sh index d1c35e41a..26241e901 100755 --- a/scripts/installscripts/buster-install-default.sh +++ b/scripts/installscripts/buster-install-default.sh @@ -1108,7 +1108,7 @@ finish_installation() { ;; *) echo 'Please select the RFID reader you want to use' - options=("USB-Reader (e.g. Neuftech)" "RC522" "PN532" "Manual configuration") + options=("USB-Reader (e.g. Neuftech)" "RC522" "PN532" "Manual configuration" "Multiple RFID reader") select opt in "${options[@]}"; do case $opt in "USB-Reader (e.g. Neuftech)") @@ -1130,6 +1130,11 @@ finish_installation() { echo "Please configure your reader manually." break ;; + "Multiple RFID reader") + cd "${jukebox_dir}"/scripts/ || exit + sudo python3 RegisterDevice.py.Multi + break + ;; *) echo "This is not a number" ;; From d5db9349357f890bb90f9dc1dcc746e10dc41fa3 Mon Sep 17 00:00:00 2001 From: themorlan <48086551+themorlan@users.noreply.github.com> Date: Sun, 5 Jul 2020 21:01:31 +0200 Subject: [PATCH 056/106] Fix incorrect ownership of ~/.config/phoniebox (#1035) The `chown` command in line 61 changes the ownership of the gpio_settings.ini to the correct user. Because the script is run with sudo command root is the of ~/.config/phoniebox which leads to an error in gpio_control.py. The altered `chown` command leads to the folder and the the .ini to be owned by the correct user. --- components/gpio_control/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/gpio_control/install.sh b/components/gpio_control/install.sh index f45137132..7f224fb7b 100755 --- a/components/gpio_control/install.sh +++ b/components/gpio_control/install.sh @@ -58,7 +58,7 @@ else done fi -chown -R ${SUDO_USER}:${SUDO_USER} $FILE +chown -R ${SUDO_USER}:${SUDO_USER} $USER_HOME/.config/phoniebox/ echo echo 'Installing GPIO_Control service, this will require to enter your password up to 3 times to enable the service' From e42963e6c77dc9b0c96b9b6e50966f315f3e158a Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Sat, 11 Jul 2020 22:34:01 +0200 Subject: [PATCH 057/106] WebUI enhancement - Add filter option for mediatypes (#1028) * Update inc.processCheckCardEditRegister.php Create a file, when youtube is selected, needed for filtering * Update lang-nl-NL.php filtering * Update lang-en-UK.php filtering * Update lang-de-DE.php filtering * Update index.php filtering * Update func.php filtering * Update inc.viewFolderTree.php filtering * Update lang-de-DE.php * Update lang-en-UK.php * Update lang-nl-NL.php * Update index.php --- htdocs/func.php | 33 +++++++- htdocs/inc.processCheckCardEditRegister.php | 4 + htdocs/inc.viewFolderTree.php | 3 +- htdocs/index.php | 94 ++++++++++++++++++++- htdocs/lang/lang-de-DE.php | 12 ++- htdocs/lang/lang-en-UK.php | 12 ++- htdocs/lang/lang-nl-NL.php | 12 ++- 7 files changed, 161 insertions(+), 9 deletions(-) diff --git a/htdocs/func.php b/htdocs/func.php index 97fd92c7f..709667794 100755 --- a/htdocs/func.php +++ b/htdocs/func.php @@ -308,6 +308,29 @@ function index_folders_print($item, $key) print ''; } */ + + /* filter */ + if (in_array($contentTree[$key]['path_abs']."/spotify.txt", $contentTree[$key]['files'])) { + print " +
    "; + + } elseif (in_array($contentTree[$key]['path_abs']."/livestream.txt", $contentTree[$key]['files'])) { + print " +
    "; + + } elseif (in_array($contentTree[$key]['path_abs']."/podcast.txt", $contentTree[$key]['files'])) { + print " +
    "; + + } elseif (in_array($contentTree[$key]['path_abs']."/youtube.txt", $contentTree[$key]['files'])) { + print " +
    "; + + } else { + print " +
    "; + } + print "
    "; @@ -332,7 +355,7 @@ function index_folders_print($item, $key) print " "; } - if (!in_array($contentTree[$key]['path_abs']."/livestream.txt", $contentTree[$key]['files']) && !in_array($contentTree[$key]['path_abs']."/spotify.txt", $contentTree[$key]['files']) && !in_array($contentTree[$key]['path_abs']."/podcast.txt", $contentTree[$key]['files']) ) { + if (!in_array($contentTree[$key]['path_abs']."/livestream.txt", $contentTree[$key]['files']) && !in_array($contentTree[$key]['path_abs']."/spotify.txt", $contentTree[$key]['files']) && !in_array($contentTree[$key]['path_abs']."/podcast.txt", $contentTree[$key]['files']) && !in_array($contentTree[$key]['path_abs']."/youtube.txt", $contentTree[$key]['files']) ) { print " "; @@ -355,11 +378,15 @@ function index_folders_print($item, $key) print $contentTree[$key]['basename']; } } elseif (in_array($contentTree[$key]['path_abs']."/livestream.txt", $contentTree[$key]['files'])) { - print " "; + print " "; print $contentTree[$key]['basename']; } elseif (in_array($contentTree[$key]['path_abs']."/podcast.txt", $contentTree[$key]['files'])) { - print " "; + print " "; + print $contentTree[$key]['basename']; + + } elseif (in_array($contentTree[$key]['path_abs']."/youtube.txt", $contentTree[$key]['files'])) { + print " "; print $contentTree[$key]['basename']; } else { diff --git a/htdocs/inc.processCheckCardEditRegister.php b/htdocs/inc.processCheckCardEditRegister.php index b10d56ff6..7d96dcf53 100755 --- a/htdocs/inc.processCheckCardEditRegister.php +++ b/htdocs/inc.processCheckCardEditRegister.php @@ -254,6 +254,10 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { // New folder is created so we link a RFID to it. Write $post['audiofolderNew'] to cardID file in shortcuts $exec = "rm ".$fileshortcuts."; echo '".$post['audiofolderNew']."' > ".$fileshortcuts."; chmod 777 ".$fileshortcuts; exec($exec); + // write $streamfile and make accessible to anyone + $ytfile = "youtube.txt"; + $exec = "echo '' > '".$foldername."/".$ytfile."'; sudo chmod -R 777 '".$foldername."'"; + exec($exec); } else { // link to existing audiofolder $foldername = $Audio_Folders_Path."/".$post['audiofolder']; diff --git a/htdocs/inc.viewFolderTree.php b/htdocs/inc.viewFolderTree.php index 2ed928ddf..70e3eb5db 100755 --- a/htdocs/inc.viewFolderTree.php +++ b/htdocs/inc.viewFolderTree.php @@ -134,7 +134,6 @@ file_put_contents($titlefile, $title); } - } else { $temp['type'] = "generic"; } @@ -179,7 +178,7 @@ //} } if(count($contentTree) > 0) { - print "\n
    "; + //print "\n
    "; $rootBranch = current($contentTree); diff --git a/htdocs/index.php b/htdocs/index.php index b42ef0c68..f45ded1e0 100755 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -9,6 +9,45 @@ html_bootstrap3_createHeader("en","Phoniebox",$conf['base_url']); ?> +
    @@ -60,7 +99,15 @@

    -
    +
    + + + + + + +
    +
    + +
    diff --git a/htdocs/lang/lang-de-DE.php b/htdocs/lang/lang-de-DE.php index d7d7d0fbb..42e52a730 100755 --- a/htdocs/lang/lang-de-DE.php +++ b/htdocs/lang/lang-de-DE.php @@ -147,7 +147,7 @@ $lang['cardFormStreamLegend'] = "Stream verlinken / erstellen"; $lang['cardFormStreamLabel'] = "Stream URL (benötigt immer einen neuen Ordner - s.o.)"; $lang['cardFormStreamPlaceholderClassic'] = "http(...).mp3 / .m3u / .ogg / .rss / .xml / ..."; -$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:(user:username:)album/track/playlist:#### / Livestream: http(....).mp3 / .m3u / .ogg / ...."; +$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:album/artist/playlist/track:#### / Livestream: http(....).mp3 / .m3u / .ogg / ...."; $lang['cardFormStreamHelp'] = "Füge die URL für spotify, Podcast, Webradio, Stream oder andere Online-Medien hinzu"; $lang['cardFormStreamTypeSelectDefault'] = "Wähle den Typ"; $lang['cardFormStreamTypeHelp'] = "Wähle die Art des Streams, den du hinzufügen möchtest"; @@ -278,4 +278,14 @@ $lang['searchExample'] = "z.B. Moonlight"; $lang['searchSend'] = "Suchen"; $lang['searchResult'] = "Suchergebnisse:"; + +/* +* Filter +*/ +$lang['filterall'] = "Zeige alle"; +$lang['filterfile'] = "Dateien"; +$lang['filterlivestream'] = "Livestream"; +$lang['filterpodcast'] = "Podcast"; +$lang['filterspotify'] = "Spotify"; +$lang['filteryoutube'] = "YouTube"; ?> diff --git a/htdocs/lang/lang-en-UK.php b/htdocs/lang/lang-en-UK.php index 999180706..e046dfaf6 100755 --- a/htdocs/lang/lang-en-UK.php +++ b/htdocs/lang/lang-en-UK.php @@ -147,7 +147,7 @@ $lang['cardFormStreamLegend'] = "Link Stream"; $lang['cardFormStreamLabel'] = "Stream URL (always requires new folder above)"; $lang['cardFormStreamPlaceholderClassic'] = "http(...).mp3 / .m3u / .ogg / .rss / .xml / ..."; -$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:(user:username:)album/track/playlist:### / Stream/Podcast like http....mp3 .xml .rss .ogg"; +$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:album/artist/playlist/track:### / Stream/Podcast like http....mp3 .xml .rss .ogg"; $lang['cardFormStreamHelp'] = "Add the URL for spotify, podcast, web radio, stream or other online media"; $lang['cardFormStreamTypeSelectDefault'] = "Select type"; $lang['cardFormStreamTypeHelp'] = "Select the type you are adding"; @@ -279,4 +279,14 @@ $lang['searchExample'] = "z.B. Moonlight"; $lang['searchSend'] = "Search"; $lang['searchResult'] = "Search-Results:"; + +/* +* Filter +*/ +$lang['filterall'] = "Show all"; +$lang['filterfile'] = "Files"; +$lang['filterlivestream'] = "Livestream"; +$lang['filterpodcast'] = "Podcast"; +$lang['filterspotify'] = "Spotify"; +$lang['filteryoutube'] = "YouTube"; ?> diff --git a/htdocs/lang/lang-nl-NL.php b/htdocs/lang/lang-nl-NL.php index 87041b66b..776fd9aaa 100755 --- a/htdocs/lang/lang-nl-NL.php +++ b/htdocs/lang/lang-nl-NL.php @@ -119,7 +119,7 @@ $lang['cardFormFolderSelectDefault'] = "Geen (Pulldown om een ​​map te selecteren)"; $lang['cardFormStreamLabel'] = "b) ... of maak verbinding met de Stream-URL"; $lang['cardFormStreamPlaceholderClassic'] = "Livestream: http(...).mp3 / .m3u / .ogg / ..."; -$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:(user:username:)album/track/playlist:### / Livestream: http(...).mp3 / .m3u / .ogg / ..."; +$lang['cardFormStreamPlaceholderPlusSpotify'] = "spotify:album/artist/playlist/track:### / Livestream: http(...).mp3 / .m3u / .ogg / ..."; $lang['cardFormStreamHelp'] = "Voeg de URL toe voor spotify, podcast, webradio, stream of andere online media"; $lang['cardFormStreamTypeSelectDefault'] = "Selecteer type"; $lang['cardFormStreamTypeHelp'] = "Selecteer het type dat u toevoegt"; @@ -205,5 +205,15 @@ $lang['searchExample'] = "z.B. Moonlight"; $lang['searchSend'] = "Zoeken"; $lang['searchResult'] = "Zoekresultaten:"; + +/* +* Filter +*/ +$lang['filterall'] = "Toon alles"; +$lang['filterfile'] = "Bestanden"; +$lang['filterlivestream'] = "Livestream"; +$lang['filterpodcast'] = "Podcast"; +$lang['filterspotify'] = "Spotify"; +$lang['filteryoutube'] = "YouTube"; ?> From c21131e697c8f60ca5589aaedb3393e026f7fb36 Mon Sep 17 00:00:00 2001 From: Luegengladiator Date: Wed, 29 Jul 2020 12:00:38 +0200 Subject: [PATCH 058/106] Update playout_controls.sh added playlistreset to enable Restart of List (mpc play 1) --- scripts/playout_controls.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/playout_controls.sh b/scripts/playout_controls.sh index 3f1964eaf..d5915b468 100755 --- a/scripts/playout_controls.sh +++ b/scripts/playout_controls.sh @@ -50,6 +50,7 @@ NOW=`date +%Y-%m-%d.%H:%M:%S` # playlistaddplay # playlistadd # playlistappend +# playlistreset # playsinglefile # getidletime # setidletime @@ -602,6 +603,13 @@ case $COMMAND in rm -f $VOLFILE fi mpc play + ;; + playlistreset) + if [ -e $PATHDATA/../shared/audiofolders/$FOLDERPATH/lastplayed.dat ] + then + echo "" > $PATHDATA/../shared/audiofolders/$FOLDERPATH/lastplayed.dat + fi + mpc play 1 ;; playsinglefile) if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " ${COMMAND} value:${VALUE}" >> ${PATHDATA}/../logs/debug.log; fi From 43ea469cd1e840a2b23074594c29edb020a92014 Mon Sep 17 00:00:00 2001 From: Andreas Brett Date: Mon, 10 Aug 2020 11:04:53 +0200 Subject: [PATCH 059/106] Add RPi throttling info to web interface (#1050) * add throttling/undervoltage info * Update lang-en-UK.php add infoOsThrottle * Update lang-de-DE.php add infoOsThrottle * Update lang-nl-NL.php add infoOsThrottle --- htdocs/lang/lang-de-DE.php | 1 + htdocs/lang/lang-en-UK.php | 1 + htdocs/lang/lang-nl-NL.php | 1 + htdocs/systemInfo.php | 39 +++++++++++++++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/htdocs/lang/lang-de-DE.php b/htdocs/lang/lang-de-DE.php index 2a10711df..8046ce325 100755 --- a/htdocs/lang/lang-de-DE.php +++ b/htdocs/lang/lang-de-DE.php @@ -247,6 +247,7 @@ */ $lang['infoOsDistrib'] = "Betriebssystem"; $lang['infoOsCodename'] = "Codename"; +$lang['infoOsThrottle'] = "Drosselung"; $lang['infoStorageUsed'] = "Speicherverbrauch"; $lang['infoMopidyStatus'] = "Mopidy Server Status"; $lang['infoMPDStatus'] = "MPD Server Status"; diff --git a/htdocs/lang/lang-en-UK.php b/htdocs/lang/lang-en-UK.php index 8d3137104..8cef80c5d 100755 --- a/htdocs/lang/lang-en-UK.php +++ b/htdocs/lang/lang-en-UK.php @@ -248,6 +248,7 @@ */ $lang['infoOsDistrib'] = "OS Distribution"; $lang['infoOsCodename'] = "Codename"; +$lang['infoOsThrottle'] = "Throttling"; $lang['infoStorageUsed'] = "Storage usage"; $lang['infoMopidyStatus'] = "Mopidy Server Status"; $lang['infoMPDStatus'] = "MPD Server Status"; diff --git a/htdocs/lang/lang-nl-NL.php b/htdocs/lang/lang-nl-NL.php index f70c32e64..144102b85 100755 --- a/htdocs/lang/lang-nl-NL.php +++ b/htdocs/lang/lang-nl-NL.php @@ -180,6 +180,7 @@ */ $lang['infoOsDistrib'] = "OS-distributie"; $lang['infoOsCodename'] = "Codenaam"; +$lang['infoOsThrottle'] = "Beperking"; $lang['infoStorageUsed'] = "Opslag gebruik"; $lang['infoMopidyStatus'] = "Mopidy Server Status"; $lang['infoMPDStatus'] = "MPD Server Status"; diff --git a/htdocs/systemInfo.php b/htdocs/systemInfo.php index e56f0046f..4f75d7497 100755 --- a/htdocs/systemInfo.php +++ b/htdocs/systemInfo.php @@ -26,6 +26,39 @@ $release = substr($res[2],strpos($res[2],":")+1,strlen($res[2])-strpos($res[2],":")); $codename = substr($res[3],strpos($res[3],":")+1,strlen($res[3])-strpos($res[3],":")); +// check RPis throttling state +function checkRpiThrottle() { + $codes = array( + 0 => "under-voltage detected", + 1 => "arm frequency capped", + 2 => "currently throttled", + 3 => "soft temperature limit active", + 16 => "under-voltage has occurred", + 17 => "arm frequency capped has occurred", + 18 => "throttling has occurred", + 19 => "soft temperature limit has occurred" + ); + + $getThrottledResult = explode("0x", exec("sudo vcgencmd get_throttled"))[1]; + + // code is zero => no issue + if ($getThrottledResult == "0") return "OK"; + + // analyse returned code + $result = []; + $codeHex = str_split($getThrottledResult); + $codeBinary = ""; + foreach ($codeHex as $fourbits) { + $codeBinary .= str_pad(base_convert($fourbits, 16, 2), 4, "0", STR_PAD_LEFT); + } + $codeBinary = array_reverse(str_split($codeBinary)); + foreach ($codeBinary as $bitNumber => $bitValue) { + if ($bitValue) $result[] = $codes[$bitNumber]; + } + return "WARNING: " . implode(", ", $result); +} +$rpi_throttle = checkRpiThrottle(); + ?>
    @@ -52,7 +85,11 @@
    -
    +
    +
    + +
    +
    From 2d16ef0c24e55d4321b22932681f5da05ced2fa1 Mon Sep 17 00:00:00 2001 From: Andreas Brett Date: Mon, 10 Aug 2020 12:29:39 +0200 Subject: [PATCH 060/106] Add RPi's temperature info to web interface (#1051) * add RPi temperature * Update lang-en-UK.php add infoOsTemperature * Update lang-de-DE.php add infoOsTemperature * Update lang-nl-NL.php add infoOsTemperature --- htdocs/lang/lang-de-DE.php | 1 + htdocs/lang/lang-en-UK.php | 1 + htdocs/lang/lang-nl-NL.php | 1 + htdocs/systemInfo.php | 5 +++++ 4 files changed, 8 insertions(+) diff --git a/htdocs/lang/lang-de-DE.php b/htdocs/lang/lang-de-DE.php index 8046ce325..d73756da1 100755 --- a/htdocs/lang/lang-de-DE.php +++ b/htdocs/lang/lang-de-DE.php @@ -247,6 +247,7 @@ */ $lang['infoOsDistrib'] = "Betriebssystem"; $lang['infoOsCodename'] = "Codename"; +$lang['infoOsTemperature'] = "Temperatur"; $lang['infoOsThrottle'] = "Drosselung"; $lang['infoStorageUsed'] = "Speicherverbrauch"; $lang['infoMopidyStatus'] = "Mopidy Server Status"; diff --git a/htdocs/lang/lang-en-UK.php b/htdocs/lang/lang-en-UK.php index 8cef80c5d..90b385e9b 100755 --- a/htdocs/lang/lang-en-UK.php +++ b/htdocs/lang/lang-en-UK.php @@ -248,6 +248,7 @@ */ $lang['infoOsDistrib'] = "OS Distribution"; $lang['infoOsCodename'] = "Codename"; +$lang['infoOsTemperature'] = "Temperature"; $lang['infoOsThrottle'] = "Throttling"; $lang['infoStorageUsed'] = "Storage usage"; $lang['infoMopidyStatus'] = "Mopidy Server Status"; diff --git a/htdocs/lang/lang-nl-NL.php b/htdocs/lang/lang-nl-NL.php index 144102b85..c3f3a6eda 100755 --- a/htdocs/lang/lang-nl-NL.php +++ b/htdocs/lang/lang-nl-NL.php @@ -180,6 +180,7 @@ */ $lang['infoOsDistrib'] = "OS-distributie"; $lang['infoOsCodename'] = "Codenaam"; +$lang['infoOsTemperature'] = "Temperatuur"; $lang['infoOsThrottle'] = "Beperking"; $lang['infoStorageUsed'] = "Opslag gebruik"; $lang['infoMopidyStatus'] = "Mopidy Server Status"; diff --git a/htdocs/systemInfo.php b/htdocs/systemInfo.php index 4f75d7497..199a2a1a1 100755 --- a/htdocs/systemInfo.php +++ b/htdocs/systemInfo.php @@ -25,6 +25,7 @@ $description = substr($res[1],strpos($res[1],":")+1,strlen($res[1])-strpos($res[1],":")); $release = substr($res[2],strpos($res[2],":")+1,strlen($res[2])-strpos($res[2],":")); $codename = substr($res[3],strpos($res[3],":")+1,strlen($res[3])-strpos($res[3],":")); +$rpi_temperature = explode("=", exec("sudo vcgencmd measure_temp"))[1]; // check RPis throttling state function checkRpiThrottle() { @@ -89,6 +90,10 @@ function checkRpiThrottle() {
    +
    +
    + +
    From 5e68a8382ec94f4fbb78739600cdf8b125425118 Mon Sep 17 00:00:00 2001 From: Andreas Brett Date: Mon, 10 Aug 2020 12:30:20 +0200 Subject: [PATCH 061/106] new attributes: throttling, temperature (#1052) --- .../MQTT-protocol/README.md | 6 ++- ...n-mqtt-client.py => daemon_mqtt_client.py} | 45 ++++++++++++++++++- ...mqtt-client.service.stretch-default.sample | 2 +- 3 files changed, 49 insertions(+), 4 deletions(-) rename components/smart-home-automation/MQTT-protocol/{daemon-mqtt-client.py => daemon_mqtt_client.py} (89%) mode change 100755 => 100644 diff --git a/components/smart-home-automation/MQTT-protocol/README.md b/components/smart-home-automation/MQTT-protocol/README.md index 4c763fe65..d81d87af5 100644 --- a/components/smart-home-automation/MQTT-protocol/README.md +++ b/components/smart-home-automation/MQTT-protocol/README.md @@ -64,6 +64,8 @@ MQTT clients can (additionally to the periodic updates) request an attribute of - remaining_stopafter [minutes left until "stop" is triggered] - remaining_shutdownafter [minutes left until shutdown] - remaining_idle [minutes left for the idle shutdown timer] +- throttling +- temperature ### Help Sending empty payload to `phoniebox/get/help` will be responded by a list of all possible attributes to `phoniebox/available_attributes` @@ -123,7 +125,7 @@ components/smart-home-automation/MQTT-protocol/ ## Auto-Starting the daemon at bootup -* The daemon is run by executing the script `daemon-mqtt-client.py` which will run in an endless loop. +* The daemon is run by executing the script `daemon_mqtt_client.py` which will run in an endless loop. * There's a sample service file (`phoniebox-mqtt-client.service.stretch-default.sample`) that can be used to register the daemon to be run at bootup. * It is currently not integrated into the one-line-install script so please run the following commands to do it manually. @@ -131,7 +133,7 @@ First step: copy files to destination locations: ~~~ # First copy the daemon script and service config file to the correct directory: -sudo cp /home/pi/RPi-Jukebox-RFID/components/smart-home-automation/MQTT-protocol/daemon-mqtt-client.py /home/pi/RPi-Jukebox-RFID/scripts/ +sudo cp /home/pi/RPi-Jukebox-RFID/components/smart-home-automation/MQTT-protocol/daemon_mqtt_client.py /home/pi/RPi-Jukebox-RFID/scripts/ sudo cp /home/pi/RPi-Jukebox-RFID/components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service.stretch-default.sample /etc/systemd/system/phoniebox-mqtt-client.service ~~~ diff --git a/components/smart-home-automation/MQTT-protocol/daemon-mqtt-client.py b/components/smart-home-automation/MQTT-protocol/daemon_mqtt_client.py old mode 100755 new mode 100644 similarity index 89% rename from components/smart-home-automation/MQTT-protocol/daemon-mqtt-client.py rename to components/smart-home-automation/MQTT-protocol/daemon_mqtt_client.py index 7d3e85f13..6794e5f8a --- a/components/smart-home-automation/MQTT-protocol/daemon-mqtt-client.py +++ b/components/smart-home-automation/MQTT-protocol/daemon_mqtt_client.py @@ -40,7 +40,7 @@ # list of available commands and attributes arAvailableCommands = ['volumeup', 'volumedown', 'mute', 'playerplay', 'playerpause', 'playernext', 'playerprev', 'playerstop', 'playerrewind', 'playershuffle', 'playerreplay', 'scan', 'shutdown', 'shutdownsilent', 'reboot', 'disablewifi'] arAvailableCommandsWithParam = ['setvolume', 'setvolstep', 'setmaxvolume', 'setidletime', 'playerseek', 'shutdownafter', 'playerstopafter', 'playerrepeat', 'rfid', 'gpio', 'swipecard', 'playfolder', 'playfolderrecursive'] -arAvailableAttributes = ['volume', 'mute', 'repeat', 'random', 'state', 'file', 'artist', 'albumartist', 'title', 'album', 'track', 'elapsed', 'duration', 'trackdate', 'last_card', 'maxvolume', 'volstep', 'idletime', 'rfid', 'gpio', 'remaining_stopafter', 'remaining_shutdownafter', 'remaining_idle'] +arAvailableAttributes = ['volume', 'mute', 'repeat', 'random', 'state', 'file', 'artist', 'albumartist', 'title', 'album', 'track', 'elapsed', 'duration', 'trackdate', 'last_card', 'maxvolume', 'volstep', 'idletime', 'rfid', 'gpio', 'remaining_stopafter', 'remaining_shutdownafter', 'remaining_idle', 'throttling', 'temperature'] def on_connect(client, userdata, flags, rc): @@ -220,6 +220,45 @@ def linux_job_remaining(job_name): return 0 +def getOsThrottling(): + codes = { + 0: "under-voltage detected", + 1: "arm frequency capped", + 2: "currently throttled", + 3: "soft temperature limit active", + 16: "under-voltage has occurred", + 17: "arm frequency capped has occurred", + 18: "throttling has occurred", + 19: "soft temperature limit has occurred" + } + + p = subprocess.Popen(['vcgencmd', 'get_throttled'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + throttling, err = p.communicate() + codeHex = throttling.rstrip().split("0x")[1] + + # code is zero => no issue + if codeHex == "0": + return "OK" + + # analyse returned code + result = [] + codeBinary = "" + for fourbits in codeHex: + codeBinary = codeBinary + bin(int(fourbits, 16))[2:].zfill(4) + codeBinary = codeBinary[::-1] + for bitNumber in range(len(codeBinary)): + if codeBinary[bitNumber] == "1": + result.append(codes[bitNumber]) + return "WARNING: " + ", ".join(result) + + +def getOsTemperature(): + p = subprocess.Popen(['vcgencmd', 'measure_temp'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + temperature, err = p.communicate() + temperature = temperature.rstrip().split("=")[1] + return temperature + + def normalizeTrueFalse(s): if s == "0": return "false" @@ -299,6 +338,10 @@ def fetchData(): result["remaining_shutdownafter"] = str(linux_job_remaining("t")) result["remaining_idle"] = str(linux_job_remaining("i")) + # fetch OS information + result["throttling"] = getOsThrottling() + result["temperature"] = getOsTemperature() + # modify refresh rate depending on play state if result["state"] == "play": refreshInterval = refreshIntervalPlaying diff --git a/components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service.stretch-default.sample b/components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service.stretch-default.sample index ecd653776..ba64af405 100644 --- a/components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service.stretch-default.sample +++ b/components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service.stretch-default.sample @@ -8,7 +8,7 @@ Group=pi Restart=always RestartSec=10 WorkingDirectory=/home/pi/RPi-Jukebox-RFID -ExecStart=/home/pi/RPi-Jukebox-RFID/scripts/daemon-mqtt-client.py +ExecStart=/home/pi/RPi-Jukebox-RFID/scripts/daemon_mqtt_client.py [Install] WantedBy=multi-user.target From 9301e421f92f3cbc728443c42c36ada5435ad4ae Mon Sep 17 00:00:00 2001 From: Maxwell <37151645+princemaxwell@users.noreply.github.com> Date: Tue, 11 Aug 2020 08:58:40 +0200 Subject: [PATCH 062/106] Fix for WebUI (#1053) * Update func.php Fix for displaced folders in WebUI... https://github.com/MiczFlor/RPi-Jukebox-RFID/pull/1028#issuecomment-668083796 * Update inc.viewFolderTree.php Fix for displaced folders in WebUI https://github.com/MiczFlor/RPi-Jukebox-RFID/pull/1028#issuecomment-668083796 --- htdocs/func.php | 3 ++- htdocs/inc.viewFolderTree.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/func.php b/htdocs/func.php index 709667794..ff829c25b 100755 --- a/htdocs/func.php +++ b/htdocs/func.php @@ -498,7 +498,8 @@ function index_folders_print($item, $key) print "
    -
    "; +
    +
    "; } function getSubDirectories( $path = '.', $level = 0, $showfiles = 0 ){ diff --git a/htdocs/inc.viewFolderTree.php b/htdocs/inc.viewFolderTree.php index 70e3eb5db..6810d29da 100755 --- a/htdocs/inc.viewFolderTree.php +++ b/htdocs/inc.viewFolderTree.php @@ -196,7 +196,7 @@ //array_walk($getSubDirectories, 'test_index_folders_print'); array_walk($getSubDirectories, 'index_folders_print'); - print "\n
    "; + //print "\n
    "; } ?> From 5e119f44b64bceaececfc493c88baea25220dda3 Mon Sep 17 00:00:00 2001 From: Andreas Brett Date: Tue, 11 Aug 2020 23:18:23 +0200 Subject: [PATCH 063/106] fix filename --- components/smart-home-automation/MQTT-protocol/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/smart-home-automation/MQTT-protocol/README.md b/components/smart-home-automation/MQTT-protocol/README.md index d81d87af5..a71a595ec 100644 --- a/components/smart-home-automation/MQTT-protocol/README.md +++ b/components/smart-home-automation/MQTT-protocol/README.md @@ -137,7 +137,7 @@ sudo cp /home/pi/RPi-Jukebox-RFID/components/smart-home-automation/MQTT-protocol sudo cp /home/pi/RPi-Jukebox-RFID/components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service.stretch-default.sample /etc/systemd/system/phoniebox-mqtt-client.service ~~~ -Now edit the file `pi/RPi-Jukebox-RFID/scripts/daemon-mqtt-client.py` to match your requirements. +Now edit the file `/home/pi/RPi-Jukebox-RFID/scripts/daemon_mqtt_client.py` to match your requirements. Now continue and activate the service. ~~~ From 79121373531b9dc044f9d96e4ce85afa8a8a8fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20N=C3=B6ding?= Date: Sun, 16 Aug 2020 20:32:13 +0200 Subject: [PATCH 064/106] Added Info-Message-Box by clicking on Play-Icon or on adding file to playlist --- htdocs/inc.navigation.php | 14 ++++++++++++++ htdocs/js/jukebox.js | 28 ++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/htdocs/inc.navigation.php b/htdocs/inc.navigation.php index e5e095480..0bd279791 100755 --- a/htdocs/inc.navigation.php +++ b/htdocs/inc.navigation.php @@ -1,3 +1,17 @@ + + +
    +