Files
ske087 bff6d70b17 Initial commit: aplicatie de cantarire si etichetare
Aplicatie Flask + SQLite pentru productie alimentara: cantarirea
componentelor unui produs finit si tiparirea etichetei prin QZ Tray.

- produse finite (retete) formate din componente cantarite
- designer vizual de etichete (mm/px, zona sigura, campuri variabile,
  cod QR cu continut din mai multe bucati)
- legare produs finit -> sablon de eticheta
- navigare pe doua taburi: Cantarire / Setari
- administrare: componente, produse finite, sabloane, campuri, istoric
- backup, resetare baza de date, checklist de pregatire, /healthz
- CLI de administrare si serviciu systemd pentru productie
- vendor/syncpulse-scale-bridge (GPL-3.0-or-later) pentru citirea cantarului
2026-10-18 23:38:45 +03:00

171 lines
6.2 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}Monitor serial{% endblock %}
{% block content %}
<section class="page-head">
<div>
<h1>Monitor serial</h1>
<p class="subtitle">Ascultă portul cântarului și află ce format trimite. Nu se scrie nimic către cântar.</p>
</div>
</section>
<div class="notice">
<strong>Folosire:</strong> conectează cântarul, pornește o cântărire pe el (sau apasă Print) și rulează
monitorul. Dacă nu apar bytes, încearcă <em>Scanează vitezele</em> sau altă setare de linie.
O captură salvată aici este exact ce trebuie ca să adăugăm un protocol nou.
</div>
<section class="card">
<form method="post" class="filters">
<div class="field">
<label for="port">Port</label>
<input id="port" name="port" type="text" list="port-list" required
placeholder="/dev/ttyUSB0 sau COM3" value="{{ values.port }}">
<datalist id="port-list">
{% for p in ports %}
<option value="{{ p.device }}">{{ p.description or p.device }}{% if p.chip %} · {{ p.chip }}{% endif %}</option>
{% endfor %}
</datalist>
</div>
<div class="field">
<label for="baud">Baud</label>
<input id="baud" name="baud" type="number" min="50" max="921600" value="{{ values.baud }}">
</div>
<div class="field">
<label for="framing">Framing</label>
<select id="framing" name="framing">
{% for f in framings %}
<option value="{{ f }}" {{ 'selected' if values.framing == f }}>{{ f }}</option>
{% endfor %}
</select>
</div>
<div class="field">
<label for="seconds">Secunde</label>
<input id="seconds" name="seconds" type="number" min="0.5" max="30" step="0.5" value="{{ values.seconds }}">
</div>
<div class="field">
<label for="name">Nume captură</label>
<input id="name" name="name" type="text" maxlength="60" value="{{ values.name }}">
</div>
<div class="field actions-field">
<button class="btn primary" type="submit">Ascultă</button>
</div>
<div class="monitor-options">
<label class="check"><input type="checkbox" name="scan" value="1" {{ 'checked' if values.scan }}> Scanează vitezele</label>
<label class="check"><input type="checkbox" name="save" value="1" {{ 'checked' if values.save }}> Salvează captura</label>
</div>
</form>
{% if ports %}
<p class="muted small">
Porturi detectate:
{% for p in ports %}<code>{{ p.device }}</code>{% if p.chip %} ({{ p.chip }}){% endif %}{% if not loop.last %}, {% endif %}{% endfor %}
</p>
{% else %}
<p class="muted small">Nu a fost detectat niciun port. Verifică adaptorul USB-RJ11 (driver, cablu).</p>
{% endif %}
</section>
{% if error %}
<div class="notice warning">{{ error }}</div>
{% endif %}
{% if saved_path %}
<div class="notice"><strong>Cauptră salvată:</strong> <code>{{ saved_path }}</code></div>
{% endif %}
{% if scan_hits %}
<section class="card">
<h2>Viteze cu date</h2>
<div class="table-wrap">
<table class="table">
<thead><tr><th>Baud</th><th>Framing</th><th class="num">Bytes</th><th>Protocoale recunoscute</th></tr></thead>
<tbody>
{% for hit in scan_hits %}
<tr>
<td>{{ hit.baud }}</td>
<td>{{ hit.framing }}</td>
<td class="num">{{ hit.bytes }}</td>
<td>
{% if hit.guesses %}
{% for g in hit.guesses %}<span class="badge ok">{{ g.protocol }}</span> {% endfor %}
{% else %}<span class="muted">necunoscut</span>{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</section>
{% endif %}
{% if result %}
<section class="card">
<div class="card-head">
<h2>Rezultat: {{ result.port }} · {{ result.baud }} {{ result.framing }}</h2>
<span class="badge {{ 'ok' if result.ok else 'err' }}">{{ result.bytes }} bytes</span>
</div>
{% if result.guesses %}
<h3>Protocoale recunoscute</h3>
<div class="table-wrap">
<table class="table compact">
<thead><tr><th>ID</th><th>Nume</th><th>Tip</th><th class="num">Valoare</th><th class="num">Cadre</th></tr></thead>
<tbody>
{% for g in result.guesses %}
<tr>
<td><code>{{ g.protocol }}</code></td>
<td>{{ g.name }}</td>
<td>{{ g.kind }}</td>
<td class="num">{{ g.value }} {{ g.unit }}</td>
<td class="num">{{ g.count }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class="muted">Niciun protocol cunoscut nu recunoaște datele. Salvează captura și o folosim ca să scriem parserul.</p>
{% endif %}
<h3>Cadre brute ({{ result.frames|length }})</h3>
{% if result.frames %}
<div class="table-wrap">
<table class="table compact">
<thead><tr><th class="num">Acum</th><th class="num">Bytes</th><th>Hex</th><th>Text</th></tr></thead>
<tbody>
{% for f in result.frames %}
<tr>
<td class="num">{{ f.age_ms }} ms</td>
<td class="num">{{ f.size }}</td>
<td><code class="hex">{{ f.hex }}</code></td>
<td><code>{{ f.text }}</code></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class="muted">Niciun byte primit. Cântarul poate fi setat să nu trimită nimic pe această interfață.</p>
{% endif %}
</section>
{% endif %}
<section class="card help-card">
<h2>Setări de încercat</h2>
<ul class="var-list">
<li><code>9600 8N1</code> — cel mai comun pentru cântare de magazin.</li>
<li><code>9600 7E1</code> / <code>4800 7E1</code> — frecvent la indicatoarele vechi.</li>
<li><code>9600 7O1</code> — dacă textul apare cu bitul 8 schimbat.</li>
<li>Unele cântare trimit doar la apăsarea <em>Print</em>: ține monitorul pornit și apasă.</li>
</ul>
<h2>Cablaj modular (RJ11 / 10P4C)</h2>
<p class="muted small">
Un adaptor USB–RJ11 funcționează doar dacă cei patru ași ai prizei cântarului sunt
<strong>TX, RX, GND</strong> la nivel RS-232 și adaptorul are aceeași ordine. Verifică pinoutul în manualul
BC800 înainte de a conecta; unele prize modulare de cântar sunt TTL sau current-loop și nu se leagă
direct la un adaptor RS-232.
</p>
</section>
{% endblock %}