I think I'm about there now, with a unified script that handles all the
tasks necessary for implementing the udev rules, without any need for
user editing.

1) It can generate the udev rules file automatically from just the name
of the sound card.  
2) It can look for the DAC via a user command at boot
3) It can be called by the udev rules to start and stop squeezelite
4) It has its own internal routine to spawn the built-in
/usr/local/etc/init.d/squeezelite script asynchronously.

So the steps are simpler now:
1) Paste the script into a file in your home directory.  I've called it
'SQLITE_control.sh' on my system, but you can call it whatever you like,
because the rules it creates will include the script's current name in
them (if you change the filename later, you will need to either edit the
rules file to reflect the new name, or just use the script again to
remake the rules file - step 2 below).  Make the script executable with 

Code:
--------------------
    chmod +x SQLITE-control.sh
--------------------


2) Make sure your DAC is plugged in and powered up, then run the script
with the find option and the name of your card ('DAC' in my case) to
create the udev rules file, e.g. 

Code:
--------------------
    ./SQLITE-control make DAC
--------------------


3) Include a line in User Commands (bottom of the Tweaks page) so that
the script is called to find the DAC at boot, e.g 

Code:
--------------------
    ./SQLITE-control find DAC
--------------------

Again, use your card name where I have DAC.

That's it.  Backup and reboot ('pcp br') and it you should be set.  If,
like rgro, you don't want squeezelite to stop when your DAC powers down,
you can use either of the options that I mentioned in 'this post'
(https://forums.slimdevices.com/showthread.php?113661-Start-restart-squeezelite-when-plug-in-USB-dac&p=1008560&viewfull=1#post1008560).

This is the current version of my unified script.  It's a bit longer
because of the extra functions and some commentary at the top, but just
select it all, then copy and paste it into your file.

Code:
--------------------
    #!/bin/sh
  
  # Script to be used by udev rules that detect when a USB DAC is connected or 
disconnected,
  # in order to start or stop Squeezelite
  # $1 : is the script option: 'restart', 'stop', 'find' or 'make'
  # $2 : For 'restart' and 'stop', $2 is the kernel name ($kernel) that is 
generated by the udev event
  #      It is used to match a 'removed' USB device against the device assigned 
when the DAC was inserted
  #      For 'find' and 'make', $2 is the (CARD)name of the DAC, as used in the 
squeezelite command string.
  # The 'find' option is used at boot to detect which device the DAC is 
connected to, 
  # in the case that the DAC is up before squeezelite attempts to start.
  # The 'make' option creates the udev rules file and adds it to 
/opt/.filetool.lst so that it is included in the user's backup
  
  # Examples:
  # SQLITE-control make DAC
  # This will create a rules file in /etc/udev/rules.d.
  # The rule number is curently fixed at 10, and the rule name will equal the 
card name; in this case 'DAC'
  # Run this once, manually from the command line.
  
  # SQLITE-control find DAC
  # This will check whether the DAC is connected, and write its kernel id to 
/tmp/DAC_kername.txt
  # This is intended to be used as a User Command, run at boot, so that the 
'stop' option knows which kernel id to look for.
  
  # SQLITE-control restart $kernel and SQLITE-control stop $kernel
  # (Re)start and stop squeezelite, respectively.
  # These two options are called by the udev rules in response to 'add' and 
'remove' events
  # They take the $kernel argument that is available when the udev rule is 
triggered.
  
  # The associated udev rules are of the form:
  # SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="08bb", 
ATTR{idProduct}=="2704", RUN+="/home/tc/SQLITE-control.sh restart $kernel"
  # SUBSYSTEM=="usb", ACTION=="remove", RUN+="/home/tc/SQLITE-control.sh stop 
$kernel"
  
  SQLITErestart() {
        local logfile=$1
        local attempts=5 # number of tries
        local interval=1 # interval between tries (seconds)
        
        local uptime
        local count=$attempts 
        while [ "$(sudo /usr/local/etc/init.d/squeezelite status)" == 
"Squeezelite not running." ]; do
                if [ $((count--)) -le 0 ]; then
                        uptime=$(printf [%12s $(cat /proc/uptime | awk {'print 
$1'})])
                        echo  "$uptime Squeezelite failed to initialize within 
$attempts attempts." >> $logfile
                        exit 1 
                fi
  
                uptime=$(printf [%12s $(cat /proc/uptime | awk {'print $1'})])
                echo  "$uptime Attempting to start squeezelite" >> $logfile
                sudo /usr/local/etc/init.d/squeezelite restart >> $logfile
                sleep $interval
        done
  
        # determine cardname from squeezelite process id
        local PID=$(sudo /usr/local/etc/init.d/squeezelite status | awk -F PID= 
{'print $2'})
        local cardname=$(ps | grep $PID | awk -F CARD= {'print $2'} | awk -F , 
{'print $1'})
        sudo /usr/local/sbin/alsactl restore $cardname
  }
  
  logfile=/var/log/pcp_DAC.log
  
  case $1 in
        restart ) # restart squeezelite when DAC is inserted/powered up
                # output the device '$kernel' name to a text file, so that it 
can be used to check against USB 'remove' events
                kername=$2
                uptime=$(printf [%12s $(cat /proc/uptime | awk {'print $1'})])
                if [ -z $kername ]; then
                        echo "$uptime DAC not detected" >> $logfile
                else
                        echo "$uptime DAC detected on $kername" >> $logfile
                        echo $kername > /tmp/DAC_kername.txt
                        SQLITErestart $logfile &
                fi
                ;;
        stop ) # stop squeezelite when DAC is removed/powered down
                # compare $kernel device name to the one created by this script 
when the DAC was inserted/powered up
                startname=$(cat /tmp/DAC_kername.txt)
                stopname="$2"
                if [ $stopname == $startname ]; then # stop squeezelite if 
names match
                        uptime=$(printf [%12s $(cat /proc/uptime | awk {'print 
$1'})])
                        echo "$uptime DAC on $stopname removed" >> $logfile
                        sudo /usr/local/etc/init.d/squeezelite stop >> $logfile
                fi
                ;;
        find ) # create the file with the kernel name
                # find Vendor and Product IDs for the DAC from the udev rules
                cardname=$2
                # name the rules file after the (CARD)name of the DAC
                rulesfile=etc/udev/rules.d/10-$cardname.rules
                idVendor=$(cat /$rulesfile | grep idVendor | awk -F idVendor 
{'print $2'} | awk -F \" {'print $2'})
                idProduct=$(cat /$rulesfile | grep idProduct | awk -F idProduct 
{'print $2'} | awk -F \" {'print $2'})
                uptime=$(printf [%12s $(cat /proc/uptime | awk {'print $1'})])
                echo "$uptime Searching for $cardname with idVendor=$idVendor 
and idProduct=$idProduct in dmesg" >> $logfile
                kername=$(dmesg | grep -m 1 "idVendor=$idVendor, 
idProduct=$idProduct" | awk -F usb {'print $2'} | awk -F : {'print $1'})
                # output the $kernel device name to a file for use when 
detecting 'removed' USB devices
                echo $kername > /tmp/DAC_kername.txt
                uptime=$(printf [%12s $(cat /proc/uptime | awk {'print $1'})])
                if [ -z $kername ]; then
                        echo "$uptime $cardname not detected" >> $logfile
                else
                        echo "$uptime $cardname detected on $kername" >> 
$logfile
                        sudo /usr/local/sbin/alsactl restore
                fi
                ;;
        make ) # make the rules file
                # one command line parameter: the name of the 'CARD', as used 
in the squeezelite command line
                
                scriptfile=$(realpath $0)
                cardname=$2
  
                # look for cardname in /proc/asound/cards to determine card 
number
                cardno=$(cat /proc/asound/cards | grep -m 1 $cardname | awk 
{'print $1'})
  
                # extract idVendor and idProduct from /proc/asound/card<n>/usbid
                usbid=$(cat /proc/asound/card$cardno/usbid)
                idVendor=$(echo $usbid | awk -F: {'print $1'})
                idProduct=$(echo $usbid | awk -F: {'print $2'})
  
                # create udev rules
                rule_add='SUBSYSTEM=="usb", ACTION=="add", 
ATTR{idVendor}=="'$idVendor'", ATTR{idProduct}=="'$idProduct'", 
RUN+="'$scriptfile' restart $kernel"'
                rule_remove='SUBSYSTEM=="usb", ACTION=="remove", 
RUN+="'$scriptfile' stop $kernel"'
  
                # create rules file
                rulesfile=etc/udev/rules.d/10-$cardname.rules
                echo $rule_add > /$rulesfile
                echo $rule_remove >> /$rulesfile
  
                # add rules file to /opt/.filetool.lst
                sed -i "\#$rulesfile#d" /opt/.filetool.lst #remove all previous 
matching entries, to make sure it's only listed once
                echo $rulesfile >> /opt/.filetool.lst
                ;;
  esac
  
--------------------


------------------------------------------------------------------------
chill's Profile: http://forums.slimdevices.com/member.php?userid=10839
View this thread: http://forums.slimdevices.com/showthread.php?t=113661

_______________________________________________
unix mailing list
[email protected]
http://lists.slimdevices.com/mailman/listinfo/unix

Reply via email to