Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-os.yml
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ jobs:
user: pi
run: |
export DEBIAN_FRONTEND=noninteractive
cd /home/pi/PlanktoScope
cd /opt/PlanktoScope
just ci

# UPLOAD OS IMAGE
Expand Down
2 changes: 1 addition & 1 deletion backend/planktoscope-org.backend.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=mosquitto.service

[Service]
Type=simple
ExecStart=/home/pi/PlanktoScope/backend/src/service.js
ExecStart=/opt/PlanktoScope/backend/src/service.js
Restart=on-failure

User=pi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=mosquitto.service
[Service]
Type=simple
Environment=HOME=/home/pi
WorkingDirectory=/home/pi/PlanktoScope/controller
WorkingDirectory=/opt/PlanktoScope/controller
ExecStart=/usr/local/bin/uv run python -m bubbler.main
User=pi
Group=pi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=mosquitto.service
[Service]
Type=simple
Environment=HOME=/home/pi
WorkingDirectory=/home/pi/PlanktoScope/controller
WorkingDirectory=/opt/PlanktoScope/controller
ExecStart=/usr/local/bin/uv run python -m display.main
User=pi
Group=pi
Expand Down
2 changes: 1 addition & 1 deletion controller/focus/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async def start() -> None:

hardware_config = None
try:
async with aiofiles.open("/home/pi/PlanktoScope/hardware.json", mode="r") as file:
async with aiofiles.open("/opt/PlanktoScope/hardware.json", mode="r") as file:
hardware_config = json.loads(await file.read())
except FileNotFoundError:
return None
Expand Down
2 changes: 1 addition & 1 deletion controller/focus/planktoscope-org.controller.focus.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=mosquitto.service
[Service]
Type=simple
Environment=HOME=/home/pi
WorkingDirectory=/home/pi/PlanktoScope/controller
WorkingDirectory=/opt/PlanktoScope/controller
ExecStart=/usr/local/bin/uv run python -m focus.main
User=pi
Group=pi
Expand Down
2 changes: 1 addition & 1 deletion controller/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import aiomqtt
import paho

HARDWARE_CONFIG_PATH = "/home/pi/PlanktoScope/hardware.json"
HARDWARE_CONFIG_PATH = "/opt/PlanktoScope/hardware.json"
hardwre_config_lock = asyncio.Lock()


Expand Down
2 changes: 1 addition & 1 deletion controller/imager/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ def close(self) -> None:
def read_config() -> typing.Any:
config = {}
try:
with open("/home/pi/PlanktoScope/hardware.json", "r") as file:
with open("/opt/PlanktoScope/hardware.json", "r") as file:
try:
config = json.load(file)
except Exception:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ After=mediamtx.service
[Service]
Type=simple
Environment=HOME=/home/pi
WorkingDirectory=/home/pi/PlanktoScope/controller
WorkingDirectory=/opt/PlanktoScope/controller
# FIXME: https://github.com/fairscope/PlanktoScope/issues/842
ExecStartPre=/bin/sleep 5
ExecStart=/usr/local/bin/uv run python -m imager.main
Expand Down
2 changes: 1 addition & 1 deletion controller/light/LM36011.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Register(enum.IntEnum):
DEFAULT_CURRENT = 10

def __init__(self):
with open("/home/pi/PlanktoScope/hardware.json", "r") as file:
with open("/opt/PlanktoScope/hardware.json", "r") as file:
config = json.load(file)
hat_version = float(config.get("hat_version") or 0)
# The led is controlled by LM36011
Expand Down
2 changes: 1 addition & 1 deletion controller/light/planktoscope-org.controller.light.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=mosquitto.service
[Service]
Type=simple
Environment=HOME=/home/pi
WorkingDirectory=/home/pi/PlanktoScope/controller
WorkingDirectory=/opt/PlanktoScope/controller
ExecStart=/usr/local/bin/uv run python -m light.main
User=pi
Group=pi
Expand Down
2 changes: 1 addition & 1 deletion controller/planktoscope-org.controller.service
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ After=mediamtx.service
[Service]
Type=simple
Environment=HOME=/home/pi
WorkingDirectory=/home/pi/PlanktoScope/controller
WorkingDirectory=/opt/PlanktoScope/controller
ExecStart=/usr/local/bin/uv run main.py
User=pi
Group=pi
Expand Down
2 changes: 1 addition & 1 deletion controller/pump/planktoscope-org.controller.pump.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=mosquitto.service
[Service]
Type=simple
Environment=HOME=/home/pi
WorkingDirectory=/home/pi/PlanktoScope/controller
WorkingDirectory=/opt/PlanktoScope/controller
ExecStart=/usr/local/bin/uv run python -m pump.main
User=pi
Group=pi
Expand Down
6 changes: 3 additions & 3 deletions documentation/docs/community/contribute/tips-and-tricks.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ PlanktoScope OS is ready.
Type the following commands

```sh
cd /home/pi/PlanktoScope
cd /opt/PlanktoScope
just update
# don't forget to copy default configs if needed/wanted
# cp default-configs/v3.0.hardware.json hardware.json
Expand Down Expand Up @@ -99,15 +99,15 @@ You can now SSH into your PlanktoScope without username / password (using `ssh $
<summary>On the PlanktoScope</summary>

```sh
cd ~/PlanktoScope
cd /opt/PlanktoScope
just developer-mode
git checkout main
git status
```

</details>

We recommend developping directly from the PlanktoScope using [Visual Studio Code and the Remote - SSH extension](https://code.visualstudio.com/docs/remote/ssh) or [Zed - Remote Development](https://zed.dev/docs/remote-development). Use `$planktoscope` as the host to connect to and open the `/home/pi/PlanktoScope` directory.
We recommend developping directly from the PlanktoScope using [Visual Studio Code and the Remote - SSH extension](https://code.visualstudio.com/docs/remote/ssh) or [Zed - Remote Development](https://zed.dev/docs/remote-development). Use `$planktoscope` as the host to connect to and open the `/opt/PlanktoScope` directory.

## Connect to router

Expand Down
2 changes: 1 addition & 1 deletion documentation/docs/operation/software-upgrades.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Before you reset/upgrade/downgrade the software installed on your PlanktoScope,

Advanced users may also want to take the following actions, depending on what changes they have made:

- If you don't want to write down your white balance gains and hardware settings/calibrations, you can instead back up your PlanktoScope's hardware settings file, which is saved at `/home/pi/PlanktoScope/hardware.json`, for example in the file browser at <http://planktoscope.local/admin/fs/files/home/pi/PlanktoScope/> . This file includes some hidden settings not exposed in the PlanktoScope's Node-RED dashboard - so if you have changed any such settings by editing this file, then you may want to back up this file.
- If you don't want to write down your white balance gains and hardware settings/calibrations, you can instead back up your PlanktoScope's hardware settings file, which is saved at `/opt/PlanktoScope/hardware.json`, for example in the file browser at <http://planktoscope.local/admin/fs/files/opt/PlanktoScope/> . This file includes some hidden settings not exposed in the PlanktoScope's Node-RED dashboard - so if you have changed any such settings by editing this file, then you may want to back up this file.

## Reset the PlanktoScope OS

Expand Down
1 change: 1 addition & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ developer-mode: setup-dev
reset: base setup
rm /home/pi/PlanktoScope/config.json
rm /home/pi/PlanktoScope/hardware.json
rm /home/pi/PlanktoScope/calibration.json
sudo reboot

install-uv:
Expand Down
2 changes: 1 addition & 1 deletion lib/cockpit.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Systemctl } from "systemctl.js"
import { randomUUID } from "node:crypto"
import { queue } from "./helpers.js"

const config_template_path = "/home/pi/PlanktoScope/os/cockpit/cockpit.ini"
const config_template_path = "/opt/PlanktoScope/os/cockpit/cockpit.ini"
const config_path = "/etc/cockpit/cockpit.conf"

async function configureCockpit({ hostname, address } = {}) {
Expand Down
17 changes: 10 additions & 7 deletions lib/file-config.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { rm, writeFile } from "fs/promises"
import { rm, writeFile, mkdir } from "fs/promises"
import { readFile, access, constants, copyFile } from "fs/promises"

const HARDWARE_PATH = "/home/pi/PlanktoScope/hardware.json"
const SOFTWARE_PATH = "/home/pi/PlanktoScope/config.json"
const CALIBRATION_PATH = "/home/pi/PlanktoScope/calibration.json"
const CALIBRATION_DEFAULTS_PATH = "/home/pi/PlanktoScope/default-configs/calibration.json"
const CALIBRATION_DEFAULTS_PATH =
"/opt/PlanktoScope/default-configs/calibration.json"

async function hasConfig(path) {
try {
Expand All @@ -16,14 +17,16 @@ async function hasConfig(path) {
}

export async function initConfigFiles(hardware_version) {
await mkdir("/home/pi/PlanktoScope")

await Promise.all([
copyFile(
`/home/pi/PlanktoScope/default-configs/${hardware_version}.config.json`,
"/home/pi/PlanktoScope/config.json",
`/opt/PlanktoScope/default-configs/${hardware_version}.config.json`,
SOFTWARE_PATH,
),
copyFile(
`/home/pi/PlanktoScope/default-configs/${hardware_version}.hardware.json`,
"/home/pi/PlanktoScope/hardware.json",
`/opt/PlanktoScope/default-configs/${hardware_version}.hardware.json`,
HARDWARE_PATH,
),
// Create calibration.json from defaults if it doesn't exist yet.
// Unlike config/hardware, this never overwrites — preserving user calibrations.
Expand Down Expand Up @@ -62,6 +65,7 @@ export async function removeConfig() {
await Promise.all([
rm(HARDWARE_PATH, { force: true }),
rm(SOFTWARE_PATH, { force: true }),
rm(CALIBRATION_PATH, { forrce: true }),
])
}

Expand Down Expand Up @@ -100,4 +104,3 @@ export async function updateCalibrationConfig(...args) {
export async function hasCalibrationConfig() {
return hasConfig(CALIBRATION_PATH)
}

4 changes: 2 additions & 2 deletions lib/mediamtx.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import os from "os"
import { queue } from "./helpers.js"

const config_template_path =
"/home/pi/PlanktoScope/os/mediamtx/mediamtx.template.yml"
const config_path = "/home/pi/PlanktoScope/os/mediamtx/mediamtx.yml"
"/opt/PlanktoScope/os/mediamtx/mediamtx.template.yml"
const config_path = "/opt/PlanktoScope/os/mediamtx/mediamtx.yml"

async function configureMediaMTX({ hostname, address } = {}) {
let content = await readFile(config_template_path, "utf8")
Expand Down
2 changes: 1 addition & 1 deletion lib/nodered.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createRequire } from "node:module"

const require = createRequire(import.meta.url)

const node_red_settings_path = "/home/pi/PlanktoScope/node-red/settings.cjs"
const node_red_settings_path = "/opt/PlanktoScope/node-red/settings.cjs"

export async function promiseDashboardOnline() {
const { uiPort: port } = require(node_red_settings_path)
Expand Down
2 changes: 1 addition & 1 deletion node-red/30-override.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ Before=mosquitto.service

[Service]
ExecStart=
ExecStart=/home/pi/.local/bin/node-red-pi $NODE_OPTIONS --settings /home/pi/PlanktoScope/node-red/settings.cjs $NODE_RED_OPTIONS
ExecStart=/home/pi/.local/bin/node-red-pi $NODE_OPTIONS --settings /opt/PlanktoScope/node-red/settings.cjs $NODE_RED_OPTIONS
2 changes: 1 addition & 1 deletion node-red/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ setup-dev:

dev:
-sudo systemctl stop nodered
node --watch-path ~/PlanktoScope/node-red/nodes/ ~/.local/bin/node-red --settings ~/PlanktoScope/node-red/settings.cjs
node --watch-path /opt/PlanktoScope/node-red/nodes/ ~/.local/bin/node-red --settings /opt/PlanktoScope/node-red/settings.cjs

test:
validator projects/dashboard/flows.json
Expand Down
2 changes: 1 addition & 1 deletion node-red/projects/dashboard
Submodule dashboard updated 2 files
+1 −1 README.md
+8,098 −7,809 flows.json
2 changes: 1 addition & 1 deletion os/caddy/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

# We want everyrthing else /* to frontend
handle /* {
root * /home/pi/PlanktoScope/frontend/dist
root * /opt/PlanktoScope/frontend/dist
try_files {path} /index.html
file_server
}
Expand Down
3 changes: 0 additions & 3 deletions os/image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ This folder contains scripts and documentation to build the PlanktoScope OS imag

The scripts should work on standard Linux installations, in case of doubt use Raspberry Pi OS.




## How to use

### Bootstrap Raspberry Pi OS
Expand Down
2 changes: 1 addition & 1 deletion os/image/mount-firmware.service
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Description=Mount firmware partition

[Service]
Type=oneshot
ExecStart=/home/pi/PlanktoScope/os/image/mount-firmware.js
ExecStart=/opt/PlanktoScope/os/image/mount-firmware.js
RemainAfterExit=yes

[Install]
Expand Down
2 changes: 1 addition & 1 deletion os/machine-name/generate-hostname.service
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Before=sysinit.target

[Service]
Type=oneshot
ExecStart=/home/pi/PlanktoScope/os/machine-name/generate-hostname.sh
ExecStart=/opt/PlanktoScope/os/machine-name/generate-hostname.sh

[Install]
WantedBy=sysinit.target
2 changes: 1 addition & 1 deletion os/machine-name/generate-machine-name.service
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Before=systemd-hostnamed.service
[Service]
Type=oneshot
ExecStartPre=sh -c "echo 'unknown' >/run/machine-name"
ExecStart=/home/pi/PlanktoScope/os/machine-name/generate-machine-name.sh
ExecStart=/opt/PlanktoScope/os/machine-name/generate-machine-name.sh

[Install]
WantedBy=sysinit.target
2 changes: 1 addition & 1 deletion os/mediamtx/justfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
setup:
sudo ./setup_h264_sysctl.sh
wget https://github.com/bluenviron/mediamtx/releases/download/v1.16.2/mediamtx_v1.16.2_linux_arm64.tar.gz -P /tmp
wget https://raw.githubusercontent.com/bluenviron/mediamtx/refs/tags/v1.16.2/internal/servers/webrtc/reader.js -O /home/pi/PlanktoScope/frontend/src/pages/preview/reader.js
wget https://raw.githubusercontent.com/bluenviron/mediamtx/refs/tags/v1.16.2/internal/servers/webrtc/reader.js -O /opt/PlanktoScope/frontend/src/pages/preview/reader.js
cd /tmp && tar -xf /tmp/mediamtx_v1.16.2_linux_arm64.tar.gz
-sudo systemctl stop mediamtx
sudo cp /tmp/mediamtx /usr/local/bin/mediamtx
Expand Down
2 changes: 1 addition & 1 deletion os/mediamtx/mediamtx.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=network.target
Wants=network.target

[Service]
ExecStart=/usr/local/bin/mediamtx /home/pi/PlanktoScope/os/mediamtx/mediamtx.yml
ExecStart=/usr/local/bin/mediamtx /opt/PlanktoScope/os/mediamtx/mediamtx.yml

[Install]
WantedBy=multi-user.target
3 changes: 2 additions & 1 deletion os/preimage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ rm -f "$HOME"/.gitconfig
rm -rf "$HOME"/.ssh
rm -rf "$HOME"/data
rm -f "$HOME"/filebrowser.db
rm -f "$HOME"/planktoScope/hardware.json
rm -f "$HOME"/PlanktoScope/hardware.json
rm -f "$HOME"/PlanktoScope/config.json
rm -f "$HOME"/PlanktoScope/calibartion.json

# Clear machine-id so that it will be regenerated on the next boot
# This is also the condition for ConditionFirstBoot=yes
Expand Down
2 changes: 2 additions & 0 deletions os/raspberry/bootloader.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ cp /usr/lib/firmware/raspberrypi/bootloader-2712/latest/recovery.bin /tmp
rpi-eeprom-config /tmp/pieeprom-2025-11-05.bin --config boot.ini --out /tmp/pieeprom.upd
rpi-eeprom-digest -i /tmp/pieeprom.upd -o /tmp/pieeprom.sig

sudo mount -o remount,rw /boot/firmware
sudo cp /tmp/pieeprom.upd /tmp/pieeprom.sig /tmp/recovery.bin /boot/firmware/
sudo mount -o remount,ro /boot/firmware

# The bootloader will be installed on first boot and the files removed
# see https://github.com/fairscope/PlanktoScope/pull/589
Expand Down
4 changes: 4 additions & 0 deletions os/raspberry/firmware.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/bash -eux

sudo mount -o remount,rw /boot/firmware

# Configure firmware
# https://www.raspberrypi.com/documentation/computers/config_txt.html
sudo bash -c "cat \"config.ini\" >> \"/boot/firmware/config.txt\""
Expand All @@ -17,3 +19,5 @@ sudo bash -c "cat \"config.ini\" >> \"/boot/firmware/config.txt\""
[ ! -f /boot/firmware/cmdline.txt ] || \
grep -qw logo.nologo /boot/firmware/cmdline.txt || \
sudo sed -i 's/$/ logo.nologo/' /boot/firmware/cmdline.txt

sudo mount -o remount,ro /boot/firmware
2 changes: 1 addition & 1 deletion os/raspberry/planktoscope-org.firstboot.service
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ConditionFirstBoot=yes

[Service]
Type=oneshot
ExecStart=/home/pi/PlanktoScope/os/raspberry/firstboot.sh
ExecStart=/opt/PlanktoScope/os/raspberry/firstboot.sh

[Install]
WantedBy=sysinit.target
4 changes: 2 additions & 2 deletions os/rauc/rauc.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ data-directory=/data/rauc
# https://rauc.readthedocs.io/en/latest/using.html#system-based-customization-handlers
[handlers]
# https://rauc.readthedocs.io/en/latest/integration.html#custom
bootloader-custom-backend=/home/pi/PlanktoScope/os/rauc/custom-bootloader-script
bootloader-custom-backend=/opt/PlanktoScope/os/rauc/custom-bootloader-script
# https://rauc.readthedocs.io/en/latest/reference.html#handlers-section
# TODO
# system-info=/usr/lib/raspberrypi-firmware-rauc-bootloader-backend/system-info

# https://rauc.readthedocs.io/en/latest/reference.html#keyring-section
[keyring]
path=/home/pi/PlanktoScope/os/rauc/demo.cert.pem
path=/opt/PlanktoScope/os/rauc/demo.cert.pem

# https://rauc.readthedocs.io/en/latest/reference.html#slot-slot-class-idx-sections
# Generated by rauc.js
6 changes: 3 additions & 3 deletions os/setup-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ export LANG="en_US.UTF-8"

# The PlanktoScope monorepo is used for running and iterating on software components
# https://github.com/fairscope/planktoscope
sudo cp -r "$build_scripts_root"/.. "$HOME/PlanktoScope"
sudo chown -R "$USER:$USER" "$HOME/PlanktoScope"
sudo cp -r "$build_scripts_root"/.. "/opt/PlanktoScope"
sudo chown -R "$USER:$USER" "/opt/PlanktoScope"

sudo apt install -y just
just --justfile "$HOME"/PlanktoScope/justfile
just --justfile /opt/PlanktoScope/justfile
./postinstall.sh
./preimage.sh
Loading
Loading