interface: Support recipe phases next and stop
This commit is contained in:
parent
88324263c9
commit
51ac9d1842
|
@ -44,11 +44,13 @@ class MockPIN(Actuator):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def enable(self, enable=True):
|
def enable(self, enable=True):
|
||||||
print('FAKE ENABLE') if enable else self.disable()
|
pass
|
||||||
|
# print('FAKE ENABLE') if enable else self.disable()
|
||||||
|
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
print('FAKE DISABLE')
|
pass
|
||||||
|
# print('FAKE DISABLE')
|
||||||
|
|
||||||
actuators = {
|
actuators = {
|
||||||
'heater': GPIOPin(
|
'heater': GPIOPin(
|
||||||
|
|
11
app.py
11
app.py
|
@ -88,13 +88,22 @@ def handle_manual_response(response):
|
||||||
def load_recipe_idx(idx):
|
def load_recipe_idx(idx):
|
||||||
statemachine.loadByIdx(idx)
|
statemachine.loadByIdx(idx)
|
||||||
|
|
||||||
|
@socketio.on('stop recipe')
|
||||||
|
def stop_recipe():
|
||||||
|
statemachine.stop()
|
||||||
|
|
||||||
|
@socketio.on('next phase')
|
||||||
|
def next_phase():
|
||||||
|
done = statemachine.next() is None
|
||||||
|
if done:
|
||||||
|
statemachine.done()
|
||||||
|
|
||||||
def run_recipes():
|
def run_recipes():
|
||||||
while True:
|
while True:
|
||||||
while statemachine.recipe is not None:
|
while statemachine.recipe is not None:
|
||||||
done = statemachine.run_step()
|
done = statemachine.run_step()
|
||||||
if done:
|
if done:
|
||||||
statemachine.done()
|
statemachine.done()
|
||||||
updateState()
|
|
||||||
sleep(1)
|
sleep(1)
|
||||||
|
|
||||||
def read_sensors():
|
def read_sensors():
|
||||||
|
|
|
@ -119,7 +119,6 @@ function render_sensors(sensordata) {
|
||||||
}
|
}
|
||||||
data.push({what: what, unit: unit, data: req_data});
|
data.push({what: what, unit: unit, data: req_data});
|
||||||
}
|
}
|
||||||
console.log({sensors:data});
|
|
||||||
html.innerHTML = Mustache.render(template, {sensors:data});
|
html.innerHTML = Mustache.render(template, {sensors:data});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +157,14 @@ function load_recipe() {
|
||||||
socket.emit('load recipe idx', localstate.recipe);
|
socket.emit('load recipe idx', localstate.recipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stop_recipe() {
|
||||||
|
socket.emit('stop recipe');
|
||||||
|
}
|
||||||
|
|
||||||
|
function next_phase() {
|
||||||
|
socket.emit('next phase');
|
||||||
|
}
|
||||||
|
|
||||||
function dismiss_modal() {
|
function dismiss_modal() {
|
||||||
applyState(state);
|
applyState(state);
|
||||||
}
|
}
|
||||||
|
@ -214,6 +221,7 @@ function current_recipe(data) {
|
||||||
html.innerHTML = '';
|
html.innerHTML = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
data.current_phase = data.phases.find(function (p) { return p.current; });
|
||||||
let template = `
|
let template = `
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<header class="card-header">
|
<header class="card-header">
|
||||||
|
@ -230,10 +238,21 @@ function current_recipe(data) {
|
||||||
{{/phases}}
|
{{/phases}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
{{current_phase.text}}
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
Next Cond: {{current_phase.text}}
|
||||||
|
<br/>
|
||||||
|
On Load: {{current_phase.onload}}
|
||||||
|
<br/>
|
||||||
|
On Exit: {{current_phase.onexit}}
|
||||||
</div>
|
</div>
|
||||||
<footer class="card-footer">
|
<footer class="card-footer">
|
||||||
<a class="card-footer-item is-primary">Pause</a>
|
<!-- <a class="card-footer-item is-primary">Pause</a> -->
|
||||||
<a class="card-footer-item">Stop</a>
|
<a onclick="next_phase()"
|
||||||
|
class="card-footer-item">Next Phase</a>
|
||||||
|
<a onclick="stop_recipe()"
|
||||||
|
class="card-footer-item">Stop</a>
|
||||||
</footer>
|
</footer>
|
||||||
</div>`;
|
</div>`;
|
||||||
html.innerHTML = Mustache.render(template, data);
|
html.innerHTML = Mustache.render(template, data);
|
||||||
|
|
17
phasectrl.py
17
phasectrl.py
|
@ -105,6 +105,10 @@ class State():
|
||||||
self.recipe = self.recipes[recipe]
|
self.recipe = self.recipes[recipe]
|
||||||
self.postload()
|
self.postload()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.current_phase().exit(self.env)
|
||||||
|
self.done(message='(concat "Recipe " (recipe-name) " stopped manually")')
|
||||||
|
|
||||||
def loadByName(self, recipe):
|
def loadByName(self, recipe):
|
||||||
r = tuple(i for (i, r) in enumerate(self.recipes) if r.name == recipe)
|
r = tuple(i for (i, r) in enumerate(self.recipes) if r.name == recipe)
|
||||||
if len(r) > 0:
|
if len(r) > 0:
|
||||||
|
@ -161,8 +165,11 @@ class State():
|
||||||
self.onupdate()
|
self.onupdate()
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
def done(self):
|
def done(self, message=None):
|
||||||
self.recipe.done(self.env)
|
self.recipe.done(self.env, message)
|
||||||
|
# Stop all actuators
|
||||||
|
for controller in self.envdata.get('controllers', {}).keys():
|
||||||
|
actuators[controller].disable()
|
||||||
self.recipe = None
|
self.recipe = None
|
||||||
self.env = self.baseenv
|
self.env = self.baseenv
|
||||||
self.envdata = {}
|
self.envdata = {}
|
||||||
|
@ -217,9 +224,9 @@ class Recipe():
|
||||||
# 'phase': self.phase
|
# 'phase': self.phase
|
||||||
}
|
}
|
||||||
|
|
||||||
def done(self, env):
|
def done(self, env, message=None):
|
||||||
safe_eval('(notify (concat "Recipe " (recipe-name) " completed at " (now)))',
|
message = message or '(concat "Recipe " (recipe-name) " completed at " (now))'
|
||||||
env)
|
safe_eval(f'(notify {message})', env)
|
||||||
|
|
||||||
class Phase():
|
class Phase():
|
||||||
def __init__(self, name, text='', nextcond='#t', onload='', onexit=''):
|
def __init__(self, name, text='', nextcond='#t', onload='', onexit=''):
|
||||||
|
|
Loading…
Reference in New Issue