interface: Support recipe phases next and stop

This commit is contained in:
Nicolò Balzarotti 2022-11-19 21:42:54 +01:00
parent 88324263c9
commit 51ac9d1842
4 changed files with 48 additions and 11 deletions

View File

@ -44,11 +44,13 @@ class MockPIN(Actuator):
super().__init__(*args, **kwargs)
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):
print('FAKE DISABLE')
pass
# print('FAKE DISABLE')
actuators = {
'heater': GPIOPin(

11
app.py
View File

@ -88,13 +88,22 @@ def handle_manual_response(response):
def load_recipe_idx(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():
while True:
while statemachine.recipe is not None:
done = statemachine.run_step()
if done:
statemachine.done()
updateState()
sleep(1)
def read_sensors():

25
dist/server.js vendored
View File

@ -119,7 +119,6 @@ function render_sensors(sensordata) {
}
data.push({what: what, unit: unit, data: req_data});
}
console.log({sensors:data});
html.innerHTML = Mustache.render(template, {sensors:data});
}
@ -158,6 +157,14 @@ function load_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() {
applyState(state);
}
@ -214,6 +221,7 @@ function current_recipe(data) {
html.innerHTML = '';
return;
}
data.current_phase = data.phases.find(function (p) { return p.current; });
let template = `
<div class="card">
<header class="card-header">
@ -230,10 +238,21 @@ function current_recipe(data) {
{{/phases}}
</ul>
</div>
{{current_phase.text}}
<br/>
<br/>
Next Cond: {{current_phase.text}}
<br/>
On Load: {{current_phase.onload}}
<br/>
On Exit: {{current_phase.onexit}}
</div>
<footer class="card-footer">
<a class="card-footer-item is-primary">Pause</a>
<a class="card-footer-item">Stop</a>
<!-- <a class="card-footer-item is-primary">Pause</a> -->
<a onclick="next_phase()"
class="card-footer-item">Next Phase</a>
<a onclick="stop_recipe()"
class="card-footer-item">Stop</a>
</footer>
</div>`;
html.innerHTML = Mustache.render(template, data);

View File

@ -105,6 +105,10 @@ class State():
self.recipe = self.recipes[recipe]
self.postload()
def stop(self):
self.current_phase().exit(self.env)
self.done(message='(concat "Recipe " (recipe-name) " stopped manually")')
def loadByName(self, recipe):
r = tuple(i for (i, r) in enumerate(self.recipes) if r.name == recipe)
if len(r) > 0:
@ -161,8 +165,11 @@ class State():
self.onupdate()
return resp
def done(self):
self.recipe.done(self.env)
def done(self, message=None):
self.recipe.done(self.env, message)
# Stop all actuators
for controller in self.envdata.get('controllers', {}).keys():
actuators[controller].disable()
self.recipe = None
self.env = self.baseenv
self.envdata = {}
@ -217,9 +224,9 @@ class Recipe():
# 'phase': self.phase
}
def done(self, env):
safe_eval('(notify (concat "Recipe " (recipe-name) " completed at " (now)))',
env)
def done(self, env, message=None):
message = message or '(concat "Recipe " (recipe-name) " completed at " (now))'
safe_eval(f'(notify {message})', env)
class Phase():
def __init__(self, name, text='', nextcond='#t', onload='', onexit=''):