diff --git a/content/post/smart-rice-cooker.md b/content/post/smart-rice-cooker.md index 066d53a..e6bada5 100644 --- a/content/post/smart-rice-cooker.md +++ b/content/post/smart-rice-cooker.md @@ -2,6 +2,16 @@ title: "Smart Rice Cooker Conversion" date: "2018-06-18" author: "William Floyd" +categories: [ + "Development", + "Hardware", + "Software" +] +tags: [ + "Arduino", + "Rice Cooker", + "Aliexpress" +] --- The "why" isn't important (read "doesn't exist"), but I want to take a regular old "dumb" rice cooker, and convert it into a "smart" rice cooker. @@ -14,7 +24,7 @@ Main list of things: - [Rice cooker](http://ali.onl/128Y) ($26.40 + $3.16 S&H - The star of the show.) - [Thermistors](http://ali.onl/128Q) ($2.97 - 100pcs, for temperature readings) -- [NodeMCU](http://ali.onl/128R) ($2.47 - To, hopefully, allow me to Wifi control the whole thing) +- [NodeMCU](http://ali.onl/128R) ($2.47 - To, hopefully, allow me to WiFi control the whole thing) - [Relay](http://ali.onl/128V) ($0.76 - To switch power on and off.) - [ESP8266 Relay](http://ali.onl/128T) ($2.91 + $0.14 S&H - Alternative to the NodeMCU + Relay pairing I'm planning on using) @@ -24,29 +34,59 @@ Ideally, I will have the rice cooker serve an API, which my Orange Pi will bounc For now though, I am away from home, working, so I can't do anything on this for at least another 2 weeks, probably 3. Many of my parts have arrived (rice cooker, thermistors, relay, and NodeMCU), so once I get home, I can hit the ground running. +# Thoughts + +## Heating + +The contents of the rice cooker should be considered when heating/cooling, as they will absorb the heat and thermal lag will be an issue. +If possible, look into either weighing the contents for a rough approximation (hard/complicated) or use recipe provided portion sizes to calculate the thermal capacity of the contents (water, mainly). + # API -I tentatively (with no real experience designing them) plan on my API being the following. +I tentatively (with no real experience designing them) plan on my API being something like the following. *Italicized* = Description -**Bolded** = Final endpoints -- /sensor - - /temperature - - *Returns temperature* -- /action - - *Contains all physical heating/cooling/moving actions* - - /temperature - - *Contains all temperature related actions* - - **/kill** - - *Stops all cooking, lets the cooker cool to room temperature* - - **/change** - - *Heat/cool to given temperature, then hold* - - *Should allow setting a target heat/cool rate* - - *Should allow setting a hold duration* -- /routine - - /cook - - **/list** - - *List known cooking routines* - - **/start** - - *Start a routine, optionally at a scheduled time* +- /sensor/temperature - *Returns temperature* +- /action/light/kill - *Stops all light activity* +- /action/light/set - *Change lighting mode, with optional duration* +- /action/temperature/kill - *Stops all heating/cooling, lets the cooker cool to room temperature alone* +- /action/temperature/set - *Heat/cool to given temperature, then hold. Should allow setting a target heat/cool rate. Should allow setting a hold duration* +- /routine/cook/list - *List known cooking routines (proxy to `/settings/cook/recipe/list`)* +- /routine/cook/start - *Start a routine* +- /routine/cook/kill - *Kill any current running routine* +- /routine/cook/schedule/list - *List any scheduled routines* +- /routine/cook/schedule/set - *Submit/modify/delete a scheduled routine* +- /settings/lighting/list - *List lighting modes* +- /settings/lighting/set - *Submit/modify/delete a lighting mode* +- /settings/cook/warm/temperature - *Set post-cook warming temperature* +- /settings/cook/warm/set - *Turn post-cook warming on/off* +- /settings/cook/warm/duration - *Determine post-cook warming duration* +- /settings/cook/recipe/list - *List known cooking routines* +- /settings/cook/recipe/set - *Submit/modify/delete a cooking routine* + +# Cooking schedule definition specifications + +Directives are distinct actions to be taken. + +They include: + +### Sleep +Just wait for given duration, or until a given condition is met. + +### Heat +Heat for a given duration, or until a given condition is met. + +### Cool +If I someday choose to use a fan, this should be an active feature. +Instead, it's the same as `Sleep` for now. + +### Temperature +Heat/cool to given temperature, optionally at a given rate of change (may be difficult for cooling if no fan is included). +This should just be a proxy directive to `Heat`, `Cool`, and `Sleep`. +For now that should work, but in due course, with tuning and benchmarks, this should run cooling at a variable rate. +Heating should be fine be fine with fairly large PWM, as the thermal lag I expect to be significant, and we want to try to hit our deadline as quickly as possible. + +# Dep Graph + + diff --git a/src/build.sh b/src/build.sh new file mode 100755 index 0000000..e25fab3 --- /dev/null +++ b/src/build.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +sed -e 's/\[depend_value\]/[color=blue]/' \ +-e 's/\[proxy_value\]/\[color=deepskyblue\]/' \ +-e 's/\[proxy_function\]/\[color=dodgerblue\]/' \ +-e 's/\[documented\]/\[fillcolor=darkolivegreen1\]/' \ +-e 's/\[done\]/\[fillcolor=chartreuse\]/' \ +-e 's/\[depend_function\]/\[color=cornflowerblue\]/' connections.dot | fdp -Ln5 -Tsvg > '../static/connections.svg' + +exit diff --git a/src/connections.dot b/src/connections.dot new file mode 100644 index 0000000..c10e315 --- /dev/null +++ b/src/connections.dot @@ -0,0 +1,173 @@ +digraph { + overlap=false + center=true + splines=true + sep="0.05" + node [style=filled, shape=record, color="black" fillcolor="tomato" ] + + subgraph cluster_key { + + node [fillcolor="none"] + + subgraph cluster_doc { + "Done"[done] + "Documented"[documented] + "Undocumented"[fillcolor="tomato"] + } + + subgraph cluster_sub { + + "Depend on value" + "Proxy to value" + "Depend on function" + + } + + "Depend on value" -> "Node"[depend_value] + "Proxy to value" -> "Node"[proxy_value] + "Depend on function" -> "Node"[depend_function] + + label="Key" + + } + + subgraph cluster_directives { + + "Sleep" + "Heat" + "Cool" + "Temperature" + label="Directives" + + } + + subgraph cluster_api { + + subgraph cluster_action { + + subgraph cluster_light { + + "/api/action/light/kill"[label="kill"] + "/api/action/light/set"[label="set"] + + label="light" + + } + + subgraph cluster_temperature { + + "/api/action/temperature/kill"[label="kill"] + "/api/action/temperature/set"[label="set"] + + label="temperature" + + } + + label="action" + } + + subgraph cluster_sensor { + + "/api/sensor/temperature"[label="temperature"] + + label="sensor" + + } + + subgraph cluster_routine { + + subgraph cluster_routine_cook { + + "/api/routine/cook/list"[label="list"] + "/api/routine/cook/start"[label="start"] + "/api/routine/cook/kill"[label="kill"] + + subgraph cluster_schedule { + + "/api/routine/cook/schedule/list"[label="list"] + "/api/routine/cook/schedule/set"[label="set"] + + label="schedule" + } + + label="cook" + } + + label="routine" + } + + subgraph cluster_settings { + + subgraph cluster_lighting { + + "/api/settings/lighting/list"[label="list"] + "/api/settings/lighting/set"[label="set"] + + label="lighting" + + } + + subgraph cluster_settings_cook { + + subgraph cluster_warm { + + "/api/settings/cook/warm/temperature"[label="temperature"] + "/api/settings/cook/warm/set"[label="set"] + "/api/settings/cook/warm/duration"[label="duration"] + + label="warm" + + } + + subgraph cluster_recipe { + + "/api/settings/cook/recipe/list"[label="list"] + "/api/settings/cook/recipe/set"[label="set"] + + label="recipe" + + } + + label="cook" + + } + + label="settings" + + } + + label="api" + } + + "Temperature" -> { "Heat" "Cool" "Sleep" }[depend_function] + "/api/routine/cook/list" -> "/api/settings/cook/recipe/list"[proxy_value] + +// Description checklist /////////////////////////////////////////////////////// + +"/api/sensor/temperature"[documented] +"/api/action/light/kill"[documented] +"/api/action/light/set"[documented] +"/api/action/temperature/kill"[documented] +"/api/action/temperature/set"[documented] +"/api/routine/cook/list"[documented] +"/api/routine/cook/start"[documented] +"/api/routine/cook/kill"[documented] +"/api/routine/cook/schedule/list"[documented] +"/api/routine/cook/schedule/set"[documented] +"/api/settings/lighting/list"[documented] +"/api/settings/lighting/set"[documented] +"/api/settings/cook/warm/temperature"[documented] +"/api/settings/cook/warm/set"[documented] +"/api/settings/cook/warm/duration"[documented] +"/api/settings/cook/recipe/list"[documented] +"/api/settings/cook/recipe/set"[documented] + +"Temperature"[documented] +"Heat"[documented] +"Cool"[documented] +"Sleep"[documented] + +//////////////////////////////////////////////////////////////////////////////// + + +} diff --git a/static/connections.svg b/static/connections.svg new file mode 100644 index 0000000..76bc33c --- /dev/null +++ b/static/connections.svg @@ -0,0 +1,306 @@ + + + + + + +%3 + + +cluster_key + +Key + + +cluster_doc + + + +cluster_sub + + + +cluster_directives + +Directives + + +cluster_api + +api + + +cluster_action + +action + + +cluster_light + +light + + +cluster_temperature + +temperature + + +cluster_sensor + +sensor + + +cluster_routine + +routine + + +cluster_routine_cook + +cook + + +cluster_schedule + +schedule + + +cluster_settings + +settings + + +cluster_lighting + +lighting + + +cluster_settings_cook + +cook + + +cluster_warm + +warm + + +cluster_recipe + +recipe + + + +Done + +Done + + + +Documented + +Documented + + + +Undocumented + +Undocumented + + + +Depend on value + +Depend on value + + + +Node + +Node + + + +Depend on value->Node + + + + + +Proxy to value + +Proxy to value + + + +Proxy to value->Node + + + + + +Depend on function + +Depend on function + + + +Depend on function->Node + + + + + +Sleep + +Sleep + + + +Heat + +Heat + + + +Cool + +Cool + + + +Temperature + +Temperature + + + +Temperature->Sleep + + + + + +Temperature->Heat + + + + + +Temperature->Cool + + + + + +/api/action/light/kill + +kill + + + +/api/action/light/set + +set + + + +/api/action/temperature/kill + +kill + + + +/api/action/temperature/set + +set + + + +/api/sensor/temperature + +temperature + + + +/api/routine/cook/list + +list + + + +/api/settings/cook/recipe/list + +list + + + +/api/routine/cook/list->/api/settings/cook/recipe/list + + + + + +/api/routine/cook/start + +start + + + +/api/routine/cook/kill + +kill + + + +/api/routine/cook/schedule/list + +list + + + +/api/routine/cook/schedule/set + +set + + + +/api/settings/lighting/list + +list + + + +/api/settings/lighting/set + +set + + + +/api/settings/cook/warm/temperature + +temperature + + + +/api/settings/cook/warm/set + +set + + + +/api/settings/cook/warm/duration + +duration + + + +/api/settings/cook/recipe/set + +set + + +