# Software

## Step by step instructions

You don't have to program the compute module yourself, but you have to set it up. The following steps help you to setup your Tracker.

{% hint style="success" %}
If you want to have a deeper insight in the code itself, you can find the documented code in the github repository: <https://github.com/oliverheisel/DataDrivenSailing>
{% endhint %}

### &#x20;A\_Basic Raspberry Pi Firmware

1. Install Raspberry **Pi OS Lite 64bit** with the [Raspberry Pi Imager](https://www.raspberrypi.com/software/) with the following settings:
   1. Hostname: hub.local (replace number accordingly)
   2. Username and Password: As you like (remcommened to have the same for every device)
   3. Wlan: Use your home network
   4. Time/location: As you need
2. Insert the SD-Card
3. Power up the Raspberry Pi
4. Connect via Remote Desktop <https://marketplace.visualstudio.com/items?itemName=ms-vscode.remote-explorer>) - this extension in visual studio code cold make you life easier.
5. Update and upgrade:  <mark style="color:red;">`sudo apt-get update && sudo apt-get -y upgrade`</mark>
6. Reboot with: <mark style="color:red;">`sudo reboot`</mark>

### Install the external wifi adapter driver

The needed driver for the chipset: <https://store.rokland.com/en-de/pages/alfa-awus036ach-driver-install-help-raspberry-pi-os?srsltid=AfmBOorBs4XS-8Mpf6uSAAeZ3Dq3ApVKE7zvbZ8CR53gpzx7WgxuYlPZ>

It needs a driver to be installed and some configuration, so it will host your wanted network.

1. install dependen packages packages: <mark style="color:red;">`sudo apt install -y raspberrypi-kernel-headers build-essential bc dkms git`</mark>
2. create directory /src: <mark style="color:red;">`mkdir -p ~/src`</mark>
3. go to the created directory: <mark style="color:red;">`cd ~/src`</mark>
4. clone the github repository with the driver: <mark style="color:red;">`git clone <https://github.com/morrownr/8812au-20210820.git`</mark><mark style="color:red;">></mark>
5. go to the downloaded folder: <mark style="color:red;">`cd ~/src/8812au-20210820`</mark>
6. install the driver: <mark style="color:red;">`sudo ./install-driver.sh`</mark>
7. reboot: <mark style="color:red;">`sudo reboot`</mark>

→ The led on the wifi module should start flashing

If not → <mark style="color:red;">`ip a`</mark> → If it not shows wlan1 → check if adapter is listed in `lsusb` → Bus 001 Device 003: ID 0bda:8812 Realtek Semiconductor Corp. RTL8812AU 802.11a/b/g/n/ac 2T2R DB WLAN Adapter

If the modul doesnt start flashing after rebooting, run the installation of the driver again.

### Create the host the network "hub"

1. check the network device status: <mark style="color:red;">`sudo nmcli device status`</mark>
2. if wlan1 connection is “**preconfigured**” → that means the external wifi adapter. The external wifi adapter is needed for the website hosting. Before disconnecting wlan1 we want to connect wlan0 to the home network. Otherwise our connection to the Pi

   Connect wlan0 to the preconfigured/ home network: <mark style="color:red;">`sudo nmcli con up "preconfigured" ifname wlan0`</mark>
3. turn autoconnect on for wlan0: <mark style="color:red;">`sudo nmcli con modify "preconfigured" connection.autoconnect yes`</mark> → you may have to reconnect with ssh
4. Create a AccessPoint with the external network: <mark style="color:red;">`sudo nmcli con add type wifi ifname wlan1 con-name hub autoconnect yes ssid hub`</mark>
5. Add the AP configuration (change the password and channel accordingly)

   ```python
   sudo nmcli con modify hub 802-11-wireless.mode ap
   sudo nmcli con modify hub 802-11-wireless.band bg
   sudo nmcli con modify hub 802-11-wireless.channel 6
   sudo nmcli con modify hub wifi-sec.key-mgmt wpa-psk
   sudo nmcli con modify hub wifi-sec.psk "SailingBoat#7xTq9!"
   sudo nmcli con modify hub 802-11-wireless-security.proto rsn
   sudo nmcli con modify hub 802-11-wireless-security.pairwise ccmp
   sudo nmcli con modify hub 802-11-wireless-security.group ccmp
   sudo nmcli con modify hub connection.autoconnect yes
   sudo nmcli con modify hub connection.autoconnect-priority 100
   ```
6. **Enable Internet Sharing (NAT routing) for wlan1**: <mark style="color:red;">`sudo nmcli con modify hub ipv4.method shared`</mark>
7. **Start the Hotspot**: <mark style="color:red;">`sudo nmcli con up hub`</mark>

<div align="left"><figure><img src="/files/9XQYog3nBG0L3JJF04vj" alt=""><figcaption></figcaption></figure></div>

8. Restart: <mark style="color:red;">`sudo reboot`</mark>
9. Check if everything works: <mark style="color:red;">`sudo nmcli device status`</mark>

### Create a script that checks the network configuration and corrects it

Add a small script, to ensure, that wlan1 stays with hosting the hub network:

1. create a script: <mark style="color:red;">`sudo nano /usr/local/bin/check_wlan1.sh`</mark>
2. paste this:

   ```python
   #!/bin/bash

   # Ensure wlan1 is always in AP mode
   if ! nmcli -t -f DEVICE,STATE device | grep -q "wlan1:connected"; then
       echo "wlan1 is down! Restarting AP..."
       nmcli con up hub
   fi

   # Ensure wlan0 is connected to either home WiFi or backup WiFi
   if ! nmcli -t -f DEVICE,STATE device | grep -q "wlan0:connected"; then
       echo "wlan0 is down! Trying home WiFi..."
       nmcli con up "preconfigured" ifname wlan0 || {
           echo "Home WiFi not available, trying backup WiFi..."
           nmcli con up "4ghotspot" ifname wlan0
       }
   fi
   ```

   “STRG” + “X” → “Y” → “Enter”
3. Make it executable: <mark style="color:red;">`sudo chmod +x /usr/local/bin/check_wlan1.sh`</mark>
4. Run it every minuite: <mark style="color:red;">`sudo crontab -e`</mark>
   1. Add this to the bottom line: <mark style="color:red;">`* * * * * /usr/local/bin/check_wlan1.sh`</mark>
5. Reboot: <mark style="color:red;">`sudo reboot`</mark>

### B\_Create a virtual environment

1. Install the python3-venv:

```bash
sudo apt install python3-venv
python3 -m venv codeenv --system-site-packages
```

2. Activate the environment with: <mark style="color:red;">`source codeenv/bin/activate`</mark>

{% hint style="info" %}
→ you should see a “(env)” in front of your Terminal name

→ for deactivate the env -> <mark style="color:red;">`deactivate`</mark>
{% endhint %}

### C\_Copy Code from GitHub

{% hint style="info" %}
Since the code is divided into two parts, we need to execute similar steps for each section.\
1\. local code: Software that is similar to the one on the trackers and deals with the gps, anemometer, compass...\
2\. nodered code: Software that supports Nodered data processes. It is callable via an API. See the&#x20;

{% endhint %}

1. Install git with: <mark style="color:red;">`sudo apt-get install git`</mark>
2. Clone the repository: <mark style="color:red;">`git clone https://github.com/oliverheisel/DataDrivenSailing.git ddsrepo`</mark>
3. Copy the code that we need to where we need it: <mark style="color:red;">`cp -r ddsrepo/code_nodered /home/globaladmin/code_nodered`</mark>&#x20;
4. Copy the code that we need to where we need it: <mark style="color:red;">`cp -r ddsrepo/Hub/Software/code /home/globaladmin/code`</mark>
5. Remove the rest: <mark style="color:red;">`rm -rf ddsrepo`</mark>
6. Install all required packages:
   1. Go to the folder with: <mark style="color:red;">`cd code_local`</mark>
   2. Install the packages: <mark style="color:red;">`pip install -r requirements.txt`</mark>

### D\_Activate pigiod

**pigpiod** itself is a daemon that provides low-level access to Raspberry Pi’s GPIO pins. Paste the following code in the terminal:

```
sudo systemctl enable pigpiod
sudo systemctl start pigpiod
```

### E\_Activate i2c

1. Open rasp-config with: <mark style="color:red;">`sudo raspi-config`</mark>
2. Select: “Interface options” > “I2c” > “Activate i2c” \_> yes
3. Exit raspi-config

### F\_Change i2c speed

1. Open the firmware configuration file with: <mark style="color:red;">`sudo nano /boot/firmware/config.txt`</mark>
2. Search for the "**dparam**" line
3. Uncomment the line by removing the hashtag
4. Add the following, so it looks like this: → changing from 400khz to 100khz:\ <mark style="color:blue;">`dtparam=i2c_arm=on,i2c_arm_baudrate=100000`</mark>
5. Reboot with: <mark style="color:red;">`sudo reboot`</mark>

### H\_Create "Local" Service

1. Create new service file with: <mark style="color:red;">`sudo nano /etc/systemd/system/startmainlocal.service`</mark>
2. Paste the following in the file and exit it with "Ctrl"+"X" > "Y" > "Enter"

```python
[Unit]
Description=Run Main.py on Boot local
After=network.target

[Service]
User=globaladmin
WorkingDirectory=/home/globaladmin/code_local
ExecStart=/bin/bash -c 'source /home/globaladmin/codeenv/bin/activate && /home/globaladmin/codeenv/bin/python /home/globaladmin/code/main.py'
Restart=always
RestartSec=2
Environment=VIRTUAL_ENV=/home/globaladmin/codeenv
Environment=PATH=/home/globaladmin/codeenv/bin:$PATH
ExecStartPre=/bin/sleep 5

[Install]
WantedBy=multi-user.target
```

3. Enable service:

```python
sudo systemctl daemon-reload
sudo systemctl enable startmainlocal.service
sudo systemctl start startmainlocal.service
```

### I\_Create "Nodered-Helper" Service

1. Create new service file with: <mark style="color:red;">`sudo nano /etc/systemd/system/startmainnodered.service`</mark>
2. Paste the following in the file and exit it with "Ctrl"+"X" > "Y" > "Enter"

```python
[Unit]
Description=Run Main.py on Boot
After=network.target

[Service]
User=globaladmin
WorkingDirectory=/home/globaladmin/code_nodered
ExecStart=/bin/bash -c 'source /home/globaladmin/codeenv/bin/activate && /home/globaladmin/codeenv/bin/python /home/globaladmin/code_nodered/main.py'
Restart=always
RestartSec=2
Environment=VIRTUAL_ENV=/home/globaladmin/codeenv
Environment=PATH=/home/globaladmin/codeenv/bin:$PATH
ExecStartPre=/bin/sleep 5

[Install]
WantedBy=multi-user.target
```

3. Enable service:

```python
sudo systemctl daemon-reload
sudo systemctl enable startmainnodered.service
sudo systemctl start startmainnodered.service
```

{% hint style="info" %}
The service will start the main script each time the Raspberry Pi boots.

If you have to stop or restart the service (in case you changed the code) you can do it with:

**STOP**: <mark style="color:red;">`sudo systemctl stop [servicename].service`</mark>

**RESTART**: <mark style="color:red;">`sudo systemctl restart [servicename].service`</mark>
{% endhint %}

### J\_Create the docker enviroment (Mosquitto, Node-Red, Influx DB, Grafana)

To not have to install everything by our self, we use IOT Stack: <https://sensorsiot.github.io/IOTstack/> \
Here you can find the instructions: <https://sensorsiot.github.io/IOTstack/Basic_setup/> \
More explanation for IOT Stack and Docker you can find here: <https://www.youtube.com/watch?v=_DO2wHI6JWQ>

{% hint style="info" %}
!!! Make sure you deactivated the virtual enviroment otherwise: <mark style="color:red;">`deactivate`</mark>
{% endhint %}

1. Download and install IOTstack: <mark style="color:red;">`curl -fsSL https://raw.githubusercontent.com/SensorsIot/IOTstack/master/install.sh | bash`</mark><br>

   <figure><img src="/files/KtFB3Hqsp0pYzzrWQXjp" alt=""><figcaption></figcaption></figure>

   → this can take a while. It also depends on the strength of your Raspberry Pi. It will install Docker and other requirements for us!\
   → it will restart in this process. Don’t worry. Just connect via SSH again
2. Go in the IOTStack directory: <mark style="color:red;">`cd IOTstack/`</mark>
3. run: <mark style="color:red;">`./menu.sh`</mark>\ <img src="/files/NmlqBRYju2znInvx3EC5" alt="" data-size="original">
   1. click "Build stack"
   2. Select with the following containers to build with the spacebar and arrow keys: (<mark style="color:blue;">**mosquitto, nodered, influxdb2, grafana**</mark>)\
      !! When you select nodered, it will show an issue. Just open the options for node red (hitting right arrow) and select “Select & build add ons list. → hit enter and next step just go with the default selection and hit enter again:

      <div align="left"><figure><img src="/files/bmGD7rIOpFZZ2pGIYjK9" alt=""><figcaption></figcaption></figure></div>
   3. Everything selected → hit enter. You will end up on the start screen
   4. Now lets start the stack: Go to “Docker commands” and select “Start stack” → It will start pulling the images for the containers - this can take a while.&#x20;
   5. ![](/files/GBzLASVaKlQVPpJGLFwE)![](/files/k9Q5FzW6LYXlKMH1IlyC)
   6. Hit enter and than exit it.
   7. To check the running containers and check their port: <mark style="color:red;">`docker ps`</mark>

      <figure><img src="/files/oi80CvNLCMhI4GUTVufy" alt=""><figcaption></figcaption></figure>
   8. To test if we can reach all service, let's check the following addresses. Make sure you are connected to the hub network:
      1. Nodered: <hub.local:1880>
      2. Grafana: <hub.local:3000>
      3. InfluxDB2: [hub.local:8087](hub.local:3000)

<div><figure><img src="/files/AzJeqwl8pK05df9794qm" alt=""><figcaption><p>Node-Red</p></figcaption></figure> <figure><img src="/files/2Hvy65AZRka3JBFJz71o" alt=""><figcaption><p>Grafana</p></figcaption></figure> <figure><img src="/files/1BmT6CgmeO6NRxOrfvXt" alt=""><figcaption><p>InfluxDB2</p></figcaption></figure></div>

### K\_Install the data explorer

To be able do download the data that we collected, to drag it into the analytic software, you need another container. Information about the image: <https://github.com/awesometic/docker-h5ai>

1. Open a terminal and ssh into the hub
2. Give permissions to the folders of the IOTstack:

{% code overflow="wrap" %}

```bash
sudo chown -R globaladmin:globaladmin /home/globaladmin/IOTstack
sudo chmod -R 775 /home/globaladmin/IOTstack
```

{% endcode %}

3. Paste this to get the data explorer image "h5ai" and run it as docker container

{% code overflow="wrap" %}

```bash
docker run -d \
  --name fileexplorer \
  --restart unless-stopped \
  -p 80:80 \
  -v /home/globaladmin/IOTstack/volumes/nodered/data/dataexport:/h5ai \
  -v /config/dir:/config \
  -e PUID=$(id -u) \
  -e PGID=$(id -g) \
  awesometic/h5ai

```

{% endcode %}

4. To check the running containers: <mark style="color:red;">`docker ps`</mark>
5. Check the webui by opening the website: <hub.local:80>

### L\_SetUp InfluxDB2

1. Go to the InfluxDB2 WebUi: <hub.local:8087>
2. Login with the default user:
   1. Username: me
   2. Password: mypassword
3. Click on "Load data" > "Buckets"
4. Create the following Buckets

<table><thead><tr><th width="133.85546875">Bucketname</th><th width="92.0625">Retention</th><th>Use</th></tr></thead><tbody><tr><td>BoatLog</td><td>12 hr</td><td>Temporary log of live boat data</td></tr><tr><td>BoatStatus</td><td>12 hr</td><td>Temporary log of boat status</td></tr><tr><td>BuoyLog</td><td>12 hr</td><td>Temporary log of live buoy data</td></tr><tr><td>Comments</td><td>7 days</td><td>Database of comments and marks for timeline</td></tr><tr><td>HubLog</td><td>7 days</td><td>Database for all sensors on the hub</td></tr></tbody></table>

5. Create a 3 API-Keys. "Load Data" > "API Tokens"
6. Click "Create API-Token" > "All Access Tokens
7. Description (1. "<mark style="color:blue;">**Grafana**</mark>", 2. "<mark style="color:blue;">**NodeRed**</mark>", 3. "<mark style="color:blue;">**RaspberryPi**</mark>")
8. Write all Keys down! You cant review them!&#x20;

### M\_Setup NodeRed

1. Download the <mark style="color:blue;">**flows.json**</mark> file from: <https://github.com/oliverheisel/DataDrivenSailing/tree/main/Hub/NodeRed>
2. Open your browser and go to [<mark style="color:blue;">hub.local:1880</mark>](hub.local:1880) to access Node-RED.
3. In Node-RED, click the hamburger menu in the top-right corner, select **Manage Palette**, go to the **Install** tab, search for **node-red-node-ui-table**, and click **Install**.
4. Click the hamburger menu again, select **Import**, and upload the <mark style="color:blue;">**flows.json**</mark> file you downloaded.

**Insert API-Key**

5. Open one flow (doesn't matter wich) and find a InfluxDB node and click on it
6. Click on the pencile next to "server"
7. Replace the token with <mark style="color:blue;">**NodeRed**</mark> you created
8. Save and exit

### N\_Setup Grafana

1. Download the dashboard files from: <https://github.com/oliverheisel/DataDrivenSailing/tree/main/Hub/Grafana>
2. Open your browser and go to <hub.local:3000> to access Grafana.
3. Go to "Dashboard" > "New" > "Import"
4. Upload the file and create a new dashboard
5. Check if the connections works - Use the InfluxDB API-Key

**Congrats, you made it 🎉**

### Optional\_Add a 4G mobile router

1. Configure the router
   1. login to your router
   2. change to SSID: hub4G
   3. wifipassword: SailingBoat#7xTq9!
   4. Set it on auto network select + roaming on
2. Set second wifi connection on Raspberry Pi
   1. ssh into the hub and paste the following into the terminal:

      ```bash
      sudo nmcli con add type wifi ifname wlan0 con-name "4ghotspot" ssid "hub4G"
      sudo nmcli con modify "4ghotspot" wifi-sec.key-mgmt wpa-psk
      sudo nmcli con modify "4ghotspot" wifi-sec.psk "SailingBoat#7xTq9!"
      sudo nmcli con modify "4ghotspot" connection.autoconnect yes

      ```
   2. Set connection priorities (The higher the priority value, the more preferred the network is.)
      1. <mark style="color:red;">`sudo nmcli con modify "preconfigured" connection.autoconnect-priority 50`</mark>
      2. <mark style="color:red;">`sudo nmcli con modify "4ghotspot" connection.autoconnect-priority 30`</mark>
   3. Check it:
      1. <mark style="color:red;">`sudo nmcli connection show`</mark>
      2. <mark style="color:red;">`sudo nmcli con show "preconfigured" | grep autoconnect-priority`</mark>
      3. <mark style="color:red;">`sudo nmcli con show "4ghotspot" | grep autoconnect-priority`</mark>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://datadrivensailing.gitbook.io/wiki/hub/hub-setup-instructions/software.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
