Extend control support to refrigerator, modify recipes accordingly.

Also, update yogurt recipe to support freezer
master
Nicolò Balzarotti 2023-02-25 10:56:13 +01:00
parent c29b3d49cf
commit 256df00325
3 changed files with 53 additions and 44 deletions

View File

@ -7,6 +7,13 @@ class FixedDutyCycle(controllers.Controller):
self.start = kwargs.pop('start_time', perf_counter())
self.period = kwargs.pop('period')
self.set_duty(kwargs.pop('duty_perc'))
operator = kwargs.pop('operator', '<')
functions = {
'<': lambda (a, b): a < b,
'>': lambda (a, b): a > b,
'==': lambda (a, b): a == b,
}
self.operator = functions[operator]
super().__init__(*args, **kwargs)
self.last_time = None
self.total_failed_read = 0
@ -42,7 +49,7 @@ class FixedDutyCycle(controllers.Controller):
return False
self.failed_read = 0
return (self.timepoint() < self.duty) if (
self.input < self.target) else False
self.operator(self.input, self.target)) else False
# 0. refractary_period is fixed (e.g. 30s, depends on the hardware)
@ -57,9 +64,10 @@ class FixedDutyCycle(controllers.Controller):
# HOW LONG MUST BE THE HISTORY?
def fixed_duty_wrapper(args):
name, duty, period = stringify(args.car, quote=False), args.cdr.car, args.cdr.cdr.car
print('name, duty, period', name, duty*100, period)
name, duty, period, op = stringify(
args.car, quote=False), args.cdr.car, args.cdr.cdr.car, args.cdr.cdr.cdr.car
print('name, duty, period, operation', name, duty*100, period, op)
return (name, FixedDutyCycle(
target=None, # reach_period_s=60*60,
duty_perc=duty*100, period=period,
start_time=perf_counter()))
start_time=perf_counter(), operator=op))

View File

@ -10,7 +10,7 @@ from actuators import actuators
from utils import consumption_diff, consumption_to_string, stohms
MY_GLOBAL_ENV = (
_('make-duty-controller', 3, fixed_duty_wrapper,
_('make-duty-controller', 4, fixed_duty_wrapper,
_('format-time', 1, lambda x: stohms(x.car),
GLOBAL_ENV)))

View File

@ -3,8 +3,8 @@
"name": "Koji Rice (MISO)",
"description": "Tiene riso alla temperatura e umidità giuste per il koji",
"controllers": [
"(make-duty-controller \"heater\" 0.40 60)",
"(make-duty-controller \"humidifier\" 0.80 100)"
"(make-duty-controller \"heater\" 0.40 60 '<)",
"(make-duty-controller \"humidifier\" 0.10 100 '<)"
],
"phases": [
{
@ -62,7 +62,7 @@
"name": "Tepache",
"description": "Tiene il tepache a ~23 gradi",
"controllers": [
"(make-duty-controller \"heater\" 0.20 120)"
"(make-duty-controller \"heater\" 0.20 120 '<)"
],
"phases": [
{
@ -78,7 +78,7 @@
"name": "Stracchino",
"description": "Tiene lo stracchino a ~35 gradi per 24 ore",
"controllers": [
"(make-duty-controller \"heater\" 0.80 120)"
"(make-duty-controller \"heater\" 0.80 120 '<)"
],
"phases": [
{
@ -90,48 +90,49 @@
}
]
},
{
"name": "Yogurt",
"description": "Pastorizza lo yogurt a 82 gradi, lascia raffreddare per fare l'inoculo, mantiene a 42 gradi fino a che è pronto.",
"controllers": [
"(make-duty-controller \"heater\" 0.20 120)"
],
"phases": [
{
"name": "Riscalda",
"description": "Preheat yogurt to 82°C",
"exit_condition": "(and (>= (get-sensor \"T_food\") 81.5)\n(> (time-in-this-phase) (minutes 15)))",
"on_load": "(begin (set-controller \"heater\" \"T_food\")\n(set-target \"T_food\" 82.0))",
"on_exit": "#t"
{
"name": "Yogurt",
"description": "Lascia raffreddare lo yogurt per fare l'inoculo, mantiene a 42 gradi fino a che è pronto, e poi porta a 4 gradi.",
"controllers": [
"(make-duty-controller \"heater\" 0.20 120 '<)"
"(make-duty-controller \"freezer\" 0.20 120 '>)"
],
"phases": [
{
"name": "Cool",
"description": "Cool to 46°C",
"exit_condition": "(and (< (get-sensor \"T_food\") 46.0)\n(> (get-sensor \"T_food\") 42.0))",
"on_load": "(begin (set-controller \"heater\" \"T_food\") (set-target \"T_food\" 46.0) (set-controller \"freezer\" \"T_ext\") (set-target \"T_ext\" 46.0))",
"on_exit": "#t"
},
{
"name": "Cool",
"description": "Cool to 46°C",
"exit_condition": "(and (< (get-sensor \"T_food\") 46.0)\n(> (get-sensor \"T_food\") 42.0))",
"on_load": "(set-target \"T_food\" 46.0)",
"on_exit": "#t"
{
"name": "Inoculate (backslopping)",
"description": "Add 50ml Yogurt",
"exit_condition": "(manual-intervention \"Inocula 50g di yogurt\" '((\"Fatto\" #t)))",
"on_load": "(notify \"Inoculate 50g of yogurt NOW!\")",
"on_exit": "(notify (concat \"Inoculated at \" (now)))"
},
{
"name": "Inoculate (backslopping)",
"description": "Add 50ml Yogurt",
"exit_condition": "(manual-intervention \"Inocula 50g di yogurt\" '((\"Fatto\" #t)))",
"on_load": "(notify \"Inoculate 50g of yogurt NOW!\")",
"on_exit": "(notify (concat \"Inoculated at \" (now)))"
{
"name": "Hold",
"description": "Keep at 42°C for 3h",
"exit_condition": "(> (time-in-this-phase) (hours 3))",
"on_load": "(begin (set-target \"T_food\" 41.0) (set-target \"T_ext\" 41.0))",
"on_exit": "(notify \"You can remove the yogurt from the heater\")"
},
{
"name": "Hold",
"description": "Keep at 42°C for 3h",
"exit_condition": "(> (time-in-this-phase) (hours 3))",
"on_load": "(set-target \"T_food\" 41.0)",
"on_exit": "(notify \"You can remove the yogurt from the heater\")"
{
"name": "Refrigerate",
"description": "Lower temperature to 4gradi",
"exit_condition": "#f",
"on_load": "(begin (set-target \"T_food\" 4.0) (set-target \"T_ext\" 4.0))",
"on_exit": "(notify \"You can remove the yogurt from the heater\")"
}
]
]
},
{
"name": "Nattō",
"description": "FIXME",
"controllers": [
"(make-duty-controller \"heater\" 0.20 120)"
"(make-duty-controller \"heater\" 0.20 120 '<)"
],
"phases": []
},
@ -139,7 +140,7 @@
"name": "Tempeh",
"description": "FIXME",
"controllers": [
"(make-duty-controller \"heater\" 0.20 120)"
"(make-duty-controller \"heater\" 0.20 120 '<)"
],
"phases": []
},
@ -147,7 +148,7 @@
"name": "Gorgonzola",
"description": "FIXME",
"controllers": [
"(make-duty-controller \"heater\" 0.20 120)"
"(make-duty-controller \"heater\" 0.20 120 '<)"
],
"phases": []
}