Identify Raspberry Pi device using built-in leds.

Introduction

Every Raspberry Pi (3 & 4) device contains two leds.

$ find /sys/class/leds/ -maxdepth 1 -follow -type d -name "led[0-9]"
/sys/class/leds/led0
/sys/class/leds/led1

The led0 indicates activity on the first memory card, the led1 is always on.

$ find /sys/class/leds/ -maxdepth 1 -follow -type d -name "led[0-9]" | xargs -I {} bash -c "echo -e \"\$(basename {})\n\tTrigger: \$(cat {}/trigger)\n\tBrightness: \$(cat {}/brightness)\" "
led0
	Trigger: none rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock timer oneshot heartbeat backlight gpio cpu cpu0 cpu1 cpu2 cpu3 default-on input panic actpwr mmc1 [mmc0] rfkill-any rfkill-none rfkill0
	Brightness: 0
led1
	Trigger: none rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock timer oneshot heartbeat backlight gpio cpu cpu0 cpu1 cpu2 cpu3 [default-on] input panic actpwr mmc1 mmc0 rfkill-any rfkill-none rfkill0
	Brightness: 255

Shell script

Create a simple shell script to temporarily alter leds behavior. It will locate power led set to default-on and temporarily change its behavior to a simple timer based or a heartbeat (blink-blink-pause) that is affected by the current load average.

#!/bin/bash
# Identify RPi device
# https://sleeplessbeastie.eu/2022/04/22/how-identify-raspberry-pi-device-using-built-in-leds/ 

# sysfs leds directory
leds_path="/sys/class/leds"

# default led trigger
led_trigger_def="default-on"

# temporary led trigger (heartbeat, timer)
led_trigger_tmp="heartbeat"

# script timeout
timeout="10"

# get leds (led0, led1, ..., led9)
get_leds(){
  find ${leds_path} -maxdepth 1 -follow -type d -name "led[0-9]" -printf '%f\n'
}

# get current trigger for specific led 
get_trigger(){
  if [ -n "${1}" ]; then
    cat ${leds_path}/${1}/trigger | awk -F "[][]" "{print \$2}"
  fi
}

# set trigger (second param) for specific led (first param)
set_trigger(){
  if [ -n "${1}" ] && [ -n "${2}" ]; then
    echo ${2} | tee ${leds_path}/${1}/trigger >/dev/null
  fi
}

# cleanup in case of exit or emergency
cleanup() {
  for led in $(get_leds); do
    if [ "$(get_trigger ${led})" == "${led_trigger_tmp}" ]; then
      set_trigger "${led}" "${led_trigger_def}"
    fi
  done
}
trap cleanup SIGINT EXIT

# main
for led in $(get_leds); do
  if [ "$(get_trigger ${led})" == "${led_trigger_def}" ]; then
    set_trigger "${led}" "${led_trigger_tmp}"
    sleep ${timeout}
  fi
done

Execute it on a Raspberry Pi device to quickly locate it.

Additional notes

Source code for the mentioned led triggers: ledtrig-heartbeat.c and ledtrig-timer.c