Skip to content

Trace CoAP methods and Observe on local UDP

Discover a local CoAP resource, read and change values, then correlate two Observe notifications by token and actual UDP bytes.

Broker Bex: I want you to match each resource action and notification to its wire evidence., your practice guide

Broker Bex: I want you to match each resource action and notification to its wire evidence.
Predict the reading, then compare it with the measurement.

Python 3 + aiocoap

Python

Discover a local CoAP resource, read and change values, then correlate two Observe notifications by token and actual UDP bytes.

Tier 2 · Python · install required · No account

Version tested: Python 3.9.21; aiocoap 0.4.7; local UDP; Xfce Terminal 1.0.4 on Xvfb. Date: 2026-10-08.

Download the three files, create a Python virtual environment, install requirements.txt, and run main.py.

Open the Python run guide (new tab)

Get the files

Download all three prepared files into one folder. No account or paid service is required.

main.py

6,183 bytes · Python program

Download

requirements.txt

15 bytes · Pinned dependencies

Download

README.md

1,107 bytes · Run guide

Download

  1. Put main.py, requirements.txt, and README.md in the same folder.
  2. Create and activate a Python virtual environment, then install requirements.txt.
  3. Run python3 main.py and compare its output with each observed result below.

Steps

Screens captured against Python 3 + aiocoap Python 3.9.21; aiocoap 0.4.7; local UDP; Xfce Terminal 1.0.4 on Xvfb on 2026-10-08; the tool may have moved on — the text steps are the contract.

  1. 1 Step 1

    Do
    In the terminal window panel, run `python3 main.py --step 1` to GET `/sensors` and inspect the returned resource links.
    You will see
    The local UDP trace contains a 2.05 Content response with `</temperature>;obs,</target>;rt="setpoint"`.
    Why it matters
    Discovery names the observable reading and the writable target before clients use either resource.
    Live local Python process output for coap-local-methods-observe step 1, captured after the real command exited.
    Step 1 · Python 3 + aiocoap; numbered callout added to a real capture. Enlarge screenshot (new tab)
  2. 2 Step 2

    Do
    In the terminal window panel, run `python3 main.py --step 2` to GET `/temperature`; compare the datagram hex, CoAP code, and decoded reading.
    You will see
    The actual response has `2.05 Content` and payload `21.5`; the output prints request and response datagram bytes.
    Why it matters
    The resource value can be tied to a specific UDP request and response rather than inferred from a page example.
    Live local Python process output for coap-local-methods-observe step 2, captured after the real command exited.
    Step 2 · Python 3 + aiocoap; numbered callout added to a real capture. Enlarge screenshot (new tab)
  3. 3 Step 3

    Do
    In the terminal window panel, run `python3 main.py --step 3` to PUT `22.0` to `/target`; inspect the response code.
    You will see
    The PUT payload is `22.0` and the application response is `2.04 Changed` with payload `22.0`.
    Why it matters
    A change operation has a different method and success code from a read.
    Live local Python process output for coap-local-methods-observe step 3, captured after the real command exited.
    Step 3 · Python 3 + aiocoap; numbered callout added to a real capture. Enlarge screenshot (new tab)
  4. 4 Step 4

    Do
    In the terminal window panel, run `python3 main.py --step 4` to GET `/target` after the PUT.
    You will see
    The follow-up GET returns `2.05 Content` with payload `22.0`.
    Why it matters
    A second read confirms that this run changed the target state.
    Live local Python process output for coap-local-methods-observe step 4, captured after the real command exited.
    Step 4 · Python 3 + aiocoap; numbered callout added to a real capture. Enlarge screenshot (new tab)
  5. 5 Step 5

    Do
    In the terminal window panel, run `python3 main.py --step 5` to register Observe and trigger two local temperature updates.
    You will see
    The initial response is `21.5 observe=0`; notifications report `22.0 observe=1` and `22.5 observe=2`.
    Why it matters
    The changing Observe values and payloads show server-initiated updates after one registration.
    Live local Python process output for coap-local-methods-observe step 5, captured after the real command exited.
    Step 5 · Python 3 + aiocoap; numbered callout added to a real capture. Enlarge screenshot (new tab)
  6. 6 Step 6

    Do
    In the terminal window panel, run `python3 main.py --step 6` and compare the response token in all three UDP datagrams.
    You will see
    Three server datagrams share one response token; `same token across initial response and updates=True`.
    Why it matters
    The token links the initial response and subsequent notifications to one observer request.
    Live local Python process output for coap-local-methods-observe step 6, captured after the real command exited.
    Step 6 · Python 3 + aiocoap; numbered callout added to a real capture. Enlarge screenshot (new tab)

Chapter checks

These questions refer to the chapter’s examples. Use the return links to review their answers.

  1. A CoAP Observe design replaces polling for a fast-changing sensor. What evidence should be reviewed before accepting it?

    Return to the chapter’s knowledge check
  2. A client sends GET /temperature with Observe: 0 and Token: 0xAB12. The server responds with Observe: 47. What does the value 47 in the server's response represent?

    Return to the chapter’s knowledge check

Caution

All values are fictional and the UDP datagrams stay on 127.0.0.1. Observe notifications are not proof of radio behavior, end-to-end security, battery savings, or a durable subscription after restart.

Return to CoAP Observe: Subscriptions and Updates · Browse Labs