bluegreencity-ki

Irrigation Review with Taipy

Scope

Phase 3 adds a human approval and execution layer around Phase 2 drafts. Taipy does not calculate priorities or modify the scientific configuration directly. It calls the existing deterministic planning and review services.

The application provides four pages:

Begründung pro Baum (SHAP-Drivers + Standortvulnerabilität)

Each decision in bgcki.irrigation_plan_decision carries three justification fields, copied from bgcki.operational_tree_product at plan-build time (migration 2026-09-27_add_decision_drivers.sql):

The Taipy Planentwurf page renders these in a “Begründung (ML + Standort)” panel next to the selected tree, so a dispatcher can answer “Warum soll Baum X jetzt bewässert werden?” directly from the UI without querying the database.

The data source is the daily-refreshed operational_tree_product table (Lagebild-Quelle); the drivers are stamped by the ML pipeline at training time (AutoGluon explain), not recomputed per planning run.

Installation

Taipy GUI is an optional UI dependency and is not required for pipeline, SWBM, or planning tests:

conda run -n bgcki_wesemann python -m pip install -r requirements-taipy.txt

Taipy GUI 4.1.2 declares python-dotenv<=1.0.1, while an independently installed FastMCP currently declares python-dotenv>=1.1.0. FastMCP is not a BlueGreenCity-KI project dependency. In the shared workstation environment the application was browser-tested successfully with python-dotenv==1.1.1; pip still reports the upstream metadata conflict. Do not silently downgrade FastMCP’s environment. If Taipy later fails with the newer dotenv version, install the optional UI in a dedicated environment instead.

Flask is pinned to 3.1.0 in the optional requirements because Flask 3.1.3 and the Taipy-pinned Flask-SocketIO 5.4.1 failed during WebSocket session setup.

Database Migration

Apply:

sql/migrations/2026-08-04_create_irrigation_review_tables.sql

It creates:

Reject and override actions require a reason. Overrides require a positive amount and date. Only selected optimizer decisions can be approved directly; an excluded decision requires an explicit override. One non-cancelled work order is allowed per tree, plan date, and policy version.

GDPR: Pseudonymised Role Identifiers

The prototype does not process personal data (Art. 4 GDPR). The reviewer, approved_by, and reported_by columns store pseudonymised role identifiers (e.g. R1, F1), never real person names. No mapping from identifier to person is stored anywhere in the system, so the values are anonymised and outside the scope of the GDPR. Operators must enter a role ID, not their name. See Issue #214 and docs/compliance/eu_ai_act_assessment.md.

Start (lokal)

conda run -n bgcki_wesemann python scripts/run_irrigation_review_gui.py

Default URL: http://127.0.0.1:5000/drafts

Host, port, draft limit, schema, and default input paths come from irrigation_review im config/config.yaml. Default ist local-only; keine Netz-Exposition, keine automatische Freigabe.

Als Dienst betreiben (Docker + Tailscale)

Plan: interne Planungsnote „Taipy-Research-Service” (2026-09-27, nicht publiziert).

Taipy läuft als Docker-Container bgcki-taipy (Repo-Compose, restart: unless-stopped, Healthcheck GET /drafts → 200):

docker compose up -d taipy          # Image builden + starten
docker logs -f bgcki-taipy          # Start prüfen ("Server starting on http://127.0.0.1:5000")

Warum kein conda-Volume-Mount: die Projekt-Env bgcki_wesemann ist eine Windows-conda-Env (python.exe, .dll) und kann in einem Linux-Container nicht laufen. Alle Taipy-Runtime-Dependencies stehen daher im Image (docker/taipy/Dockerfile: taipy-gui, Flask, scipy, geoalchemy2, geopandas, psycopg2-binary und psycopg[binary] — PostGISWriter baut Engines mit dem postgresql://-Schema, das SQLAlchemy 2.x auf psycopg v3 loest; ohne diesen Eintrag crasht der Login-/Read-Pfad im Container (Fix 2026-09-27), python-dotenv==1.0.1 wegen des taipy-gui/FastMCP-Konflikts). bluegreencity_ki/__init__.py guardet den osgeo-Import (try/except ImportError), weil die GUI GDAL nie braucht — sie liest nur aus PostGIS. Im Container lauscht die App auf 0.0.0.0 (CMD-Parameter --host), damit das Docker-Port-Forwarding auf die Container-IP ankommt; die Config bleibt für lokale Devs auf 127.0.0.1.

Netz-Exposition (Tailscale auf der Projekt-Workstation):

Dienst Mechanismus URL Reichweite
Grafana tailscale funnel (443) https://<workstation-hostname>.<tailnet>.ts.net/ öffentlich (LHH-Test)
Grafana Container-Port an Tailscale-IP https://<tailscale-ip>:3443/ Tailnet
Taipy tailscale serve --bg --https=5000 5000 https://<workstation-hostname>.<tailnet>.ts.net:5000/drafts nur Tailnet

Der Funnel für Taipy (öffentliches Internet) ist bewusst vertagt (Plan-Phase “später”: nach Saisonende 2026 / LHH-Test-Start).

Auth + Rollen: Basic Auth, Benutzer aus TAPIY_USERS in .env (Format user:pass:ROLE[,user:pass:ROLE]). Rollen: R1 (Disponent: Freigabe+Override), F1 (Fahrer: Ausführung), L1 (LHH-Test: Read-only). Pseudonymisierte Rollen-Kennungen, keine Personennamen (siehe GDPR-Block). Vor ersten Zugriffen durch Dritte das Platzhalter-Passwort in .env ändern.

Audit Semantics

Reviews and execution reports are append-only events. Work-order status is an operational projection updated in the same transaction as each field report. Observed litres remain separate from modeled demand and can later feed the canonical irrigation-event import and SWBM continuation.

The browser UI was verified on desktop and a 390 x 844 mobile viewport without horizontal overflow. The current database contains a wet reference-day draft; therefore all displayed rows currently have no_water_demand. A dry-day plan is required before meaningful approvals are issued.