- Introduction
- Install RotorHazard on a Raspberry Pi
- RotorHazard Node Code
- Optional Components
- Running the RotorHazard server
- Updating an existing installation
- Enable Port forwarding
- Other Operating Systems
- Viewing Database Files
- RotorHazard Portable
- Logging
The central software component of the RotorHazard system is its server, written in Python, which operates its functions and serves up web pages to browsers. In a standard setup, the server is run on a RaspberryPi. (It is also possible to run RotorHazard on other types of hardware -- see the Other Operating Systems section below.)
Note: If RotorHazard is already installed, see the Updating an existing installation section below.
Note: Many of the setup commands below require that the Rasperry Pi has internet access.
Install the Raspberry Pi OS, following the official instructions: https://www.raspberrypi.org/help
The standard-recommended setup is to use a Raspberry Pi 3 board and install the Raspberry Pi OS (32-bit, Desktop).
Tip: Any time you intend to use a monitor (via HDMI) with the Raspberry Pi, connect it before powering up the Pi. Connecting the monitor after power up tends to not work (blank screen).
(The options may be configured using step 2a or 2b below.)
If Raspberry Pi OS with Desktop was installed, the interface options may be configured via "Preferences" | "Raspberry Pi Configuration" | "Interfaces":
- Enable SSH, SPI, I2C, and 'Serial Port'
- Disable 'Serial Console'
- For remote access to the desktop (using a program like RealVNC viewer), enable VNC
If the Pi OS Desktop is not available, the interface options may be configured using the following command:
sudo raspi-config
- Select 'Interface Options' and enable: SSH, SPI, and I2C
- Select 'Interface Options' | 'Serial Port', and configure:
- "login shell accessible serial": No
- "serial port hardware enabled": Yes
Open a terminal window and enter:
sudo nano /boot/config.txt
Add the following lines to the end of the file:
dtparam=i2c_baudrate=75000
dtoverlay=miniuart-bt
If the Raspberry Pi in use is a Pi 3 model or older (not a Pi 4) then also add this line:
core_freq=250
If your hardware is the S32_BPill setup with shutdown button and AUX LED then add these lines:
dtoverlay=act-led,gpio=24
dtparam=act_led_trigger=heartbeat
dtoverlay=gpio-shutdown,gpio_pin=18,debounce=5000
Save and exit (CTRL-X, Y, ENTER)
The first line sets the transfer rate on the I2C bus (which is used to communicate with the Arduino node processors).
The "dtoverlay=miniuart-bt" line moves the high performance UART from the Bluetooth device to the GPIO pins, which is needed for setups like the S32_BPill that use the serial port as the communications channel to the nodes.
The "core_freq" line fixes a potential variable clock-rate issue, described here. If a Raspberry Pi 4 is being used, the "core_freq" line should be omitted (as per the Raspberry Pi documentation here).
For the S32_BPill setup, the "dtoverlay=act-led,gpio=24" and "dtparam=act_led_trigger=heartbeat" lines configure a Raspberry-Pi-heartbeat signal that the BPill processor monitors to track the status of the Pi. The "dtoverlay=gpio-shutdown..." line makes it so the shutdown button still operates if the RotorHazard server is not running.
Using a terminal window, do a system update and upgrade (this can take a few minutes):
sudo apt update && sudo apt upgrade
Using a terminal window, install Python and the Python drivers for the GPIO:
sudo apt install python3-dev libffi-dev python3-smbus build-essential python3-pip git scons swig python3-rpi.gpio
The minimum version of Python supported is 3.5 Check the current default version of Python by entering the following command:
python --version
If the version reported is older than Python 3, enter the following commands to switch the default version to Python 3:
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 2
After the above commands are entered, the system should default to using Python 3. The default version can be switched back and forth via the command: sudo update-alternatives --config python
Install the RotorHazard server code under '/home/pi/' on the Raspberry Pi as follows:
Go to the Latest Release page for the project and note the version code.
In the commands below, replace the two occurrences of "1.2.3" with the current version code, and enter the commands using a terminal window:
cd ~
wget https://codeload.github.com/RotorHazard/RotorHazard/zip/1.2.3 -O temp.zip
unzip temp.zip
mv RotorHazard-1.2.3 RotorHazard
rm temp.zip
Enter the commands below to install RotorHazard server dependencies (be patient, this may take a few minutes):
cd ~/RotorHazard/src/server
sudo pip install -r requirements.txt
In the "src/server" directory, copy the config-dist.json file to config.json:
cp config-dist.json config.json
With a command like nano config.json
edit the config.json file and modify the ADMIN_USERNAME and ADMIN_PASSWORD values. These are the login credentials you will need to enter (in the browser popup window) to access the pages reserved for the race director (i.e., the Settings and Run pages).
The contents of the config.json file must in valid JSON format. A validator utility like JSONLint can be used to check for syntax errors.
After the above setup steps are performed, the system should be rebooted by entering the following using a terminal window:
sudo reboot
The RotorHazard Race Timer User Guide contains further instructions and setup tips for using the timer and the software.
The firmware for the RotorHazard nodes will need to be installed (or updated). The nodes can be Arduino based (with an Arduino processor for each node channel), or use the multi-node S32_BPill board (with a single STM32F1 processor running 1-8 channels).
For Arduino-based node boards, see the 'src/node/readme_Arduino.md' file for more information and instructions for installing the node firmware code.
For the S32_BPill board, the recommended method for installing the currently-released node firmware is to use the Update Nodes
button (in the 'System' section on the 'Settings' page) on the RotorHazard web GUI.
The "dtoverlay=miniuart-bt" line needs to have been added to the "/boot/config.txt" file for the flash-update to succeed (see instructions above).
Note that the flash-update steps described in 'src/node/readme_S32_BPill.md' are for developers who wish to build the S32_BPill node firmware from the source code.
The node-code version may be viewed in the Server Log, and via the "About RotorHazard" item in the drop-down menu.
The installation of a real-time clock module allows the RotorHazard timer to maintain the correct date and time even when an internet connection is not available. See 'doc/Real Time Clock.md' for more information.
Support for WS2812b LED strips (and panels) is provided by the Python library 'rpi-ws281x' (which is among the libraries installed via the sudo pip install -r requirements.txt
command.
The LED_COUNT value must be set in the src/server/config.json
file; other LED configuration options will attempt to use reasonable defaults. LED_ROWS must be set for multiline displays. See the src/server/config-dist.json
file for the default configuration of the 'LED' settings. The following items may be set:
LED_COUNT: Number of LED pixels in strip (or panel)
LED_ROWS: Number of rows in a multiline LED display panel (LED_COUNT must be evenly divisible by this value; default 1)
LED_PIN: GPIO pin connected to the pixels (default 10 uses SPI '/dev/spidev0.0')
LED_FREQ_HZ: LED signal frequency in hertz (usually 800000)
LED_DMA: DMA channel to use for generating signal (default 10)
LED_INVERT: True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL: Set to '1' for GPIOs 13, 19, 41, 45 or 53
LED_STRIP: Strip type and color ordering (default is 'GRB')
PANEL_ROTATE: Optional panel-rotation value (default 0)
INVERTED_PANEL_ROWS: Optional even-index row inversion for LED panels (default false)
LED_PIN is the GPIO number, not the hardware pin index. If specified, the LED_STRIP value must be one of: 'RGB', 'RBG', 'GRB', 'GBR', 'BRG', 'BGR', 'RGBW', 'RBGW', 'GRBW', 'GBRW', 'BRGW', 'BGRW'
Running LEDs from certain GPIO pins (such as GPIO18) requires the server to be run as root. If the error message Can't open /dev/mem: Permission denied
or mmap() failed
appears on startup, you must run the server with sudo
or connect LEDs to a different GPIO pin. If using a service file to start the server on boot, it may be run as root by leaving out the "User=pi" line.
See also the WS2812b LED Support section in doc/Hardware Setup.md.
Java enables the calculating of IMD scores, which is helpful for selecting frequency sets with less interference between VTXs. To determine if Java is installed, run the following command:
java -version
If the response is "command not found" then Java needs to be installed.
For the Raspberry Pi 3 or Pi 4, use the following command:
sudo apt install default-jdk-headless
For the Raspberry Pi Zero (or an older-model Pi), use this command:
sudo apt install openjdk-8-jdk-headless
The following instructions will start the web server on the raspberry pi, allowing full control and configuration of the system to run races and save lap times.
Open a terminal window and enter the following:
cd ~/RotorHazard/src/server
python server.py
The server may be stopped by hitting Ctrl-C
To configure the system to automatically start the RotorHazard server when booting up:
Create a service file:
sudo nano /lib/systemd/system/rotorhazard.service
with the following contents
[Unit]
Description=RotorHazard Server
After=multi-user.target
[Service]
User=pi
WorkingDirectory=/home/pi/RotorHazard/src/server
ExecStart=/usr/bin/python server.py
[Install]
WantedBy=multi-user.target
Running LEDs from certain GPIO pins (such as GPIO18) requires the server to be run as root. If the error message Can't open /dev/mem: Permission denied
or mmap() failed
appears on startup, remove User=pi
from this config.
Save and exit (CTRL-X, Y, ENTER).
Update permissions:
sudo chmod 644 /lib/systemd/system/rotorhazard.service
Enable the service:
sudo systemctl daemon-reload
sudo systemctl enable rotorhazard.service
sudo reboot
If the RotorHazard server was started as a service during the boot, it may be stopped with a command like this:
sudo systemctl stop rotorhazard
To disable the service (so it no longer runs when the system starts up), enter:
sudo systemctl disable rotorhazard.service
To query the status of the service:
sudo systemctl status rotorhazard.service
A system shutdown should always be performed before unplugging the power, either by clicking on the 'Shutdown' button on the 'Settings' page, or by entering the following in a terminal:
sudo shutdown now
Before updating, any currently-running RotorHazard server should be stopped. If installed as a service, it may be stopped with a command like:
sudo systemctl stop rotorhazard
To update an existing RotorHazard installation: Go to the Latest Release page for the project and note the version code. In the commands below, replace the two occurrences of "1.2.3" with the current version code, and enter the commands:
cd ~
wget https://codeload.github.com/RotorHazard/RotorHazard/zip/1.2.3 -O temp.zip
unzip temp.zip
mv RotorHazard RotorHazard.old
mv RotorHazard-1.2.3 RotorHazard
rm temp.zip
cp RotorHazard.old/src/server/config.json RotorHazard/src/server/
cp RotorHazard.old/src/server/database.db RotorHazard/src/server/
The previous installation ends up in the 'RotorHazard.old' directory, which may be deleted or moved.
For RotorHazard the minimum version of Python supported is 3.5. If your Python is older than this, you should upgrade using the steps in the "Install RotorHazard" section under "5. Install Python."
The RotorHazard server dependencies should also be updated (be patient, this command may take a few minutes):
cd ~/RotorHazard/src/server
sudo pip install --upgrade --no-cache-dir -r requirements.txt
The RotorHazard server defaults to port 5000, as this is necessary for some 3rd party integrations. While you can change the port via HTTP_PORT
in the config.json
file, a better approach is often to forward the web default port of 80 to 5000.
By default, HTTP uses port 80. Other values will require that the port be included as part of the URL entered into client browsers. If other web services are running on the Pi, port 80 may already be in use and reusing it will cause problems. If port 80 is used directly via HTTP_PORT
, the server may need to be run using the sudo command. With the following commands, the server runs on port 5000 but the system sends the traffic from port 80 to it.
sudo apt-get install iptables
sudo iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-ports 5000
sudo iptables -A PREROUTING -t nat -p tcp --dport 8080 -j REDIRECT --to-ports 80
sudo iptables-save
sudo apt-get install iptables-persistent
After running these commands, RotorHazard will be available from both ports 80 and 5000. When available by port 80, you may leave the port off when accessing the server, i.e.: http://127.0.0.1
Note: The second iptables command will forward port 8080 to 80, so services that would normally be available on port 80 will instead be available on port 8080. If port 80 services are not present or if other services are using port 8080, this iptables command may be omitted.
The RotorHazard server may be run on any computer with an operating system that supports Python. In these alternate configurations, one or more hardware nodes may be connected via USB -- see doc/USB Nodes.md for more information. The server may also be run using simulated (mock) nodes.
To install the RotorHazard server on these systems:
-
If the computer does not already have Python installed, download and install Python from https://www.python.org/downloads . To check if Python is installed, open up a command prompt and enter
python --version
-
From the RotorHazard Releases page on github, download the "Source code (zip)" file.
-
Unzip the downloaded file into a directory (aka folder) on the computer.
-
Open up a command prompt and navigate to the
src/server
directory in the RotorHazard files (using the 'cd' command). -
Install the RotorHazard server dependencies using the 'reqsNonPi.txt' file, using one of the commands below. (Note that this command may require administrator access to the computer, and the command may take a few minutes to finish).
- On a Windows system the command to use will likely be:
python -m pip install -r reqsNonPi.txt
Note: If the above command fails with a message like "error: Microsoft Visual C++ 14.0 is required", the Visual C++ Build Tools may be downloaded (from here) and installed.
- On a Linux system the command to use will likely be:
sudo pip install -r reqsNonPi.txt
To run the RotorHazard server on these systems:
-
Open up a command prompt and navigate to the
src/server
directory in the RotorHazard files (if not already there). -
Enter:
python server.py
-
If the server starts up properly, you should see various log messages, including one like this:
Running http server at port 5000
-
The server may be stopped by hitting Ctrl-C
If hardware nodes are connected via USB, they will need to be configured in the "SERIAL_PORTS" section in the "src/server/config.json" configuration file (see doc/USB Nodes.md for details).
If no hardware nodes are configured, the server will operate using simulated (mock) nodes. In this mode the web-GUI interface may be explored and tested.
To view the web-GUI interface, open up a web browser and enter into the address bar: localhost:5000
(If the HTTP_PORT value in the configuration has been changed then use that value instead of 5000). If the server is running then the RotorHazard main page should appear. Note that pages reserved for the race director (Admin/Settings) are password protected with the username and password specified in the configuration.
A "snapshot" copy of the database file used by the RotorHazard server may be downloaded using the Backup Database
button in the 'Database' section on the 'Settings' page in the RotorHazard web GUI. A tool like DB Browser for SQLite may be used to view the raw data in the file.
A database file may be loaded into the RotorHazard server via the "--viewdb" command-line argument:
python server.py --viewdb dbFileName.db [pagename] [browsercmd]
The current server database is backed up and the specified one is loaded. If a 'pagename' value (i.e., "results") is given then a web browser is launched showing the RotorHazard web GUI at the specified page. If a 'browsercmd' value is given then that command is used to launch the web browser (for instance, a value of "C:\Program Files\Mozilla Firefox\firefox.exe" could be specified to launch the Firefox browser on a PC where is it installed but is not the default browser).
The "--launchb" command-line argument can be specified to launch a web browser after the server starts up:
python server.py --launchb [pagename] [browsercmd]
A "portable" version of the RotorHazard server, which can be useful for viewing database files on a Windows PC, may be found here. To use it, download the "rhPortable...zip" file, unpack it into a local directory, and then drag-and-drop a database file onto the 'runRotorHazard' batch file. This will launch a local copy of the RotorHazard server, load the database file, and launch a web browser for viewing the GUI. Sample RotorHazard database files may be found here. The server can be terminated by entering Ctrl-C on its console window.
(The "rhPortable...zip" file includes the needed Python support. The the 'runRotorHazardFF' batch file will attempt to launch the Firefox browser.)
The RotorHazard server generates "log" messages containing information about its operations. Below is a sample configuration for logging:
"LOGGING": {
"CONSOLE_LEVEL": "INFO",
"SYSLOG_LEVEL": "NONE",
"FILELOG_LEVEL": "INFO",
"FILELOG_NUM_KEEP": 30,
"CONSOLE_STREAM": "stdout"
}
The following log levels may be specified: DEBUG, INFO, WARNING, WARN, ERROR, FATAL, CRITICAL, NONE
If the FILELOG_LEVEL value is not NONE then the server will generate log files in the src/server/logs
directory. A new log file is created each time the server starts, with each file having a unique name based on the current date and time (i.e., "rh_20200621_181239.log"). Setting FILELOG_LEVEL to DEBUG will result in more detailed log messages being stored in the log file, which can be useful when debugging problems.
The FILELOG_NUM_KEEP value is the number of log files to keep; the rest will be deleted (oldest first).
The CONSOLE_STREAM value may be "stdout" or "stderr".
If the SYSLOG_LEVEL value is not NONE then the server will send log messages to the logging utility built into the host operating system.
The current Server Log may be displayed via the "View Server Log" item in the drop-down menu. The displayed log is "live" in that it will update as new messages are generated. The log can be displayed in a separate window by clicking on the "View Server Log" menu item with the right-mouse button and selecting the "Open Link in New Window" (or similar) option.
Clicking on the "Select Text" button will select all the displayed log text, which may then be copied and pasted. Clicking on the "Download Logs" button will create and download a '.zip' archive file containing all available log files and the current configuration and database files. The '.zip' archive file can also be generated by running the server with the following command: python server.py --ziplogs
When reporting issues, using the "Download Logs" button and including the generated '.zip' file is highly recommended.
When troubleshooting, another place to check for error messages is the "/var/log/syslog" file, which may be viewed with a command like: tail -100 /var/log/syslog
See Also:
doc/Hardware Setup.md
doc/USB Nodes.md
doc/User Guide.md
Build Resources (PCB, etc)