Seeedstudio reTerminal: How to access and use the hardware buttons and LEDs with the HA docker container installation

PS: As i’m a new user, i’m not allowed to post more than two links in this text, so i had to mask the links in this text.

:point_right: Hardware used:

  • Seeedstudio reTerminal CM4104032 (RPi CM4 powered all-in-one device (hxxps://www.seeedstudio.com/ReTerminal-with-CM4-p-4904.html)

  • MacBook Pro for remote setup and configuration via terminal (used for SSH login) and web browser (HA and Portainer)

:point_right: Prerequisite:

  • fresh installation of Raspberry Pi OS “bullseye”, 32-bit (Seeedstudio modified version to include necessary hardware drivers)
    (at the time of writing it was “32-bit 2022-07-21-Raspbian-reTerminal” found here: (hxxps://wiki.seeedstudio.com/reterminal_black_screen/#flash-raspberry-pi-os-which-is-originally-shipped-with-reterminal))

  • reTerminal connected to the internet (using wifi or ethernet)

  • additional installed software:

    • Docker CE
    • Portainer CE (Web UI for managing docker) found here: (hxxps://hub.docker.com/r/portainer/portainer-ce)
    • Home Assistant Container (hxxps://ghcr.io/home-assistant/raspberrypi4-homeassistant:stable) ( :warning: NOTE: Setup the docker container with network type “host” instead of the default type “bridge”)

Now let’s have a look at the device: :muscle:

According to the web page describing the device hardware ((hxxps://wiki.seeedstudio.com/reTerminal-hardware-interfaces-usage/)) there are 4 user programmable buttons (in fact 5 buttons: F1, F2, F3, O and the button on top of the device) and 3 user programmable LEDs (in fact 1 green led “USR” and 1 dual color red / green led “STA”) accessible via “/dev/class/leds/usr_led*” and “/dev/input/eventX”. (see: (hxxps://wiki.seeedstudio.com/reTerminal-hardware-interfaces-usage/#4-user-programmable-buttons) and (hxxps://wiki.seeedstudio.com/reTerminal-hardware-interfaces-usage/#3-user-programmable-leds))

:point_right: LEDs:

  • LED “USR” (green): /dev/class/leds/usr_led0
  • LED “STA” (red): /dev/class/leds/usr_led1
  • LED “STA” (green): /dev/class/leds/usr_led2

:point_right: Buttons:

The buttons are accessible in form of a keyboard device at “/dev/input/eventX” (normally /dev/input/event0, but i’ve seen /dev/input/event3 as well, therefore we use the device name “gpio_keys” instead later on)
The key codes are: (these are the default values, but they can be changed in the boot config: look at (hxxps://wiki.seeedstudio.com/reTerminal-hardware-interfaces-usage/#4-user-programmable-buttons), Step 5)

  • Button F1: Event code 30, KEY_A
  • Button F2: Event code 31, KEY_S
  • Button F3: Event code 32, KEY_D
  • Button O: Event code 33, KEY_F
  • Button on top: Event code 142 (undocumented)

:point_right: To control the user programmable LEDs from Home Assistant, i’ve used the “Command line” integration (hxxps://www.home-assistant.io/integrations/command_line/) and created a switch for every LED in the “configuration.yaml” file manually.

command_line:
  - switch:
      command_on: "echo 255 > /sys/class/leds/usr_led0/brightness"
      command_off: "echo 0 > /sys/class/leds/usr_led0/brightness"
      command_state: "cat /sys/class/leds/usr_led0/brightness"
      value_template: '{{ value == "255" }}'
      name: reTerminal LED USR

  - switch:
      command_on: "echo 255 > /sys/class/leds/usr_led1/brightness"
      command_off: "echo 0 > /sys/class/leds/usr_led1/brightness"
      command_state: "cat /sys/class/leds/usr_led1/brightness"
      value_template: '{{ value == "255" }}'
      name: reTerminal LED STA red

  - switch:
      command_on: "echo 255 > /sys/class/leds/usr_led2/brightness"
      command_off: "echo 0 > /sys/class/leds/usr_led2/brightness"
      command_state: "cat /sys/class/leds/usr_led2/brightness"
      value_template: '{{ value == "255" }}'
      name: reTerminal LED STA green

:point_right: To catch the button events in Home Assistant, i’ve used the “Keyboard Remote” (hxxps://www.home-assistant.io/integrations/keyboard_remote) integration and configured it in the “configuration.yaml” manually to listen on the “key up” and “key down” events of the device named “gpio_keys”.
Every button press will now trigger a “keyboard_remote_command_received” ha-event with information about the event source. (check the documentation for details)

keyboard_remote:
  - device_name: gpio_keys
    type:
      - 'key_up'
      - 'key_down'

(Hint: You can use the Events-Tab in the Developer Tools section in the sidebar to listen for the “keyboard_remote_command_received” event and check the sent data in detail.)

:point_right: As an example to use the button events in Home Assistant, i’ve though it would be a nice idea to switch the build-in LCD on and off using the hardware button on top of the device, which was a bit challenging at first, as it turned out later.

To control the build-in LCD, you have to use the X-Server tools, like “xset” for example.
The screen can be turned on and off using the DPMS screen blank commands. (in fact, it simply stops the video output, which subsequently put the “monitor” to some kind of sleep mode)

You can use the tool “xset” for that purpose:

  • Turn the screen on:
xset -d :0 dpms force on
  • Turn the screen off:
xset -d :0 dpms force off

:warning: NOTE:
If you want to try those commands on the host terminal command line, you have to prefix it with a short delay, so the xserver doesn’t get confused with your final key press, causing to turn on the screen again immediately, because it thinks, there is an ongoing user interaction.

For example:

sleep 1; xset -d :0 dpms force off

To get things up and running, you have to create another switch with the above commands in the commandline section of the configuration file, BUT…
… that won’t work as expected, because the “xset” executable is only available on the host system and not inside the docker container.
How to get around this issue? In short: Just use key-based a SSH connection from the container to the host system. (to keep this text as short as possible, i won’t go much into detail at this point)

  • Use Portainer as a convenient way to open up a terminal as user root inside the running docker container.

  • In that terminal run “ssh-keygen” to generate your public and private SSH key pair WITHOUT a passphase and save them to “/config/ssh_keys/id_rsa”.

  • Still in that terminal run “ssh-copy-id <host-user>@<host-ip>” to copy and install the public ssh key to the host system. (replace <host-user> and <host-ip> with your data, e.g. “ssh-copy-id [email protected]”)

Now you should be able to use the following ssh command to login to the host system, without entering a password.

ssh -i /config/ssh_keys/id_rsa [email protected]

We can check, if everything works as expected, when we execute the following command in the terminal inside the docker container and the screen turns off:

ssh -i /config/ssh_keys/id_rsa [email protected] 'xset -d :0 dpms force off'

Now, that we have everything together, we can finally create our configuration entry in the “configuration.yaml”

command_line:
  # ... previous entries ...

  - switch:
      command_on: ssh -i /config/ssh_keys/id_rsa [email protected] 'xset -d :0 dpms force on'
      command_off: ssh -i /config/ssh_keys/id_rsa [email protected] 'xset -d :0 dpms force off'
      command_state: ssh -i /config/ssh_keys/id_rsa [email protected] 'xset -d :0 -q | grep "Monitor is" | cut -c14-17' | grep "On" > /dev/null
      name: Host LCD

Finally we create an automations entry in the “automations.yaml” manually (or use the Web UI for that) to connect the button event to the switch command:

- id: '123456789' # WRITE A UNIQUE ID HERE
  alias: reTerminal - toggle LCD
  description: ''
  trigger:
  - platform: event
    event_type: keyboard_remote_command_received
    event_data:
      key_code: 142 # event code from the button on the top
      type: key_up
      device_name: gpio_keys
  condition: []
  action:
  - service: switch.toggle
    data: {}
    target:
      entity_id: switch.host_lcd # match this name with the name you used in the config above!
  mode: single

After reloading Home Assistant, you should be able to press the button on top of the device to switch the LCD off and on.

:warning: Final note:
I’ve written this from memory, after i spend a whole weekend to get everything up and running, therefore be kind, if there is something missing or i did any mistake in writing this all together.

2 Likes