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 ;;
86 -?*) die "Unknown option: $1" ;;
94 # check required params and arguments
95 declare -A actions=([help]=1 [list]=1)
96 [[ ${#args[@]} -ne 1 ]] && die "Incorrect action count, 1 allowed"
98 [[ ($silent -eq 1) && ($pretty -eq 1) ]] && die "Cannot use silent and pretty options simultaneously"
100 [[ -n "${actions[${args[0]}]}" ]] && action="${args[0]}"
107 if ! command -v $var &>/dev/null; then
108 die "Dependency $var was not found, please install and try again"
113 default_light_properties() {
114 # Default values for json type enforcement
116 declare hostname="N/A"
117 declare manufacturer="N/A"
130 for l in "${!lights[@]}"; do
131 json+="${lights[$l]},"
134 lights_json="[${json%,}]"
138 if [[ $pretty -eq 1 ]]; then
141 echo "$1" | jq -c -M '.'
148 die "To be implemented"
153 die "To be implemented"
157 # Scan the network for Elgato devices
158 avahi-browse -d local _elg._tcp --resolve -t | grep -v "^\+" >"$temp_file"
160 default_light_properties
162 while read -r line; do
164 # Gather information about the light
165 if [[ ($line == =*) && ($line =~ IPv4[[:space:]](.+)[[:space:]]_elg) ]]; then
166 device=$(eval echo "${BASH_REMATCH[1]}") # eval to strip whitespace
167 elif [[ $line =~ hostname.+\[(.+)\] ]]; then
168 hostname=${BASH_REMATCH[1]}
169 elif [[ $line =~ address.+\[(.+)\] ]]; then
170 ip=${BASH_REMATCH[1]}
171 elif [[ $line =~ port.+\[(.+)\] ]]; then
172 port=${BASH_REMATCH[1]}
173 elif [[ $line =~ txt.+\[(.+)\] ]]; then
174 txt=$(eval echo "${BASH_REMATCH[1]}") # eval to strip single and double quotes
176 if [[ $txt =~ mf=([^[[:space:]]*]*) ]]; then manufacturer=${BASH_REMATCH[1]}; fi
177 if [[ $txt =~ id=([^[[:space:]]*]*) ]]; then mac=${BASH_REMATCH[1]}; fi
178 if [[ $txt =~ md=.+[[:space:]]([^[[:space:]]*]*)[[:space:]]id= ]]; then sku=${BASH_REMATCH[1]}; fi
180 # Get information from the light
181 if [[ ! (-z $ip) && ! (-z $port) ]]; then
182 url="http://$ip:$port"
183 cfg=$(eval "${call} GET ${url}${settings}") >/dev/null
184 info=$(eval "${call} GET ${url}${accessory_info}") >/dev/null
185 light=$(eval "${call} GET ${url}${devices}") >/dev/null
188 # Store the light as json
189 lights["$ip"]=$(jq -n \
190 --arg dev "$device" \
191 --arg hn "$hostname" \
194 --arg mf "$manufacturer" \
198 --argjson light "$light" \
199 --argjson cfg "$cfg" \
200 --argjson info "$info" \
201 '{device: $dev, manufacturer: $mf, hostname: $hn, url: $url, ip: $ip,
202 port: $port, mac: $mac, sku: $sku, light: $light, settings: $cfg, info: $info}')
204 # Reset for next light as we are processing the last avahi line
205 default_light_properties
211 # Manage user parameters
214 # Make sure dependencies are installed
215 dependencies avahi-browse curl notify-send jq
219 # Fail if we cannot find lights
220 [[ ${#lights[@]} -eq 0 ]] && die "No lights found" 2
225 [[ $action == "usage" ]] && usage
226 [[ $action == "list" ]] && print_json "${lights_json}"
227 [[ $action == "status" ]] && status
228 [[ $action == "on" ]] && set_state 1
229 [[ $action == "off" ]] && set_state 0