# rpi-power-hat

Software package for the rpi-power-control-hat - control power and data for up to 4 downstream Raspberry Pi devices.

**Features:**
- Power control for connected devices
- Current and power monitoring
- Boot devices as mass storage gadgets 
- Flash custom OS images remotely
- Automated boot time measurement

**Supported Hardware:** rpi-power-control-hat v1.1, Pi 4, Pi 5, Pi Zero 2 W

## Hardware Setup

**Requirements:**
- HAT firmware installed (see: https://git.pitowers.org/lucas.hoffmann/rpi-power-cycling-hat) and jumpers attached correctly
- 2-4 short USB-A to USB-C cables
- 2-4 USB-C to USB-C/micro-USB cables (dependent on target device)
- 12v DC power supply (if you are planning on drawing 5A on each port, check that your power supply is able to supply up to 100W)

B is used to reference the 'bottom' board (default if only one board is used)
T is used to reference the 'top' board

> [!NOTE]
> You only need to power **ONE** HAT and the host Pi does not need
> to be powered.

Connect the host Pi to the HAT's USB-C input ports using your USB-A to USB-C cables. See the port-mappings below and connect accordingly: i.e B1 (Pi)-> B1 IN (HAT). The HAT has input ports marked `1B(T) IN`

Please see https://software-wiki.pitowers.org/index.php/File:Rpi-power-hat-cables.jpg for reference

```
## Side view looking into the Pi's USB ports ##
---------------------
|  T2 IN  |  T1 IN  |
------HAT PORTS------  <--- USB-C ports
|  B2 IN  |  B1 IN  | 
---------------------

----Pi USB----
|  B2  |  B1  |
---------------  <--- USB-A ports
|  T2  |  T1  |
---------------

!! To get the quickstart working, you only need to connect B1 to B1 IN !!
```

## Installation

### Pre-Requisites
- rpi-imager is required
- rpiboot is required (install via `sudo apt install rpiboot`)
- PiOS trixie installation for the device wearing the HAT

### Install via APT (Recommended)
```bash
sudo apt install rpiboot    # If required
# Package may be published to internal apt repository, please follow steps in the software wiki 
# to configure apt to use the internal repository
sudo apt update
sudo apt install rpi-power-hat
```

### Manual Installation

#### Clone git and install
```bash
# Additional build tools may be required
git clone https://git.pitowers.org/apt/rpi-power-hat.git

cd rpi-power-hat

debuild -b -uc -us

sudo dpkg -i ../rpi-power-hat_0.1.0_all.deb

rpi-power-hat --help
```
## Quickstart Guide

All commands use the unified `rpi-power-hat` interface. Use `rpi-power-hat -h` for general usage. The following commands will provision a Pi5, and ssh into it.

The fastest way to get setup is to connect a target Pi5 (with a blank SD card inside) to the usb-c port labelled **'1B(T) OUT'** on your _bottom_ board.

### Check HAT is working
```bash
rpi-power-hat set B1 1                  # Turn power ON
```
A red LED should now be turned on for port B1. Make sure your target device (Pi5) is connected to this port.

### Boot as a storage gadget

We will now boot the device as a mass-storage-gadget so that we can flash an image to the SD card.

Hold down the boot button on the Pi 5 and run the following:

> [!TIP]
> The Pi5 can be setup to enter bootmode without requiring a button press by following [the automating-bootmode section](#automating-bootmode)

```bash
rpi-power-hat mass-storage B1 5      # Hold down power button before running 
```

Because we specified the device '5' the program will now remember that we have a Pi5 connected to that port.

### Edit network config

Open the network.conf file using:

```
sudo nano /etc/rpi-power-hat/network.conf
```
Under the [DEFAULT] section, fill out the wlan_ssid and wlan_password fields.

### Device Flashing
```bash
rpi-power-hat flash-image B1 latest # Flash the latest stable bookworm image
# replace with 'nightly' for trixie
```
This may take several minutes, a successful run will contain something like:
```
Write successful.                         
Imaging history saved: /var/lib/rpi-power-hat/history/2025-08-20_15-39-49_T2_.log
```
### SSH

Wait for the device to boot up. This may take a while. 

```bash
sudo rpi-power-hat ssh B2 "hostname -I"            # Opens ssh terminal in target device
```

If no connection is being established check the hostnames in the `history` folder and the hostname in `ports.conf` are the same. You may also need to restart the target device using `rpi-power-hat set [PORT] 0` then `rpi-power-hat set [PORT] 1

#### Changing Hostname
To find out what the current hostname is:
```bash
rpi-power-hat get-hostname B2
```
To change the hostname
```bash
rpi-power-hat set-hostname B2 strawberrycake    # replace with your own hostname
```
You may need to restart the device using `set` and `get` or wait up to 60s for the changes to take effect. You can still use `rpi-power-hat ssh B2` but you will now also be able to use `ssh strawberrycake`

## Other commands
### Logging Power and Current

The `log-power` and `log-current` commands allow you to monitor and record the power usage and current draw of devices connected to each port. This is useful for diagnostics, benchmarking, or long-term monitoring.

#### Quick usage

- log-power: `rpi-power-hat log-power <PORT> [DURATION] [-s]`
- log-current: `rpi-power-hat log-current <PORT> [DURATION] [-s]`

Examples:

```bash
rpi-power-hat log-power B1 30 -s
rpi-power-hat log-current B1
```

Notes:
- 100 Hz sampling
- Ports: B1, B2, T1, T2
- `-s` also saves CSV in `/var/lib/rpi-power-hat/measurements/`:
  - power: `power_<PORT>_<TIMESTAMP>.csv` (header: `elapsed_time,power_reading`)
  - current: `current_<PORT>_<TIMESTAMP>.csv` (header: `elapsed_time,current_reading`)
- Console shows converted units (mW/mA); CSV stores raw hwmon readings.
- See INA260 averaging in Advanced Usage.
- When a port is ON and there is nothing connected, a non-zero power reading is still measured due to the red LED. This can be used to determine if a port is switched ON or not even without a device connected.

## Advanced Usage

### INA260 power monitor
The INA260 supports on-chip power averaging and is set by changing update_interval. The chip will continue collecting data at a constant rate, but will return the average power over the specified interval. This can be changed by running:
```bash
echo 1000 | sudo tee /sys/class/hwmon/hwmon4/update_interval    # replace 1000 and hwmon4
```
**Note**: you may not see your exact set value when checking with `cat` as the driver will set it to the nearest supported value. i.e 1000 -> 1126

## Automating bootmode 

A more complete version of these instructions is avaiable, with pictures, on https://software-wiki.pitowers.org/index.php/RPI_Power_HAT

### For Pi Zero 2 W:
You will need an SD card sniffer similar to this one: https://learn.sparkfun.com/tutorials/microsd-sniffer-hookup-guide/all.

Connect your sniffer with SD card inserted to the Pi Zero 2 W and connect a jumper from the sniffer CMD pin to a relevant GPIO pin on the HAT's 8 pin GPIO extender. See the table at the end of the section for mappings.

Plug the Zero 2 W into your HAT port of choice with a usb-c to micro-usb cable on the port labelled 'USB'

Now run `rpi-power-hat flash-image [PORT] [IMG]` as you usually would. Keep an eye on the terminal output to check whether you have fitted your jumper to the correct GPIO.

### For Pi 5:

To place the Pi5 into bootmode without needing to press the boot button, you will need to **solder a 2x1 pin header** to the pins next to the BAT connector.

Run a jumper from the pin **closest to the USB port** (i.e on the left as seen on the diagram) to a specified bootpin.

Now run `rpi-power-hat flash-image [PORT] [IMG]` as you usually would. Keep an eye on the terminal output to check whether you have fitted your jumper to the correct GPIO.

### For Pi 4:

Please follow the steps provided in https://github.com/raspberrypi/rpi-sb-provisioner/blob/main/docs/device-guidance/pi4.adoc to configure your device to use a specified GPIO boot pin. Connect this pin to the HAT's GPIO pin as mapped in the table below.

Now run `rpi-power-hat flash-image [PORT] [IMG]` as you usually would. Keep an eye on the terminal output to check whether you have fitted your jumper to the correct GPIO.

### Bootpin Mappings

<a name="bootpin-table"></a>
| Port  | GPIO Chip | GPIO Pin |
|------|-------|-----------|
| B1   | Bottom (gpiochip14) | 2 |
| B2   | Bottom (gpiochip14) | 3 |
| T1   | Top (gpiochip15) | 2 |
| T2   | Top (gpiochip15) | 3 |

## How Configuration Works

The tool remembers information about each device based on the port they were last flashed from. By editing the ports.conf file __before__ flashing, you can set config information such as the wifi password and model. The script will reference this information for SSH commands, allowing you to reference the device by port:
```
sudo rpi-power-hat ssh B2
```

Edit port settings in `/etc/rpi-power-hat/ports.conf` and Wi‑Fi in `/etc/rpi-power-hat/network.conf`:

```ini
[B1]
hostname=rpi-<Port>-<Generated>
username=pi
ssh_key=[Generated]
ssh_host=rpi-<Port>-<Generated>
port=B1
model=<model>
image_path=init/images/2025-05-13-raspios-bookworm-arm64.img.xz
```

Example network.conf:
```ini
# Default Wi-Fi used by all ports unless overridden
[DEFAULT]
wlan_ssid=YOUR_WLAN_SSID
wlan_password=YOUR_WLAN_PASSWORD

# Port-specific override (leave blank to use DEFAULT)
[B1]
wlan_ssid=SpecialNetwork
wlan_password=SpecialPassword

# This port will use DEFAULT Wi-Fi
[B2]
#wlan_ssid=
#wlan_password=
```

**Key settings:**
- `ssh_key`: SSH public key for secure access (auto-generated)
- `ssh_host`: Device hostname/IP for SSH
- `wlan_ssid/wlan_password`: WiFi credentials (in network.conf)

## Troubleshooting

### Red port lights turning on but no power to target device

Make sure the 'USB Power' jumpers are fitted as they enable power to the USB ports
You can check whether a downstream device is recieving power by turning the port on:
```
rpi-power-hat set <PORT> 1
```
And then checking the status of the port
```
rpi-power-hat get <PORT> 
```
If the port is turning ON successfully, but no power is being delivered to the target device then 


### Mass-storage not recognising device

Check your USB cables, short braided cables can exert enough force to slide out of the USB-A slightly.
Low quality USB cables can also cause imaging to fail.

### Low current problems
To check whether the firmware has recognised the HAT as a mode1 (5A capable) power-HAT run:

```
hexdump -Cv /sys/firmware/devicetree/base/chosen/power/usb_max_current_enable
```
If you see `00 00 00 01` that means that usb_max_current_enable has been set to 1 and a mode 1 device has been recognised.

If you get warnings from the host Pi along the lines of 'Power supply not capable of supplying 5A@5V...' it is most likely just the result of the order in which the Pi finds out which power sources it has, throwing an error before it recognises the power HAT. If you reboot the Pi these warnings should disappear.

### HAT Not Detected

Follow intructions from https://git.pitowers.org/lucas.hoffmann/rpi-power-cycling-hat to setup HAT

```bash
i2cdetect -y 1                    # Should show UU addresses
sudo usermod -a -G gpio,i2c $USER # Add permissions
```

Ensure stack select jumper is disconnected on top HAT and connected on bottom HAT.

### Permission Issues & device read failure
```bash
sudo usermod -a -G gpio,i2c $USER
# Log out and back in
```
If you are seeing issues such as `sed: couldn't open temporary file /etc/rpi-power-hat/sedG3emc1: Permission denied` and `device failed to read` when using mass-storage, there could be a problem with the rpiboot installation.

Try fixing with:
```
sudo apt remove rpiboot --purge       # Uninstall your rpiboot, commands may vary if you cloned and built from git
sudo apt remove rpi-power-hat --purge

sudo apt install rpi-power-hat rpiboot

### Command Not Found
```bash
sudo apt install --reinstall rpi-power-hat
```

### SSH issues
Please use `rpi-power-hat get-hostname [PORT] -h` to see whether the correct hostname is being used, if the correct hostname is in the history but not currently being used, you can use the `set-hostname` command. Please note than an unsuccessful image flash will update the hostname and keys, and this can be a likely cause for ssh issues. 

To inspect the complete details fo the latest imaging run, use:
```
cat /var/lib/rpi-power-hat/history/[DATE_TIME_PORT_HOSTNAME].log
```
If the target device performed a forced shutdown (i.e power was cut) then you may need to restart or re-enable ssh again. 

## Ports Reference

| Port | USB-C | GPIO Chip | GPIO Pin |
|------|-------|-----------|----------|
| B1   | Bottom Left | gpiochip14 | 0 |
| B2   | Bottom Right | gpiochip14 | 1 |
| T1   | Top Left | gpiochip15 | 0 |
| T2   | Top Right | gpiochip15 | 1 |


## Filesystem map
Important files and where they are installed:

`ports.conf` /etc/rpi-power-hat/ports.conf

`network.conf` /etc/rpi-power-hat/network.conf

`images` /var/lib/rpi-power-hat/images/

---

**License**: Apache 2.0 | **Support**: https://git.pitowers.org/apt/rpi-power-hat