
In den letzten zwei Jahren habe ich meine eigene IoT- Plattform entwickelt und heute bin ich bereit, ihre Alpha-Version zu zeigen.
Zusammen mit einem Partner erstellen und unterstützen wir IoT-Geräte. Wir haben im Rahmen dieser Aktivität mehr als einen Rechenschuppen abgebaut. ThingJS wurde nicht so sehr aus Begierde als vielmehr aus dem Bedürfnis heraus geboren, uns das Leben zu erleichtern, sondern gleichzeitig, hoffe ich, für Sie.
Der Artikel wird für Menschen interessant sein, die dem Thema IoT nahe stehen und in diesem Bereich bereits etwas unternommen haben. Ein wichtiger Punkt wird sein, dass die Plattform (plötzlich) JavaScript-Entwickler interessieren sollte, wie Diese Sprache wird als Grundlage für die Plattform gewählt. Natürlich haben C / C ++ - Entwickler auch etwas zu lesen.
Zuerst werde ich darüber sprechen, auf welche Hauptprobleme wir bei der Entwicklung von IoT-Geräten gestoßen sind, dann werde ich beschreiben, wie die Plattform damit umgeht, und am Ende ist alles langweilig: das Video , der technische Teil, und Sie können alles live berühren.
IoT-Probleme:
- Das Problem der kurzen Arme
IoT basiert auf einem Ökosystem. Die Entwicklung des Konzepts und der technischen Architektur ist wirklich viel Arbeit. Darüber hinaus müssen Sie noch eine Reihe von Firmware für heterogene Geräte entwickeln. Transport für den Datenaustausch zwischen Geräten nach verschiedenen physikalischen und logischen Prinzipien erfinden und implementieren. Erweitern Sie die Cloud-Ressourcen. Benutzeroberflächen ausarbeiten. Usw. usw.
Selbst wenn ein einzelner Spezialist über die erforderlichen Fähigkeiten verfügt, hat er einfach nicht genug Zeit (Hände), um eine solche Idee umzusetzen. Während er es schneiden wird, wird sie obsolet.
- Das Problem des Turms von Babel
Die Entwicklung eines vollwertigen IoT-Ökosystems erfordert einen sehr breiten technologischen Stapel. Ein Full Stack im IoT zu sein ist unkompliziert ... schwierig. Brauche überall Erfahrung. Nicht alle können sich eines so breiten Wissens- und sogar Erfahrungsspektrums rühmen. Und hier geht es nicht um geistige Fähigkeiten. Dies ist eine offensichtliche Schlussfolgerung aus dem Kurzhandproblem.
Um ein wirklich wohlhabendes Ökosystem zu schaffen, müssen viele ziemlich enge Spezialisten arbeiten, die jedoch über fundierte Kenntnisse auf ihrem Gebiet verfügen. Diese Spezialisten sprechen verschiedene Sprachen, verwenden unterschiedliche Muster und verstehen elementare Begriffe häufig auf unterschiedliche Weise. Und da IoT auf Geräten mit begrenzten Ressourcen basiert, ist eine effektive Kommunikation entscheidend für die Verwirklichung der beabsichtigten Ziele.
- Das Problem des Stockholm-Syndroms
Heute gibt es Anbieter, die ihre Ökosysteme entwickeln. Dies sind Google, Microsoft, Yandex, Megaphone, MTS usw. Einige von ihnen ermöglichen es Ihnen, Ihre eigenen Dinge zu ihren Bedingungen in ihre Ökosysteme zu integrieren. Dies deckt weitgehend die oben beschriebenen Probleme ab. Aber es schafft eine neue - Sucht. Und Anbieter möchten die Bedingungen für die Integration ändern. Und noch mehr, es gibt keine Frage der Selbstverwirklichung in diesem Paradigma.
Lösungen für Probleme:
Die oben beschriebenen Probleme blockieren tatsächlich den Zugang von Einzelpersonen zur IoT-Entwicklung. Die Entwicklung der Plattform wurde mit dem Bewusstsein dieser Probleme gestartet. Der Grundstein für die Entwicklung der Plattform durch die Community wurde gelegt.
Um diese Idee zu verwirklichen, verfügt die Plattform natürlich über eine offene Codebasis und ein Abhängigkeitsparadigma auf allen Ebenen.
Wenn Sie nicht wissen, was Sucht ist, ist es Zeit, sie kennenzulernen. Wenn Sie jedoch versuchen, dies sehr einfach zu erklären, hängt das Modul, das Sie entwickeln, möglicherweise von einem anderen Modul ab, das Ihr Freund schreibt. Und Sie werden über eine vordefinierte Schnittstelle auf das Modul zugreifen.
Gleichzeitig können viele Menschen unabhängig voneinander ihre eigenen Plattformkomponenten entwickeln und vorhandene, die von jemandem entwickelt wurden, wiederverwenden. Dies löst das Problem der kurzen Hände grundlegend.

