DDM-Polling über I2C scripten: Welche A2h-Bytes halten die Live-Werte und welche die Schwellwerte
Ich schreibe einen kleinen Poller, der Temperatur, Spannung, Bias und optische Leistung direkt von den Modulen auf unseren Whitebox-Geräten abgreift, damit wir eine Trendlinie bekommen, statt dass jemand einen Link erst anstarrt, nachdem er schon anfängt zu fehlern. Das NOS druckt hübsche Werte, aber ich will die Rohzahlen zusammen mit den Herstellerschwellen daneben, damit Alarmschwellen über gemischte Optiken hinweg konsistent sind, statt pro Modell von Hand geschrieben.
Stand:
- Linux-Host, Modulkäfige hinter einem einfachen I2C-Mux, Bus 1
- gemischte SFP-, SFP+- und SFP28-Optiken von drei Herstellern
- gelesen wird nur mit i2c-tools, keine Hersteller-SDK
Die Diagnostikseite lese ich so:
# i2cdump -y 1 0x51
und das hier ist mein Entwurfsparser, wo ich mir unsicher bin:
temp = s16(a2[96:98]) / 256.0
vcc = u16(a2[98:100]) * 100e-6
bias = u16(a2[100:102]) * 2e-6
Was ich schon gemacht habe:
- meine berechneten Werte mit dem verglichen, was das NOS druckt: bei manchen Modulen nah dran, bei anderen deutlich daneben
- SFF-8472 durchgelesen, kann aber immer noch nicht sicher sagen, wo der Schwellenblock endet und wo der Kalibrierungsbereich anfängt
- den Mux ausgeschlossen, indem ich dasselbe Modul an einem direkten Bus gedumpt habe, gleiche Zahlen
Also: Wie sieht die tatsächliche Karte von A2h aus, wo sitzen die Schwellen, wo fangen die Echtzeitwerte an, und gibt es irgendwo ein Flag, das mir sagt, ob das Modul erwartet, dass ich an diesen rohen Wörtern etwas mache, bevor ich ihnen traue?
Comments 7
Welche Werte sind die, die klar daneben liegen, alle vier oder nur Bias und die Leistungen? Das entscheidet meistens die ganze Antwort. Dabei gleich A0h dumpen und auf Byte 92 schauen: Es sagt, ob das Modul überhaupt Diagnostik meldet, und ob es intern oder extern kalibriert ist. Wenn ein Teil der Flotte extern kalibriert ist und der Parser alle gleich behandelt, dann ist die Abweichung erwartetes Verhalten und kein Bug in der Arithmetik.
A0h Byte 92 über das ganze Tray gezogen, und es ist nicht einheitlich. Manche Module flaggen externe Kalibrierung, manche nicht, und genau die, die vom NOS-Output abweichen, sind die externen. Temperatur und Spannung liegen bei allen im Rauschen; Bias und die beiden Leistungen sind das, was driftet. Es sieht also eher so aus, als würde mir ein Schritt fehlen, statt dass ich die falschen Offsets lese. Was muss ich bei dieser Teilmenge tatsächlich mit den rohen Wörtern machen?
A2h bei 0x51 zerfällt in vier Blöcke, die relevant sind:
Einheiten im Live-Block: Temperatur vorzeichenbehaftet, 1/256 C pro LSB; Spannung 100 uV pro LSB; Bias 2 uA; TX- und RX-Power 0.1 uW. Euer Ausschnitt skaliert das schon korrekt, die Offsets sind also nicht das Problem.
Das fehlende Stück ist genau das Flag, das ihr gerade gefunden habt. Bei einem extern kalibrierten Modul sind die Wörter bei 96-105 rohe ADC-Ausgabe, und die Konstanten bei 56-95 müssen angewendet werden, bevor sie etwas bedeuten; ein intern kalibriertes Modul hat das schon für euch erledigt. Diese Weiche ist der Unterschied zwischen euren zwei Gruppen.
Wer ein Layout zum Gegenprüfen will, statt mir aufs Wort zu glauben: Der FreeBSD-Header sff8472.h und py-sfp-eeprom buchstabieren die Offsets beide Feld für Feld aus. Trotzdem würde ich vor dem Aufhängen von Alarmen ein Modul pro Hersteller gegen einen vertrauenswürdigen Wert verifizieren.
Ergänzend, warum der Schwellenblock die interessante Hälfte ist. Die Werte in 0-55 stehen in denselben Einheiten wie der Live-Block, sobald die Skalierung stimmt, bekommt man also die eigenen Alarm- und Warnpunkte des Herstellers gratis dazu und muss nie Grenzwerte pro Modell erfinden. Allein das rechtfertigt schon, A2h direkt zu lesen, statt den hübschen Printer von irgendjemandem zu parsen.
Ein praktischer Hinweis aus dem Betrieb auf einem gemischten Tray: das Poll-Intervall bescheiden halten. Diese Seite ist ein gewöhnlicher I2C-Read, und der Modul-Controller ist nicht schnell. Jedes Modul jede Sekunde zu hämmern, auf einem Bus, der zusätzlich hinter einem Mux sitzt, ist ein guter Weg, um kurze Reads einzusammeln, die in den Graphen genau wie flatternde Optiken aussehen.
Vorsicht bei der Formulierung, denn Leute lesen das als "Konstanten immer anwenden" und wundern sich dann, warum ihre Zahlen schlechter wurden. Die Konstanten bei 56-95 gelten nur, wenn Byte 92 in A0h sagt, dass das Modul extern kalibriert ist. Sie über ein intern kalibriertes Modul laufen lassen, und aus einwandfreien Messwerten wird Unsinn, weil das Modul diese Arbeit schon erledigt hat. Erst das Flag lesen, danach verzweigen, beide Pfade im Parser behalten und loggen, welchen Pfad ein gegebenes Modul genommen hat, damit sich die zwei Fehlerarten später auseinanderhalten lassen.
Dieselbe Art Falle bei der Temperatur: Sie ist vorzeichenbehaftet. Unsigned geparst, kommt alles unter null als wild hohe Zahl zurück, was am ersten kalten Morgen, an dem es einen aus dem Bett pagert, sehr unterhaltsam ist.
Update von meiner Seite. Ich verzweige jetzt auf A0h Byte 92 und wende die Konstanten nur an, wo das Modul external sagt. Bias und beide Leistungen folgen jetzt dem, was das NOS bei jedem Modul druckt, das ich zum Vergleich hatte, und Temperatur und Spannung waren von Anfang an kein Problem. Zwei Module melden Diagnostik zwar weiterhin als vorhanden, geben aber Schwellen zurück, denen ich nicht traue, für die falle ich also auf eigene Grenzwerte zurück und markiere das Modul im Inventar, statt so zu tun als ob. Ich erkläre das Ganze noch nicht für abgeschlossen, aber die Karte oben war genau das, was mir gefehlt hat.
Noch etwas, bevor das in Produktion geht. Byte 110 sitzt auf derselben Seite und ist Status plus Steuerung, und die Steuerhälfte enthält TX disable. Ein Poller hat auf A2h überhaupt nichts zu schreiben, aber wenn die Bibliothek irgendwo ein Read-Modify-Write macht, oder man sich beim Testen an einer Live-Box mit i2cset vertippt, kann man aus dem Userspace einen Kundenlink killen. Den Bus im Poller read-only öffnen und jeden Schreibpfad in einem separaten Tool halten, das bewusst gestartet werden muss.
Dasselbe Byte liefert TX fault und RX LOS, und beide lohnt es sich, neben den analogen Werten zu exportieren. Ein Modul, das bei vernünftiger RX-Power mit gesetztem LOS dasteht, erzählt eine ganz andere Geschichte als eines, das einfach niedrig misst.