inanimate/courier

0.2.0

Latest
uploaded 4 days ago
Batteries-included ESP32 connectivity library — WiFi, WebSocket, MQTT, reconnection, all handled

readme

# courier

Batteries-included JSON messaging for ESP32. WiFi and user configuration, WebSocket, MQTT, reconnection — all handled.

Motivation: When you make something neat on your [M5Stick](https://shop.m5stack.com/products/m5stickc-plus2-esp32-mini-iot-development-kit?variant=44269818216705) you want the quickest path to messaging the back-end, and you want to carry it to places to show people and configure the Wi-Fi from your phone. Courier is how you do that.

Courier expects JSON messages with a `"type"` field. Messages are parsed with ArduinoJson and the `type` string is passed to `onMessage` callbacks alongside the parsed document. Use `onRawMessage` for non-JSON or custom framing.

```cpp
#include <Courier.h>

CourierConfig makeConfig() {
  CourierConfig cfg;
  cfg.host = "api.example.com";
  cfg.port = 443;
  cfg.path = "/ws";
  return cfg;
}

Courier courier(makeConfig());

void setup() {
  courier.onConnected([]() { courier.send("{\"type\":\"hello\"}"); });
  courier.onMessage([](const char* type, JsonDocument& doc) {
    Serial.printf("Got: %s\n", type);
  });
  courier.setup();
}

void loop() { courier.loop(); }
```

## What it does

- **WiFi** — captive portal config via WiFiManager, auto-reconnection
- **WebSocket** — built-in transport with TLS, ping/pong heartbeat
- **MQTT** — opt-in transport with subscribe/unsubscribe, topic-addressed publishing
- **Reconnection** — exponential backoff (5s-60s), health monitoring, automatic recovery
- **Time sync** — NTP primary (continuous drift correction) + HTTP Date header fallback
- **JSON routing** — messages parsed and dispatched by `type` field
- **Transport map** — named transports, broadcast or targeted sending

## Opinionated

Courier bundles a number of other great libraries:

- **WebSocket** — esp_websocket_client [Documentation](https://docs.espressif.com/projects/esp-protocols/esp_websocket_client/docs/latest/index.html)
- **MQTT** — esp_mqtt_client [Documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/mqtt.html)
- **WiFi config** — WiFiManager [GitHub](https://github.com/tzapu/WiFiManager)
- **JSON** — ArduinoJson [Documentation](https://arduinojson.org/)
- **Time** — ezTime [GitHub](https://github.com/ropg/ezTime)

Use `onConfigure` hooks to access the full configuration surface of each bundled library.

## Install

**PlatformIO:**
```ini
lib_deps = inanimate/courier
```

**ESP-IDF Component:**
```yml
dependencies:
  inanimate-tech/courier:
    version: "^0.1.0"
```

## API

See [docs/api.md](docs/api.md) for the full API reference.

Quick overview:

```cpp
// State
courier.isConnected();
courier.getState();        // CourierState enum

// Sending — "To" suffix means you specify the transport
courier.send(payload);                              // default transport + topic
courier.sendTo("mqtt", payload);                    // named transport
courier.sendBinaryTo("ws", data, len);              // named transport, binary
courier.publishTo("mqtt", "my/topic", payload);     // named transport + topic

// Transports
courier.addTransport("mqtt", &mqttTransport);
courier.suspendTransports();   // free SRAM for OTA
courier.resumeTransports();

// Callbacks (multiple registrations supported, up to 4 per type)
courier.onMessage([](const char* type, JsonDocument& doc) { });
courier.onRawMessage([](const char* payload, size_t len) { });
courier.onConnected([]() { });
courier.onDisconnected([]() { });
courier.onError([](const char* category, const char* msg) { });

// Raw ESP-IDF config access
courier.builtinWS().onConfigure([](esp_websocket_client_config_t& cfg) { });
mqtt.onConfigure([](esp_mqtt_client_config_t& cfg) { });
courier.onConfigureWiFi([](WiFiManager& wm) { });
```

## Connectivity state machine

```
BOOTING -> WIFI_CONNECTING -> WIFI_CONNECTED -> TRANSPORTS_CONNECTING -> CONNECTED
                                                        ^                    |
                                                   RECONNECTING <-----------+
                                                        |
                                                CONNECTION_FAILED
```

`onConnectionChange` fires at each state transition. `onError` fires alongside transitions caused by failures, providing a category and reason (e.g. `"WIFI"`, `"connection lost"`).

## Limitations

- **Single instance** — WiFiManager requires a static callback, so only one Courier instance per process
- **Single message slot** — transport callbacks queue one pending message at a time; messages arriving before the main loop drains are dropped
- **Arduino + ESP-IDF** — depends on Arduino framework for WiFiManager, ArduinoJson, ezTime

## License

MIT

Links

License: MIT

To add this component to your project, run:

idf.py add-dependency "inanimate/courier^0.2.0"

download archive

Stats

  • Archive size
    Archive size ~ 986.63 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

inanimate/courier version: 0.2.0
|