Compare commits
No commits in common. "36dd18f53a43ab2e6aedfd81e214857b04b32071" and "9f07896b05f570379a1b1bed0ae8ac1e0abb3161" have entirely different histories.
36dd18f53a
...
9f07896b05
4 changed files with 2 additions and 172 deletions
34
ChangeLog.md
34
ChangeLog.md
|
|
@ -1,39 +1,5 @@
|
||||||
# Changelog NetDiag
|
# Changelog NetDiag
|
||||||
|
|
||||||
## 1.1.2 — 2026-08-16
|
|
||||||
|
|
||||||
### Geräte-Monitor bekommt einen eigenen PDF-Zweig
|
|
||||||
|
|
||||||
Die Dauerüberwachung lief bisher in den generischen `else`-Zweig von
|
|
||||||
`netdiag_pdf.lib.php` und wurde von `netdiagPdfFlattenResult()` zu **einer**
|
|
||||||
`|`-getrennten Zeile zusammengeschoben. Bei zehn überwachten Geräten standen
|
|
||||||
damit die zehn Geräte-Zeilen UND sämtliche Einzelausfälle in einer einzigen
|
|
||||||
Tabellenzelle — vollständig, aber beim Kunden nicht lesbar. Dauertest und
|
|
||||||
WLAN-Kanal hatten längst je einen Tabellen-Renderer, der Monitor nicht.
|
|
||||||
|
|
||||||
- **`netdiagPdfMonitor()`**: Kennzahlenzeile, Tabelle „Überwachte Geräte",
|
|
||||||
Tabelle „Einzelne Ausfälle" mit Uhrzeiten, Hinweis zum Messverfahren am Ende.
|
|
||||||
- **Die Falle dabei**, gegen die es einen Kommentar im Code gibt: beim Dauertest
|
|
||||||
führt ein gesetztes `hinweis` zum sofortigen Abbruch der Ausgabe. Der Monitor
|
|
||||||
legt aber IMMER einen Hinweis an (das Messverfahren gehört zur Aussage dazu) —
|
|
||||||
derselbe Aufbau hätte hier bei **jedem** Lauf alle Zahlen verschluckt. Nur
|
|
||||||
`fehler` bricht ab, der Hinweis steht am Schluss.
|
|
||||||
- Tabellenköpfe wiederholen sich nach einem Seitenumbruch („— Fortsetzung"),
|
|
||||||
wie in der Geräteliste.
|
|
||||||
- Obergrenze 200 Ausfallzeilen gegen den pathologischen Fall (ein im
|
|
||||||
Sekundentakt flappendes Gerät erzeugt über einen Arbeitstag vierstellig viele
|
|
||||||
Segmente). Gekürzt wird **sichtbar**: „… und N weitere Ausfälle" steht im
|
|
||||||
Dokument, sonst läse sich das Protokoll als vollständig.
|
|
||||||
- **`ausfallzeitSek` heißt jetzt „Ausfallzeit (schlechtestes Gerät)"** — der
|
|
||||||
Wert ist der des schlechtesten Geräts, nicht die Summe über alle. Bei zehn
|
|
||||||
überwachten Geräten las sich „Ausfallzeit: 8 min" wie eine Gesamtaussage.
|
|
||||||
Gleiche Korrektur in `app/src/lib/messfelder.ts`, damit App und PDF dasselbe
|
|
||||||
Feld gleich benennen.
|
|
||||||
|
|
||||||
Geprüft gegen die lokale Testinstanz mit vier konstruierten Fällen (10 Geräte
|
|
||||||
mit Aussetzern, ein durchgehend totes Gerät, 250 Einzelausfälle über sechs
|
|
||||||
Seiten, abgerissener Lauf) und gegen die echte Monitor-Messung aus ND2026-0016.
|
|
||||||
|
|
||||||
## 1.1.1 — 2026-08-16
|
## 1.1.1 — 2026-08-16
|
||||||
|
|
||||||
### Vier stille Fehler im Kundendokument und im Sync
|
### Vier stille Fehler im Kundendokument und im Sync
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ class modNetDiag extends DolibarrModules
|
||||||
$this->editor_url = '';
|
$this->editor_url = '';
|
||||||
$this->editor_squarred_logo = '';
|
$this->editor_squarred_logo = '';
|
||||||
|
|
||||||
$this->version = '1.1.2';
|
$this->version = '1.1.1';
|
||||||
|
|
||||||
// Konstanten-Name in llx_const für Modul-Status
|
// Konstanten-Name in llx_const für Modul-Status
|
||||||
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
|
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
|
||||||
|
|
|
||||||
|
|
@ -338,10 +338,7 @@ function netdiagKundenfelder()
|
||||||
// vollständig ins Kundendokument, nicht nur die Ampel.
|
// vollständig ins Kundendokument, nicht nur die Ampel.
|
||||||
'geraeteAnzahl' => array('Überwachte Geräte', ''),
|
'geraeteAnzahl' => array('Überwachte Geräte', ''),
|
||||||
'verfuegbarkeitProzent' => array('Verfügbarkeit (schlechtestes Gerät)', '%'),
|
'verfuegbarkeitProzent' => array('Verfügbarkeit (schlechtestes Gerät)', '%'),
|
||||||
// „Ausfallzeit" allein war irreführend: der Wert ist der des schlechtesten
|
'ausfallzeitSek' => array('Ausfallzeit', 's'),
|
||||||
// Geräts, nicht die Summe über alle. Bei zehn überwachten Geräten liest
|
|
||||||
// sich „Ausfallzeit: 8 min" sonst wie eine Gesamtaussage.
|
|
||||||
'ausfallzeitSek' => array('Ausfallzeit (schlechtestes Gerät)', 's'),
|
|
||||||
'aussetzer' => array('Aussetzer', ''),
|
'aussetzer' => array('Aussetzer', ''),
|
||||||
'geraete' => array('Je Gerät', ''),
|
'geraete' => array('Je Gerät', ''),
|
||||||
'ausfaelle' => array('Einzelne Ausfälle', ''),
|
'ausfaelle' => array('Einzelne Ausfälle', ''),
|
||||||
|
|
|
||||||
|
|
@ -198,8 +198,6 @@ function netdiagGeneratePdf($db, $protocol, $outputlangs)
|
||||||
netdiagPdfStressTest($pdf, $m->result);
|
netdiagPdfStressTest($pdf, $m->result);
|
||||||
} elseif ($m->tool === 'wifikanal') {
|
} elseif ($m->tool === 'wifikanal') {
|
||||||
netdiagPdfWifiKanal($pdf, $m->result);
|
netdiagPdfWifiKanal($pdf, $m->result);
|
||||||
} elseif ($m->tool === 'monitor') {
|
|
||||||
netdiagPdfMonitor($pdf, $m->result);
|
|
||||||
} else {
|
} else {
|
||||||
$pdf->MultiCell(180, 5, netdiagPdfFlattenResult($m->result), 1, 'L');
|
$pdf->MultiCell(180, 5, netdiagPdfFlattenResult($m->result), 1, 'L');
|
||||||
}
|
}
|
||||||
|
|
@ -373,137 +371,6 @@ function netdiagPdfStressTest($pdf, $json)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Geräte-Dauerüberwachung strukturiert ins PDF schreiben.
|
|
||||||
*
|
|
||||||
* Dritter eigener Zweig neben Dauertest und WLAN-Kanal, aus demselben Grund:
|
|
||||||
* `netdiagPdfFlattenResult()` schiebt alles zu EINER `|`-getrennten Zeile
|
|
||||||
* zusammen. Bei zehn überwachten Geräten standen damit die zehn Zeilen aus
|
|
||||||
* `geraete` UND sämtliche Einzelausfälle in einer einzigen Tabellenzelle —
|
|
||||||
* vollständig, aber beim Kunden nicht lesbar.
|
|
||||||
*
|
|
||||||
* ACHTUNG, Unterschied zu netdiagPdfStressTest(): dort führt ein gesetztes
|
|
||||||
* `hinweis` zum sofortigen Abbruch. Hier darf es das NICHT — der Monitor legt
|
|
||||||
* IMMER einen Hinweis an (das Messverfahren gehört zur Aussage dazu, siehe
|
|
||||||
* `buildMonitorMeasurement()` in app/src/lib/monitor.ts). Ein Frühabbruch
|
|
||||||
* würde also bei jedem Monitor-Lauf sämtliche Zahlen verschlucken. Der Hinweis
|
|
||||||
* steht deshalb am Ende, nur `fehler` bricht ab.
|
|
||||||
*
|
|
||||||
* @param TCPDF $pdf PDF-Objekt (Cursor steht direkt hinter der Titelzeile)
|
|
||||||
* @param string $json result-JSON der Messung
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function netdiagPdfMonitor($pdf, $json)
|
|
||||||
{
|
|
||||||
$data = json_decode((string) $json, true);
|
|
||||||
if (!is_array($data)) {
|
|
||||||
$pdf->MultiCell(180, 5, netdiagPdfFlattenResult($json), 1, 'L');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!empty($data['fehler']) || !empty($data['error'])) {
|
|
||||||
$pdf->MultiCell(180, 5, netdiagKundentext((string) ($data['fehler'] ?? $data['error'])), 1, 'L');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kennzahlenzeile. Bezeichnungen bewusst wie in netdiagKundenfelder(),
|
|
||||||
// damit dasselbe Feld im PDF und in der Dolibarr-Ansicht gleich heißt.
|
|
||||||
$sum = array();
|
|
||||||
if (isset($data['dauerSekunden'])) {
|
|
||||||
$sum[] = 'Messdauer: '.netdiagDauerLesbar($data['dauerSekunden']);
|
|
||||||
}
|
|
||||||
if (isset($data['intervallSek'])) {
|
|
||||||
$sum[] = 'Messabstand: '.$data['intervallSek'].' s';
|
|
||||||
}
|
|
||||||
if (isset($data['geraeteAnzahl'])) {
|
|
||||||
$sum[] = 'Überwachte Geräte: '.$data['geraeteAnzahl'];
|
|
||||||
}
|
|
||||||
if (isset($data['verfuegbarkeitProzent']) && $data['verfuegbarkeitProzent'] !== null) {
|
|
||||||
$sum[] = 'Verfügbarkeit (schlechtestes Gerät): '.number_format((float) $data['verfuegbarkeitProzent'], 1, ',', '').' %';
|
|
||||||
}
|
|
||||||
if (isset($data['aussetzer'])) {
|
|
||||||
$sum[] = 'Aussetzer: '.$data['aussetzer'];
|
|
||||||
}
|
|
||||||
if (!empty($data['ausfallzeitSek'])) {
|
|
||||||
$sum[] = 'Ausfallzeit (schlechtestes Gerät): '.netdiagDauerLesbar($data['ausfallzeitSek']);
|
|
||||||
}
|
|
||||||
if (!empty($data['laengsterAusfallSek'])) {
|
|
||||||
$sum[] = 'Längster Ausfall: '.netdiagDauerLesbar($data['laengsterAusfallSek']);
|
|
||||||
}
|
|
||||||
if (!empty($sum)) {
|
|
||||||
$pdf->MultiCell(180, 5, implode(' | ', $sum), 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Je Gerät eine eigene Zeile — das ist der eigentliche Beleg. Die Zeilen
|
|
||||||
// kommen vorformatiert aus der App (dieselben, die dort in der Messungs-
|
|
||||||
// liste stehen), wie beim Dauertest: eine Quelle der Wahrheit.
|
|
||||||
$geraete = (isset($data['geraete']) && is_array($data['geraete'])) ? $data['geraete'] : array();
|
|
||||||
if (!empty($geraete)) {
|
|
||||||
netdiagPdfEnsureSpace($pdf, 10);
|
|
||||||
$pdf->SetFont('', 'B', 8);
|
|
||||||
$pdf->Cell(180, 5, 'Überwachte Geräte ('.count($geraete).')', 1, 1, 'L');
|
|
||||||
$pdf->SetFont('', '', 8);
|
|
||||||
foreach ($geraete as $line) {
|
|
||||||
netdiagPdfEnsureSpace($pdf, 5, function ($p) use ($geraete) {
|
|
||||||
$p->SetFont('', 'B', 8);
|
|
||||||
$p->Cell(180, 5, 'Überwachte Geräte ('.count($geraete).') — Fortsetzung', 1, 1, 'L');
|
|
||||||
$p->SetFont('', '', 8);
|
|
||||||
});
|
|
||||||
$pdf->Cell(180, 5, dol_trunc((string) $line, 120), 1, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Einzelne Ausfälle mit Uhrzeit. Genau das ist der Nachweis bei der
|
|
||||||
// häufigsten Reklamation („die Kamera fällt ständig aus").
|
|
||||||
$ausfaelle = (isset($data['ausfaelle']) && is_array($data['ausfaelle'])) ? $data['ausfaelle'] : array();
|
|
||||||
netdiagPdfEnsureSpace($pdf, 10);
|
|
||||||
if (empty($ausfaelle)) {
|
|
||||||
$pdf->SetFont('', 'I', 8);
|
|
||||||
$pdf->Cell(180, 5, 'Kein Ausfall während der Überwachung.', 1, 1, 'L');
|
|
||||||
$pdf->SetFont('', '', 8);
|
|
||||||
} else {
|
|
||||||
$pdf->SetFont('', 'B', 8);
|
|
||||||
$pdf->Cell(180, 5, 'Einzelne Ausfälle ('.count($ausfaelle).')', 1, 1, 'L');
|
|
||||||
$pdf->SetFont('', '', 8);
|
|
||||||
/*
|
|
||||||
* Obergrenze gegen den pathologischen Fall: ein im Sekundentakt
|
|
||||||
* flappendes Gerät erzeugt über einen Arbeitstag vierstellig viele
|
|
||||||
* Segmente — das wären zweistellig viele Seiten reine Ausfallliste.
|
|
||||||
* 200 Zeilen sind rund vier Seiten und belegen jede reale Störung
|
|
||||||
* ausreichend. Gekürzt wird NICHT stillschweigend: die Restzahl steht
|
|
||||||
* sichtbar im Dokument, sonst läse sich das Protokoll als vollständig.
|
|
||||||
*/
|
|
||||||
$max = 200;
|
|
||||||
$i = 0;
|
|
||||||
foreach ($ausfaelle as $line) {
|
|
||||||
if ($i >= $max) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
netdiagPdfEnsureSpace($pdf, 5, function ($p) use ($ausfaelle) {
|
|
||||||
$p->SetFont('', 'B', 8);
|
|
||||||
$p->Cell(180, 5, 'Einzelne Ausfälle ('.count($ausfaelle).') — Fortsetzung', 1, 1, 'L');
|
|
||||||
$p->SetFont('', '', 8);
|
|
||||||
});
|
|
||||||
$pdf->Cell(180, 5, dol_trunc((string) $line, 120), 1, 1, 'L');
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
$rest = count($ausfaelle) - $max;
|
|
||||||
if ($rest > 0) {
|
|
||||||
netdiagPdfEnsureSpace($pdf, 5);
|
|
||||||
$pdf->SetFont('', 'I', 8);
|
|
||||||
$pdf->Cell(180, 5, '… und '.$rest.' weitere Ausfälle, hier aus Platzgründen nicht einzeln aufgeführt.', 1, 1, 'L');
|
|
||||||
$pdf->SetFont('', '', 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hinweis zum Schluss: Messverfahren und ggf. abgerissener Lauf.
|
|
||||||
if (!empty($data['hinweis'])) {
|
|
||||||
netdiagPdfEnsureSpace($pdf, 10);
|
|
||||||
$pdf->SetFont('', 'I', 7);
|
|
||||||
$pdf->MultiCell(180, 4, netdiagKundentext((string) $data['hinweis']), 1, 'L');
|
|
||||||
$pdf->SetFont('', '', 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WLAN-Kanal-Momentaufnahme im PDF als Tabelle ausgeben.
|
* WLAN-Kanal-Momentaufnahme im PDF als Tabelle ausgeben.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue