Spenser - a developer's companion
1.0.0 - STU1
Spenser - a developer's companion, published by Zeora. This guide is not an authorized publication; it is the continuous build for version 1.0.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/costateixeira/spenser/tree/master and changes regularly. See the Directory of published versions
The firmware runs on an ESP32-S3-based dispenser using the M5Stack AtomS3 Lite and M5Stack Atomic Motion Base, designed to dispense chocolate upon receiving FHIR MedicationRequests over HTTP.
It supports:
InventoryReport for reporting (GET) and adjusting (POST) inventoryMedicationRequest resources via HTTP POST and reply with MedicationDispensefirmware folder, run PlatformIo to compile, upload and monitorThese endpoints conform to FHIR R5:
GET /metadataCapabilityStatementPOST /MedicationRequestMedicationRequest resource (JSON)MedicationDispense resourceMedicationDispensePOST /InventoryReportInventoryReport resourcecountType: snapshot โ replace inventorycountType: difference โ adjust inventory incrementallyGET /InventoryReportInventoryReport representing current stockThese are utility endpoints for diagnostics, setup, and interactive testing.
| Endpoint | Description |
|---|---|
GET /wifi-settings |
Mark device to enter Wi-Fi config mode on reboot |
GET /wifi-reboot-config |
Immediately reboot into config mode |
GET /wifi-reset |
Clear stored Wi-Fi credentials |
GET /startConfig |
Trigger Wi-Fi setup mode and reboot |
GET /wifi |
Redirect to config portal if not connected |
| Endpoint | Description |
|---|---|
GET / |
Serve UI from SPIFFS or redirect in AP mode |
GET /ui.html |
Serve static UI (index.html) |
GET /success |
Confirmation screen after Wi-Fi setup |
GET /ip-info |
Show IP and auto-redirect to it |
| Endpoint | Description |
|---|---|
GET /setColor |
Change the RGB LED color via query params |
GET /setServos |
Set servo angles via query params |
GET /reset |
Reset LED and both servos to 0 |
GET /flashServo1 |
Flash servo 1 to dispenseAngle briefly |
GET /flashServo2 |
Flash servo 2 to dispenseAngle briefly |
GET /inventory |
Show current inventory levels in JSON |
GET /resetInventory?dark=10&milk=15 |
Manually set inventory counts |
GET /battery |
Report battery voltage and percentage |
These endpoints redirect to /success to handle platform-specific captive portals:
/generate_204/hotspot-detect.html/fwlink/connecttest.txt/ncsi.txt/iWhen started, the firmware tries to connect to the Wi-Fi network defined in WiFiCredentials.h. It also creates an AP with an SSID spenser, and an IP 192.168.4.1.
So, to get started, simply connect to the spenser Wi-Fi network and go to http://192.168.4.1.
dispenseAngle: 97ยฐindex.html and UI assets.forceConfig flag for Wi-Fi setup.(WIP / YMMV)
GET /batteryUse these endpoints to test functionality:
GET /flashServo1 โ Dispense dark chocolate manuallyGET /flashServo2 โ Dispense milk chocolate manuallyGET /setColor?red=0&green=255&blue=0 โ Set LED to greenGET /resetInventory?dark=20&milk=20 โ Reset inventoryMedicationRequest POST{
"resourceType": "MedicationRequest",
"id": "req-123",
"status": "active",
"intent": "instance-order",
"medicationCodeableConcept": {
"coding": [
{
"code": "chocolate-dark",
"display": "Dark Chocolate"
}
]
},
"dosageInstruction": [
{ "text": "Dispense one dark chocolate" }
],
"subject": { "reference": "Patient/example" }
}