Page 1 of 2

Einige Fragen zu Virtuellen Devices / RAP files

Posted: 18 Mar 2020, 12:12
by thseiler
Liebes Kunbus Team,

Ich habe hier einige Labornetzteile welche über SCPI / LXI (tcp) angesprochen werden, und möchte diese gerne als Virtuelle Devices im Prozessabbild darstellen (ähnlicher Ansatz wie der piModbusMaster)
Dabei soll pro Labornetzteil ein virtuelles Gerät in Pictory hinzugefügt werden, und anschliessend pro Gerät die IP Adresse und der TCP Port konfiguriert werden können. Ich habe also einen kleinen Unix Daemon geschrieben, welcher auch schon mit meinen Netzteilen kommuniziert. Aktuell sind die IP Adressen / TCP ports aber noch statisch in einem Header definiert.

Mein Ziel ist es nun, dass sich der Daemon die Konfiguration der IP Adressen / Ports von der in Pictory definierten Konfiguration lädt.

Daher habe ich zunächst gemäß diesem Tutorial eine eigene RAP Datei für meine Netzteile erstellt (basierend auf der ModbusTcpMaster_20180122_1_1.rap), und kann nun Netzteile im Pictory als virtuelle Devices hinzufügen. Der Benutzer kann so die IP Adressen und Ports für jedes Netzteil im Pictory konfigurieren. Mein Daemon findet mittels Aufruf von piControlGetDeviceInfoList() heraus wie viele Devices es abzubilden gilt, und findet so auch die Offsets seiner Instanzen im Prozessabbild, soweit so gut.

Als nächstes habe ich versucht, die IP Adresse und Ports aus dem Prozessabbild dynamisch zu lesen. Der dazu relevante Teil der RAP Datei ist vom ModbusTCPMaster kopiert und ganz leicht angepasst:

Code: Select all

     "memory": [
                {
                        "name": "IP_address",
                        "type": "STRING",
                        "offset": 48,
                        "maxsize": 16,
                        "range": {
                                "type": "tooltip_loop",
                                "values": [0,255,1]
                        },
                        "default": "192.168.1.104",
                        "unit": "",
                        "tags": "memory, string",
                        "edit": "1",
                        "order": 25,
                        "export": false
                },
                {
                        "name": "TCP_port",
                        "type": "WORD",
                        "offset": 64,
                        "maxsize": 65535,
                        "range": {
                                "type": "tooltip_loop",
                                "values": [0,65535,1]
                        },
                        "default": "8462",
                        "unit": "",
                        "tags": "memory, word",
                        "edit": "1",
                        "order": 26,
                        "export": false
                }
        ],
Dem Benutzer wird wie erwartet in Pictory Value Pane unter IP_address und TCP_port der entsprechende "default" wert angezeigt. Der Benutzer kann jedem Netzteil eine eindeutige IP Adresse zuweisen, und nach dem speichern finden sich diese werte auch in der _config.rsc wieder.

Mein Deamon kann auch den TCP_port aus dem Prozessabbild lesen, jedoch nicht den STRING IP_address. Stattdessen bekomme ich lauter '\0'. Ich habe es auch mit piTest -rOFFSET,LEN,FORMAT versucht und es scheint tatsächlich so dass dieser Bereich des Prozessabbilds nicht initialisiert wurde.

Aus Neugierde habe ich dann das selbe Experiment mit einem ModbusTCPMaster wiederholt, und auch hier wurde nur das WORD slave_TCP_port initialisiert, aber nicht der STRING slave_IP_address.
Trotzdem kann piModbusMaser die passende TCP Verbindung zum konfigurierten slave ohne probleme aufbauen. Sehr interessant, woher kennt piModbusMaster die IP Adresse ???

Daher habe ich jetzt einen ganzen Katalog von Fragen zum RAP Format und zu den Virtuellen Devices:

