Skip to content
BoKSA

City Sensor Dashboard

City Sensor Dashboard

Picture the Learning Group city Raspberry Pi in the HvA server room (6th floor WBH). On the school network a laptop opens a browser — and the city's sensor feed is already on screen: a few charts, a live status, and a way to send a control/override to a hub. When the feed goes quiet, the dashboard does not keep drawing yesterday's line as if nothing happened. It shows a clear fail-state. That is full-stack city tech in miniature: MQTT (or city protocol) in, a database that stores readings with metadata, REST out, a shared dashboard, and a path to talk to the city's microcontrollers.

In this challenge you design and build the city's shared sensor dashboard stack: ingest sensor data (simulated first), store it, show it, connect to hubs, and allow an override. Your work lands in the city's one shared back-end and one shared front-end (Docker Compose on the city Pi) — not a private solo stack. You work through research, advice, design, and realisation for your Sprint 1-2 Learning Goal. Follow the city Requirements. Evidence is individual, even though you integrate in the Learning Group.

Your Learning Goal title in Portflow

Use: Sprint 1-2 - Learning Goal - City Sensor Dashboard (adjust the sprint number if needed). See the Learning Goal page for the Portflow template.

Illustration

The animation below shows the chain you are aiming for — sensor hubs in the city, the city Raspberry Pi running MQTT, a database, and a REST API, then a monitor with the shared dashboard. Blue dots are the readings. When the feed stops, the status square turns red.

Challenge

Your Learning Group needs a city sensor dashboard on the shared full-stack stack: sensor data arrives from hubs (or a simulator while hubs are not ready); a database stores normalised readings with metadata; a REST API exposes latest + history; a front-end shows charts and status; and the stack can connect to city microcontrollers and override a hub decision (for example force traffic lights on a road to red). Everything runs in Docker Compose on the city Raspberry Pi (one Pi per city, server room, school network).

You will deliver a working prototype and the documents that justify and explain it. Work in this order:

  1. Understand the problem. Which city quantities will you show first? When is the dashboard “live” vs “stale”? What override can an operator send to a hub? Write clear rules, e.g. “Live while a reading arrived in the last 15 s; stale otherwise.” Stored history may still be visible when the feed is stale — the status must not look healthy.
  2. Research. Compare realistic ways to run MQTT (or another city protocol) + a database + REST + a small dashboard on a Raspberry Pi, and how the stack will talk to ESP32 hubs. Keep the report short: enough to choose a stack and a hub contract, not a survey of smart-city platforms. Cite sources for decisions.
  3. Advise. Recommend one architecture for the shared city back-end and front-end: Compose services, topic/payload contract, normalised schema + metadata, API resources (including override), how the Pi is reached, and how you connect to microcontrollers. State what you are not building in this period. Hosting on the city Raspberry Pi in the server room is already decided.
  4. Design. Specify services, networks, published ports, data model, API contract, dashboard views, hub connection + override, fail-state behaviour, and city code conventions so someone else could rebuild and extend the shared stack.
  5. Realise. Build and test in small steps (simulator first, then API, then UI, then hub path). Integrate into the shared Compose project on GitLab main. Deploy on the city Pi and demonstrate: a classmate opens the dashboard, sees charts from stored readings, sees the fail-state when the feed stops, and can trigger a documented override. Use simulation/stubs so you do not wait on embedded classmates.

Minimum scope (Sprint 1–2)

