3.3 KiB
3.3 KiB
Demeter ESP - CoAP Sensor Node with Observe
CoAP (RFC 7252) sensor node firmware for ESP32/ESP8266 running MicroPython, with CoAP Observe (RFC 7641) support for real-time push notifications.
Project Structure
demeter-esp/
├── microcoapy/ # Extended microCoAPy library
│ ├── __init__.py
│ ├── coap_macros.py # Constants + COAP_OBSERVE option number
│ ├── coap_option.py # CoapOption (str-compatible)
│ ├── coap_packet.py # CoapPacket + setObserve(), getObserveValue(), setMaxAge()
│ ├── coap_reader.py # Packet parser (unchanged)
│ ├── coap_writer.py # Packet serializer (unchanged)
│ ├── microcoapy.py # Main Coap class + Observe server/client methods
│ └── observe_manager.py # Observer registry with per-resource tracking
├── config.py # WiFi, device ID, pin assignments, thresholds
├── sensors.py # Hardware abstraction for analog/digital sensors
├── main.py # Entry point: CoAP server + sensor loop
└── tests/
└── test_observe.py # Observe extension tests (runs on CPython)
CoAP Resources
| URI Path | Method | Observable | Description |
|---|---|---|---|
/sensors/soil_moisture |
GET | Yes (periodic) | Soil moisture 0–100% |
/sensors/temperature |
GET | Yes (periodic) | Temperature in °C |
/sensors/water_level |
GET | Yes (periodic) | Water level 0–100% |
/events/trigger |
GET | Yes (event-driven) | Digital input state change |
/device/info |
GET | No | Device metadata, uptime |
/config/interval |
GET, PUT | No | Read/set polling interval |
Observe Behavior
- Periodic sensors (soil, temp, water): NON-confirmable notifications at configurable intervals. Only sent when value changes beyond a configurable threshold.
- Trigger events: CON-confirmable notifications sent immediately on GPIO state change via hardware interrupt.
- Max observers: 4 per resource, 8 total (configurable in
observe_manager.py). - Deregistration: Via Observe option value 1, or automatically on RST response.
Setup
- Flash MicroPython to your ESP32/ESP8266
- Edit
config.pywith your WiFi credentials, device ID, and pin assignments - Upload all files to the board (via
mpremote,ampy, or Thonny) - The node starts automatically and listens on UDP port 5683
Testing with aiocoap (from Demeter server)
# Simple GET
aiocoap-client coap://ESP_IP/sensors/temperature
# Observe subscription
aiocoap-client coap://ESP_IP/sensors/soil_moisture --observe
# Set polling interval to 10 seconds
echo '{"interval": 10}' | aiocoap-client coap://ESP_IP/config/interval -m PUT
Running Tests
python tests/test_observe.py
Changes from upstream microCoAPy
- Added
COAP_OBSERVE = 6to option numbers - Added
setObserve(),getObserveValue(),setMaxAge(),getUriPath()toCoapPacket - Added
ObserveManagerclass for server-side observer tracking - Added
notifyObservers(),observeGet(),observeCancel()toCoap - Modified
handleIncomingRequest()to detect and handle Observe registrations - Added RST handling to deregister observers
- Made
CoapOptionacceptstrinput (CPython compatibility)