1. Zur Funktion des Attribut "maxsize" in RAP Dateien:
- Zunächst einmal wird es in der RAP Dokumentation nicht erwähnt.
- In den ModbusTCPMaster.rap wird es beim STRING slave_IP_address auf 16 gesetzt, was darauf hindeutet dass es die maximale länge des STRINGs beschreibt, dies passt auch zu den Offsets der nächsten Variablen.
- In der selben ModbusTCPMaster.rap wird es beim WORD slave_TCP_port auf 65535 gesetzt, was jedoch darauf hindeuten würde, dass es auch etwas mit dem maximalen wertebereich zu tun hat (aber was???)
- In den RevPiDIO.rap wird es beim BYTE InputMode schliesslich auf 0 gesetzt. Es macht den Anschein, dass hier eine Variablen so definiert werden soll, dass Sie keinen Platz im Prozessabbild verwenden, z.B. zur Konfiguration. Wenn man sich den Offset der darauffolgenden Variablen anschaut, wird aber trotzdem Platz für 20 InputMode BYTEs reserviert. Zudem müsste im Fall eines Konfigurations-STRING ja trozdem auch eine maximale Länge spezifiziert werden können, damit Pictory die Prüfung des Formulars durchführen kann. Was also genau bewirkt maxsize = 0?

2. Die Funktion der Attribute im block "actions": Offenbar kann pictory unix daemons enablen wenn ein virtuelles Gerät hinzugefügt wird, und die entsprechenden Kommandos kann man z.B. im ModbusTCPMaster rap sehen, sie starten /usr/bin/revpi-config.
- Wenn ich das erste von mehreren Virtuellen Geräten im pictory lösche, dann wird der entsprechende Service bereits gestoppt. Ist das beabsichtigt oder ein Bug?

3. Die Funktion des Attributes "default" in RAP Dateien: Gemäß der Doku setzt es den vorgegebener Standardwert des Attributs (ein beliebiger DIN61131 Datentyp), und muss dabei aber selbst immer ein JSON String sein, der zusätzlich nicht als binary-safe angesehen werden darf, da JSON. Dieser String wird im Kernel Modul piControl in dieser Funktion in einen uint32 Wert umgewandelt.
Das bedeutet also, dass es mit dem Aktuellen Kernel Modul nicht möglich ist, Default werte zu setzen für alles was sich nicht als uint32 darstellen wie z.B. die 64bit datentypen LINT, ULINT , LWORD, LREAL, LTIME, LREAL sowie alle STRINGs und WSTRINGs.

- Wie konnte piModbusMaster trotzdem an IP Adresse von seinem slave kommen, wenn diese gar nie im Prozessabbild verfügbar war?
- Wie werden default werte für REALs gehandhabt ? Das Kernelmodul kann den float /double nicht direkt parsen (da fpu im kernelspace = tabu)?
- Habt ihr eine Vision in welche Richtung das default handling gehen soll ( userspace daemon vs kernel modul aufbohren ?) und währt ihr an Patches in diesem Bereich interessiert?

Vielen Dank und freundliche Grüsse,
Thomas Seiler

Re: Einige Fragen zu Virtuellen Devices / RAP files

Posted: 24 Mar 2020, 11:18
by Frank
Hallo Thomas,

ich bin gerade dabei mich um Deine Fragen im Einzelnen zu kümmern, benötige dafür aber teilweise die Unterstützung von fachlich spezialisierten Kollegen.

1. Was ich schon beantworten kann ist die Frage nach der 'MAXSIZE'. Diese wird aktuell NUR für die Prüfung bzw. Validierung von String-Längen verwendet, da diese die einzigen wirklich variablen Bytegrössen darstellen. Die MAXSIZE Angabe ist deshalb bei Strings in Bytes (also Charactern) zu verstehen und wird auch nur dort tatsächlich verwendet.

