Files
demeter/esp/README.md

78 lines
3.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 0100% |
| `/sensors/temperature` | GET | Yes (periodic) | Temperature in °C |
| `/sensors/water_level` | GET | Yes (periodic) | Water level 0100% |
| `/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
1. Flash MicroPython to your ESP32/ESP8266
2. Edit `config.py` with your WiFi credentials, device ID, and pin assignments
3. Upload all files to the board (via `mpremote`, `ampy`, or Thonny)
4. The node starts automatically and listens on UDP port 5683
## Testing with aiocoap (from Demeter server)
```bash
# 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
```bash
python tests/test_observe.py
```
## Changes from upstream microCoAPy
- Added `COAP_OBSERVE = 6` to option numbers
- Added `setObserve()`, `getObserveValue()`, `setMaxAge()`, `getUriPath()` to `CoapPacket`
- Added `ObserveManager` class for server-side observer tracking
- Added `notifyObservers()`, `observeGet()`, `observeCancel()` to `Coap`
- Modified `handleIncomingRequest()` to detect and handle Observe registrations
- Added RST handling to deregister observers
- Made `CoapOption` accept `str` input (CPython compatibility)