TCP/JSON GPIO relay control service targeting Raspberry Pi 4 (Debian Trixie, libgpiod ≥ 2.0). Specifically for use with PgTgBridge built-in plugin PgTg PiGpio. Can be used as a smart wrapper to GPIOD that is accessible using JSON strings such as from Node-Red.
Commands are newline-delimited JSON sent over TCP. The connection remains open between commands.
| Direction | Example |
|---|---|
| Set ON | {"cmd":"set","output":"output1","value":1} |
| Set OFF | {"cmd":"set","output":"output2","value":0} |
| Timed ON (30s) | {"cmd":"set","output":"output1","value":30} |
| Read all | {"cmd":"read"} |
| OK (set) | {"status":"ok","output":"output1","value":1} |
| OK (read) | {"status":"ok","outputs":{"output1":1,"output2":0}} |
| Error | {"status":"error","message":"unknown output: output5"} |
| Value | Behaviour |
|---|---|
0 |
Static OFF — cancels any running timer |
1 |
Static ON — cancels any running timer |
2–999 |
Drives output ON; auto-forces OFF after that many seconds. A new value ≥ 2 before expiry resets the timer. |
On expiry the server sends {"status":"ok","output":"<name>","value":0} on the open connection if a client is connected.
When the PgTgBridge GPIO plugin is configured with an Amp PTT output, it sends value: 15
(not 1) whenever the amplifier PTT is keyed. This starts a 15-second channel watchdog timer on
the service side. PgTgBridge then re-sends value: 15 every 10 seconds to keep the watchdog
alive for the duration of the transmission. When PTT is released the PgTgBridge sends value: 0.
If the PgTgBridge loses connectivity, the watchdog expires after 15 seconds and the PTT output is automatically deactivated — preventing a stuck transmitter if the connectivity to the host machine is lost.
If the PgTgBridge service is stopped, PgTg sends value: 0 to all configured GPIO channels before halting.
Location: /etc/PgTgPiGpio/PgTgPiGpio.conf
# PgTgPiGpio configuration file
# You may need to change the gpio_chip assignment to suit your particular hardware.
port = 5555
gpio_chip = /dev/gpiochip0
# output<N> = GPIO BCM offset
# These numbers are the GPIO number, not pin numbers on the Raspberry Pi!
output1 = 6
output2 = 13
output3 = 19
output4 = 26The live conf file is created from the package template on first install and is preserved on upgrade and removal. Edit it directly on the Pi; it is never overwritten by apt.
The service runs as the dedicated system user pgtgpigpio (member of the gpio group) — no root required.
[Unit]
Description=PgTgPiGpio TCP/JSON GPIO relay control service
After=network.target
Wants=network.target
[Service]
Type=simple
ExecStart=/usr/bin/PgTgPiGpio /etc/PgTgPiGpio/PgTgPiGpio.conf
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=PgTgPiGpio
User=pgtgpigpio
Group=gpio
[Install]
WantedBy=multi-user.targetThe service file is installed and enabled automatically by the Debian package.
Two build workflows are available — cross-compile from a WSL2 host, or build natively on the Pi. If building under WSL2, a deb package is created.
Prerequisites (install once on the Pi):
sudo apt install cmake ninja-build pkg-config libgpiod-dev./build
# Produces: build-native/PgTgPiGpioThe script verifies all prerequisites and the libgpiod version before building.
You will be responsible for copying the PgTgPiGpio binary to:
/usr/bin/PgTgPiGpio
make sure it is marked as executable:
sudo chmod +x /usr/bin/PgTgPiGpio
and creating the configuration file here:
/etc/PgTgPiGpio/PgTgPiGpio.conf
(you need to setup the cross-compiler yourself)
./build-with-cross-compiler
# Produces: build-aarch64/PgTgPiGpio (ELF aarch64)./package
# Produces: pgtgpigpio_1.0.0_arm64.deb
# Sources binary from build-aarch64/PgTgPiGpio./deploy
# SCPs pgtgpigpio_1.0.0_arm64.deb to pi@<yourPiIpaddress>:/home/pi/Browse to https://github.com/KD4Z/PgTgPiGpio/releases and check for latest release filename. For example: pgtgpigpio_1.0.0_arm64.deb Change the filename in wget below if different.
From your Pi shell prompt
cd /tmp
wget https://github.com/KD4Z/PgTgPiGpio/releases/download/1.0.0/pgtgpigpio_1.0.0_arm64.deb
sudo apt install /tmp/pgtgpigpio_1.0.0_arm64.deb
Now edit the conf file for particular configuration
sudo nano /etc/PgTgPiGpio/PgTgPiGpio.conf
sudo systemctl restart PgTgPiGpio
The package installer:
- Creates the
pgtgpigpiosystem user and adds it to thegpiogroup - Copies the factory-default config to
/etc/PgTgPiGpio/PgTgPiGpio.conf(first install only) - Copies the daemon binary to
/usr/bin - Installs and starts the systemd service
# Upgrade (live config is preserved)
sudo apt install /home/pi/pgtgpigpio_1.0.0_arm64.deb
# Remove (binary and service removed; config kept)
sudo apt remove pgtgpigpio
# Full purge (config and system user also removed)
sudo apt purge pgtgpigpio# Set output1 ON
echo '{"cmd":"set","output":"output1","value":1}' | nc localhost 5555
# Read all output states
echo '{"cmd":"read"}' | nc localhost 5555
# Set output1 OFF
echo '{"cmd":"set","output":"output1","value":0}' | nc localhost 5555
# Timed ON — output1 goes ON, forces OFF after 30 seconds
echo '{"cmd":"set","output":"output1","value":30}' | nc localhost 5555
# Monitor in journald
journalctl -f -u PgTgPiGpio# Start and follow logs
sudo systemctl start PgTgPiGpio && journalctl -u PgTgPiGpio -f
# Stop (triggers clean GPIO release — verify in journal)
sudo systemctl stop PgTgPiGpio
# Confirm service is running as pgtgpigpio (not root)
ps aux | grep PgTgPiGpio
or to see user and group in list
ps -eo user,group,cmd | grep PgTgPiGpio