2. Das Verfahren zum starten/stoppen der Services bei Hinzufügen und Entfernen virtueller Devices in 'PiCtory' wurde erst recht spät implementiert ist und ist deshalb sicher noch nicht perfekt. Es gab allerdings bisher noch nie entsprechende negative Rückmeldungen so dass wir keinen Handlungsbedarf hatten.
Es ist möglich, dass wenn man mehrere virtuelle Geräte DESSELBEN Typs in der Konfiguration drin hat, und eines davon entfernt, die darauffolgende Deltabildung nicht bemerkt, dass noch andere Geräte des Typs den Dienst benötigen - uind ihn fälschlicherweise stoppt. Das wäre dann ein Bug. Ich werden den entsprechenden Code mal analysieren und wenn sich der Verdacht bestätigt möglichst für das nächste Release einen Update durchführen. Ich kann Dir den entsprechenden Code dann ggf. vorab schon zum Beta-Testing zur Verfügung stellen, wenn Du daran Interesse hast - kann Dir dafür aber noch keinen genauen Zeitpunkt nennen.

Ich melde mich sobald ich weitere Fragen klären konnte.

freundliche Grüße
Frank

Re: Einige Fragen zu Virtuellen Devices / RAP files

Posted: 24 Mar 2020, 11:41
by Frank
Hallo nochmal,

wie ich inzwischen klären konnte ist die IP-Adresse nur in der _config.rsc Projektdatei von 'PiCtory' vorhanden, da sie nur zu den Konfigurations- aber nicht zu den Arbeitsdaten gehört, und deshalb nur einmalig beim Start eingelesen wird. Es dürfte deshalb nötig sein, dass Du die _config.rsc Datei parsed um auf all jene Daten zuzugreifen, die nur zur Config-Time und nicht zur Runtime, also nicht im Prozessabbild vorhanden sind.

Bitte kurzes Feedback geben, falls hier ein Mißverständnis besteht ...

Gruß
Frank

Re: Einige Fragen zu Virtuellen Devices / RAP files

Posted: 25 Mar 2020, 08:08
by thseiler
Hallo Frank,

Vielen Dank für die ausführlichen Antworten, das hilft mir schon mal sehr viel weiter.
Frank wrote: 24 Mar 2020, 11:18 1. Was ich schon beantworten kann ist die Frage nach der 'MAXSIZE'. Diese wird aktuell NUR für die Prüfung bzw. Validierung von String-Längen verwendet, da diese die einzigen wirklich variablen Bytegrössen darstellen. Die MAXSIZE Angabe ist deshalb bei Strings in Bytes (also Charactern) zu verstehen und wird auch nur dort tatsächlich verwendet.
Soweit alles klar.

Als Entwickler eines Virtuellen Devices würde ich diese Info aber zuerst in der RAP JSON Dokumentation vom Core bzw. vom Connect suchen. Wenn ihr also einen Moment Zeit findet, könntet ihr das dort noch hinzufügen? z.B so was:

Code: Select all

E.4
maxsize
Gibt die maximal erlaubte Länge (in Bytes) eines STRING Attributs vor, und wird von Pictory bei der Validierung von Eingaben benutzt. Sollte bei allen STRING Attributen gesetzt werden.
Specifies the max permitted length (in bytes) of a STRING Attribute, and is used by Pictory for validating user input. Should be specified for every attribute of type STRING.
Num.
optional

Vielen Dank!

PS:
Aktuell haben einige offizielle *.rap files das maxsize bei WORD und BYTE Attributen gesetzt:

Code: Select all