Your contribution must include:

  • Work in the city’s one shared back-end and one shared front-end (Docker Compose on the city GitLab project / main) — do not ship a parallel personal stack that never joins the city project.
  • The city Raspberry Pi (one per city) in the HvA server room (6th floor WBH), with a known IP on the school network, running that shared stack.
  • Docker Compose with these application services:
    • an MQTT broker (or the city-agreed hub protocol bridge)
    • a database that persists readings (Compose service such as PostgreSQL or MariaDB, or SQLite with a named volume — justify in research)
    • a REST API that writes incoming readings to the database, reads latest + recent history, and exposes at least one override / control action toward hubs
    • a frontend dashboard (shared city UI)
  • A sensor simulator that publishes fake readings on a timer so you can progress without waiting for hardware. Simulation is the minimum path; connecting a real hub is expected in the design and demoable with a stub if no MCU is ready yet.
  • A documented path to connect to the city's microcontrollers: protocol, network path, example messages to read sensor/state data and to send a command, plus a short how-to for the Learning Group.
  • At least one override example (e.g. force a hub into a safe state such as “all lights red” / “gate closed” / “lid lock”) exposed via API and visible or confirmable in the UI or logs.
  • Networking so another device on the school network can open the dashboard using the Pi’s IP on port 80 (and 443 if you use HTTPS). Prefer one HTTP entry; keep MQTT and the database on the Compose network unless you have a documented reason to publish them.
  • Dashboard visuals: at least two charts or equivalent visuals fed by the API from stored readings — not a table-only page, not only the last in-memory message.
  • Normalised storage with relevant metadata per reading (at least date/time, device/hub id, and location or tile/spot id; add IP or equivalent if available).
  • Fail-state when data stops: if no new message arrives within a documented timeout, the API marks readings stale and the dashboard shows that visibly. History may still be plotted; do not present a healthy live city on a frozen feed.
  • Documented protocol / topic + payload, data model, API contract (including override), and city full-stack code conventions you follow.
  • Decisions and protocol notes in English Markdown (city MkDocs / repo), with references where you chose a technology or pattern.

If you have time, add one or more of:

  • HTTPS on 443 (reverse proxy with a lab certificate or HTTP→HTTPS redirect) if you already serve HTTP on 80.
  • A second simulated feed (still a fixed list — not “every sensor in Amsterdam”).
  • Live MQTT (or protocol) from a classmate’s embedded prototype (e.g. Smart Traffic Light) in addition to the simulator. Simulation must still work on its own.
  • A short deploy script (compose up on boot, or documented systemd) so a reboot brings the dashboard back.
  • City branding consistency on the shared front-end so it looks like one city product.

Out of scope for this challenge

These are not part of this challenge:

  • A city-wide multi-tenant “city OS”, or maps of Amsterdam (or any whole city).
  • Kubernetes, cloud hosting, or managed IoT platforms as the place you demo.
  • Time-series platforms, data warehouses, or observability stacks (Prometheus/Grafana) as the product — a small SQL or document database is the store you need.
  • Machine learning, prediction, or anomaly models.
  • Auth / SSO / user accounts — unless you can prove the minimum cannot work without them (it can).
  • Production TLS public CAs as a blocker for the lab demo.
  • Building the embedded firmware yourself — that is embedded work. You do define and use the interface they expose.
  • A separate personal Compose stack that never merges into the city’s shared back-end and front-end.

Demo and safety context

Treat the prototype as lab equipment on the school network, not production city infrastructure:

  • Default to stale when the sensor feed is missing, late, or malformed — analogue of “default to red”.
  • Overrides are explicit and logged. Document who may trigger them and what safe state they force.
  • Predictable rules — document the timeout and what the UI shows.
  • Clear demo script — anyone in your Learning Group can show “simulator on → charts live”, “simulator off → fail-state (history still visible)”, “open from another laptop via the Pi IP on port 80”, and “override command → documented hub/stub response”.
  • Independent progress. Use simulation and stubs so you do not wait on embedded classmates.
  • Do not expose admin interfaces, database ports, or default broker passwords to the whole campus network.

Starting points

Use these concrete first steps early in Sprint 1:

  1. Read the city Requirements and agree your challenge with the Learning Group (no duplicate challenges).
  2. Agree on feed, fail-state, and override rules. One or more quantities, topic(s), timeout, and one override example. Write the rules in plain language.
  3. Inventory the city Pi — Raspberry Pi OS in the server room, Docker + Compose, school-network IP, confirmation that 80 (and 443 if you need it) are the ports you will use. Confirm access with your coach.
  4. Hello Compose on port 80 — One container that serves a static “hello” page from the Pi IP. See Containerization.
  5. Draft the hub connection with embedded classmates (protocol + example messages). Agree a simulator/stub so neither side waits.
  6. Draft your research question. Example: Which Compose stack and hub contract best fit the city Pi (ARM, memory, ports 80–443) given normalised storage, override control, and shared back-end/front-end conventions?
  7. Create your Learning Goal in Portflow. Link the product deliverables you plan to submit. Follow Learning Goal.
  8. Integrate only what works. Prove simulator → store → charts → fail-state, then override/stub, then merge into the shared city Compose project.

Suggested sprint timeline

The Learning Group does not use Scrum, but you still follow the sprint rhythm of the Group Project: two sprints for this challenge (Sprint 1-2).

In the first sprint you focus on research and advice. In the second sprint you focus on design and realisation of the shared stack on the city Pi (including hub connection path and override).

