Walkthrough: DEMO_DDF.csv
DEMO_DDF.csv ist das Referenzbeispiel für GUI-DDF. Eine MODBUS-RTU-Wetterstation (SenTec SEM9000) liefert die Daten, ein responsives Wetter-Widget stellt sie dar. Es zeigt alle GUI-Techniken gemeinsam: mehrere SVG-Vorlagen, Platzhalter, CSS-Klassen, Verläufe, Rotation, berechnete Koordinaten, Mehrsprachigkeit, Layout je Kachelgröße und Mausereignisse.
1. Geräteteil
Den Geräteteil (*GENERAL, *READ, *GROUP, *ITEM) beschreibt MODBUS RTU. Für das Widget ist wichtig: Die Items haben IDs 0…15 und tragen Messwerte wie Temperatur, Wind und UV.
2. *OBJECT-Zeilen
*OBJECT;GROUP;ID;ALIAS;TYPE;ENUM;ENUMTEXT;ENUMVAL;MIN;MAX;IOTYPE;DIGITS;DEFAULT;ITEMID;UNIT;ALARM;ALARMVAL;ALARMTIME;OUTTYPE;CMDITEMID;COMMAND;COMMANDENUM;COMMANDVAL;VIEWTYPE;LOG;SVG;SVGANIMATE;SVGEVENT
;0;0;Widget;4;;;;0;100;;;;;;;;;;;;;;0;1;"<SVG-Vorlagen>";"<SVGANIMATE>";"<SVGEVENT>"
;0;1;Winddirection;4;;;;0;360;;;;0;°;;;;;;;;;0;1
;0;2;Wind;4;;;;0;90;;2;;1;m/s;;;;;;;;;0;1
;0;3;Temperature;4;;;;-60;60;;1;;2;°C;;;;;;;;;0;1
…
;0;16;PM10 concentration;4;;;;0;2000;;1;;14;µg/m3;;;;;;;;;0;1
Objekt 0 der Gruppe 0 trägt SVG und Formeln und ersetzt damit die Standarddarstellung der Gruppe. Die Objekte 1–16 bilden die Werteliste (ITEMID → Item-ID, DIGITS, UNIT, LOG=1).
3. SVG-Vorlagen
Das SVG-Feld enthält sieben Vorlagen:
| alias | viewBox | Inhalt |
|---|---|---|
Qual |
200×100 | Luftqualität: AQI-Badge, Farbskala, Marker, PM1/PM2.5/PM10 |
UV |
200×100 | UV-Index mit 12-Segment-Skala und Abdunkelung |
Solar |
200×100 | Solarstrahlung mit Skala, UV-Strahlung und Tagessumme |
General |
400×100 | große Übersicht: Himmel mit Verlauf, Sonne, Temperatur, 6 Messwerte |
Wind |
100×100 | Kompass mit gedrehtem Pfeil |
GeneralCompact |
200×100 | kompakte Übersicht |
GeneralMini |
250×200 | Kachel für 504/508 |
Techniken in den Vorlagen
CSS-Klassen (ohne ;, eine Eigenschaft je Zeile):
<style>
.tile {
fill: #0c1a32
stroke: #1c2f4e
stroke-width: 0.5
}
.text-primary {
fill: #ffffff
font-weight: 600
}
</style>
<rect class='tile' x='0' y='0' width='200' height='100' rx='5' ry='5'/>
Platzhalter im Text:
<text class='text-label' x='26' y='15' font-size='7'>$(TITLE)</text>
<text x='192' y='13' fill='#d8f7c8' text-anchor='end' font-size='9' font-weight='600'>$(AQI)</text>
Berechnete Koordinate (Marker auf der AQI-Skala):
<rect x='8+($(AQIPOS)/30*184)' y='38' width='4' height='11' rx='2' ry='2' fill='#ffffff'/>
Platzhalter als Maß (Abdunkelung rechts vom aktuellen Wert):
<rect x='$(UVPOS)' y='52.5' width='$(UVW)' height='8' fill='#0c1a32' fill-opacity='0.72'/>
Rotation (Windpfeil um den Kompassmittelpunkt 34/57):
<path class='arrow' transform='rotate($(DIR) 34 57)' d='M 34 36 L 38 46 L 34 43.5 L 30 46 Z'/>
Verläufe:
<linearGradient id='genSky' x1='0' y1='0' x2='0' y2='1'>
<stop offset='0' stop-color='#1f4f9a'/>
<stop offset='1' stop-color='#6f9fd6'/>
</linearGradient>
<path d='M 6.56 0 L 393.44 0 A 6.56 6.56 0 0 1 400 6.56 L 400 62 L 0 62 L 0 6.56 A 6.56 6.56 0 0 1 6.56 0 Z' fill='url(#genSky)'/>
4. SVGANIMATE – die Zeichenformel
4.1 Sprache und Testdaten
language := $.CTRLROOTVAR.WEBVISER_DISPLAY[0].iLANGUAGE+1;
IF $.CTRLVAR.isys == 14 THEN
valoutside:=22.1;
…
ELSE
valoutside:=32.1;
…
ENDIF;
Die Sprache kommt aus der Display-Konfiguration. $.CTRLVAR.isys ist die Systemnummer des Elements, an dem das Widget hängt. Im Demo sind die Werte Testkonstanten. In einem produktiven Widget stehen hier $.CTRLVAR.…- bzw. $.VARLOCAL.…-Zugriffe.
4.2 Texte nur bei Sprachwechsel setzen
IF language != languageOld THEN
SWITCH language
CASE 1:
tUV:='UV-Index';
…
CASE 2:
tUV:='Indice UV';
…
DEFAULT:
tUV:='UV Index';
…
ENDSWITCH;
ENDIF;
languageOld:=language;
Variablen wie languageOld bleiben zwischen den Zeichenvorgängen erhalten. Dadurch wird die Textzuweisung nur einmal je Sprachwechsel ausgeführt.
4.3 Werte aufbereiten
strTemp:=PRINT(FLOAT,'%.1f',valoutside);
uvpos:=8+valUV*184/12;
IF uvpos>192 THEN
uvpos:=192;
ENDIF;
uvw:=192-uvpos;
strUVPOS:=PRINT(FLOAT,'%.1f',uvpos);
Platzhalter sind Strings. Zahlen werden mit PRINT formatiert. Positionen werden in den Koordinaten der Vorlage gerechnet (die Skala reicht von x = 8 bis 192).
Klassifizierungen werden mit IF … ELSE IF … ENDIF;-Ketten gebildet (AQI-Stufen, UV-Stufen, Windrichtung in 8 Sektoren).
4.4 Layout je Kachelgröße
xy:=$.GUI.W/$.GUI.H;
SWITCH $.GUI.WIDGETTYPE
CASE 504:
GUI.setWindow(0,0,245,195,1.0);
GUI.paintSVG('GeneralMini',0,0,245,195,0,'TEMP',strTemp,'MAX',strTempMax,'MIN',strTempMin,'CONDITION',genCond,…);
CASE 508:
GUI.setWindow(0,0,245,395,1.0);
GUI.paintSVG('GeneralMini',0,0,245,195,0,…);
GUI.paintSVG('Qual',0,200,245,195,0,'PM1',strPM1,'PM25',strPM25,'PM10',strPM10,…);
CASE 1004:
GUI.setWindow(0,0,495,195,1.0);
GUI.paintSVG('General',0,0,495,195,0,…);
CASE 1008:
GUI.setWindow(0,0,495,395,1.0);
GUI.paintSVG('General',0,0,495,195,0,…);
GUI.paintSVG('Qual',0,200,245,195,0,…);
GUI.paintSVG('UV',250,200,245,195,0,…);
DEFAULT:
IF xy <1.3 THEN
GUI.setWindow(0,0,410,370,1.0);
GUI.paintSVG('General',5,0,405,120,0,…);
GUI.paintSVG('Qual',5,125,200,120,0,…);
GUI.paintSVG('UV',210,125,200,120,0,…);
GUI.paintSVG('Solar',5,250,200,120,0,…);
GUI.paintSVG('Wind',210,250,120,120,0,…);
ELSE IF xy <2.4 THEN
…
ELSE
…
ENDIF;
ENDSWITCH;
- Für Standard-Kacheln gibt es ein festes Layout je
WIDGETTYPE. - In der Vollansicht (
DEFAULT) richtet sich das Raster nach dem Seitenverhältnisxy. - Jede Vorlage wird mit ihren eigenen Platzhalterpaaren gezeichnet.
flowchart TD
W{$.GUI.WIDGETTYPE} -->|504| A[GeneralMini]
W -->|508| B[GeneralMini + Qual]
W -->|1004| C[General]
W -->|1008| D[General + Qual + UV]
W -->|sonst| E{Seitenverhältnis}
E -->|< 1.3| F[General, Qual, UV, Solar, Wind]
E -->|< 2.4| G[General, Qual, UV]
E -->|sonst| H[General, Qual, UV, Solar, Wind – breit]
5. SVGEVENT – Interaktion
IF ($.MOUSE.X >( $.GUI.W/2)) && ($.MOUSE.Y >( $.GUI.H/2))THEN
$.MOUSE.HANDLED:=1;
test:=$.VARLOCAL.temperature; /* historisch; seit 09.11.2026 entfernt → $.VAL.temperature */
test2:=$.VARGLOBAL.systems.network.language; /* historisch; entfernt → $.VAL / $.CTRLROOTVAR */
ELSE
$.MOUSE.HANDLED:=0;
ENDIF;
Klicks ins rechte untere Viertel verarbeitet das Widget selbst (HANDLED=1). Alle anderen Klicks gehen an die Standardbehandlung. Nebenbei zeigt das Beispiel den Lesezugriff auf lokale und globale Aliase.
6. Lehren aus dem Demo
| Regel | Grund |
|---|---|
| Vorlagen statisch halten, nur Platzhalter variieren | d und points werden nicht ersetzt |
Zahlen vor der Übergabe mit PRINT formatieren |
Platzhalter sind Text |
| Positionen im Vorlagen-Koordinatensystem rechnen | paintSVG skaliert die Vorlage |
| Texte nur bei Sprachwechsel setzen | spart Rechenzeit bei jedem Repaint |
Layout per WIDGETTYPE und Seitenverhältnis |
responsive Darstellung |
HANDLED immer explizit setzen |
definiertes Klickverhalten |