Ok, Vers. 0.2 after some polishing:


Code:
--------------------
    #!/bin/sh
  
  # 
--------------------------------------------------------------------------------------------------------------------------
  # Script polls "pcp mode" every 500 ms and sets a GPIO when squeezelite is 
playing.
  # Aki 9/2020 - Home: 
https://forums.slimdevices.com/showthread.php?110277-Feature-request-picoreplayer-Play-state-to-GPIO
 
  # 
--------------------------------------------------------------------------------------------------------------------------
  # Vers 0.2: Cleanup of GPIO on exit. Reentrance cleared. -k kills running 
instance. Clean reaction on 'pcp mode' outages.
  
  BASE_GPIO_PATH=/sys/class/gpio
  ScriptName=$(basename -- "$0")
  #Parameters=$@
  
  function msg () {
  echo "$(date +"%T") $ScriptName: $@";
  } # function msg
  
  function err () {
  echo "$(date +"%T") $ScriptName: Error: $1" >&2; exit 1 
  } # function err
  
  function cleanup () {  
  if [ -e $BASE_GPIO_PATH/gpio$myGPIO ]; then # GPIO initialized    
  echo "$((!$PlayVal))" > $BASE_GPIO_PATH/gpio$myGPIO/value # Set to off state
  echo "$myGPIO" > $BASE_GPIO_PATH/unexport
  fi # GPIO de-initialized
  exit 0 
  } # on Exit
  
  function Usage () {
  echo ""
  echo "PlayMode to GPIO ($ScriptName) sets a GPIO when squeezelite is playing."
  echo "--------------------------------------------------------------------"
  echo "Usage: sudo $0 -g GPIO [-s n] [-f] [-v] [-b] [-k] [-h]"
  echo ""
  echo "-g : GPIO-number"
  echo "-s : Set value for \"play\" mode: 0,1. Default=1 sets GPIO to 3V when 
playing"
  echo "-v : Verbose output from background"
  echo "-f : run in foreground with verbose output"
  echo "-b : Blink mode, GPIO is blinking when playing"    
  echo "-k : Kill running $ScriptName" 
  echo "-h : Shows this help"
  echo ""
  echo "Examples:"
  echo "---------"
  echo "  sudo $0 -g 27        : Sets GPIO27 to 3V when playing"  
  echo "  sudo $0 -g 4 -s 0 -f : Sets GPIO4  to 0V when playing, running in 
foreground"
  echo "  sudo $0 -g 4 -s 1 -v : Sets GPIO4  to 3V when playing, running in 
background with output"
  echo "  sudo $0 -g27 -b      : Sets GPIO27 to 3V, blinking when playing"   
  echo "  sudo $0 -k           : Kills running $ScriptName"  
  echo ""
  exit 1
  } # function Usage
  
  function Loop () { 
  trap cleanup INT TERM # cleanup GPIO on exit
  while true; do  
  MODE=`pcp mode 2> /dev/null`
  if [ ! "$MODE" ]; then MODE=unknown; fi # no result, wget error
  
  if [ "$MODE" = "play" ] && $Blink; then # Blink on play
  actGPIOval=$(cat $BASE_GPIO_PATH/gpio$myGPIO/value) 
  echo "$((!$actGPIOval))" > $BASE_GPIO_PATH/gpio$myGPIO/value
  fi # Blink on play      
  
  if [ ! "$MODE" = "$OldMode" ]; then # MODE change
  if [ "$MODE" = "play" ] || [ "$MODE" = "pause" ] || [ "$MODE" = "stop" ] || [ 
"$MODE" = "unknown" ]; then # valid or empty MODE 
  msgtxt="pcp mode is \"$MODE\"."
  if [ "$MODE" = "play" ]; then GPIOval=$PlayVal; else GPIOval=$((!$PlayVal)); 
fi # Set GPIO value        
  if [ ! "$GPIOval" = "$oldGPIOval" ]; then
  msgtxt="Set GPIO$myGPIO to $GPIOval. ${msgtxt}"
  echo "$GPIOval" > $BASE_GPIO_PATH/gpio$myGPIO/value
  oldGPIOval=$GPIOval
  fi # GPIO val change
  msg $msgtxt         
  else # invalid MODE
  msg "\"pcp mode\" results to invalid mode \"$MODE\", should be play, pause, 
stop" 
  fi # valid/invalid MODE
  OldMode=$MODE
  fi # MODE change 
  sleep 0.5
  done # while true
  } # function Loop
  
  ############
  ### Main ###
  ############
  
  # Parameter
  # ---------
  
  if [ ! $1 ]; then Usage; fi # No Param, please give at least the GPIO
  
  # Defaults
  myGPIO=
  PlayVal=1 # active high
  Verbose=false # no output from loop when daemonized
  foreground=false # no more need to foreground
  Blink=false # stoy active
  
  while getopts g:s:vfbkh opt 
  do 
  case $opt in
  g ) # Check for valid GPIO
  if [ "$OPTARG" -ge 2 ] && [ "$OPTARG" -le 27 ] 
  then myGPIO=$OPTARG
  else err "\"$OPTARG\" is not a valid GPIO, please use 2 .. 27"; fi # Check 