pi@RevPi00000:/var/www/pictory/resources/data/rap $ grep -B3 "maxsize.*65535" *
ModbusTCPMaster_20170215_0_1.rap-                       "name": "slave TCP port",
ModbusTCPMaster_20170215_0_1.rap-                       "type": "WORD",
ModbusTCPMaster_20170215_0_1.rap-                       "offset": 190,
ModbusTCPMaster_20170215_0_1.rap:                       "maxsize": 65535,
--
ModbusTCPMaster_20180122_1_1.rap-                       "name": "slave TCP port",
ModbusTCPMaster_20180122_1_1.rap-                       "type": "WORD",
ModbusTCPMaster_20180122_1_1.rap-                       "offset": 190,
ModbusTCPMaster_20180122_1_1.rap:                       "maxsize": 65535,
--
RevPiSeven_20171011_1_0.rap-                    "name": "Local_TSAP",
RevPiSeven_20171011_1_0.rap-                    "type": "WORD",
RevPiSeven_20171011_1_0.rap-                    "offset": 1074,
RevPiSeven_20171011_1_0.rap:                    "maxsize": 65535,
--
RevPiSeven_20171011_1_0.rap-                    "name": "Remote_TSAP",
RevPiSeven_20171011_1_0.rap-                    "type": "WORD",
RevPiSeven_20171011_1_0.rap-                    "offset": 1076,
RevPiSeven_20171011_1_0.rap:                    "maxsize": 65535,

pi@RevPi00000:/var/www/pictory/resources/data/rap $ grep -B3 "maxsize.* 0" *
RevPiCompact_20171023_1_0.rap-                  "name": "InputDebounce",
RevPiCompact_20171023_1_0.rap-                  "type": "BYTE",
RevPiCompact_20171023_1_0.rap-                  "offset": 29,
RevPiCompact_20171023_1_0.rap:                  "maxsize": 0,
--
RevPiDI_20160818_1_0.rap-                       "name": "InputMode",
RevPiDI_20160818_1_0.rap-                       "type": "BYTE",
RevPiDI_20160818_1_0.rap-                       "offset": 88,
RevPiDI_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDI_20160818_1_0.rap-                       "name": "InputDebounce",
RevPiDI_20160818_1_0.rap-                       "type": "WORD",
RevPiDI_20160818_1_0.rap-                       "offset": 104,
RevPiDI_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDI_20160818_1_0.rap-                       "name": "OutputPushPull",
RevPiDI_20160818_1_0.rap-                       "type": "WORD",
RevPiDI_20160818_1_0.rap-                       "offset": 106,
RevPiDI_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDI_20160818_1_0.rap-                       "name": "OutputOpenLoadDetect",
RevPiDI_20160818_1_0.rap-                       "type": "WORD",
RevPiDI_20160818_1_0.rap-                       "offset": 108,
RevPiDI_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDI_20160818_1_0.rap-                       "name": "OutputPWMActive",
RevPiDI_20160818_1_0.rap-                       "type": "WORD",
RevPiDI_20160818_1_0.rap-                       "offset": 110,
RevPiDI_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDI_20160818_1_0.rap-                       "name": "OutputPWMFrequency",
RevPiDI_20160818_1_0.rap-                       "type": "BYTE",
RevPiDI_20160818_1_0.rap-                       "offset": 112,
RevPiDI_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDIO_20160818_1_0.rap-                      "name": "InputMode",
RevPiDIO_20160818_1_0.rap-                      "type": "BYTE",
RevPiDIO_20160818_1_0.rap-                      "offset": 88,
RevPiDIO_20160818_1_0.rap:                      "maxsize": 0,
--
RevPiDIO_20160818_1_0.rap-                      "name": "InputDebounce",
RevPiDIO_20160818_1_0.rap-                      "type": "WORD",
RevPiDIO_20160818_1_0.rap-                      "offset": 104,
RevPiDIO_20160818_1_0.rap:                      "maxsize": 0,
--
RevPiDIO_20160818_1_0.rap-                      "name": "OutputPushPull",
RevPiDIO_20160818_1_0.rap-                      "type": "WORD",
RevPiDIO_20160818_1_0.rap-                      "offset": 106,
RevPiDIO_20160818_1_0.rap:                      "maxsize": 0,
--
RevPiDIO_20160818_1_0.rap-                      "name": "OutputOpenLoadDetect",
RevPiDIO_20160818_1_0.rap-                      "type": "WORD",
RevPiDIO_20160818_1_0.rap-                      "offset": 108,
RevPiDIO_20160818_1_0.rap:                      "maxsize": 0,
--
RevPiDIO_20160818_1_0.rap-                      "name": "OutputPWMActive",
RevPiDIO_20160818_1_0.rap-                      "type": "WORD",
RevPiDIO_20160818_1_0.rap-                      "offset": 110,
RevPiDIO_20160818_1_0.rap:                      "maxsize": 0,
--
RevPiDIO_20160818_1_0.rap-                      "name": "OutputPWMFrequency",
RevPiDIO_20160818_1_0.rap-                      "type": "BYTE",
RevPiDIO_20160818_1_0.rap-                      "offset": 112,
RevPiDIO_20160818_1_0.rap:                      "maxsize": 0,
--
RevPiDO_20160818_1_0.rap-                       "name": "InputMode",
RevPiDO_20160818_1_0.rap-                       "type": "BYTE",
RevPiDO_20160818_1_0.rap-                       "offset": 88,
RevPiDO_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDO_20160818_1_0.rap-                       "name": "InputDebounce",
RevPiDO_20160818_1_0.rap-                       "type": "WORD",
RevPiDO_20160818_1_0.rap-                       "offset": 104,
RevPiDO_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDO_20160818_1_0.rap-                       "name": "OutputPushPull",
RevPiDO_20160818_1_0.rap-                       "type": "WORD",
RevPiDO_20160818_1_0.rap-                       "offset": 106,
RevPiDO_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDO_20160818_1_0.rap-                       "name": "OutputOpenLoadDetect",
RevPiDO_20160818_1_0.rap-                       "type": "WORD",
RevPiDO_20160818_1_0.rap-                       "offset": 108,
RevPiDO_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDO_20160818_1_0.rap-                       "name": "OutputPWMActive",
RevPiDO_20160818_1_0.rap-                       "type": "WORD",
RevPiDO_20160818_1_0.rap-                       "offset": 110,
RevPiDO_20160818_1_0.rap:                       "maxsize": 0,
--
RevPiDO_20160818_1_0.rap-                       "name": "OutputPWMFrequency",
RevPiDO_20160818_1_0.rap-                       "type": "BYTE",
RevPiDO_20160818_1_0.rap-                       "offset": 112,
RevPiDO_20160818_1_0.rap:                       "maxsize": 0,
Da beim entwickeln eigener Devices (ob virtuell oder Makerset) bestehende rap files kopiert werden, werden so auch diese "Schönheitsfehler" mitkopiert. Entsprechend wird es schwieriger, später einmal strikter zu parsen, z.B. wenn pictory einen rap editor bekommt. Vielleicht wäre es klug, diese statements beim nächsten Pictory release zu entfernen. Das sollte ohne Kompabillitätprobleme zu bestehenden Projekten möglich sein, gerade weil diese Statements ja keinen Effekt haben/hatten... :)

Re: Einige Fragen zu Virtuellen Devices / RAP files

Posted: 25 Mar 2020, 09:54
by Frank
Hallo Thomas,

Du hast völlig Recht bzgl. der Doku und dieser 'Schönheitsfehler'. Ich werde den Code nochmal durchgehen, ob die MAXSIZE Angabe bei WORD nicht irgendeinen Seiteneffekt hat. Der Code stammt zwar von mir, die .RAP-Dateien hat jedoch ein Mitarbeiter erstellt, der nicht mehr im Unternehmen ist. Ich kann deshab aktuell nicht nachvollziehen, ob er sich irgendetwas dabei gedacht hat - denn eigentlich werden bei den DIN61131 ja keine expliziten Grössenbegrenzungen benötigt, weil diese aus der Norm ableitbar sind - wenn sie nicht rein fachlich begründet sind.

