Crumbforest Seed Kit – Pflanz‑Bauplan v1

Ziel: Ein kleinster, stabiler Startpunkt, damit Kinder („Krümel“) sofort etwas pflanzen können – offline‑freundlich, mit Terminal‑Missionen, Logging (KrümelLog) und optionaler Anbindung an eure bestehende crumbapi/Qdrant‑Welt.


Quickstart (Übersicht)

  1. Config anlegen: /etc/crumb/seed.conf
  2. Missionen installieren: /usr/local/bin/crumbmissions/…
  3. MenĂź: /usr/local/bin/mission_selector.sh
  4. Start: sudo /usr/local/bin/mission_selector.sh (oder über ttyd als Web‑Terminal)

Alle Pfade sind bewusst schlicht gehalten und funktionieren ohne Docker. Passt Variablen bei Bedarf an.


1) Konfiguration

Datei: /etc/crumb/seed.conf

# Crumbforest Seed Kit – Grundkonfiguration
CRUMBAPI_URL="https://194-164-194-191.sslip.io/crumbapi"   # oder leer lassen, wenn nicht vorhanden
QDRANT_URL="http://localhost:6333"                         # oder Remote‑URL
LOG_DIR="/opt/crumb/log"                                   # KrümelLog‑Ablage
ROBOT_USER="robot"                                        # Terminal‑Nutzer
TTYD_PORT=7780                                              # Web‑Terminal Port (optional)

2) Missions‑Menü

Datei: /usr/local/bin/mission_selector.sh

#!/usr/bin/env bash
set -euo pipefail
MISSION_DIR="/usr/local/bin/crumbmissions"
mkdir -p "$MISSION_DIR"

while true; do
  clear || true
  echo "🌱 Crumbforest – Missionen"
  echo "----------------------------------"
  i=0
  mapfile -t missions < <(find "$MISSION_DIR" -maxdepth 1 -type f -name 'mission_*.sh' | sort)
  if ((${#missions[@]}==0)); then
    echo "(Noch keine Missionen gefunden in $MISSION_DIR)"
  else
    for m in "${missions[@]}"; do
      ((i++))
      b=$(basename "$m")
      title=$(head -n1 "$m" | sed 's/^# *//; s/^$/'"$b"'/')
      printf "%2d) %s\n" "$i" "$title"
    done
  fi
  echo "  q) Quit"
  echo
  read -rp "Wähle: " choice || true
  [[ "${choice:-}" == "q" ]] && exit 0
  if [[ "${choice:-}" =~ ^[0-9]+$ ]] && (( choice>=1 && choice<=${#missions[@]} )); then
    echo
    "${missions[choice-1]}" || true
    echo
    read -rp "↩︎ Enter für Menü …" _ || true
  fi
done

Rechte setzen:

sudo chmod +x /usr/local/bin/mission_selector.sh

3) Mission 00 – System‑Check & KrümelLog

Datei: /usr/local/bin/crumbmissions/mission_00_check.sh

#!/usr/bin/env bash
# Mission 00 – System‑Check & KrümelLog
set -euo pipefail
CONF="/etc/crumb/seed.conf"
[[ -f "$CONF" ]] && source "$CONF" || { echo "Fehlende $CONF"; exit 1; }
LOG_FILE="${LOG_DIR:-/opt/crumb/log}/kruemellog.jsonl"
mkdir -p "$(dirname "$LOG_FILE")"

log(){
  local emoji="$1" msg="$2" src="mission_00_check"
  printf '{"ts":"%s","emoji":"%s","msg":"%s","src":"%s"}\n' "$(date -Is)" "$emoji" "$msg" "$src" | tee -a "$LOG_FILE"
}

# 1) Router / Default‑Gateway
GW=$(ip route | awk '/default/ {print $3; exit}')
if [[ -n "${GW:-}" ]]; then
  if ping -c1 -W1 "$GW" >/dev/null 2>&1; then
    log "🛰️" "Gateway erreichbar: $GW"
  else
    log "⚠️" "Gateway NICHT erreichbar: $GW"
  fi
else
  log "⚠️" "Kein Default‑Gateway gefunden"
fi

# 2) crumbapi‑Health (optional)
if [[ -n "${CRUMBAPI_URL:-}" ]]; then
  if curl -sk "${CRUMBAPI_URL}/health" | grep -q '"ok":\s*true'; then
    log "🧁" "crumbapi OK: ${CRUMBAPI_URL}"
  else
    log "❌" "crumbapi NICHT OK: ${CRUMBAPI_URL}"
  fi
else
  log "ℹ️" "CRUMBAPI_URL nicht gesetzt – übersprungen"
fi

# 3) Qdrant‑Ping (optional)
if [[ -n "${QDRANT_URL:-}" ]]; then
  if curl -s "${QDRANT_URL}/collections" | grep -qi 'status'; then
    log "📦" "Qdrant erreichbar: ${QDRANT_URL}"
  else
    log "❌" "Qdrant NICHT erreichbar: ${QDRANT_URL}"
  fi
else
  log "ℹ️" "QDRANT_URL nicht gesetzt – übersprungen"
fi

# 4) Serielle / I²C Geräte – sanfter Check
if ls /dev/ttyACM* /dev/ttyUSB* /dev/i2c-* >/dev/null 2>&1; then
  DEVICES=$(ls /dev/ttyACM* /dev/ttyUSB* /dev/i2c-* 2>/dev/null | xargs -r echo)
  log "🔌" "Sensor‑/Busgeräte sichtbar: ${DEVICES:-none}"
else
  log "🌾" "Keine seriellen/I²C Geräte entdeckt – ok für reines Terminal"
fi

echo
echo "✅ System‑Check abgeschlossen. Log: $LOG_FILE"

Rechte setzen:

sudo mkdir -p /usr/local/bin/crumbmissions
sudo chmod +x /usr/local/bin/crumbmissions/mission_00_check.sh

4) Mission 01 – Samen setzen (Pflanz‑Protokoll)

Datei: /usr/local/bin/crumbmissions/mission_01_seed.sh

#!/usr/bin/env bash
# Mission 01 – Samen setzen
set -euo pipefail
CONF="/etc/crumb/seed.conf"
[[ -f "$CONF" ]] && source "$CONF" || { echo "Fehlende $CONF"; exit 1; }
GARDEN_DIR="/opt/crumb/garden/seeds"
LOG_FILE="${LOG_DIR:-/opt/crumb/log}/kruemellog.jsonl"
mkdir -p "$GARDEN_DIR" "$(dirname "$LOG_FILE")"

read -rp "🌱 Wie soll dein Samen heißen? " NAME
[[ -z "${NAME// }" ]] && { echo "Bitte einen Namen eingeben."; exit 1; }
ID=$(date +%s)
FILE="$GARDEN_DIR/${ID}_$(echo "$NAME" | tr ' ' '_' | tr -cd '[:alnum:]_').json"

cat >"$FILE" <<JSON
{
  "id": $ID,
  "name": "${NAME}",
  "author": "${USER}",
  "ts": "$(date -Is)",
  "note": "Erster Samen im Krümel‑Garten",
  "tags": ["seed","kid"]
}
JSON

printf '{"ts":"%s","emoji":"%s","msg":"%s","src":"%s"}\n' "$(date -Is)" "🌱" "Samen \"${NAME}\" gesetzt → $(basename "$FILE")" "mission_01_seed" | tee -a "$LOG_FILE"

cat <<'ASCII'

   .
  .'.
  |o|    🌱 Dein Samen wurde gesetzt.
 .'o'.   Er wächst, wenn du Fragen stellst.
 |.-.|
 '   '
ASCII

Rechte setzen:

sudo chmod +x /usr/local/bin/crumbmissions/mission_01_seed.sh

5) Terminal‑Start (lokal oder per Web‑Terminal)

A) Direkt starten

sudo /usr/local/bin/mission_selector.sh

B) Web‑Terminal mit ttyd (optional)

Service: /etc/systemd/system/ttyd.service

[Unit]
Description=Crumbterm (ttyd)
After=network.target

[Service]
EnvironmentFile=/etc/crumb/seed.conf
ExecStart=/usr/bin/ttyd -p ${TTYD_PORT:-7780} -i 0.0.0.0 -t title:Crumbterm bash -lc /usr/local/bin/mission_selector.sh
Restart=always
User=${ROBOT_USER:-robot}

[Install]
WantedBy=multi-user.target

Aktivieren:

sudo systemctl daemon-reload
sudo systemctl enable --now ttyd

6) KrümelLog – Format

Wir loggen einfach lesbar als JSON‑Zeilen (JSONL), z. B. in "$LOG_DIR/kruemellog.jsonl":

{"ts":"2025-09-23T19:12:34+02:00","emoji":"🌱","msg":"Samen \"Birke\" gesetzt → 1695492754_Birke.json","src":"mission_01_seed"}
{"ts":"2025-09-23T19:13:02+02:00","emoji":"🧁","msg":"crumbapi OK: https://…/crumbapi","src":"mission_00_check"}

Dieses Log ist bewusst pädagogisch – es erleichtert Kindern (und Erwachsenen) das Verstehen. Es kann später in CakePHP/CrumbAPI eingelesen werden.


7) Offline‑freundlich & sicher

  • Keine Cloud notwendig: Missionen laufen auch ohne Internet. CRUMBAPI_URL/QDRANT_URL sind optional.
  • Sanfte Checks: Nichts bricht hart; alles meldet verständlich.
  • Erweiterbar: Neue Missionen = neue Dateien mission_*.sh.

8) Nächste Mini‑Schritte (optional)

  • Mission 02 – Foto‑Samen: Kamera/USB prĂźfen, Foto knipsen, als seed_photo ablegen.
  • Mission 03 – Sensor‑Echo: Z. B. Temperatur/Feuchte lesen (I²C) → in Samen‑JSON anhängen.
  • Mission 04 – Echo zur Crew: Wenn crumbapi verfĂźgbar, Samen als Event posten.

9) Troubleshooting (Kurz)

  • Fehlende /etc/crumb/seed.conf → Datei anlegen (siehe oben).
  • curl: not found/ip: not found → sudo apt install curl iproute2 -y.
  • ttyd: not found → Paket bereitstellen/kompilieren oder bestehendes TTYD nutzen (ihr habt das meist schon).

Fertig. Das ist ein kompakter Startpunkt ohne neue Abhängigkeiten. Wenn ihr soweit seid, ergänzen wir Missionen für Blockly, MQTT/LoRa und eure bestehende CakePHP‑API – Schritt für Schritt, ohne Drift.