diff --git a/__pycache__/app.cpython-310.pyc b/__pycache__/app.cpython-310.pyc index 596867e..e7432ba 100644 Binary files a/__pycache__/app.cpython-310.pyc and b/__pycache__/app.cpython-310.pyc differ diff --git a/app.py b/app.py index 84317a1..7cd80d8 100644 --- a/app.py +++ b/app.py @@ -226,6 +226,7 @@ def init_db(): ('ical_token',''), ('ha_url',''), ('ha_token',''), + ('ha_poll_interval','60'), ] conn.executemany('INSERT OR IGNORE INTO settings VALUES (?,?)', defaults) @@ -1303,8 +1304,11 @@ def job_detail(id): return redirect(url_for('jobs')) import math as _math total_plates_needed = _math.ceil((job['order_qty'] or 1) / max(1, job['pieces_per_plate'] or 1)) + _s = get_settings() + ha_poll_interval = int(_s.get('ha_poll_interval', 60)) return render_template('job_detail.html', job=job, slots=slots, - total_plates_needed=total_plates_needed) + total_plates_needed=total_plates_needed, + ha_poll_interval=ha_poll_interval) @app.route('/jobs//delete', methods=['POST']) def delete_job(id): @@ -1716,7 +1720,8 @@ def _check_capacity(conn, start_dt, end_dt, max_printers, exclude_id=None): """ q = """SELECT planned_start, planned_end FROM print_slots WHERE status NOT IN ('cancelled','failed','done') - AND planned_start < ? AND planned_end > ?""" + AND planned_start < ? AND planned_end > ? + AND planned_end > datetime('now')""" params = [end_dt.isoformat(), start_dt.isoformat()] if exclude_id: q += ' AND id != ?' @@ -1752,7 +1757,8 @@ def _check_overlap(conn, printer_id, start_dt, end_dt, exclude_id=None): FROM print_slots ps JOIN jobs j ON ps.job_id=j.id WHERE ps.printer_id=? AND ps.status NOT IN ('cancelled','failed','done') - AND ps.planned_start < ? AND ps.planned_end > ?""" + AND ps.planned_start < ? AND ps.planned_end > ? + AND ps.planned_end > datetime('now')""" params = [printer_id, end_dt.isoformat(), start_dt.isoformat()] if exclude_id: q += ' AND ps.id != ?' @@ -2063,7 +2069,14 @@ def _start_ha_poll(): time.sleep(10) while True: _ha_sync_once() - time.sleep(120) + try: + _c = sqlite3.connect(DATABASE, timeout=5) + _c.row_factory = sqlite3.Row + _interval = int(_c.execute("SELECT value FROM settings WHERE key='ha_poll_interval'").fetchone()['value']) + _c.close() + except Exception: + _interval = 60 + time.sleep(max(10, _interval)) t = threading.Thread(target=_loop, daemon=True, name='ha-poll') t.start() diff --git a/templates/calendar_blocks.html b/templates/calendar_blocks.html index da40b4a..2d7f863 100644 --- a/templates/calendar_blocks.html +++ b/templates/calendar_blocks.html @@ -14,9 +14,15 @@
Ajouter une exception
-
- - +
+
+ + +
+
+ + +
@@ -55,12 +61,17 @@ {% if blocks %} - + {% for b in blocks %} - +
DateTypeMachineNote
PériodeTypeMachineNote
{{ b.date }} + {{ b.date }} + {% if b.date_end and b.date_end != b.date %} + {{ b.date_end }} + {% endif %} + {% if b.type == 'off' %}Off {% elif b.type == 'tt' %}TT @@ -89,3 +100,14 @@ {% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/templates/job_detail.html b/templates/job_detail.html index ede3bda..7326eeb 100644 --- a/templates/job_detail.html +++ b/templates/job_detail.html @@ -385,6 +385,129 @@ + +{% set plates_done = slots | selectattr('status','in',['done']) | list | length %} +{% set plates_running = slots | selectattr('status','equalto','running') | list | length %} +{% set plates_planned = slots | selectattr('status','in',['planned','running']) | list | length %} +{% set plates_total = slots | rejectattr('status','in',['cancelled']) | list | length %} +{% set missing_plates = [total_plates_needed - plates_total, 0] | max %} + +
+
+
+
+ Plateaux d'impression +
+ {% if total_plates_needed > 1 %} + + {{ plates_done }}/{{ total_plates_needed }} terminé{{ 's' if plates_done > 1 else '' }} + + {% endif %} + {% if missing_plates > 0 %} + + {{ missing_plates }} plateau{{ 'x' if missing_plates > 1 else '' }} à planifier + + {% endif %} + + Planning + +
+
+ + {% if slots %} +
+ + + + + + + + + + + + {% for s in slots %} + {% if s.status != 'cancelled' %} + + + + + + + + {% if s.status == 'running' and s.ha_entity_prefix %} + + + + {% endif %} + {% endif %} + {% endfor %} + +
#DébutMachinePiècesStatut / Progression
{{ loop.index }}{{ s.planned_start[:16].replace('T',' ') }}{{ s.printer_name }} + {% set ep = s.effective_pieces %} + {% set ig = s.pieces_ignored %} + {% if ig > 0 %} + {{ ep - ig }}/{{ ep }} + ({{ ig }} ignorée{{ 's' if ig > 1 }}) + {% else %}{{ ep }}{% endif %} + + {% set sc = {'planned':'secondary','running':'primary','done':'success','failed':'danger'} %} + {% set sl = {'planned':'Planifié','running':'En cours','done':'Terminé','failed':'Échec'} %} + {{ sl.get(s.status, s.status) }} + {% if s.status == 'running' and s.ha_entity_prefix %} + + + + {% endif %} + {% if s.failure_note %}
{{ s.failure_note }}{% endif %} +
+
+
+
+
+
+
+ {% else %} +
+ Aucun créneau planifié. +
+ Aller au planning + +
+ {% endif %} + + {% if total_plates_needed > 1 %} + + {% endif %} +
+
+
+