Sprint Focus Outcome
1 Research & advise Research report; advisory report; stack choice; topic/schema/override sketch; hub connection draft; simulator plan
2 Design & realisation Design (contracts, model, ports, override); shared Compose on city GitLab main; deploy on city Pi; charts + fail-state + override demo; Portflow evidence linked; reflection

Tools, frameworks, and hardware

Area Suggestions
Host City Raspberry Pi (server room, 6th floor WBH); school network IP; published ports 80 (and 443 if TLS)
Compose Shared city stack: MQTT broker (e.g. Eclipse Mosquitto), database, REST API, frontend; reverse proxy (Caddy/nginx) only for 80/443
Database PostgreSQL, MariaDB, or SQLite with a named volume — justify in research; normalised readings + metadata
Simulator / stubs Tiny publisher on a timer; stub consumer for override when no MCU is ready
API Node/Express, Python/FastAPI, or similar — justify in research; include read + override endpoints
Frontend Shared city UI: HTML/JS + chart library or small framework — justify in research
Version control City GitLab project, shared back-end/front-end on main
Documentation English Markdown on city MkDocs + repo; cite sources for decisions

Profile knowledge worth revisiting:

Products

Your challenge evidence is a set of products — studio deliverables tied to learning outcomes. Submit them in Portflow and link them from your Learning Goal.

Analyse & Advise

Product What you deliver Template
Research Short analysis of shared Compose stack options for the city Pi (broker/protocol, database, API, dashboard, hub connection, override); comparison with criteria; recommendation for design Research product
Advice Decision document: shared architecture, topic/API contract, normalised data model + metadata, fail-state, override, hub connection plan, and implementation order. Pi hosting in the server room is given. Advisory report

Suggested titles for Portflow

  • Research: Shared Compose stack for the city sensor dashboard on the server-room Pi
  • Advice: MQTT–database–REST–dashboard architecture with hub override

The advice report should build on the research report — do not repeat the full comparison tables. If research grows past a stack and contract choice, you are over scope — cut it so you still deploy.

Design & Realise

Product pages for design and realisation are still being added to the studio catalogue. For this challenge, deliver the following and attach them as evidence (repository links, PDFs, or videos as your coach specifies).

Product Learning outcome What you deliver
System design Design & Realise Self-contained design document: context, city Requirements link-in, Compose/block diagram for the shared stack, protocol/topic and payload, normalised data model + metadata, REST resources (read + override) and example JSON, dashboard views, hub connection how-to, published ports, fail-state/timeout rules, city code conventions, and test plan
Prototype realisation Design & Realise Working shared Compose stack on the city Raspberry Pi, source on city GitLab main, README with build/deploy steps, and validation evidence showing live charts from stored readings, fail-state when the feed stops, and an override (live hub or stub), opened from another device on http://<pi-ip>/

Suggested titles for Portflow

  • Design: City Sensor Dashboard — shared Compose, data model, API, override, and UI
  • Realisation: City Sensor Dashboard — city Pi deploy and validation

System design — minimum contents

Your design document should let a peer rebuild and extend the shared system without guessing:

  • Requirements. Simulated feed first; persist with metadata; REST out; charts; live vs stale; hub connection; override; shared back-end/front-end.
  • Architecture diagram. Broker/bridge, database, API, frontend, simulator/stubs; Compose networks; what is published on 80/443; path to microcontrollers.
  • Contracts. Protocol/topic + payload; normalised tables/collections and keys; metadata fields; REST paths including override; stale/last-seen fields.
  • Dashboard. Which charts, which API calls, how fail-state and override look.
  • Network. City Pi IP (server room), host port map or reverse-proxy routes, why MQTT and the database stay internal (or how you expose them safely).
  • Timeouts and recovery. When data is stale; Compose restart; stored history vs live feed.
  • Code conventions. Which city full-stack conventions you follow.
  • Test plan. e.g. “simulator on → live charts”, “simulator stopped → stale UI”, “classmate laptop → port 80”, “override → stub/hub ack”, “compose restart → readings still stored”.

Realisation — minimum evidence

  • Work on the city GitLab project: shared Compose merged (or ready to merge) into main.
  • docker-compose.yml (and Dockerfiles) that a peer can start on the city Pi.
  • README: clone → configure → compose up → open http://<pi-ip>/; hub connection how-to; simulator/stub instructions.
  • Demo script (numbered steps) matching your video or live assessment, including fail-state and override.
  • Proof you progressed without waiting on embedded (simulator/stubs).
  • Honest known limitations (e.g. HTTP only, stub override not yet wired to a real hub, short retention window).

