https://github.com/bkahlert/pihero

Ansible-based tool to make your Raspberry Pi discoverable, accessible, and fun to use

https://github.com/bkahlert/pihero

Science Score: 13.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (3.1%) to scientific vocabulary

Keywords

ansible ethernet gadget network raspberry-pi raspberrypi rpi usb
Last synced: 5 months ago · JSON representation

Repository

Ansible-based tool to make your Raspberry Pi discoverable, accessible, and fun to use

Basic Info
  • Host: GitHub
  • Owner: bkahlert
  • License: mit
  • Language: Shell
  • Default Branch: master
  • Homepage:
  • Size: 6.31 MB
Statistics
  • Stars: 3
  • Watchers: 2
  • Forks: 1
  • Open Issues: 0
  • Releases: 0
Topics
ansible ethernet gadget network raspberry-pi raspberrypi rpi usb
Created over 2 years ago · Last pushed almost 2 years ago
Metadata Files
Readme Funding License Codeowners

README.md

Pi Hero License Buy Me A Unicorn

Pi Hero Banner

About

Pi Hero is an Ansible-based tool to make your Raspberry Pi discoverable, accessible, and fun to use.

Pi Hero makes your Raspberry Pi:

  • show a splash screen during boot and shutdown,
  • show up in your network with a nice icon,
  • share device information,
  • create an Ethernet over USB connection,
  • configure Windows-compatible Samba shares,
  • accept serial connection, and
  • allow for custom features like behaving like a keyboard, mouse, mass storage, etc.
  • create a Bluetooth PAN

Supported are even old models like the Raspberry Pi Zero with no network accessibility at all.

Features

Easy configuration

A sample inventory for sample devices, namely foo.local and bar.local is provided to get you started:

```yaml

Device "foo" with the following features:

- Bluetooth PAN with custom CIDR and one (pre-)trusted device

- Ethernet over USB

foo.local: btpan: cidr: 10.11.10.10/29 devices: { mac: 00:11:22:33:44:55, pin: '*', trusted: true } usbgadget: ethernet:

Device "bar" with custom model and the following features:

- Ethernet over USB with custom CIDR

- USB Serial Port

- custom USB Mass Storage

bar.local: deviceinfo: { model: MacPro7,1@ECOLOR=226,226,224 } usbgadget: ethernet: { cidr: 10.10.20.20/29 } serial: mass_storage: # ... ```

Discoverable

Avahi is installed to make your Raspberry Pi discoverable in your network. By default, your Raspberry Pi shows up as a 4th-generation AirPort device. The samba shares, SSH, and SFTP services are advertised as well.

| network browser foo.local and bar.local in network browser | network info foo foo.local info | network info bar bar.local info | |-------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|

Accessible

File sharing

Samba shares are configured for home directories and the root directory /.

ℹ️ Don't forget to set a Samba password using sudo smbpasswd -a $USER samba password

| samba login samba login | samba shares samba shares | samba home share samba home share | samba rootfs share samba rootfs share | |------------------------------------------------------------------------------|----------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------|

Bluetooth PAN

If your device has Bluetooth, a Personal Area Network PAN—more specifically a Network Access Point NAP—can be created. It lets your configured devices connect to your Raspberry Pi via Bluetooth.

| discoverable Raspberry Pi discoverable Raspberry Pi
| connected with Mac via Bluetooth PAN connected with Mac via Bluetooth PAN
| ping with iPhone via Bluetooth PAN ping with iPhone via Bluetooth | samba share via Bluetooth PAN samba share accessed with iPhone via Bluetooth | |-------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|

Devices are identified by their MAC address. To find out your device's MAC address:

  • On macOS, run system_profiler SPBluetoothDataType | grep "Address:" | head -n 1
  • On an iPhone, go to Settings > General > About > Bluetooth
  • On Windows, run ipconfig /all | findstr "Bluetooth"
  • On Linux, run bt-adapter -i | grep "Address:" | head -n 1

Ethernet over USB

If your device has no Wi-Fi or Ethernet port, or you use them for a different purpose, just connect via USB. An Ethernet over USB network interface is automatically created and configured.

| network devices USB network devices | network device rpi 0 bar.local USB network device | network device rpi 0 details bar.local network device details | |--------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|

By default, your Raspberry Pi uses the IP address 10.10.10.10, and configures your computer via DHCP.

The most complicated part is to use the right USB port: you'll need to use the so-called USB-OTG port. It's typically the one in the middle.

Serial port

Additionally, a serial port over USB is set up.

