6 trap destroy SIGINT SIGTERM ERR EXIT
9 temp_file="/tmp/elgatokeylights"
10 script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)
11 icon="${script_dir}/assets/elgato.png"
16 declare action="usage"
20 declare call="curl --silent --show-error --location --header 'Accept: application/json' --request"
21 declare devices="/elgato/lights"
22 declare accessory_info="/elgato/accessory-info"
23 declare settings="/elgato/lights/settings"
25 if [ ! -r "${icon}" ]; then icon=sunny; fi
28 if [ $silent -eq 0 ]; then
29 notify-send -i "$icon" "Key Light Controller" "$1"
40 rm "$temp_file" 2>/dev/null
47 Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-l] [-p] [-s] [-v] <action>
49 Elgato Lights controller. Works for Key Light and Key Light Air.
52 list List available lights
53 status Get state of lights
55 off Turn all lights off
56 temperature Set temperature level (260-470)
57 brightness Set brightness level (0-100)
58 increase Increases brightness by 10
59 decrease Decreases brightness by 10
63 -h, --help Print this help and exit
64 -p, --pretty Pretty print console output
65 -v, --verbose Print script debug info
66 -f, --flag Some flag description
67 -s, --silent Supress notifications
73 # default values of variables set from params
78 -p | --pretty) pretty=1;;
79 -v | --verbose) set -x ;;
80 -s | --silent) silent=1 ;;
81 -t | --target) target=1
85 -?*) die "Unknown option: $1" ;;
93 # check required params and arguments
94 declare -A actions=([help]=1 [list]=1)
95 [[ ${#args[@]} -ne 1 ]] && die "Incorrect action count, 1 allowed"
97 [[ ($silent -eq 1) && ($pretty -eq 1) ]] && die "Cannot use silent and pretty options simultaneously"
99 [[ -n "${actions[${args[0]}]}" ]] && action="${args[0]}"
106 if ! command -v $var &>/dev/null; then
107 die "Dependency $var was not found, please install and try again"
115 for l in "${!lights[@]}"; do
116 json+="${lights[$l]},"
119 lights_json="[${json%,}]"
123 if [[ $pretty -eq 1 ]]; then
126 echo "$1"|jq -c -M '.'
133 die "To be implemented"
138 die "To be implemented"
143 # Scan the network for Elgato devices
144 avahi-browse -d local _elg._tcp --resolve -t | grep -v "^\+" >"$temp_file"
146 # Declaration for json type forcing
148 declare hostname="N/A"
149 declare manufacturer="N/A"
155 while read -r line; do
157 # Gather information about the light
158 if [[ ($line == =*) && ($line =~ IPv4[[:space:]](.+)[[:space:]]_elg) ]]; then
159 device=$(eval echo "${BASH_REMATCH[1]}") # eval to strip whitespace
160 elif [[ $line =~ hostname.+\[(.+)\] ]]; then hostname=${BASH_REMATCH[1]};
161 elif [[ $line =~ address.+\[(.+)\] ]]; then ip=${BASH_REMATCH[1]};
162 elif [[ $line =~ port.+\[(.+)\] ]]; then port=${BASH_REMATCH[1]};
163 elif [[ $line =~ txt.+\[(.+)\] ]]; then
164 txt=$(eval echo "${BASH_REMATCH[1]}") # eval to strip single and double quotes
166 if [[ $txt =~ mf=([^[[:space:]]*]*) ]]; then manufacturer=${BASH_REMATCH[1]}; fi
167 if [[ $txt =~ id=([^[[:space:]]*]*) ]]; then mac=${BASH_REMATCH[1]}; fi
168 if [[ $txt =~ md=.+[[:space:]]([^[[:space:]]*]*)[[:space:]]id= ]]; then sku=${BASH_REMATCH[1]}; fi
171 # Get information from the light
176 if [[ ! (-z $ip) && ! (-z $port) ]]; then
177 url="http://$ip:$port"
178 cfg=$(eval "${call} GET ${url}${settings}") > /dev/null
179 info=$(eval "${call} GET ${url}${accessory_info}") > /dev/null
180 light=$(eval "${call} GET ${url}${devices}") > /dev/null
182 # Store the light as json
183 lights["$ip"]=$( jq -n \
184 --arg dev "$device" \
185 --arg hn "$hostname" \
188 --arg mf "$manufacturer" \
192 --argjson light "$light" \
193 --argjson cfg "$cfg" \
194 --argjson info "$info" \
195 '{device: $dev, manufacturer: $mf, hostname: $hn, url: $url, ip: $ip,
196 port: $port, mac: $mac, sku: $sku, light: $light, settings: $cfg, info: $info}' )
198 # Reset for next light
199 declare {device,hostname,manufacturer,url,ip,mac,protocol,sku,cfg}="N/A"
205 # Manage user parameters
208 # Make sure dependencies are installed
209 dependencies avahi-browse curl notify-send jq
213 # Fail if we cannot find lights
214 [[ ${#lights[@]} -eq 0 ]] && die "No lights found" 2
219 [[ $action == "usage" ]] && usage
220 [[ $action == "list" ]] && print_json "${lights_json}"
221 [[ $action == "status" ]] && status
222 [[ $action == "on" ]] && set_state 1
223 [[ $action == "off" ]] && set_state 0