I'm using tasker and udp sender to send udp packets with commands to a listening socat.
So if I send, for example (trailing blank line is intentional):
hue_onmy Hue lights and HTPC will turn on. Tasker is then set up to send these commands when my phone connects to my home network. Simple and effective.
kodi_on
On to the script.
Please note:
The tdtool-lines you see in the case file is a tool for Tellstick which can be used to toggle power switches on and off remotely.
The ssh command requires you to have set up ssh keys to automate ssh logins.
Kodi stuff requires that your Kodi installation is set up to accept calls to its JSON-RPC API.
With that out of the way ...
The script is actually made up of at least three files.
One containing variables and functions (sourced in main script as *.fv):
### Variables htpc_name=user@computername kodi_json=http://computername:8080/jsonrpc kodi_mac=00:00:00:00:00:00 hue_bridge=0.0.0.0 hue_apikey=1234567890 hue_lights=1,2,3,4,5 rc_ip=0.0.0.0 ### Functions doKodi() { curl -s --data-binary "{ \"jsonrpc\": \"2.0\", \"method\": $1,\"params\":{$2} , \"id\": \"mybash\" }" \ -H 'content-type: application/json;' $kodi_json } doHue() { curl -s -X PUT -H "Content-Type: application/json" -d \ "{\"ct\":600,\"bri\":254,\"on\":$2,\"transitiontime\":100}" http://$hue_bridge/api/$hue_apikey/lights/$1/state } doLX() { telnet $rc_ip 2> /dev/null } doHTPC() { ssh -n -f $htpc_name "sh -c 'nohup $1 &> /dev/null &'" }
One, or more, containing the case statement (sourced in main script as *.do):
# Changes to this file does NOT require reload of main script. # Note that line endings must be LF or bash gets confused and cranky. case "$1" in ### DAC dac_on) echo DAC: on tdtool -n 1 ;; dac_off) echo DAC: off tdtool -f 1 ;; ### FAN fan_on) echo FAN: on tdtool -n 2 ;; fan_off) echo FAN: off tdtool -f 2 ;; ### Reciever rc_on) echo Reciever: on { sleep 0.1; echo "PO"; sleep 6; echo "01FN"; sleep 2; } | doLX ;; rc_off) echo Reciever: off { sleep 0.1; echo "25FN"; sleep 2; } | doLX ;; ### KODI dlna_on) echo Kodi: DLNA on doKodi '"Input.Home"' '' sleep 1 doKodi '"Profiles.LoadProfile"' '"profile":"optical"' ;; dlna_off) echo Kodi: DLNA off doKodi '"Input.Home"' '' sleep 1 doKodi '"Profiles.LoadProfile"' '"profile":"Master user"' ;; kodi_on) echo Kodi: system on wol $kodi_mac ;; kodi_off) echo Kodi: system off doKodi '"Input.Home"' '' sleep 1 doKodi '"System.Shutdown"' '' ;; ### HUE hue_on) echo HUE: all on for x in $hue_lights; do doHue $x true & sleep .3 done ;; hue_off) echo HUE: all off for x in $hue_lights; do doHue $x false & sleep .3 done ;; ### HTPC spotify_on) echo Spotify: Start doHTPC "start_spotify.sh" ;; spotify_off) echo Spotify: Stop doHTPC "pkill Spotify" ;; esac
And finally the main script tying it all together:
#!/bin/bash ### Figure out who we are me=$(basename $0) ### Figure out where we are dir="${BASH_SOURCE%/*}" if [[ ! -d "$dir" ]]; then dir="$PWD"; fi ### Figure out where to talk logfile=$dir/$me.log #touch $logfile echo > $logfile ### Figure out where to listen socat_port=2222 ### Figure out how to do # Sourcing functions and variables from .fv files for readability # Changes to .fv-files requires reload of main script. . $dir/*.fv ### Go, do. doFluff() { # tell bash to separate on comma IFS=',' ### Figure out what to do ... # Sourcing cases from .do files for readability. # If a incomming call is present in more than one file, # both commands will be executed. # Changes to .do-files does NOT require reload of main script. for f in $dir/*.do; do . $f done unset IFS # restore IFS to default } ### Right round, baby, right round. loop() { socat udp-listen:$socat_port,reuseaddr,fork - | while read do; do local d=$(date +"%F %T") echo -n $d >> $logfile echo " :: do: $do" >> $logfile doFluff $do >> $logfile echo >> $logfile done } killtree() { local pid=$1 child for child in $(pgrep -P $pid); do killtree $child done [ $pid -ne $$ ] && kill -kill $pid } ### If we are already alive, kill us ... if [ $(pgrep -c $me) -gt 1 ]; then echo " Killing previous instance(s) of $me" #pkill -of $me pids=($(pgrep "$me")) for i in "${pids[@]}" do #(( $$ != i)) && kill -- -"$i" #(( $$ != i)) && kill -- -$(ps -o pgid=$i | grep -o [0-9]*) killtree $i &> /dev/null done fi ### then rise again ... loop & ### and fade away. echo " Loop engaged, script backgrounded." exit 0