Gruß & Gute Gesundheit!
Frank

Re: Einige Fragen zu Virtuellen Devices / RAP files

Posted: 25 Mar 2020, 15:16
by thseiler
Hallo nochmals,
Frank wrote: 24 Mar 2020, 11:18 2. Das Verfahren zum starten/stoppen der Services bei Hinzufügen und Entfernen virtueller Devices in 'PiCtory' wurde erst recht spät implementiert ist und ist deshalb sicher noch nicht perfekt. Es gab allerdings bisher noch nie entsprechende negative Rückmeldungen so dass wir keinen Handlungsbedarf hatten.
Habe das gerade noch einmal durchprobiert, und jetzt funktioniert alles wunderbar. Bitte ignoriert den Bug-Report, offenbar lag der Fehler zwischen meinem linken und rechten Ohr...

Der Vollständigkeit halber liste ich hier noch die Schritte, die nötig waren damit pictory meinen daemon automatisch startet und stoppt:

1) rap file anpassen und darin meine actions für "onAdd" und "onDelete" definieren
2) /var/www/pictory/resources/data/rap/actionRules.json erweitern (warum ist dieser Schritt eigentlich notwendig bzw was ist die Funktion der actionRules.json ??? ist mir noch nicht so klar...)
3) entsprechendes /etc/sudoers.d/02-www-data-yadayada file erstellen, damit der webserver user auch die Rechte hat um die kommandos in der rap datei auszuführen

Liebe Grüsse & Gute Gesundheit
Thomas

Re: Einige Fragen zu Virtuellen Devices / RAP files

Posted: 26 Mar 2020, 18:10
by Frank
Hallo Thomas,

vielen Dank für die Rückmeldung, dass die Action-Verarbeitung doch korrekt bei Dir funktioniert - das wissen wir sehr zu schätzen, wenn ein User diesen Schritt noch macht und das gewonnene Know-How auch anderen zur Verfügung stellt. Zu Deine Frage bzgl. der 'actionRules.json' Datei ... diese dient der Zentralisierung zusammenhängender Aktionen bei Gruppen von Gerätetypen - und der einfacheren Deltabildung zwischen dem vorhergehenden und dem aktuellen Konfigurationszustand. Sie hätte sicher in der aktuellen ersten Form auch noch direkt in den .RAP-Dateien untergebracht werden können. Aber die Idee war, eine hierarchisch über der einzelnen .RAP-Datei liegende Steuerungsebene einzuführen, mit der sich Aktionen bei bestimmten Ereignissen zentraler definieren und die Ausführungsregeln einfacher prüfen lassen. Das war also eher eine Investition in die Zukunft, als eine aktuelle Notwendigkeit.

viele Grüße & Gute Gesundheit
Frank

Re: Einige Fragen zu Virtuellen Devices / RAP files

Posted: 30 Mar 2020, 16:43
by thseiler
Hallo,

Zu meinem problem 3) mit den IP Adressen:
Ich habe mein Program jetzt so angepasst, dass die Datei /etc/revpi/config.rsc geparst wird, der daemon bekommt jetzt seine IP adressen und alles funktioniert soweit nach einem neustart.
Wenn ich jetzt aber eine IP Adresse in pictory ändere, die Startconfig speichere und dann den Treiber neu lade (reset), ohne neu zu starten, dann bekommt das mein Daemon nicht mit.
Die deltabildung in Pictory erkennt ja richtig, dass der daemon laufen soll, und dass er ja schon läuft. der daemon wird also nicht neu gestartet, und weiss somit auch nichts von der geänderten config.
Und da die IP adressen ja eben gerade nicht im prozess abbild existieren, kann ich auch nicht pollen um eine änderung festzustellen.

-> Gibt es einen weg ich ich von meinem select() main loop aus erkennen kann, dass ein reset stattgefunden hat, um daraufhin die config neu zu lesen? Ich habe die funktion

Code: Select all

piControlWaitForEvent
im Auge aber ich bräuchte etwas was non-blocking ist, oder aber ein fd auf das ich select() anwenden kann. Geht das aktuell?

Dann ist mir ebenfalls aufgefallen: Aktuell enthällt die _config.rsc nur die bitlänge der Variable jedoch nicht den DIN61131 datatype derselben (BOOL, BYTE, WORD, REAL, STRING etc...).

-> Wäre es möglich, in der nächsten Version von pictory, die _config.rsc im Array C.13 um einen weiteren String mit dem Datentyp am Offset 10 zu erweitern? Die bitlänge reicht nicht in allen fällen aus, um den Datentyp herzuleiten (z.B.32bit = REAL oder DWORD?)

Das wäre der erste schritt um dem kernel modul zu ermöglichen, den default json string fürs initialisieren bei weiteren datentypen zu implementieren, denn das parsen des strings zu einem binären resultat ist datentypabhängig, als muss das kernel modul den datentyp kennen.

Liebe Grüsse und gute Gesundheit!
Thomas

Re: Einige Fragen zu Virtuellen Devices / RAP files

Posted: 30 Mar 2020, 19:00
by Frank
Hallo Thomas,

freut mich, dass es bei Dir vorwärts geht und Du das parsen der _config.rsc implementiert hast.
Zum ersten Teil Deiner Frage muss ich mich noch mit einem Kollegen beraten, der näher an der Steuerungslogik auf den Geräten selbst dran drin.

Zu Deiner zweiten Frage bzgl. des Hinzufügens der Datentypen ... die _config.rsc hat aktuell _drei_ grundlegende Funktionen, deshalb enthält sie:

1. ein paar wenige Versions- und Layout-Daten von -PiCtory-, primär zur Prüfung der Kompatibilität und damit die beim Erstellen der Konfiguration verwendete Fensterbereichs-Optik wieder restauriert werden kann (man kann ja mit beliebig vielen eigenen Projektdateien arbeiten)
2. alle nötigen Gerätedaten, die -PiCtory- braucht um die eigentliche Gerätekonfiguration beim laden (zurück in -PiCtory- selbst) wieder herzustellen
3. die eigentlichen Arbeitsdaten (incl. der optionalen Erweiterungsdaten, wie sie zum Beispiel Modbus-Geräte zum Betrieb brauchen) zur Steuerung der konfigurierten Geräte, die sich dann im Basismodul (Core, Connect) als Memory-Abbild niederschlagen.

Die _config.rsc ist deshalb ein Mix dieser drei Zwecke, und enthält aktuell das minimal Notwendige, um diese Zwecke zu erfüllen. Sie enthält bewusst KEINE Daten, die ausschliesslich während der Konfiguration in -PiCtory- selbst, benötigt werden - wie zum Beispiel die Datentypen - da diese in -PiCtory-. immer in Form der geladenen .RAP-Dateien im Zugriff sind!
Du hast jetzt das klassische Problem, dass Du zur 'Runtime' Informationen aus den .RAP-Dateien brauchst, die das Gesamtsystem eigentlich nur zur 'Configtime' braucht (also soetwas was im .NET Umfeld zum Beispiel 'Reflection' heisst) ... das habe ich so wahrscheinlich richtig verstanden. Eine Erweiterung der .RSC-Dateien um redundante Daten aus den .RAP-Dateien wäre natürlich möglich - ich muss mir diese Idee aber erst mal näher durch den Kopf gehen lassen und auch vom benötigten Aufwand erst mal abklären, ob wir das dann in absehbarer Zeit umsetzen können. Es gäbe dafür dann ja auch verschiedene Möglichkeiten - zum Beispiel könnte das nur optional, über ein 'Setting' in -PiCtory- aktiviert werden - oder der User könnte selbst definieren, welche .RAP-Daten er genau in die .RSC-Datei übernehmen will. Diese könnten dann entweder bei den Gerätedaten selbst stehen, oder auch in einem separaten Block, wie die 'Extended Data' Einträge von Modbus ... Ich nehme mir die Idee auf jeden Fall gern mal auf meine Liste für mögliche Optimierungen - kann Dir aber leider aktuell zu ihrer Umsetzung noch keinerlei Zusagen machen, da muss ich Dich um Verständnis bitten. Du bist auch meines Wissens der Erste, der überhaupt danach fragt!