Auch das Problem des „Turms von Babel“ wird gelöst. Abhängigkeiten werden so erstellt, dass die verschiedenen Ebenen der Plattform, die in verschiedenen Sprachen entwickelt wurden, einen vorgegebenen Mechanismus zum Erstellen von Abhängigkeiten untereinander haben.
Ein C-Entwickler kann beispielsweise eine vorgefertigte Front-End-Komponente nutzen, indem er ihm die erforderliche Schnittstelle zur Verfügung stellt. Im Gegenteil, der Front-End-Entwickler kann eine in C geschriebene vorgefertigte Komponente verwenden Jeder wird das tun, was er am besten weiß.
- Mehr Versprechen und Abstraktionen
Das Kommunikationsprotokoll zwischen Geräten ist nicht definiert. Stattdessen gibt es eine Abstraktion - einen Datenbus. Das Gerät kann ein Ereignis an den Bus senden oder den Bus abhören. Es ist nicht klar, wer im Voraus in den Bus schreibt und wer empfängt. Und wenn auch. Asynchroner Datenaustausch und Lieferung werden nicht garantiert. Im Allgemeinen - Hölle. Keine Panik. So konzipiert.
Die Sache ist, dass das Ökosystem eine Gruppe von separaten, autarken Geräten ist. Einige Geräte sind möglicherweise zu keinem Zeitpunkt verfügbar. Aus verschiedenen Gründen. Es ist nicht das beste Szenario, die Aktivität anderer Geräte zu stoppen, wenn ein Teil nicht verfügbar ist. Es ist notwendig, das zu legalisieren, was nicht verhindert werden kann.
Die Plattform implementiert das Paradigma von Versprechungen zur Bereitstellung von Veranstaltungen. Das erste Gerät schließt sich dem Versprechen des zweiten an, ihm Informationen zu geben. Es gibt jedoch keine Garantien. Der Abonnent muss entscheiden, was zu tun ist, wenn ihm Daten nicht rechtzeitig zur Verfügung gestellt werden.
Das Problem der synchronen Kommunikation wird gelöst, indem Ereignisse über den Bus mit Verbindungen zu synchronen Kanälen übertragen werden. Das Synchronkanalprotokoll wird durch die Art des Ereignisses selbst bestimmt. Sie können beispielsweise ein Ereignis mit dem Typ "do-render-video-stream" senden und IP-WEB-Kameras als Nutzdaten senden. Somit weiß der Empfänger, dass Sie den Videostream von der angegebenen Adresse abspielen müssen.

Aber wie funktioniert der Bus physisch? Die Umsetzung des Busses liegt bei der Gemeinde. Der Reifen dehnt sich mit dem Transport aus, den Ihr Projekt benötigt. Beispielsweise wird ein Ereignis über http empfangen und über UART weitergeleitet. Für alle Elemente des Ökosystems wird sich äußerlich nichts ändern.
- Virtuelle IoT-Geräte
Für ThingJS ist eine Sache nicht nur eine physische Sache, sondern auch eine spezielle Anwendung - eine virtuelle Sache. Darüber hinaus kann eine physische Sache mehrere virtuelle Dinge (Anwendungen) enthalten, die die Ressourcen einer physischen Sache nutzen.
Mit diesem Ansatz können Sie die Interaktion zwischen dem bedingten Backend (Controller / Server / Cloud usw.) und dem Frontend (Browser, Anwendung usw.) sowie b2b und sogar f2f vereinheitlichen. Erstellen Sie eine Matrix, keine Hierarchie von Interaktionen.

Ein einfaches Beispiel wäre eine WEB-Kamera, die an sich eine virtuelle Sache hat - eine Benutzeroberfläche. Wenn der Benutzer zur Adresse http://192.168.4.1 wechselt , wird die WEB-Seite geöffnet, auf der das virtuelle Objekt zu "leben" beginnt. Die Kamera (physische Sache) und die Seite (virtuelle Sache) werden automatisch zu einem Ökosystem, in dem ein einheitlicher Datenbus verfügbar ist. Dadurch kommuniziert das virtuelle Ding mit dem physischen. In diesem Fall: Das physische Objekt teilt dem virtuellen Objekt über den Bus die Adresse des Videostreams, seinen Status usw. mit, und das virtuelle Objekt zeigt dem Benutzer das Video und gibt dem physischen Objekt die erforderlichen Befehle.
Die logische Fortsetzung ist die Fähigkeit, virtuelle Dinge in den Clouds zu hosten und in ein gemeinsames Ökosystem einzubeziehen. Auf diese Weise können Sie virtuelle Geräte mit riesigen Ressourcen erstellen, die Probleme lösen, die beispielsweise für KI verfügbar sind.
Sie können solche Geräte selbst erstellen oder bereits erstellte verwenden. Das Stockholm-Syndrom ist besiegt. Sie bestimmen selbst, wovon Ihr Projekt abhängt und wie Sie es entwickeln werden.
ThingJS-Anwendungsstruktur

Technologie-Stack
Die ausgewählte Hardwareplattform ist der ESP32- Controller. Die Plattform wurde als hardwareunabhängig konzipiert. Leider war keine Zeit für die Partitionierung auf anderen Geräten.
Für die Entwicklung der Firmware werden die empfohlenen Espressif-Tools verwendet . Die Firmware wurde in C entwickelt. Der cmake-Sammler. Das Projekt verwendet das Komponentenkonzept, das ebenfalls von Espressif gefördert wird.
Zusätzlich zu esp-idf wird Mongoose WEB Server sowie ein modifizierter JavaScript-Interpreter Mongoose mJS verwendet .
Für die Anwendungsentwicklung wird JavaScript mit dem VUE 2-Framework verwendet. Erstellen Sie Anwendungen mit Webpack. Der Paketmanager ist npm. Die VUE CLI wurde als Basis für die Entwicklungsumgebung verwendet.
Um die Anwendungsvisualisierung zu standardisieren und die Kreativität der Benutzeroberfläche zu lindern, ist das vuetifyjs- Paket in der Plattform enthalten.
Funktionen der Entwicklungsumgebung
Für JavaScript-Entwickler (virtuelle Dinge):
- Empfohlene IDE - WEBStorm;
- Alle Gewinne, die VUE CLI und IDE bringen;
- Systeminternes Debuggen von Anwendungen (mJS-Debugger auf dem Controller);
- MJS implementiert den Debugger-Befehl, mit dem Sie den Debugger an einer beliebigen Stelle aufrufen können.
- Hot Upload aktualisierter Dateien auf den Controller während der Entwicklung (JavaScript-Entwickler können ohne diese Funktion bereits nicht leben);
- Die Laufzeitentwicklung wird mit einem echten Controller gepaart. Sie programmieren und sehen genau dort das Ergebnis auf der Hardware.
- Konfigurierte ESLint zum Verständnis von Plattformobjekten.
Für C-Entwickler (physische Dinge):
- Empfohlene IDE - CLion;
- Alle Gewinne esp-idf und IDE;
- Die Plattform ist im Rahmen des esp-idf-Konzepts in Komponenten unterteilt.
- Einfache Integration in die native Komponentenplattform.
Unterstützte Geräte
Derzeit wird nur ESP32 unterstützt. Der Chip ist aufgrund seiner Verfügbarkeit mit erstaunlichen technischen Eigenschaften beliebt. Auf dieser Grundlage wurden viele vorgefertigte IoT-Geräte erstellt, die unter ThingJS verwendet werden können.
Vergleich mit Mitbewerbern
Ich schlage vor, nicht so weit zu rennen. Ich wage es nicht, kommerzielle Plattformen als Konkurrenten zu bezeichnen. Und Open Source erscheint und verschwindet, ohne eine merkliche Spur zu hinterlassen. Daher habe ich keinen Vergleich gemacht. Wenn jedoch jemand einen Wunsch hat, bin ich bereit, das Ergebnis seiner Arbeit hier zu veröffentlichen.
Schnellstart
Ich muss nur zuschauen
Ich möchte es versuchen
Um die Plattform auf echter Hardware zu testen, benötigen Sie jedes auf ESP32 basierende Gerät mit Flash 4 MB und die Fähigkeit, es über USB zu flashen. Die ESP32-Kernplatine v2 ist jedoch am besten geeignet.

Sie können solche Dinge problemlos bei Aliexpress oder Ebay kaufen. Darüber hinaus gibt es in Russland sogar Repräsentanzen. Ich persönlich kaufe in St. Petersburg .
Um den Betrieb der Testanwendung „Blink“ zu testen, müssen Sie eine LED anschließen. Einige Versionen der Karten verfügen über eine vorinstallierte LED, die an GPIO2 angeschlossen ist. Wenn Sie ein solches Board haben, können Sie nichts tun. Das Blinken sollte ohne unnötige Bewegungen funktionieren. Wenn Sie nur eine Diode (Netzteil) haben, müssen Sie die Anzeigediode selbst anschließen. Das ist nichts kompliziertes.
Sie benötigen eine Anzeige-LED und einen Widerstand von 1 bis 5K.

Sie müssen nur noch das Benutzerpaket auf dem Gerät bereitstellen. Sie können es hier nehmen . Dort finden Sie Anweisungen zur Bereitstellung.
Blink App
Montage von der Quelle
Blink ist ein einfaches Ökosystem, das aus einem virtuellen Gerät, das die Benutzeroberfläche implementiert, und einem physischen Gerät besteht. Ein virtuelles Gerät startet von einem physischen Gerät, wenn Sie über einen Browser darauf zugreifen.
Das Skript ist einfach. Bei der Installation der Anwendung auf einem physischen Gerät beginnt die LED (zuvor angeschlossen) mit einer Frequenz von 1 Hz zu blinken. Der Benutzer kann das Blinken der Diode über die Schnittstelle ein- oder ausschalten. Sie können das Video im Abschnitt "Ich kann nur sehen" ansehen.
Quellen befinden sich im Repository src / applications / blink. Um Blink zu sammeln und damit zu spielen, benötigen Sie nur dieses Repository. Stellen Sie sicher, dass Sie git, npm und nodejs bereits installiert haben.
git clone --branch alpha https://github.com/rpiontik/ThingJS-front cd ThingJS-front npm install npm run build
Wenn alles reibungslos verlief, erhalten Sie Folgendes:

Herzlichen Glückwunsch! Sie haben Ihre erste ThingJS-App erstellt. Sie finden es im Ordner dist / apps / blink und versuchen sofort, es auf dem Gerät zu installieren, basierend auf dem Video aus dem Abschnitt "Ich schaue nur" .
Anwendungszusammensetzung
Sie können sich mit allen Details der Anwendung selbst vertraut machen. Ich werde mich auf mehrere Dateien konzentrieren.
manifest.json
{ "name": "Blink", "vendor" : "rpiontik", "version" : 1, "subversion" : 0, "patch" : 0, "description": { "ru": " ", "en": "Blink Example" }, "components": {...}, "scripts": {...}, "requires" : {...} }
Wie der Name der Datei angibt, ist dies das Anwendungsmanifest. Es enthält allgemeine Metadaten, deren Zweck leicht zu erraten ist. Zusätzlich gibt es drei wichtige Blöcke. Schauen wir sie uns genauer an:
Komponentenblock
"components": { "blink-app": { "source": "blink.js", "intent_filter": [ { "action": "thingjs.intent.action.MAIN", "category": "thingjs.intent.category.LAUNCH" } ] } }
Der Block beschreibt die gesamte Komponentenbasis der Anwendung. Das Feld „source“ zeigt auf den Mount-Punkt der Komponente (siehe blink.js) und ist der Assembly-Einstiegspunkt für das Webpack ( Eintrag ). Somit wird jede Komponente in einem separaten Bundle ausgegeben. Dieses Bundle wird nach Bedarf geladen ( Lazy Load ).
Eine wichtige Struktur ist intent_filter . Wenn Sie zufällig für Android programmieren, werden Sie etwas finden, das Ihnen vertraut ist. Und machen Sie keinen Fehler. Das System generiert Schnittstellen- und Serviceereignisse, die die Komponente abonniert. Wenn ein Ereignis eintritt, das die Filterbedingungen erfüllt, wird die Komponente geladen und die Steuerung an den Einhängepunkt übertragen.
In diesem Fall abonniert die Komponente "Blink-App" das Startereignis der Hauptschnittstellenkomponente der Anwendung. Wenn der Launcher die Anwendung startet, wird diese Komponente eingeführt.
Wenn Sie das Manifest durch Ändern der Zeile ändern
thingjs.intent.category.LAUNCH >> thingjs.intent.category.PREFERENCE
Nach der Montage und Installation stellt sich heraus, dass die Anwendung auf dem Desktop nicht mehr geöffnet ist. Im Abschnitt "Einstellungen" wurde jedoch eine neue "Kachel" angezeigt. Gleichzeitig hat sich funktional nichts geändert.
Daher haben wir dem Launcher mitgeteilt, dass diese Komponente ein Schnittstellenelement zum Anpassen unserer Anwendung ist. Und diese Komponente begann in den Einstellungen zu erscheinen.
Skripte blockieren
"scripts": { "entry": "blink", "subscriptions" : ["$-script-restart", "blink"], "modules": { "blink": { "hot_reload": true, "source": "scripts/blink.js", "optimize": false } } }
Dieser Block ähnelt in seiner Funktion dem Block "Komponenten", beschreibt jedoch die Basis der Anwendungskomponenten auf der Controllerseite.
Es zeigt deutlich den Einstiegspunkt an. Im Feld "Eintrag". Unabhängig davon werde ich darauf achten, dass das Skript bei der Installation der Anwendung nicht sofort gestartet wird. Es wird nur gestartet, wenn eines der Ereignisse eintritt, für die das Skript abonniert ist.
Das Feld "Abonnements" ist für Abonnements verantwortlich. Jetzt zeigt es zwei Ereignisse an:
- $ -script-restart - tritt auf, wenn das System gestartet oder neu gestartet wird ;
- Blink ist ein benutzerdefiniertes Ereignis, das für das Blink-Ökosystem relevant ist.
Im Block „Module“ folgt eine Beschreibung der Zusammensetzung von Skripten. Ich werde zwei Felder beachten:
- hot_reload - Wenn dieses Feld auf true gesetzt ist, wird eine Datei beim Ändern im Entwicklungsmodus automatisch auf den Controller heruntergeladen (Hot Reload).
- Optimieren - Wenn dies der Fall ist, wird das Skript beim Erstellen des Projekts optimiert und aggregiert.
Der Block "erfordert"
"requires" : { "interfaces" : { "blink" : { "type" : "bit_port", "required" : true, "default" : 2, "description" : { "ru" : "LED ", "en" : "LED indicator" } } } }
Sie haben wahrscheinlich bereits bemerkt, dass Sie bei der Installation der Anwendung den Pin auswählen müssen, an dem die LED blinkt. Standardmäßig ist es jedoch bereits als GPIO2 ausgewählt. Dieser Block ist für diese Einstellungen verantwortlich.
In diesem Block werden Abhängigkeiten angezeigt. In diesem Fall muss die Anwendung eine Schnittstelle mit dem Typ "bit_port" bereitstellen, damit sie funktioniert. Diese Schnittstelle ist eine erforderliche Anforderung (erforderlich = wahr) und standardmäßig ist GPIO2 angegeben (Standard = 2). Es wird mit dem Namen "blink" in das Skript projiziert.
Bei der Installation der Anwendung wird das Profil des Geräts berücksichtigt, auf dem die Skripte bereitgestellt werden. Dieses Profil listet die verfügbaren Schnittstellen und die verfügbaren Hardwareressourcen für sie auf (insbesondere Pins und ihre Kombinationen). Überprüft die Kompatibilität von Anforderungen und Ausrüstung. Wenn das Gerät die Anforderungen der Anwendung erfüllen kann, wird dem Benutzer ein Ressourcenzuweisungsschema angezeigt, bei dem Primärressourcen automatisch zugewiesen werden, wobei Empfehlungen aus dem Manifest berücksichtigt werden. Das heißt aus dem gleichen "Standard" -Feld.
Somit können mehrere Anwendungen auf einem Gerät installiert werden, die Hardwareressourcen untereinander gemeinsam nutzen können.
blink.js
import App from './Blink.vue'; import Langs from './langs'; $includeLang(Langs); $exportComponent('blink-app', App);
Die Datei ist der Einhängepunkt der im Manifest angekündigten Komponente (siehe manifest.js / components). Sie registriert die VUE-Komponente 'blink-app' über die Abstraktionsmethode $ exportComponent und registriert auch das Sprachpaket.
Sie fragen sich vielleicht - warum solche Schwierigkeiten? Warum registrieren Sie nicht sofort die VUE-Komponente, die Sie in der Quelle angegeben haben? Tatsache ist, dass das Manifest öffentliche Komponenten beschreibt. Diese Komponenten können von Anwendungen von Drittanbietern angefordert werden (Laufzeitabhängigkeiten). Der Einhängepunkt kann wiederum verwandte Komponenten (für den internen Gebrauch) sowie Dienste registrieren. Bereiten Sie also die Komponentenumgebung vor.
Blink.vue
export default { name: 'Blink', watch: { blink_state (state) {
Der Code spricht für sich. Wenn die Eigenschaft "blink_state" geändert wird, wird eine Nachricht mit dem aktuellen Wert an den Bus ($ bus) gesendet. Dies ist alles, was Sie tun müssen, damit das Skript auf der Controllerseite den gewünschten Befehl erhält.
scripts / blink.js
let active = true; let state = true;
Im Allgemeinen ist der Code der klassischen Verwendung eines Timers in JavaScript sehr ähnlich. Nur dass es nicht in diesem Dialekt von JavaScript ist. Es ist in der Plattform implementiert. Treffen Sie diese mJS . Weitere Informationen finden Sie auf der offiziellen Seite des Projekts.
Für die Bedürfnisse der Plattform wird der Dialekt finalisiert. Es wurden Timer sowie ein nützlicher Befehl wie "Debugger" eingeführt. Nun, der Debugger selbst. Mehr dazu separat im Abschnitt "Entwicklungsumgebung" .
Achten Sie auf die globalen Objekte der Plattform. Sie werden mit dem Zeichen "$" benannt.
- $ res - enthält Ressourcen, die dem Skript zugewiesen sind.
- $ bus - Busschnittstelle.
Weil Die Anwendung forderte eine Schnittstelle mit dem Typ "bit_port" (siehe profile.json / require) und dem Namen "blink" an. Sie wurde als $ res.blink angegeben. Die Schnittstelle implementiert nur drei Funktionen:
- set (Wert) - Stellen Sie den GPIO-Pegel ein
- get () - Liefert den aktuellen GPIO-Level
- Richtung (Wert) - GPIO-Modus einstellen
Für die Richtungsfunktion werden verfügbare Konstanten über dieselbe Schnittstelle $ res.blink beschrieben .: DIR_MODE_DISABLE; DIR_MODE_DEF_INPUT; DIR_MODE_DEF_OUTPUT; DIR_MODE_INPUT_OUTPUT_OD; DIR_MODE_INPUT_OUTPUT.
Das Abonnieren von Busereignissen erfolgt über die Methode $ bus.on. In diesem Fall werden alle Ereignisse, die das Skript abonniert hat, an den Handler gesendet. Der Handler akzeptiert drei Parameter:
- Ereignis - Ereigniskennung . In diesem Fall sind nur zwei möglich: "$ -script-restart" und "blink". Davon wird nur einer verarbeitet - blink. Das Abonnieren des zweiten Skripts ist nur erforderlich, damit das Skript sofort beim Systemstart gestartet wird.
- Inhalt - Daten können mit dem Ereignis kommen. Ihre Größe ist basierend auf der Länge der Ereigniskennung auf 126 Byte begrenzt.
- Daten - Daten, die beim Abonnieren des Ereignisses als zweiter Parameter übertragen werden. Und in diesem Fall sind sie null.
Schnittstellen sind erweiterbar. Im Folgenden finden Sie eine Beschreibung zum Erstellen Ihrer eigenen Benutzeroberfläche.
Schnittstellenimplementierung
Mit ThingJS können Sie verfügbare Hardware- und Serviceressourcen über spezielle Schnittstellen erweitern. Sie können unabhängig voneinander eine Schnittstelle erstellen, die komplexe, genaue, geladene usw. implementiert. funktional.
Beispielsweise können Sie eine Integrationsschnittstelle mit Ihrem Cloud-Service implementieren. Oder ein asynchroner Hintergrundprozess, mit dem das Skript Nachrichten austauschen kann. Nun, oder implementieren Sie Display-Unterstützung. Es wird ebenso einfach herzustellen und zu verwenden sein. Sowohl du als auch andere. Richtig, dafür müssen Sie C kennen.
Betrachten Sie die Implementierung der bit_port-Schnittstelle, die im Blink-Beispiel verwendet wird. Zum Starten müssen Sie das Alpha-Release-Projekt ThingJS-template bereitstellen. Die Bereitstellungsdokumentation befindet sich im Projekt selbst.
git clone --branch alpha https://github.com/rpiontik/ThingJS-template
Das Projekt umfasst Komponenten:
- ThingJS-Boards - enthält Gerätekonfigurationen. Bisher nur ESP32_CORE_BOARD V2 und kompatibel;
- ThingJS-extern - Bibliotheken von Drittanbieterprojekten, die ThingJS verwendet;
- ThingJS-Core - Plattformkern;
- ThingJS-front - Anwendungsentwicklungsumgebung;
- ThingJS-stdi - Standardschnittstellen.
Wir interessieren uns für das ThingJS-stdi-Projekt. Seine Struktur ist wie folgt:
Tatsächlich interessiert uns nur eine Datei - Implementierung / tgsi_bit_port.c. Es enthält alles, was einer gesonderten Erklärung bedarf.
void thingjsBitPortRegister(void) { static int thingjs_bit_port_cases[] = DEF_CASES( DEF_CASE(GPIO0), DEF_CASE(GPIO2), DEF_CASE(GPIO3), DEF_CASE(GPIO4), DEF_CASE(GPIO5), DEF_CASE(GPIO12), DEF_CASE(GPIO13), DEF_CASE(GPIO14), DEF_CASE(GPIO15), DEF_CASE(GPIO16), DEF_CASE(GPIO17), DEF_CASE(GPIO18), DEF_CASE(GPIO19), DEF_CASE(GPIO21), DEF_CASE(GPIO22), DEF_CASE(GPIO23), DEF_CASE(GPIO25), DEF_CASE(GPIO26), DEF_CASE(GPIO27), DEF_CASE(GPIO32), DEF_CASE(GPIO33) ); static const struct st_thingjs_interface_manifest interface = { .type = "bit_port", .constructor = thingjsBitPortConstructor, .cases = thingjs_bit_port_cases }; thingjsRegisterInterface(&interface); }
Die Funktion thingjsBitPortRegister registriert eine Komponente im ThingJS-Kern. Dazu ruft es die Funktion thingjsRegisterInterface auf, an die es eine Struktur mit einer Schnittstellenbeschreibung übergibt.
- Typ - Schnittstellenkennung. Er ist der Typ, der in der Datei manifest.json der Anwendung angegeben ist.
- Konstruktor - Link zum Schnittstellenkonstruktor. Die Funktion wird jedes Mal aufgerufen, wenn Sie eine neue Instanz der Schnittstelle erstellen müssen.
- case ist ein Array, das mögliche Hardwareressourcen beschreibt, die die Schnittstelle für ihre Arbeit verwenden kann. In diesem Fall handelt es sich um einzelne GPIOs. Ihre Kombinationen oder Abhängigkeiten können jedoch separat beschrieben werden.
Der Schnittstellenkonstruktor stellt die Schnittstelle in der mJS-Maschine bereit.
mjs_val_t thingjsBitPortConstructor(struct mjs *mjs, cJSON *params) {
Wie Parameter übergeben werden:
- mjs - globaler Ausführungskontext;
- params - Parameter für die Schnittstelleninitialisierung. In diesem Fall ist dies die GPIO-Nummer.
Ein mJS-Schnittstellenobjekt wird erstellt, in dem die Methoden und Eigenschaften der Schnittstelle bereitgestellt werden:
- gpio - schreibgeschützte Eigenschaft, in der die Anzahl der verwendeten GPIO gespeichert ist;
- set - Methode zum Einstellen des Signalpegels;
- get - eine Methode zum Erhalten des aktuellen Signalpegels;
- Richtung - Einstellen des GPIO-Modus;
Außerdem werden Konstanten bereitgestellt, mit denen Skripte arbeiten können (DIR_MODE_DISABLE, DIR_MODE_DEF_INPUT usw.).
Nach dem Erstellen der Schnittstelle wird sie im globalen $ res-Objekt unter einer bestimmten Kennung (im Blink-Beispiel ist es "blink") bereitgestellt. Ein Anwendungsbeispiel finden Sie im Abschnitt Blink ( scripts / blink.js ).
Sie können Schnittstellen in separate Komponenten oder Pakete formatieren. Auf diese Weise können Sie die Firmware als Lego zusammenstellen.
Entwicklungsumgebung
Anwendungsentwicklung
Die Anwendungsentwicklungsumgebung basiert auf der VUE CLI, die an die Anforderungen der ThingJS-Plattform angepasst wurde. Dies ist eine harte Gabel, inkl. Es lohnt sich, auf neue Funktionen von VUE CLI zu warten, wenn sie das Leben direkt erheblich erleichtern.
Um die Umgebung bereitzustellen , müssen Sie das Alpha-Release-Projekt ThingJS-front klonen. Stellen Sie sicher, dass Sie git, npm und nodejs bereits installiert haben.
git clone --branch alpha https://github.com/rpiontik/ThingJS-front cd ThingJS-front npm install
Bei der Entwicklung empfehle ich die Verwendung des IDE WEBStorm.
Die Zusammensetzung und Struktur des Projekts erbt von VUE CLI. Ich werde signifikante Unterschiede reflektieren:
- Überarbeitete Build-Skripte im Build-Ordner.
- Eine Umgebungsvariable "HW_DEVICE_URL" wurde der dev-Umgebungskonfiguration (config / dev.env.js) hinzugefügt. Es ist erforderlich, einen Link zu dem physischen Gerät anzugeben, mit dem Sie arbeiten werden.
- Der Systemordner src / applications wurde angezeigt. Es enthält Anwendungen, die automatisch erstellt werden. Insbesondere enthält es zwei Anwendungen: ante (Launcher) und blink (Anwendung).
- Alles über dem Ordner src / applications wird als Plattformmodul und Ressourcen betrachtet. Natürlich können Sie Änderungen daran vornehmen, aber in diesem Fall werden sie erst nach dem Flashen im Controller angezeigt. T.ch. Wenn Sie sich keine konkreten Ziele setzen, ist es besser, diese nicht zu berühren.
Zum Testen können Sie den Dev-Server sofort starten. Obwohl Sie ohne die physische Hardware nicht vollständig entwickeln können, beeinträchtigt dies die Entwicklung der Schnittstelle nicht. Und so startet der Entwickler-Server:
npm run dev
Das Ergebnis sollte ungefähr so aussehen:

Wenn Sie den Browser öffnen und http://0.0.0.0:8080 in die Adressleiste eingeben , wird die Plattform im Entwicklungsmodus angezeigt :

Der Schnittstellenentwicklungsprozess selbst unterscheidet sich nicht wesentlich von der klassischen Front-End-Entwicklung auf VUE. Abgesehen davon, dass es globale Plattformobjekte gibt, die Sie beachten müssen:
- $ const - enthält Plattformkonstanten sowie Sprachpakete;
- $ bus - Datenbus;
- $ store - globaler Speicher (VUEX).
Anhand der Beispiele können Sie verstehen, wie Sie sie verwenden.
Mehrsprachigkeit wird auf einfachste Weise implementiert - durch den Filter „lang“. Geben Sie eine Sprachkonstante an, die je nach Sprache der Benutzeroberfläche in Text interpretiert wird.
v-bind:label="'BLINK_SATE' | lang"
Um die Funktionen der Entwicklungsumgebung vollständig bewerten zu können, benötigen Sie einen vorbereiteten (zusammengefügten) Controller. Sie können die Firmware selbst aus dem Projekt zusammenstellen oder die vorgefertigte Firmware und das Dienstprogramm von hier aus verwenden .
Nachdem Sie den Controller geflasht und eine Verbindung zum Netzwerk hergestellt haben, müssen Sie sicherstellen, dass der Controller von Ihrem Computer aus über IP erreichbar ist. Geben Sie dazu im Browser http: // [ Controller- IP ] ein. Die WEB-Schnittstelle sollte sich öffnen.
Jetzt müssen Sie die Adresse des Controllers in der Datei config / dev.env.js angeben
'use strict' const merge = require('webpack-merge') const prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"', HW_DEVICE_URL: '"http://[IP ]"'
Wenn der Entwicklungsserver gestartet wurde, stoppen Sie ihn und starten Sie ihn neu. Starten Sie in Zukunft den Entwicklungsserver nach dem Ändern der Build-Dateien, der Konfiguration und des Anwendungsmanifests immer neu.
Obwohl bei der Arbeit in einer Entwicklungsumgebung alle Anwendungen angezeigt werden, die sich im installierten Ordner src / application befinden, funktionieren nur diejenigen, die tatsächlich auf dem Controller installiert sind. Dies ist keine Funktion, sondern ein Alpha-Fehler. In Zukunft erfolgt die Synchronisation von Hardware und Entwicklungsumgebung automatisch. Im Moment müssen Sie die Anwendung jedoch manuell auf dem Controller installieren, damit die Umgebung sie „einbindet“ und mit dem synchronisiert, was sich in dev befindet.
Wir montieren die Anwendung im Prod-Modus:
npm run prod
Installieren Sie die gesammelten Anwendungen direkt auf dem Controller. Nicht über den Entwickler-Server .
Jetzt können Sie mit der Entwicklung beginnen. Alle Änderungen, die Sie an Ihren Dateien vornehmen, beginnen automatisch mit der Neuerstellung von Anwendungen und das Bild auf dem Bildschirm ändert sich (Hot-Reload). Die gleiche Regel gilt für Controller-Skripte. Beispielsweise können Sie den Debugger-Befehl zum Blink-Anwendungsskript hinzufügen und das Ergebnis anzeigen.
Wenn sich nun der Status des Kontrollkästchens der Blink-Anwendung ändert, gibt die Entwicklungsumgebung die folgende Meldung aus:

Durch Klicken auf den Link "Debugger starten" gelangen Sie zum Debugger. Die Zeile, in der der Stopp aufgetreten ist, wird angezeigt.

Der Debugging-Prozess selbst unterscheidet sich nicht wesentlich von anderen Debuggern.

Der Debugger ist in vier Abschnitte unterteilt. Im zentralen Code selbst. Links installierte Anwendungen auf dem Controller. Ihre Struktur und Zusammensetzung. Richtig, Inspektor. Das Protokoll wird unten angezeigt. Unten links sehen Sie den aktuellen Status der Kommunikation mit der Steuerung.
Die Debugging-Umgebung befindet sich in einer intensiven Entwicklung. Es müssen noch viele weitere Überwachungs- und Debugging-Tools erstellt werden. Ich entschuldige mich im Voraus für mögliche Fehler.
Firmware-Entwicklung
Die Firmware-Entwicklung basiert auf dem von Espressif vorgeschlagenen Konzept. Ich kann die native Dokumentation in dieser Hinsicht nicht übertreffen.
Für einen schnellen Start wurde ein Repository vorbereitet. Es enthält Bereitstellungsinformationen. Ein Anwendungsbeispiel finden Sie unter „Implementieren einer Schnittstelle“ .
Die Montage ist sehr einfach und in buchstäblich 1-2 Stunden werden Sie die Firmware bereits ohne Probleme montieren.
Was weiter?
Wenn die Plattform für die Community von Interesse ist, ist Folgendes geplant:
- Entwicklung einer Debugging-Umgebung;
- Standardisierung der Benennung von Schnittstellen, Ereignissen, Komponenten;
- Detaillierte Dokumentation auf der Plattform;
- Cloud-Hosting für virtuelle Dinge;
- Laufzeit-Repositorys
- Partitionierung auf verschiedene fertige Geräte.
Außerdem suche ich Leute, die die Plattform mit mir entwickeln möchten. Es ist bereits sehr umfangreich und ehrgeizig. Ich gehe von einer gleichberechtigten Zusammenarbeit aus, deren Ziel es sein wird, die Plattform nach einem vollwertigen OpenSource-Prinzip zu entwickeln.
pull- .
Referenzen
ThingJS:
ThingJS:
:
FAQ
.