Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
# x730-script
This is the safe shutdown script for x730;

NOTE:
This is the safe shutdown script for x730

We test this shell script base official Raspbian '2018-11-13-raspbian-stretch.img' version;
We test this shell script base official Raspbian '2019-09-26 Raspbian Buster' version also;
> [!NOTE]
>
> This version targets newer Raspberry Pi OS versions supporting `pinctrl` instead of `/sys/class/gpio` or `raspi-gpio`

How to use?

* step 1:
> wget https://raw.githubusercontent.com/geekworm-com/x730-script/master/x730.sh
## Prequisites

> sudo chmod +x x730.sh
1. OS supporting systemd
2. `bash` shell (v5+ or GNU coreutils)
3. Either sleep supporting fractions of seconds or perl or python
4. `pinctrl` binary on path

> sudo bash x730.sh

* step 2:
## Installation

> printf "%s\\n" "alias x730off='sudo x730shutdown.sh'" >> ~/.bashrc
Run `sudo install.sh`

* step 3:
> sudo reboot

* how to safe shut down, run the following comamdn:
> x730off
## Usage

Use default GUI or terminal possibilities for poweroff/reboot or press the button of you PI's case (short reboot, long shutdown).
49 changes: 49 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env bash

SCRIPT_PATH="${BASH_SOURCE}"
while [ -L "${SCRIPT_PATH}" ]; do
SCRIPT_DIR="$(cd -P "$(dirname "${SCRIPT_PATH}")" >/dev/null 2>&1 && pwd)"
SCRIPT_PATH="$(readlink "${SCRIPT_PATH}")"
[[ ${SCRIPT_PATH} != /* ]] && SCRIPT_PATH="${SCRIPT_DIR}/${SCRIPT_PATH}"
done
SCRIPT_PATH="$(readlink -f "${SCRIPT_PATH}")"
SCRIPT_DIR="$(cd -P "$(dirname -- "${SCRIPT_PATH}")" >/dev/null 2>&1 && pwd)"

# Test is root
if [ "$EUID" -ne 0 ]
then
echo "Please run as root"
exit
fi


# Check prequisites
echo "Checking prequisites ..."

echo "Test required binaries"
for bin in "systemctl" "pinctrl" "bash"
do
if ! command -v "$bin" &> /dev/null
then
echo "$bin ... missing"
exit 1
else
echo "$bin ... passed"
fi
done

echo "Test "


# Install shell scripts
chmod 755 "$SCRIPT_DIR"/src/*.sh
cp "$SCRIPT_DIR"/src/*.sh /usr/local/bin/


# Install systemd units
chmod 644 "$SCRIPT_DIR"/src/*.service
cp "$SCRIPT_DIR"/src/*.service /etc/systemd/system/

systemctl enable x730poweroff
systemctl enable x730reboot
systemctl enable --now x730button
11 changes: 11 additions & 0 deletions src/x730button.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=X730 Case Button
After=local-fs.target

[Service]
Type=exec
RemainAfterExit=no
ExecStart=/usr/local/bin/x730button.sh

[Install]
WantedBy=multi-user.target
70 changes: 70 additions & 0 deletions src/x730button.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env bash

SHUTDOWN=4
REBOOT_PULSE_MINIMUM_MILLISECONDS=200
REBOOT_PULSE_MAXIMUM_MILLISECONDS=600
SLEEP_PULSE_SECONDS="0.200"
pinctrl set "$SHUTDOWN" ip pd

BOOT=17
pinctrl set "$BOOT" op pn dl
pinctrl set "$BOOT" dh

python() {
"$(command -v python3 || command -v python || command -v python2)" "$@"
}

exSleep() {
sleep "$1" \
|| perl -e "select(undef, undef, undef, $1)" \
|| python -c "import time; time.sleep($1)"
}

getShutdownSignal() {
pinctrl lev "$SHUTDOWN"
}

getPulseTimestamp() {
if [ -n "$EPOCHREALTIME" ]
then
local us="${EPOCHREALTIME/[^0-9]/}"
echo "${us:0:-3}"
else
python -c "import time; print(int(time.time() * 1000))" \
|| date +%s%3N
fi
}

sleepPulse() {
exSleep "$SLEEP_PULSE_SECONDS"
}

echo "X730 Shutting down..."

while :
do
shutdownSignal=$(getShutdownSignal)
if [ "$shutdownSignal" = 0 ]
then
sleepPulse
else
pulseStart=$(getPulseTimestamp)
while [ "$shutdownSignal" = 1 ]
do
sleepPulse
if [ $(( $(getPulseTimestamp) - $pulseStart )) -gt $REBOOT_PULSE_MAXIMUM_MILLISECONDS ]
then
echo "X730 Shutting down, halting Rpi ..."
sudo poweroff
exit
fi
shutdownSignal=$(getShutdownSignal)
done
if [ $(( $(getPulseTimestamp) - $pulseStart )) -gt $REBOOT_PULSE_MINIMUM_MILLISECONDS ]
then
echo "X730 Rebooting, recycling Rpi ..."
sudo reboot
exit
fi
fi
done
13 changes: 13 additions & 0 deletions src/x730poweroff.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=X730 Case Poweroff
DefaultDependencies=no
Conflicts=reboot.target
Before=poweroff.target halt.target shutdown.target

[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/usr/local/bin/x730shutdown.sh "4"

[Install]
WantedBy=poweroff.target halt.target shutdown.target
13 changes: 13 additions & 0 deletions src/x730reboot.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=X730 Case Reboot
DefaultDependencies=no
Conflicts=poweroff.target halt.target
Before=reboot.target

[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/usr/local/bin/x730shutdown.sh "1"

[Install]
WantedBy=reboot.target
25 changes: 25 additions & 0 deletions src/x730shutdown.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash

BUTTON=18

pinctrl set "$BUTTON" op pn dl
pinctrl set "$BUTTON" dh

exSleep() {
sleep "$1" \
|| perl -e "select(undef, undef, undef, $1)" \
|| python3 -c "import time; time.sleep($1)"
}

# 1-2 sec for reboot, 3-7 for poweroff (default) 8+ crash (pull the plug)
SLEEP=${1:-4}

if ! [[ "$SLEEP" =~ ^[0-9\.]+$ ]] ; then
echo "error: sleep time not a number" >&2; exit 1
fi

echo "X730 Shutting down..."
exSleep "$SLEEP"

#restore GPIO 18
pinctrl set "$BUTTON" dl
30 changes: 30 additions & 0 deletions uninstall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env bash

SCRIPT_PATH="${BASH_SOURCE}"
while [ -L "${SCRIPT_PATH}" ]; do
SCRIPT_DIR="$(cd -P "$(dirname "${SCRIPT_PATH}")" >/dev/null 2>&1 && pwd)"
SCRIPT_PATH="$(readlink "${SCRIPT_PATH}")"
[[ ${SCRIPT_PATH} != /* ]] && SCRIPT_PATH="${SCRIPT_DIR}/${SCRIPT_PATH}"
done
SCRIPT_PATH="$(readlink -f "${SCRIPT_PATH}")"
SCRIPT_DIR="$(cd -P "$(dirname -- "${SCRIPT_PATH}")" >/dev/null 2>&1 && pwd)"

# Test is root
if [ "$EUID" -ne 0 ]
then
echo "Please run as root"
exit
fi


# Uninstall systemd units
systemctl disable x730poweroff
systemctl disable x730reboot
systemctl disable --now x730button
rm /etc/systemd/system/x730poweroff.service
rm /etc/systemd/system/x730reboot.service
rm /etc/systemd/system/x730button.service

# Unnstall shell scripts
rm /usr/local/bin/x730shutdown.sh
rm /usr/local/bin/x730button.sh
72 changes: 0 additions & 72 deletions x730.sh

This file was deleted.