Gruß & Gute Gesundheit
Frank

Re: Einige Fragen zu Virtuellen Devices / RAP files

Posted: 30 Mar 2020, 22:21
by thseiler
Hallo Frank,

Danke vielmals fürs abklären bezüglich der Möglichkeiten zum erkennen eines Resets. Ich bin sehr auf die Antworten gespannt.

Mir liegt bei meiner zweiten Frage genau die im Punkt 3) genannte Funktion am Herzen:
3. die eigentlichen Arbeitsdaten (incl. der optionalen Erweiterungsdaten, wie sie zum Beispiel Modbus-Geräte zum Betrieb brauchen) zur Steuerung der konfigurierten Geräte, die sich dann im Basismodul (Core, Connect) als Memory-Abbild niederschlagen.
Bei jedem piControlReset() übernimmt das piControl Kernelmodul ja die Aufgabe, das Prozessabbild wieder neu zu initialisieren, und alle Variablen im Prozessabbild auf ihre jeweiligen Initialwerte zu setzen. Die hierzu notwendigen Informationen holt sich das piControl Kernelmodul ausschliesslich aus der config.rsc, genauer aus den JSON arrays in Devices [ i ] .inp, Devices [ i ]. out und Devices [ i ] . mem (C13-C15).

Der Defaultwert kommt dabei in der Form eines JSON Strings in der Array Position 3, und wird innerhalb des Kernelmoduls in eine passende binäre Representation umgewandelt (siehe hier)
Nehmen wir zum Beispiel eine Variable, die den Default String "1" hätte, (dieser besteht im Speicher aus einem Byte 0x31, ASCII für 1, gefolgt von einem Byte 0x00 um den String zu beenden):
- Für ein DWORD wäre die entsprechende binäre Representation die das Kernelmodul erzeugen muss 0x00 0x00 0x00 0x01
- Für ein REAL wäre die entsprechende binäre Representation hingegen 0x3F 0x80 0x00 0x00 (ein IEEE-754 single precision wert, aka float32 representation für 1.0)
- Für einen STRING der länge 32 (bit) widerum wäre die binäre Representation 0x31 0x00 0x00 0x00.
- Alle drei Fälle weisen eine Bitlänge von 32 auf, die Kenntnis alleine der Bitlänge reicht also nicht aus, um die passende _Umwaldung_ im Kernelmodul vornehmen zu können, der Datentyp wird zwingend ebenfalls benötigt.

Aktuell kann piControl nur das DWORD korrekt initialisieren, REAL und STRING funktionieren nicht. Ich sehe das ganze als Bug, der mich zwar aktuell (noch?) nicht in meinem Projekt einschränkt, aber trotzdem gefixt gehört. Ich kann nicht nachvollziehen, warum die Initialisierung der Variablen nur bei einigen Datentypen notwendig sein sollte, von daher gehe ich davon aus dass es einfach an der Zeit gefehlt hat. Hier könnte z.B. die Community übernehmen.
Nur leider kann das so wie es jetzt implementiert ist nicht gefixt werden, da eine wesentliche Information zu diesem Zeitpunkt bereits fehlt: der ursprüngliche Datentyp.

Ich hoffe ich konnte mein Anliegen damit ein wenig klarer darlegen.

Freundliche Grüsse und gute Gesundheit!
Thomas