voidcruiser-test.nl/content/rambles/pwr-switch.md
2022-10-14 14:02:39 +02:00

5.2 KiB

title date author tags description
PWR Switch 2022-10-14T10:50:56+02:00 $HUMANOID
linux
ssh
iot
Hacked together IOT setup with some semblance of security

Introduction

As we all know, the "S" in IOT stands for security. We've all seen countless stories of people's networks getting hijacked due to some 3 year old vulnerability in the software stack of their insert smart device here. These things barely get any patches at all. On top of that, the most they do is spy on you and send your footage to the police without asking for your consent.

Still, on the other hand, it can be really convenient to be able to control some of the electronics in your home without having to walk towards them. I personally have a lamp that I frequently forget to turn off when leaving my room. The solution was an Olimex PWR-switch in combination with a Raspberry Pi 4 that I have running 24/7 regardless (mostly to watch YouTube videos and listen to music over my speaker set; I might write a post about this beautifully hacky contraption at some point in the future).

Setup

Setting it up was relatively easy.

First I connected a European extension socket to a random 230 volt cable I still had laying around. Then I hooked that up to my PWR-switch and plugged my lamp into that contraption.

From there I got little bag of jumper wires from my local electronics store and hooked up the PWR-switch to my Raspberry Pi. I hooked up the PWR-switch's positive to GPIO 15 and it's ground to the preceding ground pin. Here's a reference page.

Note, GPIO 15 is in reference to pin number 10 and the preceding ground pin is pin number 6.

From there I looked up how to send power to GPIO 15 in order to have it toggle to the "on" state. The first step to this end is to initialise the pin. This can be done with:

echo 15 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio15/direction

Then, sending power to it can be done using something like...

echo 1 > /sys/class/gpio/gpio15/value

...and the opposite can be done using:

echo 0 > /sys/class/gpio/gpio15/value

Deinitialising the pin can be done with:

echo 15 > /sys/class/gpio/unexport

To make this all a little easier I have written a wrapper in POSIX Shell: {{< start-details summary="Click to see script" >}}

#!/bin/sh

INIT_PIN(){
	# the PWR-SWITCH is connected to GPIO 15 and the preceding ground pin
	# reference page https://pinout.xyz/pinout/
	[ -d /sys/class/gpio/gpio15 ] && echo "Pin already initialised" && exit 0
	echo 15 > /sys/class/gpio/export
	echo out > /sys/class/gpio/gpio15/direction
}

DEINIT_PIN(){
	[ -d /sys/class/gpio/gpio15 ] || echo "Pin not initialised" && exit 0
	echo 15 > /sys/class/gpio/unexport
}

PIN_STATUS(){
	if [ -d /sys/class/gpio/gpio15 ] ; then
		echo "pin status: Pin initialised"
	else
		echo "pin status: Pin not initialised"
	fi
}

SWITCH_ON(){
	# initialise pin before doing anything
	[ -d /sys/class/gpio/gpio15 ] || INIT_PIN
	echo 1 > /sys/class/gpio/gpio15/value
}

SWITCH_OFF(){
	# initialise pin before doing anything
	[ -d /sys/class/gpio/gpio15 ] || INIT_PIN
	echo 0 > /sys/class/gpio/gpio15/value
}

TOGGLE_SWITCH(){
	# initialise pin before doing anything
	[ -d /sys/class/gpio/gpio15 ] || INIT_PIN
	case $(cat /sys/class/gpio/gpio15/value) in
		1) SWITCH_OFF;;
		0) SWITCH_ON;;
	esac
}

USAGE(){
	cat >&2 <<EOF
Usage: pwr-switch <on|off|init|deinit>
	on: send on signal
	off: send off signal
	init: initialise pin
	deinit: deinitialise pin
	status: show pin initialisation state
	toggle: toggle on/off signal
EOF
}

case $1 in
	on) SWITCH_ON;;
	off) SWITCH_OFF;;
	init) INIT_PIN;;
	deinit) DEINIT_PIN;;
	status) PIN_STATUS;;
	toggle) TOGGLE_SWITCH;;
	*) USAGE;;
esac

{{< end-details >}}

You could probably also do this in Python, but my knowledge of Python is nearly none.

Remote interaction

You can probably make a guess as to how I set up the automation and interaction from other devices. That's right, I used an SSH forced command:

no-pty,command="/usr/local/sbin/pwr-switch toggle" ssh-ed25519 <contents of <lamp-key>.pub>

The unique thing here being that it needs to be executed as the root user in order to mess with the state of the pins. (Or at least in the case of my setup.) So having it be a forced command is a security benefit here as it prevents whatever device you're using to toggle your lamp from having to log in as the root user. All a device with the <lamp-key> can do, is toggle the state of GPIO 15.

You could contrivedly call this SIOT...

Since Android 12, there is the "Device controls" tile in the swipe-down-from-the-top-of-the-screen-menu. Termux can interact with the API that this system provides and allows you to add buttons corresponding to Termux' shortcuts. These shortcuts are executables found in ~/.shortcuts within the Termux environment. Here I've created a little script that logs into my Raspberry Pi using the <lamp-key>, allowing me to toggle my lamp at the tap of a button as long as I'm on my home network.