Skip to content

Instantly share code, notes, and snippets.

@altercation
Created September 5, 2014 10:28
Show Gist options
  • Save altercation/7bd96cb41f4efd06b99a to your computer and use it in GitHub Desktop.
Save altercation/7bd96cb41f4efd06b99a to your computer and use it in GitHub Desktop.
Helper script to handle unplug events from my root usb hub on the surface pro 3
#!/usr/bin/env zsh
# plug/unplug usb to internal usb hub will suspend/resume machine
setopt EXTENDED_GLOB NO_UNSET ERR_EXIT
# udevadm info -a -p /sys/devices/pci0000:00/0000:00:14.0/usb1/1-1
# udevadm test --action remove /sys/devices/pci0000:00/0000:00:14.0/usb1/1-1
# sudo udevadm monitor --environment --udev
# ---------------------------------------------------------------------
# script values
# ---------------------------------------------------------------------
typeset -g SCRIPTNAME="${${SCRIPTPATH:=$(readlink -f $0)}:t}"
typeset -g SCRIPTROOT="${SCRIPTPATH:h}"
typeset -g SCRIPTCONF="$HOME/${XDG_CONFIG_HOME:-.config}/$SCRIPTNAME"
[[ -d $SCRIPTCONF ]] || mkdir $SCRIPTCONF &>/dev/null
# ---------------------------------------------------------------------
# initializers
# ---------------------------------------------------------------------
envinit () {
${(P)${(U)0}:-false} && return 0 || eval typeset -g ${(U)0}=true # run once only per script execution
typeset -gx DISPLAY="$(print /tmp/.X11-unix/*(:t:s/X/:))"
[[ $(loginctl list-sessions) =~ "seat0" ]] || { print "No X Session identified"; exit 1 }
export XAUTHORITY=/home/${${(s:/:)SCRIPTPATH}[2]}/.Xauthority
}
install () {
[[ $USER == root ]] || { print "run with sudo or as root when calling $SCRIPTNAME $0"; exit 1 }
# works but also too broad, but we'll use the test function below to determine if we sleep
rulepath=/etc/udev/rules.d/99-usb-removal.rules
rule='ACTION=="remove", ENV{ID_USB_INTERFACE_NUM}=="01", RUN+="'$SCRIPTPATH' conditionalSuspend $parent"'
[[ -f $rulepath ]] && rm -f $rulepath
print $rule > $rulepath || { print "Failed to initialize udev rule '$rulepath'"; exit 1 }
print "Successfully initialized udev rules $rulepath"
}
conditionalSuspend () {
# there are four builtin usb hub devices, so thats the count if we've unplugged everything
if (( ${#${(f)"$(lsusb -s 001:)"}} == 4 )) && [[ -z ${*:-} ]]
then
envinit
# make sure that usb hub is set to resume and then suspend
if [[ "$(</sys/devices/pci0000:00/0000:00:14.0/usb1/power/wakeup)" != enabled ]]
then
notify-send "Setting usb hub to wakeup mode, then suspending."
print "enabled" > /sys/devices/pci0000:00/0000:00:14.0/usb1/power/wakeup || {
notify-send "Failed!"; exit }
sleep 2 # to see the notification
fi
systemctl suspend
fi
}
$*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment