TinyC .pvs chart editorTinyC .pvs-Diagramm-Editor

Look at and edit the persist data of a running TinyC programDie persist-Daten eines laufenden TinyC-Programms ansehen und bearbeiten

Start

A single HTML file. Open tinyc_chart_editor.html from the tinyc/utils folder in any browser — no server, nothing is uploaded. It edits the .pvs of a TinyC slot: the file the running program keeps its persist variables in (/sml_chart.tcb/sml_chart.pvs). Chart history, counter zero points, settings — everything that survives a restart.

Fetch and put back through the device's file manager, http://<device>/ufsd.

Moving over from a Tasmota Scripter script? That is the converter.

Eine einzelne HTML-Datei. tinyc_chart_editor.html aus dem Ordner tinyc/utils im Browser öffnen — kein Server, es wird nichts hochgeladen. Bearbeitet wird die .pvs eines TinyC-Slots: die Datei, in der das laufende Programm seine persist-Variablen hält (/sml_chart.tcb/sml_chart.pvs). Diagrammverläufe, Zähler-Nullpunkte, Einstellungen — alles, was den Neustart überlebt.

Holen und zurückspielen über den Dateimanager des Geräts, http://<geraet>/ufsd.

Umzug von einem Tasmota-Scripter-Script? Dafür gibt es den Konverter.

The .pvs fileDie .pvs-Datei

PVS3 is what the current compiler writes. Name-keyed and without any checksum:

'P' 'V' '3'  count:u8
per entry:   nameLen:u8  name:nameLen  slotCount:u16 LE  data:slotCount*4 LE

PVS2 is the predecessor ('P','V','H', layout_hash:u32, and index:u16 instead of the name). That hash covers the layout — count, index, slot count — not the data. Changing values leaves it valid, so the stored hash bytes are simply carried through. Both versions are read and written back in the same version.

The loader on the device is forgiving: unknown names are skipped, a missing entry keeps its current value, a short entry is restored as far as it goes. A file written here is therefore just as valid as one the device wrote.

Without an edit the output is byte-for-byte identical to the input. Only what you changed is rewritten — entries the editor does not even know go back out untouched.

PVS3 ist das, was der aktuelle Compiler schreibt. Namensbasiert und ohne Prüfsumme:

'P' 'V' '3'  count:u8
je Eintrag:  nameLen:u8  name:nameLen  slotCount:u16 LE  data:slotCount*4 LE

PVS2 ist der Vorgänger ('P','V','H', layout_hash:u32, und index:u16 statt des Namens). Dieser Hash geht über das Layout — Anzahl, Index, Slotzahl — nicht über die Daten. Werte zu ändern lässt ihn gültig, deshalb werden die gespeicherten Hash-Bytes einfach durchgereicht. Beide Versionen werden gelesen und in derselben Version wieder geschrieben.

Der Loader im Gerät ist nachsichtig: unbekannte Namen werden übersprungen, ein fehlender Eintrag behält seinen aktuellen Wert, ein zu kurzer wird so weit geladen wie er reicht. Eine hier geschriebene Datei ist damit genauso gültig wie eine vom Gerät.

Ohne Änderung ist die Ausgabe Byte für Byte identisch mit der Eingabe. Nur Bearbeitetes wird neu geschrieben — auch Einträge, die der Editor gar nicht kennt, gehen unverändert wieder hinaus.

EditingBearbeiten

  1. Download the .pvs from the device's file manager and drop it in.
  2. Every entry is listed: series as a chart with a value box, scalars as an input field. Anything changed gets a blue frame. Hovering a chart shows the exact value with its unit.
  3. Download the .pvs and put it back:
    • Stop the slot: Tools › TinyC Console › the red ■
    • Upload: Tools › Manage File system › Upload — same name, same path
    • Start the slot: Tools › TinyC Console › the green ▶

The order matters: if the slot is still running while you upload, saveVars() writes its own values over yours when it stops.

Changed a counter zero point, the month day or a setting? Those are taken from tc_options.cfg at start-up, not from the .pvs — upload the tc_options.cfg as well, see below. The editor says so under Save.

The .pvs is read at start-up and not renamed — it is the storage, not an import file. The CSV export is for reading only; the device never imports it.

  1. Die .pvs im Dateimanager des Geräts herunterladen und hier hineinziehen.
  2. Alle Einträge werden aufgelistet: Reihen als Diagramm mit Wertefeld, Skalare als Eingabefeld. Geändertes ist blau umrandet. Mit der Maus über ein Diagramm zeigt den genauen Wert samt Einheit.
  3. Die .pvs herunterladen und zurückspielen:
    • Slot stoppen: Tools › TinyC Console › das rote ■
    • Hochladen: Tools › Manage File system › Upload — gleicher Name, gleicher Pfad
    • Slot starten: Tools › TinyC Console › das grüne ▶

Die Reihenfolge zählt: läuft der Slot beim Hochladen noch, schreibt saveVars() beim Stoppen seine eigenen Werte über deine.

Einen Zähler-Nullpunkt, den Monatstag oder eine Einstellung geändert? Die holt sich das Programm beim Start aus der tc_options.cfg, nicht aus der .pvs — also die tc_options.cfg mit hochladen, siehe unten. Der Editor weist unter Speichern darauf hin.

Die .pvs wird beim Start gelesen und nicht umbenannt — sie ist der Speicher, keine Import-Datei. Die CSV-Ausgabe ist nur zum Nachlesen; das Gerät liest sie nie ein.

tc_options.cfg

All TinyC programs share /tc_options.cfg: language, meter, pins, the emulator and CT options — and the counter zero points. It carries them across a program change, and on the first tick it wins over the .pvs:

sml_dval = tcOptGetF(0, sml_dval);   // sml_chart.tc, first tick

A value changed only in the .pvs is therefore back to the cfg's one second after the start. That applies to every variable with a key in the file:

.pvstc_options.cfg
sml_dval · sml_mval · sml_yvalimp_day · imp_month · imp_year
sml_dval2 · sml_mval2 · sml_yval2exp_day · exp_month · exp_year
sml_stmin · sml_chmainchart_short · chart_onmain
sml_da, ui_*, sml_* settings, mb_*, es_*, ct_*same name

The editor has its own card for it. Load the device's tc_options.cfg there (or drop it into the load field); the table shows .pvs value and cfg value side by side and marks where they differ. Changing such a variable in the .pvs copies it into the card automatically, or type a new value straight into the card. Download replaces only the changed lines and keeps everything else — the file also holds the settings of programs that are not running right now. Upload it together with the .pvs, with the slot stopped.

Alle TinyC-Programme teilen sich /tc_options.cfg: Sprache, Zähler, Pins, die Emulator- und CT-Optionen — und die Zähler-Nullpunkte. Sie trägt sie über einen Programmwechsel, und beim ersten Tick gewinnt sie gegen die .pvs:

sml_dval = tcOptGetF(0, sml_dval);   // sml_chart.tc, erster Tick

Ein Wert, der nur in der .pvs geändert wurde, steht deshalb eine Sekunde nach dem Start wieder auf dem aus der cfg. Das gilt für jede Variable mit einem Schlüssel in der Datei:

.pvstc_options.cfg
sml_dval · sml_mval · sml_yvalimp_day · imp_month · imp_year
sml_dval2 · sml_mval2 · sml_yval2exp_day · exp_month · exp_year
sml_stmin · sml_chmainchart_short · chart_onmain
sml_da, ui_*, sml_*-Einstellungen, mb_*, es_*, ct_*gleicher Name

Der Editor hat dafür eine eigene Karte. Dort die tc_options.cfg des Geräts laden (oder ins Ladefeld ziehen); die Tabelle zeigt .pvs-Wert und cfg-Wert nebeneinander und markiert, wo sie abweichen. Wer so eine Variable in der .pvs ändert, bekommt sie automatisch in die Karte übernommen, oder trägt den neuen Wert direkt dort ein. Herunterladen ersetzt nur die geänderten Zeilen und lässt alles andere stehen — die Datei enthält auch die Einstellungen von Programmen, die gerade nicht laufen. Zusammen mit der .pvs bei gestopptem Slot hochladen.

TypesTypen

A slot is always 4 bytes. How to read them is not in the file — only the program knows. The editor knows the variables of the SML programs:

NameTypeValues
sml_s4h, sml_s24hint16481 / 1441
sml_dcon, sml_dprodfloat31 each
sml_mcon, sml_mprodfloat12 each
sml_s4h_pos, sml_s24h_pos, sml_daint321
sml_dval, sml_mval, sml_yval and the 2 twinsfloat1
sml_stmin, sml_chmain, sml_pv, sml_sndpwr, sml_meter_selui_*, mb_*, es_*, ct_*int321
ct_mac, ct_mailbyte16 / 64

int16 is packed: (n+1)/2 slots, element i at byte offset i·2. byte packs four: (n+3)/4 slots, element i at byte offset i.

Unknown entries are shown as float — unless every value would come out as a denormal number (an int 240 read as float32 is 3.4e-43), then as int32. The type can be switched per entry, which makes the editor usable for other TinyC programs too.

Ein Slot sind immer 4 Bytes. Wie sie zu lesen sind, steht nicht in der Datei — das weiß nur das Programm. Der Editor kennt die Variablen der SML-Programme:

NameTypWerte
sml_s4h, sml_s24hint16481 / 1441
sml_dcon, sml_dprodfloatje 31
sml_mcon, sml_mprodfloatje 12
sml_s4h_pos, sml_s24h_pos, sml_daint321
sml_dval, sml_mval, sml_yval und die 2-Zwillingefloat1
sml_stmin, sml_chmain, sml_pv, sml_sndpwr, sml_meter_selui_*, mb_*, es_*, ct_*int321
ct_mac, ct_mailbyte16 / 64

int16 liegt gepackt: (n+1)/2 Slots, Element i an Byte-Offset i·2. byte packt vier: (n+3)/4 Slots, Element i an Byte-Offset i.

Unbekannte Einträge werden als float gezeigt — außer alle Werte kämen als denormale Zahl heraus (ein int 240 als float32 gelesen ist 3.4e-43), dann als int32. Der Typ lässt sich je Eintrag umschalten, damit ist der Editor auch für andere TinyC-Programme brauchbar.

The .bin — import onlyDie .bin — nur zum Importieren

A .bin is read and written as well. It is the import file: raw float32 in the order from sml_chart_common.tc, no header.

FileContentswithoutwith baselines
sml_chart.binsml_s4h · sml_s24h · sml_dcon · sml_mcon19651969
sml_chart_pv.binsml_dprod · sml_mprod4346

The program reads it once at start-up, writes it into the .pvs and deletes it afterwards. The baseline block is only appended when all of its values are present — the program reads it whole or not at all.

For the normal case the .pvs is the better route: it holds all variables, the .bin only these. Either way the baselines also have to go into the tc_options.cfg — loading a .bin with baselines puts them into that card automatically.

Eine .bin wird ebenfalls gelesen und geschrieben. Sie ist die Import-Datei: rohe float32 in der Reihenfolge aus sml_chart_common.tc, kein Kopf.

DateiInhaltohnemit Basiswerten
sml_chart.binsml_s4h · sml_s24h · sml_dcon · sml_mcon19651969
sml_chart_pv.binsml_dprod · sml_mprod4346

Das Programm liest sie beim Start einmal, schreibt sie in die .pvs und löscht sie danach. Der Basiswert-Block wird nur angehängt, wenn alle seine Werte da sind — das Programm liest ihn ganz oder gar nicht.

Für den normalen Fall ist die .pvs der bessere Weg: sie enthält alle Variablen, die .bin nur diese. In beiden Fällen müssen die Basiswerte zusätzlich in die tc_options.cfg — wer eine .bin mit Basiswerten lädt, bekommt sie automatisch in diese Karte übernommen.