Bring bed leveling inboard

This commit is contained in:
Reid D McKenzie 2025-01-28 00:08:22 -07:00
parent 81e60284c0
commit 5dd0694a98
8 changed files with 76 additions and 15 deletions

View file

@ -2,7 +2,7 @@
"""The core app entrypoint."""
from datetime import datetime
from datetime import datetime, timedelta
import logging
from pathlib import Path
import tomllib
@ -46,6 +46,7 @@ def create_j2_request_global(app):
app.jinja_env.globals["ctx"] = ctx
app.jinja_env.globals["request"] = request
app.jinja_env.globals["datetime"] = datetime
app.jinja_env.globals["timedelta"] = timedelta
def user_session():

View file

@ -21,7 +21,7 @@ from aiosql.query_loader import QueryLoader
_sqlite = get_adapter("sqlite3")
_loader = QueryLoader(_sqlite, None)
_queries = Queries(_sqlite)
_queries = Queries(_sqlite, kwargs_only=False)
for f in files("tentacles.sql").iterdir():
if f.is_file() and f.name.endswith(".sql"):
print("Loading", f)

View file

@ -26,6 +26,9 @@ CREATE TABLE IF NOT EXISTS jobs (
, FOREIGN KEY(printer_id) REFERENCES printer(id)
);
-- name: migration-0001-jobs-add-print-time#
ALTER TABLE jobs ADD COLUMN time_left INTEGER DEFAULT (0);
-- name: create-job^
INSERT INTO jobs (
user_id
@ -81,6 +84,7 @@ SELECT
, (SELECT name FROM filament WHERE id = fa.filament_id) AS filament_name
, (SELECT name FROM job_statuses WHERE id = j.status_id) AS status
, j.started_at
, j.time_left
, j.cancelled_at
, j.finished_at
, j.user_id
@ -220,3 +224,10 @@ UPDATE jobs
WHERE
id = :jid
;
-- name: update-job-time-left!
UPDATE jobs
SET time_left = :time_left
WHERE
id = :jid
;

View file

@ -78,6 +78,9 @@ ALTER TABLE printers ADD enabled BOOLEAN DEFAULT TRUE;
-- name: migration-0005-create-printer-nozzle#
ALTER TABLE printers ADD nozzle_diameter FLOAT DEFAULT 0.4;
-- name: migration-0006-create-printer-level-date#
ALTER TABLE printers ADD last_level_date TEXT DEFAULT NULL;
-- name: try-create-printer^
INSERT INTO printers (
name
@ -98,6 +101,7 @@ SELECT
, p.stream_url
, p.api_key
, p.last_poll_date
, p.last_level_date
, p.filament_id
, p.chassis_id
, p.enabled
@ -116,6 +120,7 @@ SELECT
, p.stream_url
, p.api_key
, p.last_poll_date
, p.last_level_date
, s.name as status
, p.enabled
, f.name as filament_name
@ -166,6 +171,14 @@ WHERE
id = :pid
;
-- name: update-printer-level-date!
UPDATE printers
SET
, last_level_date = datetime('now')
WHERE
id = :pid
;
-- name: edit-printer!
UPDATE printers
SET

View file

@ -22,6 +22,14 @@
margin-top: 4px;
}
.div .job {
}
.div .job:not(:last-child) {
border-bottom: none;
}
.file .details,
.printer .details,
.key .details,

View file

@ -25,8 +25,8 @@
{% endif %}
</div>
<div class="controls u-flex u-ml-auto u-mv-auto">
{{ macros.start_job(file.id) }}
{{ macros.download_file(file.id) }}
{{ macros.start_job(file.id) }}
{{ macros.delete_file(file.id) }}
</div>
</div>

View file

@ -10,18 +10,24 @@
<span name="filename">{{ctx.db.fetch_file(ctx.uid, job.file_id).filename or "it's a secret"}}</span>
</div>
{% if job.printer_id %}
<div class="job-printer 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">
<label for="runtime">Runtime</label>
<span name="Runtime">{{ (datetime.utcnow() - datetime.fromisoformat(job.started_at)) }}</span>
</div>
{% else %}
<div class="job-constraint u-flex">
<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>
{{ job.filament_name }}
</div>
@ -29,7 +35,6 @@
<label>Limits</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
</div>
{% endif %}
{% if job.user_id != ctx.uid %}
<div class="job-user u-flex">
<label>Owner</label>
@ -37,7 +42,7 @@
</div>
{% endif %}
</div>
<div class="two columns">
<div class="two columns u-mv-auto">
<div class="job-status u-flex">
<label for="state">Status</label>
<div class="dot {{ macros.job_state(job) }} {{ macros.job_active(job) }} tooltip bottom" data-text="{{ macros.job_state(job) }}" style="--dot-size: 1em;"> </div>

View file

@ -89,10 +89,12 @@ def poll_printers(app: App, db: Db) -> None:
)
if "error" in status:
log.error(f"Printer {printer.id} failed to report bed readiness with {status!r}")
log.error(
f"Printer {printer.id} failed to report bed readiness with {status!r}"
)
return False
similarity = status.get("similarity", 0.0) ** 3 # Cube it
similarity = status.get("similarity", 0.0) ** 3 # Cube it
return similarity > 0.9
printer_job = {}
@ -216,6 +218,21 @@ def push_jobs(app: App, db: Db) -> None:
else:
raise
# FIXME: Time since last job ended?
if last_level_date := printer.last_level_date:
last_level_date = datetime.fromisoformat(last_level_date)
if not last_level_date or (
datetime.utcnow() - last_level_date >= timedela(hours=24)
):
log.info(f"Printer {printer.id} needs to be leveled...")
client.gcode(
[
"G29",
]
)
db.update_printer_level_date(pid=printer.id)
client.select(Path(file.path).name)
client.start()
db.start_job(jid=job.id)
@ -275,6 +292,12 @@ def pull_jobs(app: App, db: Db) -> None:
log.info(f"Job {job.id} has succeeded")
db.finish_job(jid=job.id, state="success")
elif job_state.get("progress", {}).get("completion", 0.0) < 100.0:
time_left = float(
job_state.get("progress", {}).get("printTimeLeft", "3600.0")
)
db.update_job_time_left(jid=job.id, time_left=time_left)
elif printer_state.get("error"):
log.warn(f"Job {job.id} has failed")
db.finish_job(jid=job.id, state="failed")