Skip to content

Instantly share code, notes, and snippets.

@mattorp
Created March 2, 2024 12:06
Show Gist options
  • Save mattorp/1eab74b0d137ec72ed8f4a63f7454261 to your computer and use it in GitHub Desktop.
Save mattorp/1eab74b0d137ec72ed8f4a63f7454261 to your computer and use it in GitHub Desktop.
Limit Bluesound sound level while ignoring specificed inputs. E.g. for analog and optical
#!/bin/bash
# Default values for the script's operation
IP=''
TIMEOUT=50 # Timeout in milliseconds
LIMIT=-55 # Volume limit (negative value)
SKIP_INPUTS=('input0' "optical") # Inputs to skip when limiting volume
# Overriding default values with environment variables if they exist
if [ -n "$BLUOS_IP" ]; then
IP=$BLUOS_IP
fi
if [ -n "$BLUOS_TIMEOUT" ]; then
TIMEOUT=$BLUOS_TIMEOUT
fi
if [ -n "$BLUOS_LIMIT" ]; then
LIMIT=$BLUOS_LIMIT
fi
if [ -n "$BLUOS_SKIP_INPUTS" ]; then
IFS=',' read -r -a SKIP_INPUTS <<<"$BLUOS_SKIP_INPUTS"
fi
# Function to display help information
function help() {
echo "Usage: limitVolume.sh [-i IP] [-t TIMEOUT] [-l LIMIT] [-s SKIP_INPUTS]"
echo "Options:"
echo " -i IP: IP address of the BluOS device."
echo " -t TIMEOUT: Timeout in milliseconds before checking volume."
echo " -l LIMIT: Maximum allowed volume (negative value)."
echo " -s SKIP_INPUTS: Comma-separated list of input IDs to skip."
echo ""
echo "Environment variables can also be used to set these options:"
echo " BLUOS_IP, BLUOS_TIMEOUT, BLUOS_LIMIT, BLUOS_SKIP_INPUTS"
}
# Parsing command-line arguments
while getopts "i:t:l:s:" opt; do
case $opt in
i) IP=$OPTARG ;;
t) TIMEOUT=$OPTARG ;;
l) LIMIT=$OPTARG ;;
s) IFS=',' read -r -a SKIP_INPUTS <<<"$OPTARG" ;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
# Show current configuration
echo "IP: $IP"
echo "TIMEOUT: $TIMEOUT ms"
echo "LIMIT: $LIMIT dB"
echo "SKIP_INPUTS: ${SKIP_INPUTS[*]}"
echo "-------------------"
# Validate required arguments
if [ -z "$IP" ]; then
echo "IP is required."
help
exit 1
fi
# Initialize variables to store the last known state
lastDb=0
lastInputId=''
# Function to limit the volume
limitVolume() {
local ip=$1
# Base URL for the BluOS device
local baseUrl="http://$ip:11000"
# Wait for the specified timeout duration
sleep $((TIMEOUT / 1000))
# Fetch current status from the device
local response=$(curl -s "${baseUrl}/Status")
# Extract the current input ID
local inputId=$(echo "$response" | sed -n 's|.*<inputId>\(.*\)</inputId>.*|\1|p')
if [ -z "$inputId" ]; then
return
fi
# Check if input has changed
if [ "$inputId" != "$lastInputId" ]; then
echo "Input: $inputId"
# Notify if this input is being skipped
lastInputId=$inputId
for skip in "${SKIP_INPUTS[@]}"; do
if [ "$inputId" == "$skip" ]; then
echo "Skipping volume limit for this input"
return
fi
done
fi
# Skip processing for specified inputs
for skip in "${SKIP_INPUTS[@]}"; do
if [ "$inputId" == "$skip" ]; then
return
fi
done
# Extract and process the current volume level
local db=$(echo "$response" | sed -n 's|.*<db>\(.*\)</db>.*|\1|p' | awk '{print int($1)}')
if [ -z "$db" ]; then
echo "Failed to get volume"
exit 1
fi
if [ $db != $lastDb ]; then
echo "Volume: $db dB"
lastDb=$db
fi
# Limit the volume if it exceeds the set limit
if [ $db -le $LIMIT ]; then
return
fi
# Send request to adjust the volume
curl -s -X POST "${baseUrl}/Volume?abs_db=${LIMIT}" >/dev/null
echo "Limited volume to $LIMIT dB"
}
# Main function to initiate the script
main() {
limitVolume $IP
# Continuously monitor and adjust the volume
while true; do
limitVolume $IP
done
}
# Execute the main function
main
@mattorp
Copy link
Author

mattorp commented Mar 2, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment