Um ein Skript anwendungsgerecht erstellen zu können, ist die Kenntnis über verschiedene ESP32 interne Speicherarten und deren Verwendung zumindest sehr nützlich.
Grundlegend gibt es zwei Speicherarten,
- den zugriffslangsamen, nichtflüchtigen (persistenten) Speicher und
- den flüchtigen Speicher, welcher als zugriffsschneller Arbeitsspeicher (RAM = Random Access Memory) dient.
(Der ESP32 verwaltet mehr also solche zwei Speicherarten, deren einzelne Eigenschaften hier aber unwesentlich sind - bei Bedarf kann hier nachgelesen werden: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/memory-types.html)
Der nichtflüchtige Speicher ist besonders interessant. Er wird NVS (Non Volatile Storage) genannt. Dieser Speicher entspricht einer Festplatte bzw. internem SSD eines PC und bietet ähnlich langsame Zugriffe gegenüber dem flüchtigen Arbeitsspeicher. Er wird entsprechend auf vielfältige Weise genutzt, zur dauerhaften Speicherung
- von Skripten (an Hand eines einfachen, kleinen Dateisystems),
- von Schedule Jobs (Zeitpläne),
- des letzten Schalzustandes eines Schaltrelais bzw. Ausgangs, wenn entsprechend konfiguriert,
- von persistenten Variablen, deren Wert somit nach einem Reboot eingelesen und in einer Skript-Variablen genutzt werden können.
zu 1. Ich fand bisher nicht heraus, ob ein aktiviertes, also zur Ausführung genutztes Skript vom NVS in den flüchtigen und zugriffsschnelleren Arbeitsspeicher geladen und dort (interpretierend) ausgeführt wird. Die Shelly Firmware greift auf ein Skript ausschließlich per Skript-Id zu, einer fortlaufenden Nummer. Der Name eines Skript braucht somit nicht eindeutig zu sein, der gleiche Name kann für verschiedene Skripte verwendet werden, was jedoch nicht empfehlenswert ist.
zu 2. Die Einträge von Schedule Jobs müssen auch bei Stromausfall erhalten bleiben.
zu 3. Wenn der letzte Zustand eines Schaltausgangs nach einem Reboot, bspw. nach Stromausfall, wiederhergestellt werden soll, muss mit jeder Zustandsänderung des Ausgangs dieser Zustand im NVS gespeichert werden.
zu 4. Der Zugriff auf Variablen im NVS erfolgt nicht wie im flüchtigen RAM per Adresse sondern per Schlüssel. Dies entspricht im PC dem Zugriff auf eine Datei per Dateiname, wobei der Dateiname den Schlüssel darstellt. Variable im NVS werden somit prinzipiell als Name-Wert-Paare, engl. key-value-pairs, gespeichert. Name ist hier synonym zu Schlüssel zu verstehen und muss eindeutig sein. Dieser Zugriff ist während einer Skriptabarbeitung nicht synchron möglich, d.h. dass der Zugriff immer mit erheblicher Verzögerung im Millisekundenbereich den angeforderten Wert liefert. Deshalb liegt ein solcher angeforderter Wert nie unmittelbar nach der Anforderung vor. Ein synchroner Zugriff ist ausschließlich per Skriptvariable möglich, die im flüchtigen Speicher liegen. Deshalb ist es fast immer zweckmäßig, mit dem Start eines Skripts die benötigten persistenten Werte aus dem NVS anzufordern und zwecks weiterer Verwendung in Skriptvariablen abzulegen. Danach ist der synchrone Zugriff auf einen solchen Wert möglich.
Da nichtflüchtige Variable ausschließlich per eindeutigem Schlüssel zugreifbar sind und dafür jeweils eine Key-Value Struktur gespeichert werden muss, nennt Allterco diese Speicherverwendung KVS (Key Value Storage). Neben dem letzten Gerätezustand ist es zielführend, anwendungsbezogene Konfigurationsparameter im KVS abzulegen. Welche Parameter dies sein mögen, hängt von der Anwendung ab. Der Zugriff auf den KVS erfolgt per RPC (Remote Procedure Call) und ist somit auch per Adresseingabe in einem Web-Browser möglich.
Der zugriffsschnelle flüchtige Speicher ist der Arbeitsspeicher und bedarf wohl keiner weiteren Erklärung. Er entspricht schlicht dem RAM eines PC.
Ergänzend sei erwähnt, dass der NVS bei Schreibzugriffen erheblich schneller altert als der flüchtige Speicher. Deshalb sollte im Einzelfall sorgfältig geprüft werden, ob die Vorteile eines persistent gespeicherten Wertes wesentlich für eine Anwendung sind. Wenn dies nicht der Fall ist, sollte von einer KVS-Speicherung abgesehen werden. Wird eine KVS-Speicherung implementiert, dann zweckmäßigerweise nur zu wirklich erforderlichen Zeitpunkten bzw. Stellen in einer Skriptabarbeitung. Hier ist seltener die anzustrebende Tendenz.