| serial device Serial device on the host | serial login Login using serial connection | serial logged in Logged-in using serial connection | serial ping to host Successful ping of host | |--------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|

  • To list all available serial ports, type ls /dev/tty.usbmodem*.
  • To connect to the first available serial port, you need a terminal emulator program such as:
    • screen $(ls /dev/tty.usbmodem* | head -n 1) 115200 (exit with Ctrl+A K)
    • cu -s 115200 -l $(ls /dev/tty.usbmodem* | head -n 1) (exit with ~.)
    • minicom -b 115200 -D $(ls /dev/tty.usbmodem* | head -n 1) (exit with Meta+Z X)

Maintainable

The pihero tool provides diagnostics, that help you resolve problems.

Simply type pihero diag to get a report on possible configuration problems.

| Pi Hero commands Available Pi Hero commands | Pi Hero succeeded diagnostics Succeeded diagnostics | Pi Hero failed diagnostics Failed diagnostics | |----------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|

Extensible

The USB-based features are based on the Linux kernel's multifunction composite gadget, or g_multi. The gadget is configured using a shell script that supports any gadget function, you would like your Raspberry Pi to provide.

The serial port and USB over Ethernet functions are supported by default.

The following configuration shows a custom USB mass storage gadget that creates a 1 GB removable hard drive:

```yaml usbgadget: massstorage: | #!/usr/bin/env bash

    # create disk image
    if [ ! -f /data/hdd.img ]; then
      mkdir -p /data
      fallocate -l 1GB /data/hdd.img
      mkfs.exfat -v -L 'RaspiDrive' -f /data/hdd.img
    fi

    # create mass storage gadget, see kernel.org/doc/html/latest/usb/gadget-testing.html#mass-storage-function
    echo 1 >stall
    echo /data/hdd.img                  > lun.0/file
    echo 'SanDisk Cruzer Edge     1.20' > lun.0/inquiry_string
    echo 1                              > lun.0/removable

```

| mass storage drive info Drive info | mass storage drive details Drive details | |-----------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|

  • You can add any supported gadget function, e.g. hid, or mass_storage (see above) to the usb_gadget node of your Ansible configuration.
  • The value needs to be a shell script (either inline, or the path to it on your device).
  • The most part is already done for you.
  • All you have to do is to configure the function itself.
  • The necessary functions/<function>.<instance> directory is already created and the working directory of your script.
  • If your script does not exit with code 0, the function will simply not be enabled.
  • Eventually occurred problems are logged, see Troubleshooting.

Installation

Preparations

  • Install Ansible on your computer.
  • Checkout this repository: shell git clone https://github.com/bkahlert/pihero.git cd pihero

Configuration

  • Copy the sample inventory to inventory/berries and adapt it to your needs: shell cp -r inventory/sample inventory/berries

By default, your device is advertised as an AirPort (4th generation) device. After having tried a dozen configurations, this one turned out to be the best, because it's recognized by most devices, is of kind Mac but looks like a tiny network device and not like a classical computer.

If you'd like to go with a different configuration, these are the ones I'd recommend:

| Model | AirPort4 | AirPort5 | AirPort6 | Macmini8,1 | Macmini9,1 | MacPro6,1 | MacPro5,1 | MacPro7,1
@ECOLOR=
225,225,223 | MacPro7,1
@ECOLOR=
226,226,224 | Xserve3,1 | |---------|:-----------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------:| | Kind | Mac | AirPort Extreme | Time Capsule | Mac | Mac | Mac | Mac | Mac | Mac | Mac | | Icon | com.apple.airport-express.png | com.apple.airport-extreme.png | com.apple.time-capsule.png | com.apple.macmini-2018.png | com.apple.macmini-2020.png | com.apple.macpro-cylinder.png | com.apple.macpro.png | com.apple.macpro-2019.png | com.apple.macpro-2019-rackmount.png | com.apple.xserve.png | | Sidebar | com.apple.airport-express-sidebar.png | com.apple.airport-extreme-sidebar.png | com.apple.time-capsule-sidebar.png | com.apple.macmini-2018-sidebar.png | com.apple.macmini-2020-sidebar.png | com.apple.macpro-cylinder-sidebar.png | com.apple.macpro-sidebar.png | com.apple.macpro-2019-sidebar.png | com.apple.macpro-2019-rackmount-sidebar.png | com.apple.xserve-sidebar.png |

Raspberry Pi preparation

  • Flash the latest Raspberry Pi OS Lite image to your SD card.
  • Boot your Raspberry Pi and connect it to your network.

