# Measure a multi-hop WSN collection path

Measure delivery, sample delay and each link’s round-trip latency in a six-node greenhouse collection model.

## Run on Linux x86-64 with Docker and X11

The image, Java, compiler and simulator ran on this host under Apptainer.
Docker is unavailable here: the laptop Docker invocation is syntax-reviewed,
not claimed as laptop-tested. Windows, macOS and ARM display setup is outside
this recipe. No paid service or account is required.

Download `lab-files.tar.gz` from this lab page. In a terminal:

```bash
mkdir cooja-lab
cd cooja-lab
tar -xzf ~/Downloads/lab-files.tar.gz
git clone --depth 1 --branch release/v4.9 https://github.com/contiki-ng/contiki-ng.git contiki-ng
test "$(git -C contiki-ng rev-parse HEAD)" = c20b12cd2db707d6c07918f8b26cfeb52cf298ca
git -C contiki-ng submodule update --init --depth 1 tools/cooja
test "$(git -C contiki-ng/tools/cooja rev-parse HEAD)" = 33d41ae9f8acd6075fb903b0bcd5b4122bad8d8f
mkdir -p jdk17 home/contiki-ng
curl -fL 'https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.20.1%2B1/OpenJDK17U-jdk_x64_linux_hotspot_17.0.20.1_1.tar.gz' -o jdk17.tar.gz
echo '3808d1d15e3ec6bd5b84057fb5d84c33d8a1536a258146bcea2e603fc726e08e  jdk17.tar.gz' | sha256sum -c -
tar -xzf jdk17.tar.gz --strip-components=1 -C jdk17
xhost +si:localuser:$(id -un)
bash cooja-wsn-data-collection/docker-launch.sh
# After closing Cooja:
xhost -si:localuser:$(id -un)
```

The launcher binds the packet at `/lab`. Cooja loads `/lab/cooja-wsn-data-collection.csc`
and compiles the included unmodified upstream C files. The project header enables
logging and any explicitly documented parameter changes. The supplied Makefiles
expect the recipe's `/home/user/contiki-ng` mount. The first Gradle build requires
Internet. To use your own native Java 17 installation, set CONTIKI in the supplied
Makefiles to your checkout and open the CSC with that release's Cooja.

The script starts automatically and stops at `TEST OK` or `TEST FAILED`. The GUI
stays open. Use **Mote output → Filter** to show the rows named in the steps;
clear the filter to inspect other messages. **File → Open simulation → Browse...**
loads another CSC. Reopen the original CSC for a fresh seed-1 run.
Times are simulated times, not wall-clock times. `expected-output.txt` is the
unaltered headless serial/test log, including actual measurements and the test result.

For headless Docker execution, replace `--gui --autostart` in the launcher with
`--no-gui --logdir=/lab/run-output` and remove the display requirement/mount.
Cooja writes `COOJA.testlog` under that writable output directory.

## Scenario, variables and acceptance

A greenhouse has five sampling clients and one collection sink. The stock
`hello N` payload is a synthetic sample identifier, not temperature or vibration.
No physical sensor, calibration, real battery or cloud gateway is simulated.
This lab exercises collection and evidence recording from the legacy WSN lab;
coverage, energy, gateway translation and season-long deployment remain review
questions below. The firmware is unchanged upstream `examples/rpl-udp`.

Seed 1; 120 seconds; UDGM transmit range 50 m, interference 100 m, transmit and
receive success 1. Positions (metres): 1=(0,0), 2=(-30,25), 3=(30,25),
4=(-60,55), 5=(0,55), 6=(60,55). Keep these and traffic unchanged for a repeat.
The ScriptRunner logs every serial event and asserts five sending and replying
clients, one matched latency per sink reception, and the scheduled ping results.
The real log ends TEST OK. Modelled radio distance is not physical coverage.

## Measurement ledger

Use source + sequence as the packet identity. Count Sending request rows as
attempted application samples, Received request at ID:1 as deliveries, and
Received response at each source as reply evidence. A sample never attempted
while a source has no route is not in this delivery denominator: also inspect
Not reachable yet and Tx/Rx/MissedTx so absence is visible.

Record: claim; fixed inputs; source; sequence; parent snapshot and time;
send time; sink time; one-way application delay; reply status; missing/stale
source; decision; owner; retest trigger. The COLLECTION rows calculate only
send-to-sink application delay. They do not split queueing and forwarding time.

For per-hop latency, the script pings 4→2 at 65 s and 2→1 at 72 s, then
4→1 at 80 s. Results are **RTT**, not one-way latency: 31, 45 and 81 ms.
Do not divide by two or present their sum as a measured end-to-end delay.
The application and radio layers have different counts: 46 useful synthetic
samples, 46 sink deliveries, 404 radio transmissions in the GUI run.

## Preserve the original field-rehearsal decisions

Before moving sensors, separate point/area sensing coverage from a connected
radio path. A connected mote can still miss the greenhouse zone of interest.
List required test points, what each sensor observes, redundancy and blind spots.
Two additional relay locations may repair connectivity without adding any
sensing coverage. Do not replace either test with a drawing of the other.

For energy, list sampling interval, sleep policy, retries, forwarding load and
which near-sink relay is limiting. This always-on CSMA experiment has no battery
lifetime result. For gateway review, write identity, time, units, quality and
missing-source status before a dashboard can hide a missing node.

A field fault record needs baseline, exact change, first symptom, missed/late or
duplicate reports, first recovered sample and a retest decision. This packet
has no injected fault; run the separate join-and-heal lab to observe a controlled
relay failure. Neither run proves a greenhouse wall or seasonal interference
model. A deployment decision remains held until site coverage, power and gateway
boundaries are measured. Assign an owner and repeat after firmware, placement,
traffic or gateway changes. Preserve failed runs as evidence.


## Tested version

Contiki-NG release/v4.9 c20b12cd, Cooja 4.8 (2022071901), Temurin 17.0.20.1, image sha256:b14d5afb0a2a852d9e72bbed607ead03f6ccc5f4d4dee44f0799110be2f4b609
