Color and continuous printing
This commit is contained in:
parent
35ae07d7e3
commit
8712ddc377
6 changed files with 81 additions and 59 deletions
|
@ -119,6 +119,7 @@ def create_file(location: Optional[str] = None):
|
||||||
fid=row.id,
|
fid=row.id,
|
||||||
cid=None,
|
cid=None,
|
||||||
pid=None,
|
pid=None,
|
||||||
|
cont=False, # FIXME: How to decide this?
|
||||||
)
|
)
|
||||||
|
|
||||||
return {"status": "ok"}, 202
|
return {"status": "ok"}, 202
|
||||||
|
|
|
@ -39,17 +39,20 @@ def manipulate_jobs():
|
||||||
fid=int(request.form.get("file_id")),
|
fid=int(request.form.get("file_id")),
|
||||||
cid=maybe(int, request.form.get("color_id")),
|
cid=maybe(int, request.form.get("color_id")),
|
||||||
pid=maybe(int, request.form.get("printer_id")),
|
pid=maybe(int, request.form.get("printer_id")),
|
||||||
|
cont=request.form.get("continuous") == "on",
|
||||||
)
|
)
|
||||||
flash("Job created!", category="info")
|
flash("Job created!", category="info")
|
||||||
|
|
||||||
case "duplicate":
|
case "duplicate":
|
||||||
if job := ctx.db.fetch_job(
|
if job := ctx.db.fetch_job(
|
||||||
uid=ctx.uid, jid=int(request.form.get("job_id"))
|
uid=ctx.uid,
|
||||||
|
jid=int(request.form.get("job_id")),
|
||||||
):
|
):
|
||||||
ctx.db.create_job(
|
ctx.db.create_job(
|
||||||
uid=ctx.uid,
|
uid=ctx.uid,
|
||||||
fid=job.file_id,
|
fid=job.file_id,
|
||||||
cid=job.color_id,
|
cid=job.color_id,
|
||||||
|
cont=job.continuous,
|
||||||
# FIXME: Need to dissociate job copies from the original mapped printer. Can't tell the difference
|
# FIXME: Need to dissociate job copies from the original mapped printer. Can't tell the difference
|
||||||
# between the requested printer in the original job and the mapped printer from a scheduler run.
|
# between the requested printer in the original job and the mapped printer from a scheduler run.
|
||||||
pid=None,
|
pid=None,
|
||||||
|
|
|
@ -27,10 +27,13 @@ CREATE TABLE IF NOT EXISTS jobs (
|
||||||
);
|
);
|
||||||
|
|
||||||
-- name: migration-0001-jobs-add-print-time#
|
-- name: migration-0001-jobs-add-print-time#
|
||||||
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS time_left INTEGER DEFAULT (0);
|
ALTER TABLE jobs ADD COLUMN time_left INTEGER DEFAULT (0);
|
||||||
|
|
||||||
-- name: migration-0002-jobs-add-print-color#
|
-- name: migration-0002-jobs-add-print-color#
|
||||||
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS color_id INTEGER DEFAULT (NULL);
|
ALTER TABLE jobs ADD COLUMN color_id INTEGER DEFAULT (NULL);
|
||||||
|
|
||||||
|
-- name: migration-0003-jobs-add-continuous#
|
||||||
|
ALTER TABLE jobs ADD COLUMN continuous BOOLEAN DEFAULT (FALSE);
|
||||||
|
|
||||||
-- name: create-job^
|
-- name: create-job^
|
||||||
INSERT INTO jobs (
|
INSERT INTO jobs (
|
||||||
|
@ -38,12 +41,14 @@ INSERT INTO jobs (
|
||||||
, file_id
|
, file_id
|
||||||
, color_id
|
, color_id
|
||||||
, printer_id
|
, printer_id
|
||||||
|
, continuous
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
:uid
|
:uid
|
||||||
, :fid
|
, :fid
|
||||||
, :cid
|
, :cid
|
||||||
, :pid
|
, :pid
|
||||||
|
, :cont
|
||||||
)
|
)
|
||||||
RETURNING
|
RETURNING
|
||||||
*
|
*
|
||||||
|
@ -78,36 +83,46 @@ WHERE
|
||||||
|
|
||||||
-- name: list-job-queue
|
-- name: list-job-queue
|
||||||
SELECT
|
SELECT
|
||||||
j.id as id
|
*
|
||||||
, j.file_id
|
FROM (
|
||||||
, coalesce(j.color_id, fa.color_id) as color_id
|
SELECT
|
||||||
, fa.id as analysis_id
|
j.id as id
|
||||||
, fa.max_x
|
, j.file_id
|
||||||
, fa.max_y
|
, coalesce(j.color_id, fa.color_id) as color_id
|
||||||
, fa.max_z
|
, fa.id as analysis_id
|
||||||
, fa.max_bed
|
, fa.max_x
|
||||||
, fa.max_end
|
, fa.max_y
|
||||||
, fa.nozzle_diameter
|
, fa.max_z
|
||||||
, fa.filament_id
|
, fa.max_bed
|
||||||
, (SELECT name FROM filament WHERE id = fa.filament_id) AS filament_name
|
, fa.max_end
|
||||||
, (SELECT name AS name FROM filament_color WHERE id = coalesce(j.color_id, fa.color_id)) AS color_name
|
, fa.nozzle_diameter
|
||||||
, (SELECT name FROM job_statuses WHERE id = j.status_id) AS status
|
, fa.filament_id
|
||||||
, j.started_at
|
, (SELECT name FROM filament WHERE id = fa.filament_id) AS filament_name
|
||||||
, j.time_left
|
, (SELECT name AS name FROM filament_color WHERE id = coalesce(j.color_id, fa.color_id)) AS color_name
|
||||||
, j.cancelled_at
|
, j.status_id
|
||||||
, j.finished_at
|
, (SELECT name FROM job_statuses WHERE id = j.status_id) AS status
|
||||||
, j.user_id
|
, j.started_at
|
||||||
, j.printer_id
|
, j.time_left
|
||||||
FROM jobs j
|
, j.cancelled_at
|
||||||
INNER JOIN files f
|
, j.finished_at
|
||||||
ON j.file_id = f.id
|
, j.user_id
|
||||||
LEFT JOIN file_analysis fa
|
, j.printer_id
|
||||||
ON fa.file_id = f.id
|
, j.continuous
|
||||||
WHERE
|
FROM jobs j
|
||||||
finished_at IS NULL
|
INNER JOIN files f
|
||||||
AND cancelled_at IS NULL
|
ON j.file_id = f.id
|
||||||
AND (:uid IS NULL OR j.user_id = :uid)
|
LEFT JOIN file_analysis fa
|
||||||
AND f.id IS NOT NULL
|
ON fa.file_id = f.id
|
||||||
|
WHERE
|
||||||
|
finished_at IS NULL
|
||||||
|
AND cancelled_at IS NULL
|
||||||
|
AND (:uid IS NULL OR j.user_id = :uid)
|
||||||
|
AND f.id IS NOT NULL
|
||||||
|
)
|
||||||
|
ORDER BY
|
||||||
|
status_id DESC
|
||||||
|
, continuous DESC
|
||||||
|
, id
|
||||||
;
|
;
|
||||||
|
|
||||||
-- name: poll-job-queue^
|
-- name: poll-job-queue^
|
||||||
|
|
|
@ -9,32 +9,14 @@
|
||||||
<label for="filename">File</label>
|
<label for="filename">File</label>
|
||||||
<span name="filename">{{ctx.db.fetch_file(ctx.uid, job.file_id).filename or "it's a secret"}}</span>
|
<span name="filename">{{ctx.db.fetch_file(ctx.uid, job.file_id).filename or "it's a secret"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{% if job.printer_id %}
|
<div class="job-constraint u-flex">
|
||||||
<div class="job-printer u-flex u-flex-break">
|
|
||||||
<label for="printer">Printer</label>
|
|
||||||
<span name="printer">{{ ctx.db.fetch_printer(job.printer_id).name }}</span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if job.started_at %}
|
|
||||||
<div class="job-runtime u-flex u-flex-break">
|
|
||||||
<label for="runtime">Runtime</label>
|
|
||||||
<span name="Runtime">{{ (datetime.utcnow() - datetime.fromisoformat(job.started_at)) }}</span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if job.time_left > 0 %}
|
|
||||||
<div class="job-remaining-time u-flex u-flex-break">
|
|
||||||
<label for="remaining-time">Remaining time</label>
|
|
||||||
<span name="remaining-time">{{ timedelta(seconds=job.time_left) }}</span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="job-constraint u-flex u-flex-break">
|
|
||||||
<label>Material</label>
|
<label>Material</label>
|
||||||
{{ job.color_name }}
|
{{ job.color_name }}
|
||||||
{{ job.filament_name }}
|
{{ job.filament_name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="job-constraint u-flex u-flex-break">
|
<div class="job-cont u-flex">
|
||||||
<label>Limits</label>
|
<label>Continuous</label>
|
||||||
{{ job.max_x }}mm x{{ job.max_y }}mm x{{ job.max_z }}mm, bed {{ job.max_bed }}c, end {{ job.max_end }}c, nozzle {{ "%.2f"|format(job.nozzle_diameter) }}mm
|
{% if job.continuous == 1 %}True{% else %}False{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if job.user_id != ctx.uid %}
|
{% if job.user_id != ctx.uid %}
|
||||||
<div class="job-user u-flex">
|
<div class="job-user u-flex">
|
||||||
|
@ -42,6 +24,24 @@
|
||||||
{{ ctx.db.fetch_user(uid=job.user_id).name }}
|
{{ ctx.db.fetch_user(uid=job.user_id).name }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if job.printer_id %}
|
||||||
|
<div class="job-printer u-flex">
|
||||||
|
<label for="printer">Printer</label>
|
||||||
|
<span name="printer">{{ ctx.db.fetch_printer(job.printer_id).name }}</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if job.started_at %}
|
||||||
|
<div class="job-runtime u-flex">
|
||||||
|
<label for="runtime">Runtime</label>
|
||||||
|
<span name="Runtime">{{ (datetime.utcnow() - datetime.fromisoformat(job.started_at)) }}</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if job.time_left > 0 %}
|
||||||
|
<div class="job-remaining-time u-flex">
|
||||||
|
<label for="remaining-time">Remaining time</label>
|
||||||
|
<span name="remaining-time">{{ timedelta(seconds=job.time_left) }}</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="two columns u-mv-auto">
|
<div class="two columns u-mv-auto">
|
||||||
<div class="job-status u-flex">
|
<div class="job-status u-flex">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{# #################################################################################################### #}
|
{# #################################################################################################### #}
|
||||||
{# Job CRUD #}
|
{# Job CRUD #}
|
||||||
{% macro start_job(file) %}
|
{% macro start_job(file) %}
|
||||||
<form class="inline" method="post" action="/jobs">
|
<form class="start-menu inline u-flex" method="post" action="/jobs">
|
||||||
<input type="hidden" name="action" value="enqueue" />
|
<input type="hidden" name="action" value="enqueue" />
|
||||||
<input type="hidden" name="file_id" value="{{ file.id }}" />
|
<input type="hidden" name="file_id" value="{{ file.id }}" />
|
||||||
<select name="color_id">
|
<select name="color_id">
|
||||||
|
@ -9,7 +9,11 @@
|
||||||
<option value="{{c.id}}" {% if file.color_id == c.id %}selected{%endif%}>{{c.name}}</option>
|
<option value="{{c.id}}" {% if file.color_id == c.id %}selected{%endif%}>{{c.name}}</option>
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
</select>
|
</select>
|
||||||
<input id="submit" type="image" src="/static/print.svg" height="24" width="24" />
|
<div class="u-flex u-ml-auto u-mv-auto u-flex u-ml-1">
|
||||||
|
<label class="u-flex u-mv-auto" for="continuous">Cont.</label>
|
||||||
|
<input class="u-flex u-mv-auto" type="checkbox" name="continuous" false>
|
||||||
|
</div>
|
||||||
|
<input id="submit" type="image" src="/static/print.svg" height="24" width="24" />
|
||||||
</form>
|
</form>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
|
@ -270,8 +270,7 @@ def pull_jobs(app: App, db: Db) -> None:
|
||||||
if runtime >= timedelta(seconds=15): # 3 polling cycles
|
if runtime >= timedelta(seconds=15): # 3 polling cycles
|
||||||
log.info(f"Job {job.id} has succeeded")
|
log.info(f"Job {job.id} has succeeded")
|
||||||
|
|
||||||
# Attempt to automatically clear the bed
|
if job.continuous:
|
||||||
if False:
|
|
||||||
log.info(f"Attempting to clear bed of {printer.id} ({printer.url})")
|
log.info(f"Attempting to clear bed of {printer.id} ({printer.url})")
|
||||||
client.gcode(
|
client.gcode(
|
||||||
"""\
|
"""\
|
||||||
|
|
Loading…
Reference in a new issue