| Using Wi-Fi | Using Ethernet | Using USB | |-----------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|------------------------------------------------------------| | Configure your Wi-Fi upfront.
The easiest way to do that is using the Raspberry Pi Imager's customization feature. | Connect your Pi with an Ethernet cable to your DHCP enabled network. | Use a USB to Ethernet adapter and connect to your network. |

  • Locate your Raspberry Pi
    • Ideally you should be able to ping your device using ping raspberry.local, or the hostname you configured.
    • If that doesn't work, you can
      • use netmon,
      • check your Router's web interface, or
      • scan your network with nmap -sn nmap -sn 192.168.0.0/24 (adapt to your network)
    • If you can't, you can use nmap to scan your network for devices:

Ansible

  • Start the setup process using: ```shell # Setup only the device foo.local ansible-playbook playbook.yml -l foo.local

# Setup only the device foo.local declared in the given inventory, and use the specified IP address to connect ansible-playbook playbook.yml -l foo.local \ -e "ansible_host=10.10.10.99" \ -i inventory/other/hosts.yml ``` - If you used the provided sample inventory with two Raspberry Pis,
the output should look like the one in sample-installation.md.

- Alternatively, you can integrate Pi Hero in your playbook with the following snippet:
  ```yaml
  - hosts: "{{ inventory if inventory is defined else 'all' }}"
    gather_facts: false
    tasks:
      - name: check if plymouth-themes directory exists
        ansible.builtin.stat: { path: "{{ playbook_dir }}/plymouth-themes/" } # ← used to store custom splash screens
        register: plymouth_themes_stat
      - name: set fact for local_plymouth_themes_dir
        set_fact: { local_plymouth_themes_dir: "{{ playbook_dir }}/plymouth-themes/" }
        when: plymouth_themes_stat.stat.isdir is defined and plymouth_themes_stat.stat.isdir
        tags: [ never, pihero ]

  - name: run Pi Hero playbook, if --tags pihero is specified
    ansible.builtin.import_playbook: ../../pihero/playbook.yml                # ← location of Pi Hero
    tags: [ never, pihero ]
  ```
  To run the Pi Hero playbook, add `--tags pihero` to your `ansible-playbook` command.
  • Wait for the playbook to finish and your Raspberry Pi to reboot.

    • If you used a USB to Ethernet adapter, you should remove the adapter and connect to your computer directly.
    • You can do so when the Raspberry Pi is about to reboot.
    • If you missed this moment, just unplug the adapter and restart.

Your Raspberry Pi is now ready to use, and should show up in your network properly.

| device info foo foo.local device information | device info bar bar.local device information | |-----------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|

Usage

Log in using ssh foo.local and you'll be greeted with a message containing information about the configured features:

```text Linux gadget 6.1.21-v8+ #1642 SMP PREEMPT aarch64

─=≡▰▩▩[ 蓬•o•]⊐ Shares smb://foo.local/pi → /home/pi smb://foo.local/rootfs → / (read-only)

─=≡▰▩▩[ 蓬•o•]⊐ USB gadget FEATURES: mass_storage, serial, ethernet

─=≡▰▩▩[ 蓬•o•]⊐ USB ethernet INTERFACE: usb0 — IP 10.10.10.10 / 255.255.255.248 — DHCP: 10.10.10.11 - 10.10.10.14 HELP: pihero gadget

─=≡▰▩▩[ 蓬•o•]⊐ Bluetooth PAN INTERFACE: usb0 — IP 10.11.10.10 / 255.255.255.248 — DHCP: 10.11.10.11 - 10.11.10.14 HELP: pihero pan

Last login from 10.10.10.12 ```

Troubleshooting

You can run a diagnosis script with:

```shell

all diagnostics

pihero diag

or

only USB gadget diagnostics

pihero gadget diag ```

usb gadget diag

It produces output like the following with additional hints on how to proceed

``` Checking if /boot/config.txt contains dtoverlay=dwc2... ✔︎ Checking if /boot/cmdline.txt contains modules-load=dwc2... ✔︎ Checking if /boot/cmdline.txt contains no line breaks... ✔︎ Checking if libcomposite module is loaded... ✔︎ Checking if usb-gadget service is active... ✔︎

...

Checking if usb0 interface config is not malformed... ✔︎ Checking if usb0 interface config is not malformed... ✔︎ Checking if usb0 interface exists... ✔︎ All checks passed.

Useful commands: - check usb-gadget service: systemctl status usb-gadget.service; journalctl -b -u usb-gadget.service - run usb-gadget yourself: sudo usb-gadget - scan for connected hosts: command -v nmap >/dev/null 2>&1 || sudo apt-get install -yqq nmap; nmap -sn 10.10.10.11-14 - check networking: systemctl status networking - check dnsmasq service: systemctl status dnsmasq.service - check dnsmasq config: dnsmasq --test - stop dnsmasq service: sudo systemctl stop dnsmasq.service - start dnsmasq manually: dnsmasq --no-daemon --log-queries ```

