Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,138 @@ Recipe (JSON, "Make Now") → RecipeEngine → GrillController → auger/i
All fire safety lives in `GrillController`; recipes and the network can only ask
it to do safe things. Full design in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).

## Data model / ERD

OpenEmber does not use SQL. The ERD below maps the persisted LittleFS JSON files
and the live REST/MQTT status payloads to their firmware structs.

```mermaid
erDiagram
DEVICE_CONFIG {
string hostname
string wifiSsid
string wifiPass
float kp
float ki
float kd
float grillOffsetF
string mqttHost
int mqttPort
string mqttUser
string mqttPass
bool haDiscovery
}

RECIPE {
string id PK
string name
string author
bool keepWarm
int stepCount
}

RECIPE_STEP {
string recipeId FK
int stepIndex PK
string name
float setpointF
bool superSmoke
}

ADVANCE_RULE {
string recipeId FK
int stepIndex FK
string type
int seconds
int probeIndex
float targetF
}

RESUME_STATE {
bool active
string recipeId FK
int stepIndex FK
bool paused
}

STATUS_SNAPSHOT {
string fw
int uptimeS
}

GRILL_STATUS {
string state
float tempF
float setpointF
bool augerOn
float augerDuty
bool igniterOn
bool fanOn
bool superSmoke
bool lit
int secondsInState
string error
}

COOK_STATUS {
string state
string recipe
int stepIndex
int stepCount
string stepName
float stepSetpointF
bool stepSuperSmoke
string advanceType
float stepProgress
int stepElapsedS
int stepRemainingS
int percentComplete
int probeIndex
float probeTargetF
}

PROBE_READING {
int index PK
bool connected
float tempF
}

NET_STATUS {
string mode
bool connected
string ip
}

OUTPUT_COMMAND {
float augerSpeed
bool augerReverse
bool igniter
float fanSpeed
bool aux
}

DEVICE_CONFIG ||--o{ RECIPE : stores
DEVICE_CONFIG ||--|| NET_STATUS : configures
RECIPE ||--|{ RECIPE_STEP : contains
RECIPE_STEP ||--|| ADVANCE_RULE : advances_by
RECIPE ||--o| RESUME_STATE : persisted_as
RECIPE_STEP ||--o| RESUME_STATE : resumes_at
RECIPE ||--o| COOK_STATUS : drives
RECIPE_STEP ||--o| COOK_STATUS : current_step
STATUS_SNAPSHOT ||--|| GRILL_STATUS : includes
STATUS_SNAPSHOT ||--o| COOK_STATUS : includes
STATUS_SNAPSHOT ||--|{ PROBE_READING : includes
STATUS_SNAPSHOT ||--|| NET_STATUS : includes
GRILL_STATUS ||--|| OUTPUT_COMMAND : commands
PROBE_READING ||--o| ADVANCE_RULE : can_satisfy
```

Persistence is intentionally small: `/config.json` stores `DeviceConfig`,
`/recipes/<id>.json` stores each `Recipe` with its ordered steps and advance
rules, and `/resume.json` stores the current recipe/step pointer for reboot
recovery. `GET /api/status` and `<hostname>/state` publish `StatusJson`, which
embeds grill, cook, probe, and network status in one snapshot.

## Hardware

You need a small controller board: an ESP32, an RTD amplifier (MAX31865) for the
Expand Down