Step 7 S7 -1200 HTML Array of Struct lesen mit JavaScript

Malaus

Level-2
Beiträge
21
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich bastel momentan an einer Website für meine Siemens S7 1200 Steuerung und bin bisher sehr gut voran gekommen. In der Steuerung selbst verwende ich einen Array um Laufzeiten mit Datum zu speichern. Diesen Array möchte ich nun auf der Website darstellen.
Da die Anzahl vorher nicht bekannt ist, dachte ich daran das ich das per JavaScript auslese und die Daten für die Website aufbereite.

Leider kann ich nicht mal per Javascript eine bestimmte Info aus dem Array lesen.
Code:
[FONT=Consolas][COLOR=#569cd6]let Array = := "Variablen".state[1].Datum:;[/COLOR][/FONT]

Was ist da falsch?

Auf der Website funktioniert es mit:
Code:
<td>:=[COLOR=#569CD6][FONT=Consolas]"Variablen".state[1].Datum:</td>[/FONT][/COLOR]

Hoffe mir kann jemand helfen. :)
 
Das was du auf der Webseite siehst, wird dir an der gleichen Stelle auch im Javascript eingesetzt. Mit Arrays geht da erst mal gar nichts, die Standardvorgehensweise ersetzt dir immer nur die AWP-Anweisungen durch Variablenwerte, nicht mehr. Komplette Arrays oder Structs lassen sich dort auch soweit ich weiß nicht angeben.

Etwas mehr Dynamik ist erst mit den neueren 1500er Steuerungen möglich, dort wurde ein Webapi ergänzt mit dem sich auch ohne feste AWP Definitionen Variablen lesen lassen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich kenne mich nun nicht damit aus, wie das bei Siemens läuft, aber wenn ich Thomas' Antwort lese, heißt das, daß die Syntax

:="Meine Variable":

ist, um etwas einsetzen zu lassen.

Kann es eventuell sein, daß im oberen Code von #1 das Leerzeichen zwischen = und " das Problem ist? Wie flexibel ist Siemens hier?

Prinzipiell sollte es ja funktionieren, ein Array in Javascript zu füllen. Nur nicht per Schleife, sondern händisch.
Und das bedeutet, Deine Array-Größe ist von vornherein festgelegt.

Dann sagst Du eben, Du kannst z.B. 100 Werte anzeigen. Dann müßtest Du Dir händisch ein Array mit 100 Werten füllen. Das kann man ja über Excel relativ schnell coden.
In der Seite selber kannst Du dann mit dem Array[1..100] arbeiten.

Und wenn Du nur 80 Elemente auslesen kannst, was passiert mit den Variablen, die "nicht existieren"? Die sind dann ggf. undefined in Javascript. Darauf kann man ja abfragen...
 
Das Problem ist nicht Javascript, sondern dass der Webserver nicht so einfach gesamte Arrays einbinden kann.
Bei der 1500er ist auch in neueren Versionen ein Array-Zugriff in etwas anderer Weise hinzugekommen, das ist aber soweit ich weiß bei der 1200er wie andere Funktionen nicht ergänzt worden. Allgemein wurde beim Webserver im Laufe der Zeit viel geändert, d.h. was das konkrete Modell kann muss man genau anhand der Firmwareversion und eines evtl. alten Handbuchs herausfinden. Nach meinem Gefühl wurde irgendwann nur noch die 1500er weiterentwickelt und die Funktionen in der 1200er nicht mehr ergänzt. Zu Anfang waren die Webserverfunktionen zumindest was die AWP Anweisungen betrifft, bei 1200 und 1500 identisch.

Wenn du wirklich flexibel und unabhängig von der Steuerungsvariante und Firmwareversion sein willst, dann kannst du in der SPS im Programmcode einen oder mehrere Strings (z.B. als Komma getrennte Liste oder gleich im Json-Format) generieren, und diese dann in Javascript verarbeiten. Das hat zwar den Nachteil Stringhandling im SPS-Programm zu haben, macht dafür die Webseite erheblich schneller als mit Einzelwerten. Gerade der Webserver der 1200 wird bei vielen Einzelvariablen schnell sehr langsam, bei 100 Variablen in einer Seite dauert die Auslieferung dann mehrere Sekunden.
 
ja, die Idee mit JSON hatte ich auch...
Den String könnte man sich ja schnell in der SPS zusammenbauen und in Javascript wieder in ein Array umwandeln
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja mir ist das auch schon aufgefallen, dass die Website sehr schnell langsamer wird. Daher habe ich auch schon angefangen im Programm selbst alles auszulegen, so dass ich es nur noch in der Website anzeige und nicht noch mit Javascript bearbeite.
Schade, dass das mit einem Array nicht direkt funktioniert. Ich probiere das mal mit den Strings aus.

Danke euch!
 
Was für ein Datentyp besitzt denn "Variablen".state[1].Datum, und was wird in deinem <td> ausgegeben?
Wenn das ein Datumsstring wie 12.02.2021 ist, dann musst du das Ganze in deinem Javascript-Teil noch mal in Anführungszeichen packen, also:
Code:
let Array = ":="Variablen".state[1].Datum:";

Wenn der AWP-Webseiten-Parser das noch verarbeiten kann. Das ist dann aber nicht wirklich ein Array, sondern ein String.
 
Datum ist ein DTL und die Laufzeit ist INT. Beides speichere ich in einem Array of Struct.
Die Array Größe habe ich jetzt mal auf 50 definiert. Und da ja von vorne rein nicht alles belegt ist, habe ich mir einen Counter dazu gemacht, der mir die Info gibt, wieviele Variablen im Array existieren. Und mit dieser Info wollte ich das eben in JavaScript aufbereiten und es als Tabelle in HTML anzeigen lassen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe das mal mit den zusätzlichen Anführungszeichen probiert und das hat funktioniert.

Code:
[COLOR=#333333][FONT=Courier]let Array = ":="Variablen".state[1].Datum:";[/FONT][/COLOR]

Ich kann also Array´s mit einem expliziten Pfad anzeigen lassen bzw in JavaScript benutzen.
Allerdings funktioniert es nicht, wenn ich nachträglich aus der 1 eine 2 mache.

Habe das auch schon mit einer replace funktion ausprobiert, aber da ändert er nur den String der in dem Pfad des Arrays steckt.
Ich probiere nun mal das hier aus:

Wenn du wirklich flexibel und unabhängig von der Steuerungsvariante und Firmwareversion sein willst, dann kannst du in der SPS im Programmcode einen oder mehrere Strings (z.B. als Komma getrennte Liste oder gleich im Json-Format) generieren, und diese dann in Javascript verarbeiten. Das hat zwar den Nachteil Stringhandling im SPS-Programm zu haben, macht dafür die Webseite erheblich schneller als mit Einzelwerten. Gerade der Webserver der 1200 wird bei vielen Einzelvariablen schnell sehr langsam, bei 100 Variablen in einer Seite dauert die Auslieferung dann mehrere Sekunden.
 
Allerdings funktioniert es nicht, wenn ich nachträglich aus der 1 eine 2 mache.

"Nachträglich" meinst Du: mit Javascript!?

Ja, das kann nicht funktionieren.

Du mußt unterschieden zwischen "Serverside" (in der SPS) und "Clientside" (in Deinem Browser).
Das Einfügen der Variablen in Deinen Code passiert "serverside", also vor der Auslieferung des Codes an Deinen Browser.

Erst wenn die Seite geladen ist, fängt Javascript an, zu arbeiten/funktionieren. Zu dem Zeitpunkt sind also die Variablen schon eingesetzt und Du kannst nur mit den Daten arbeiten, die schon im Dokument vorhanden sind.

Man kann sich z.B. auch versteckte Formularfelder machen, um Dokumente zu speichern.
Aber mit Strings im JSON-Format bist Du wesentlich flexibler. Die kannst Du dann "clientside", also im Browser aufdröseln und relativ performant damit arbeiten.
 
Ich habe mir nun mal die Thematik mit JSON-Format angeschaut. Das ist ja ein komplett anderer Ansatz, wie ich das bisher aufgebaut habe.

Da ich noch nicht so viel Erfahrung mit Siemens SPS und JSON habe, stelle ich mir nun die Frage, ob ich alles auf JSON auslegen sollte, oder nur die Thematik mit dem String.
So, wie du das schreibst, hört es sich für mich an, als wäre es flexibler, wenn ich alles auf JSON umstelle, richtig?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zumindest die Übertragung von der SPS in den Quellcode ist einfacher.

Du baust Dir einen String zusammen, wie er nach der JSON-Notation ein Liste repräsentiert. Die SPS braucht dann nur EINE Variable abfragen und in den Quelltext zu schreiben.

Und im Quelltext kannst Du dann mit JSON.parse() eine Liste draus machen, die Du bearbeiten kannst, wie Du willst.

Dir sind ja zum Einen Beschränkungen in der Textlänge in der SPS gesetzt, zum Anderen wirst Du sicher nicht alles über Objekte in der Seite handeln wollen/können.
Daher würde ich das primär erst einmal für Dein Array-Problem sehen, so wie Thomas das in #4 beschrieben hat.
 
Ohne weiteren Aufwand müsstest du das Array explizit mit den einzelnen Array-Variablen initialisieren, so in der Art für die ersten 3:

Code:
let Array = [ ":="Variablen".state[1].Datum:", ":="Variablen".state[2].Datum:", ":="Variablen".state[3].Datum:" ];

Manchmal reicht das schon aus, wenn du in einer anderen Variable die Anzahl der aktiven Elemente stehen hast, dann kannst du über dein Javascript beispielsweise auch nur die Aktiven zur Anzeige bringen.
Bei vielen Variablen wird das nur irgendwann sehr langsam, probier es einfach aus ob es sich stört.
 
Man jetzt schon merkt, wie die Seite langsamer wird, daher werde ich die Methode mit JSON ausprobieren bzw bin schon dabei. Ich habe nun eine Beispiel Datei von Siemens. Da ist auch ein S7 Framework und jquery2.1.3_min dabei. Diese Dateien sind reine Bibliotheken oder? Da muss ich nichts bearbeiten?

EDIT:

Ich bin mal ein anderen Weg gegangen:
JSON Datei erstellt:
Code:
callback(
{
"test" : ":="Status".testhex:"
});

Und in der js Datei:
Code:
function callback(json){
console.log('json' + json.test);
}

in der console erhalte ich dann den Wert von testhex.

Bin mir nur nicht sicher, ob es das der Weg ist, den ihr gemeint habt.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich kenne nicht das Siemens Projekt welches du dir ansiehst.
Ich vermute aber mal eher, dass dort Ajax verwendet wird. Das dient dazu Werte innerhalb einer Seite zu aktualisieren, ohne die gesamte Seite neu zu laden. Das behebt aber nicht das Geschwindigkeitsproblem, es ist bei der Verfahrensweise aber nicht so sichtbar wenn die Antwort im Hintergrund 5 Sekunden benötigt, als wenn die Seite beim Neuladen 5 Sekunden weiß bleibt.
 
Es ist das hier:
html_18_S7Framework

aber ich vermute ich bin mit der zweiten Methode eher auf der richtigen Spur. Dort könnte ich ja nun in der JSON Datei noch ein Array usw. einbauen
Code:
[COLOR=#9CDCFE][FONT=Consolas]"test"[/FONT][/COLOR][COLOR=#D4D4D4][FONT=Consolas] : [[/FONT][/COLOR][COLOR=#D4D4D4][FONT=Consolas]        
        {[COLOR=#9cdcfe]"zeit"[/COLOR] : [COLOR=#ce9178]":="[/COLOR][COLOR=#f44747]Status[/COLOR][COLOR=#ce9178]".testarray[0]:"[/COLOR]},
        {[COLOR=#9cdcfe]"unsinn"[/COLOR] : [COLOR=#ce9178]":="[/COLOR][COLOR=#f44747]Status[/COLOR][COLOR=#ce9178]".testarray[1]:"[/COLOR]}
[/FONT][/COLOR]
[COLOR=#D4D4D4][FONT=Consolas]    ][/FONT][/COLOR]

Dies würde er dann nur einmal abfragen müssen, um alle Daten zu erhalten oder?
Oder hast du es so gemeint, dass ich alles in ein String packe und diesen in JavaScript wieder auspacke? Nur müsste ich ja dann vorher schon wissen, wie der String aufgebaut ist. Damit ich alles richtig entschlüsseln kann.
 
Oder hast du es so gemeint, dass ich alles in ein String packe und diesen in JavaScript wieder auspacke? Nur müsste ich ja dann vorher schon wissen, wie der String aufgebaut ist. Damit ich alles richtig entschlüsseln kann.

Du kannst ja als ersten Wert die Anzahl der Daten schicken und danach die Auswertung der Webseite darauf aufbauen, oder den String mit maximaler Länge machen und 0 Werte übertragen, die dann auf der Webseite gar nicht, oder leer etc. angezeigt werden.

Wie viele Daten willst Du schicken?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das mit dem ersten Wert, der die Anzahl übergibt, ist eine gute Idee!

Wieviele Daten?
Das kommt drauf an, wie oft die Laufzeit ausgewertet wurde. Ich habe das mal auf 50 begrenzt aber kann durchaus auch mehr werden.

Wobei ich ja da schon weiter denke und alles, was ich lesen möchte in diesen String bzw Strings setze.
 
Wenn du viel im SPS-Programm mit Strings hantierst, dann benötigt das auch irgendwann gut Zykluszeit.
Außerdem ist das Stringhandling mit der Begrenzung auf die 254 Zeichen je String auch nicht immer so einfach. Wenn deine Datensätze länger werden musst du auch noch stückeln oder entsprechend vorplanen.

Hast du denn mal getestet wie lange das Laden einer Seite mit 50 Variablen benötigt?
 
Ich mache aus den Strings bei vielen Daten dann noch einen WString, der max. 16382 Zeichen enthalten kann, wenn ich mir das richtig notiert habe.
Hab aber nur in Ausnahmefällen WString verwendet, und ich glaube mich zu erinnern, dass nur eine beschränkte Anzahl an WStrings gegangen sind.
Dann ist irgendein Fehler gekommen, aber das war nicht mit der letzten FW.

Bei meiner 1515 sind die 168 Zeiten auf einer Seite (ein und zwei stellige zahlen) ohne Verzögerung beim öffnen der Seite da. Bei zyklischer Abfrage hängts dann vom Endgerät ab, wobei auch heutige Tablets oder Handys da schnell genug sein sollten.
 
Zurück
Oben