Configuring a Node (Meshtastic) - jonatello/farmalytics GitHub Wiki
In this example I'm using a Raspberry Pi Zero W with an Adafruit RFM95W bonnet in order for it to communicate over Meshtastic:
- Raspberry Pi Zero W (https://www.raspberrypi.org/products/raspberry-pi-zero-w/)
- Adafruit Lora Radio bonnet with OLED - RFM95W (https://www.adafruit.com/product/4074)
Configure the Operating System
https://github.com/jonatello/farmalytics/wiki/Configuring-a-Node-(Software)
Ensure it is running Raspbian 12 (bookworm)
Install Meshtastic
This guide is a great starting place and includes supported hardware - https://meshtastic.org/docs/hardware/devices/linux-native-hardware/
The following steps should all be done within the terminal:
Add the meshtastic repository and install meshtasticd
echo 'deb http://download.opensuse.org/repositories/network:/Meshtastic:/beta/Raspbian_12/ /' | sudo tee /etc/apt/sources.list.d/network:Meshtastic:beta.list
curl -fsSL https://download.opensuse.org/repositories/network:Meshtastic:beta/Raspbian_12/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/network_Meshtastic_beta.gpg > /dev/null
sudo apt update
sudo apt install meshtasticd
Enable SPI and I²C support
echo 'dtparam=spi=on' | sudo tee -a /boot/firmware/config.txt
echo 'dtparam=i2c_arm=on' | sudo tee -a /boot/firmware/config.txt
Configure Meshtastic
Enable I²C detection
sudo sed -i 's/# I2CDevice/ I2CDevice/g' /etc/meshtasticd/config.yaml
Enable the Webserver for device management
sudo sed -i 's/# Port/ Port/g' /etc/meshtasticd/config.yaml
sudo sed -i 's/# RootPath/ RootPath/g' /etc/meshtasticd/config.yaml
sudo sed -i 's/# SSLKey/ SSLKey/g' /etc/meshtasticd/config.yaml
sudo sed -i 's/# SSLCert/ SSLCert/g' /etc/meshtasticd/config.yaml
Enable the MAC Address Source for wlan0 (assuming it's using wireless)
sudo sed -i 's/# MACAddressSource: eth0/ MACAddressSource: wlan0/g' /etc/meshtasticd/config.yaml
Add device configuration specific for the RFM95W
wget https://raw.githubusercontent.com/jonatello/farmalytics/refs/heads/master/lora-Adafruit-RFM9x.yaml
sudo mv ./lora-Adafruit-RFM9x.yaml /etc/meshtasticd/config.d/
Enable the meshtasticd service to start on boot and restart it due to new configuration changes
sudo systemctl enable meshtasticd
sudo systemctl restart meshtasticd
Configure Meshtastic CLI
The CLI will be used for interfacing with Meshtastic via the Raspberry Pi terminal.
First, setup a Python Virtual Environment - https://learn.adafruit.com/python-virtual-environment-usage-on-raspberry-pi/basic-venv-usage
sudo apt install python3.11-venv
Install pip
sudo apt install python3-pip
In this case we're calling it "meshtastic"
python3 -m venv meshtastic
Enter the virtual environment
source meshtastic/bin/activate
Next, we can install the CLI within the virtual environment - https://meshtastic.org/docs/software/python/cli/installation/
pip3 install --upgrade pytap2
pip3 install --upgrade "meshtastic[cli]"
To exit the virtual environment, use the following command
deactivate
For a reference of available Meshtastic CLI commands, see https://meshtastic.org/docs/software/python/cli/
Extending functionality
For bot functionality, including features for sending/receiving images and files over Meshtastic, configure the bot service as follows. These steps will assume that the user is "pi".
Install dependencies
sudo apt install jpegoptim libjpeg-progs python3-pip imagemagick jp2a
source meshtastic/bin/activate
pip3 install zopfli flask tailer
Copy the meshtastic_receiver.py, meshtastic_sender.py, meshtastic_bot.py, and meshtastic_web.py scripts to the home directory (/home/pi/ in this case)
Create a templates directory and copy the html files into it for the web service
Copy meshtastic_bot.service to /etc/systemd/system
cp meshtastic_bot.service /etc/systemd/system/
Copy meshtastic_web.service to /etc/systemd/system
cp meshtastic_web.service /etc/systemd/system/
Reload the systemd daemon
sudo systemctl daemon-reload
Start the web and bot services and enable them at boot
sudo systemctl start meshtastic_bot.service
sudo systemctl enable meshtastic_bot.service
sudo systemctl start meshtastic_web.service
sudo systemctl enable meshtastic_web.service
To view the logs in realtime, use the following commands
sudo journalctl -u meshtastic_bot.service -f
sudo journalctl -u meshtastic_web.service -f
For some of the advanced bot commands (such as restartbot!, restartweb! and reboot!) add the following to sudoers under the "User privilege specification" section
Edit sudoers
sudo visudo
Commands to add
pi ALL=(ALL) NOPASSWD: /bin/systemctl restart meshtastic_bot.service
pi ALL=(ALL) NOPASSWD: /bin/systemctl restart meshtastic_web.service
pi ALL=(ALL) NOPASSWD: /sbin/reboot
Usage
The general idea is to configure multiple nodes using the above steps and after the bot is running you can easily interface with it from other Meshtastic nodes. Make sure to update the primary channel, you do not want to spam LongFast, I'd recommend creating a new private channel and ensuring it's the only one that exists on these nodes. You can also direct message them and get responses.
The "help!" command can be used to view all available commands. "ping!" is a simple one that will reply with SNR and RSSI values. "sysinfo!" will reply with non-Meshtastic system information about the node itself.
When it comes to sending an image you can direct message a single node the "send!" command with appropriate parameters (it uses query-string syntax) to begin the process. The below example will cause it to leverage the meshtastic_sender.py script to send an image captured with Motion (attached webcam - https://github.com/jonatello/farmalytics/wiki/Configuring-a-Node-(Webcam)), resize to 800x600, and then transfer with a prepended header of "nc". The meshtastic_sender.py script is written in a way that it will initially send a "receive!" command to the specified "dest" node. The receiving node will receive this command telling it to run the meshtastic_receiver.py script with supplied parameters. This message will include the "expected" parameter, telling it how many chunked messages are going to be sent (so that it knows when to stop listening and reconstruct the message). In my case on the receiving node I've updated the default values of "upload" to True and the corresponding "remote_target" and "ssh_key" values to properly have it upload the restored content to a file share that the receiving node has TCP/IP connectivity to. I've defaulted the "run_time" parameter to 60 minutes to prevent it from running indefinitely, but again it will stop immediately and return to bot functionality when the total expected messages have arrived. You can hard code values in the meshtastic_receiver.py and meshtastic_sender.py scripts per node to make these commands simpler to run.
send!dest=!47a78d36&mode=image_transfer&resize=800x600&header=nc