Color and continuous printing

This commit is contained in:
Reid D McKenzie 2025-02-07 23:59:32 -07:00
parent 35ae07d7e3
commit 8712ddc377
6 changed files with 81 additions and 59 deletions

View file

@ -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

View file

@ -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,

View file

@ -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^

View file

@ -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">

View file

@ -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 %}

View file

@ -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(
"""\ """\