Quality indicators

When assessing this challenge as a whole, the following indicators are used. Use them as a self-check before you submit.

Problem fit

  • The sensor feed, live vs stale rules, and override behaviour are described in plain language.
  • Scope is explicit: this challenge delivers the city's shared dashboard stack on the city Pi (server room) with hub connection path — not a private solo Compose app and not a city platform.
  • The work respects the city Requirements (shared back-end/front-end, Docker on the city Pi, connect to microcontrollers, override, normalised data + metadata, no waiting on classmates).

Analyse & Advise products

  • Research and advice reports meet the research and advisory report quality indicators — kept short enough that deploy still happens.
  • The advice report references the research report and states one clear recommended architecture, including hub connection and override.
  • Stack choices are supported by current docs (ARM/Pi images, Compose, database, port publishing), not only opinion. Decisions cite resources. Pi hosting is not re-litigated.

Design

  • The design document is self-contained and includes contracts, a normalised data model with metadata, a port/reachability map, hub connection how-to, override, and fail-state rules that match the intended software behaviour.
  • Compose services and published ports match the realised prototype (or differences are documented with reason).
  • Fail-safe behaviour is designed explicitly (stale/timeout, recovery when the simulator returns; safe override semantics).

Realisation

  • The stack runs on the city Raspberry Pi and the dashboard is reachable from another school-network device on port 80 (and 443 if TLS is used).
  • Work lives in the city’s shared Compose project on GitLab main (or is clearly opened as an integration MR), following city full-stack code conventions.
  • MQTT/broker (or protocol bridge), database, REST API, and frontend are separate concerns in Compose; the API persists readings with metadata; the dashboard shows at least two charts/visuals from stored data.
  • An override is demonstrable (live hub or stub) via API/UI.
  • Stopping the feed produces a visible fail-state; restarting it returns to live. Stored history is still available; live status is not faked.
  • Code is readable: meaningful names, documented topic/API contract and schema, no unexplained magic numbers for timeouts.
  • Validation evidence covers live, stale, override, and at least one edge case (e.g. malformed payload, Compose restart with readings still stored).
  • Repository README explains how to build, deploy on the city Pi, run the simulator/stub, and run the demo.

Professional practice

  • Learning Goal in Portflow uses the correct naming format and links to all product evidence.
  • End-of-sprint reflection connects results to your learning question and to full-stack practice (shared Compose, database, API contract, hub connection, deploy, fail-state).
  • Documentation is in English Markdown and usable by other city students.
  • You did not block on classmates: simulation, stubs, or a local demo kept you moving.

Focus points

Watch out for these common issues while you work:

  • Private solo stack. The city has one shared back-end and one shared front-end — integrate, do not fork forever.
  • Research that never ends. A stack choice plus Pi/port/hub contract is enough. If you have no deploy, the research was too large.
  • Demo only on localhost. The challenge is the city Pi on the school network, ports 80–443.
  • Waiting on embedded. Simulation and stubs are mandatory progress tools; a live hub is a bonus once ready.
  • Read-only dashboard. Requirements include override toward hubs — design and demo it (stub OK).
  • Publishing every container port. Prefer one HTTP entry (80/443). MQTT and the database do not need to be campus-wide services.
  • Charts without a fail-state. Stored history can look “fine” after the feed dies. Show stale on purpose.
  • In-memory only / no metadata. Persist normalised readings with date/time, device, and location (or equivalent).
  • Advice without analysis. Coaches will send back an advice report that invents new comparisons not present in research.
  • Design–code drift. Update the design document when you change topics, ports, schema, or timeouts during realisation.

Key points

  • Core task: shared city stack on the server-room Raspberry Pi — ingest → store (with metadata) → REST + dashboard → hub connection + override.
  • Use a simulator/stubs so you do not wait on embedded; integrate into one shared back-end and front-end.
  • Deliver four products: research, advice, system design, and prototype realisation.
  • Work research → advice → design → realise; Sprint 1 emphasises research & advice; Sprint 2 emphasises design & realisation.
  • City platforms, Kubernetes, cloud, ML, and SSO are out of scope for this challenge.
  • Link everything to your Learning Goal in Portflow and reflect at the end of Sprint 1-2.