for valid GPIO
  ;;
  s ) # Check parameter for setting GPIO to 0 or 1 when playing
  if [ $OPTARG ]; then # Set GPIO to 0 or 1 when playing
  if [ "$OPTARG" -eq 0 ] || [ "$OPTARG" -eq 1 ] 
  then PlayVal=$OPTARG 
  else err "\"$OPTARG\" is not a valid GPIO state, please use 0 or 1"; fi
  fi # Check parameter for setting GPIO to 0 or 1 when playing
  ;;
  v ) Verbose=true;;
  f ) foreground=true;;
  b ) Blink=true;;
  k ) msg "Killing running instance."; killall -15 $ScriptName;;        
  h ) Usage;;
  [?]) Usage;;
  esac
  done
  if [ ! $myGPIO ]; then err "Mandatory parameter -g \"GPIO\" is missing"; fi
  
  # Kill old instance, if exists
  for pid in $(pidof $ScriptName); do    
  if [ ! $pid = $$ ]; then
  msg "Killing old instance (pid $pid) of $ScriptName"
  kill -15 $pid
  until [ ! -e $BASE_GPIO_PATH/gpio$myGPIO ]; do 
  sleep 0.1 # Give the exit routine some time. on pi 3b+ 0.1s is enough
  done # Wait for ols exit routine finished
  fi # old instance found     
  done # Kill old instance
  
  # Init
  # ----
  
  # Wait for squeezelite to come online
  wt=0
  until pids=$(pidof squeezelite squeezelite-dsd); do
  sleep 1; wt=$(($wt+1))
  msg "Waited $wt seconds for for squeezelite ..." 
  if [ "$wt" -ge 60 ]; then err "Waited too long for squeezelite"; fi
  done
  
  # Init GPIO
  if [ ! -e $BASE_GPIO_PATH/gpio$myGPIO ]; then # Init GPIO
  msg "Export GPIO$myGPIO to userspace"
  echo "$myGPIO" > $BASE_GPIO_PATH/export
  fi # Init GPIO
  msg "Set GPIO$myGPIO as an output"
  echo "out" > $BASE_GPIO_PATH/gpio$myGPIO/direction
  
  # Start loop
  # ----------
  
  if $foreground; then # run in foreground:
  msg "Foreground loop polling, with output. Stop with \"ctrl-c\"."
  Loop
  else # daemonize
  if $Verbose; then
  msg "Background loop polling with output. Stop with \"sudo $0 -k\" or restart 
of script." 
  Loop &
  else # Background loop polling with output
  msg "Background loop polling. Stop with \"sudo $0 -k\" or restart of script." 
  Loop > /dev/null 2>&1 &
  fi # Background loop polling
  fi # Start fore- or background loop polling
  exit
  
  # End of Program
  
  
--------------------


Working fine, but polling uses >10% more CPU and energy and gives a
little delay. Suggestion:

The Squeezelite call of "Power On/Off Script" gets some more states:

Now:

2: Init
1: On
0 :Off

Future:

5: stop
4: play
3: pause
2: init
1: on
0: off

So everyone can build nice status LEDs or switch his perifery to his
needs.

By the way: "stop" vs. "off" could get some clarification ;-)

Scripting in unknown terrain is the real adventure game :)

Have fun
Aki


------------------------------------------------------------------------
Aki7's Profile: http://forums.slimdevices.com/member.php?userid=67596
View this thread: http://forums.slimdevices.com/showthread.php?t=110277

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

Reply via email to