As advised by the diagnosis script, you can also try:

shell journalctl -b -u usb-gadget.service

usb gadget log

This prints something like the following, which is quite handy when debugging custom gadget functions:

text systemd[1]: Starting Pi Hero USB Gadget... usb-gadget[642]: Setting up USB gadget pihero... usb-gadget[642]: Creating gadget pihero... usb-gadget[642]: Creating configuration c.1... usb-gadget[642]: Creating function ecm.usb0... usb-gadget[642]: Associating function ecm.usb0 with configuration c.1... usb-gadget[642]: Creating function acm.usb0... usb-gadget[642]: Associating function acm.usb0 with configuration c.1... usb-gadget[642]: Creating function mass_storage.usb0... usb-gadget[642]: Delegating creation of function mass_storage.usb0 to usb-gadget-custom... usb-gadget[664]: Creating custom function mass_storage.usb0 using inline script... usb-gadget[664]: Invoking /tmp/tmp.mrFN5Lqm7H mass_storage usb0 in functions/mass_storage.usb0... usb-gadget[668]: /tmp/tmp.mrFN5Lqm7H: line 12: lun.1/removable: No such file or directory usb-gadget[664]: ERROR: Invocation terminated with exit code 1. usb-gadget[664]: ERROR: Failed to execute script /tmp/tmp.mrFN5Lqm7H for function mass_storage.usb0. usb-gadget[642]: ERROR: The function mass_storage.usb0 failed to create. It won't be associated with configuration c.1. usb-gadget[642]: This is what functions/mass_storage.usb0 looked like: usb-gadget[642]: Directory /sys/kernel/config/usb_gadget/pihero/functions/mass_storage.usb0 usb-gadget[642]: total 0 usb-gadget[642]: drwxr-xr-x 2 root root 0 Aug 6 23:40 lun.0/ usb-gadget[642]: -rw-r--r-- 1 root root 4.0K Aug 6 23:40 stall usb-gadget[642]: usb-gadget[642]: functions/mass_storage.usb0/lun.0: usb-gadget[642]: total 0 usb-gadget[642]: -rw-r--r-- 1 root root 4.0K Aug 6 23:40 cdrom usb-gadget[642]: -rw-r--r-- 1 root root 4.0K Aug 6 23:40 nofua usb-gadget[642]: -rw-r--r-- 1 root root 4.0K Aug 6 23:40 removable usb-gadget[642]: -rw-r--r-- 1 root root 4.0K Aug 6 23:40 ro usb-gadget[642]: --w------- 1 root root 4.0K Aug 6 23:40 forced_eject usb-gadget[642]: -rw-r--r-- 1 root root 4.0K Aug 6 23:40 inquiry_string usb-gadget[642]: -rw-r--r-- 1 root root 4.0K Aug 6 23:40 file usb-gadget[642]: Enabling gadget in /sys/kernel/config/usb_gadget/pihero... ✔︎ systemd[1]: Finished Pi Hero USB Gadget.

The relevant line here is /tmp/tmp.mrFN5Lqm7H: line 12: lun.1/removable: No such file or directory. When you look closely, you can see that lun.1 was used instead of lun.0.

Contributing

Want to contribute? Awesome! The most basic way to show your support is to star the project, or to raise issues. You can also support this project by making a PayPal donation to ensure this journey continues indefinitely!

Thanks again for your support, it is much appreciated! :pray:

License

MIT. See LICENSE for more details.

Owner

  • Name: Björn Kahlert
  • Login: bkahlert
  • Kind: user
  • Location: Berlin, Germany

GitHub Events

Total
Last Year

Issues and Pull Requests

Last synced: about 1 year ago

All Time
  • Total issues: 0
  • Total pull requests: 1
  • Average time to close issues: N/A
  • Average time to close pull requests: less than a minute
  • Total issue authors: 0
  • Total pull request authors: 1
  • Average comments per issue: 0
  • Average comments per pull request: 0.0
  • Merged pull requests: 1
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
  • bkahlert (1)
Top Labels
Issue Labels
Pull Request Labels

Dependencies

requirements.txt pypi
  • netaddr *