Tutorial RAP Datei selbst erstellen am Beispiel RevPiTimer

Was sind RAP Dateien und wozu brauchst Du die eigentlich? Sicherlich hast Du Dich das gerade gefragt, als Du auf die Überschrift geklickt hast.

RAP steht für RevolutionPi Adapter Profile. Diese Dateien werden von PiCtory verwendet, um Geräte zu beschreiben.

Am Beispiel des „RevPiTimer“ möchten wir Dir zeigen, wie Du eigene RAP Dateien erstellen kannst und was Du dabei beachten musst.

Projektarbeit

Bevor wir in die Tasten hauen, machen wir uns einige Gedanken zu unserem Projekt und formulieren ein Ziel. Was soll unser Gerät tun und was nicht.

Ziel formulieren

Welches Gerät benötigst Du?

  • Wir benötigen eine Zeitschaltuhr.

Was soll dieses Gerät machen?

  • Sie soll auf einer Wochenbasis wiederholende Ein- und Ausschaltzeiten verwalten.
  • Es sollen mehrere Schaltzeiten zur Verfügung stehen.
  • Die Schaltzeiten sollten minutengenau sein.
  • Die Schaltzeiten sollten akviv und inaktiv geschalten werden können.

Was soll dieses Gerät nicht machen?

  • Emails verschicken 😉

Was möchtest Du damit konkret erreichen?

Ich möchte …

  • von Montag bis Freitag etwas um 7:15 Uhr einschalten und um 16:45 ausschalten.
  • jeden Dienstag etwas um 00:00 Uhr einschalten aber nicht ausschalten.
  • in der Lage sein, Schaltzeiten manuell zu deaktivieren
  • Samstags etwas um 12 Uhr ausschalten

Anforderungen

In diesem Schritt leiten wir die Anforderungen ab, die sich aus den Zielen ergeben.

  • Es soll eine Zeitschaltuhr auf Wochenbasis erstellt werden.
  • Die Zeitschaltuhr soll 16 Schaltzeiten haben.
  • Jede Schaltzeit besteht aus einem Einschaltzeitpunkt und einem Ausschaltzeitpunkt.
  • Die Ein- und Ausschaltzeitpunkte bestehen aus:
    • Allen Wochentagen Mo,Di,…So.
    • Zeit in Stunden und Minuten.
    • Aktivschaltung Ja/Nein.
  • Der Zustand der 16 Timer kann abgefragt werden ( Ist der Timer An oder Aus?).

Umsetzung

Da wir nun die Anforderungen beisammen haben, können wir uns jetzt an die Umsetzung wagen. Zuerst ermitteln wir die Eingangs- und Ausgangsdaten, die wir benötigen. Diese werden im Prozessabbild stehen. Je weniger Platz die Daten im Speicherbild brauchen, diese sind desto effizienter kann unser RevPi Core sie verarbeiten.

In diesem Beispiel benötigen wir folgende Daten:

  • Eingangsdaten
    • Timer Status der 16 Timer
  • Ausgangsdaten
    • 16 Schaltzeiten

Das klingt erst mal seltsam, denn eigentlich könnte man meinen, dass es genau andersherum sein sollte. Aus Sicht der Prozesskette sind die Daten des Timer Status Eingangsdaten, die weiter verarbeitet werden.

Datenmodellierung

So, jetzt geht’s aber ans Eingemachte! Welche Datentypen benötigen wir? Also Bitfelder, Bytes, etc…

Eingangsdaten

  • Timer Status
    • 16 Binärwerte
    • 1 : Timer hat den Zustand Ein
    • 0 : Timer hat den Zustand Aus
Bit 7 6 5 4 3 2 1 0
Timer Nr. Timer8 Timer7 Timer6 Timer5 Timer4 Timer3 Timer2 Timer1
Bit 15 14 13 12 11 10 9 8
Timer Nr. Timer16 Timer15 Timer14 Timer13 Timer12 Timer11 Timer10 Timer9

Summe Eingangsdaten: 2 Bytes

Ausgangsdaten

Pro Timer haben wir zwei Zeitpunkte (Ein- und Ausschaltzeitpunkt). Im Prozessabbild sieht das dann so aus:

Timer 1: Zeitpunkt einschalten Timer 1: Zeitpunkt ausschalten
Timer 2: Zeitpunkt einschalten Timer 2: Zeitpunkt ausschalten
Timer 16: Zeitpunkt einschalten Timer 16: Zeitpunkt ausschalten

Ein Zeitpunkt besteht aus:

  • Wochentag und Aktivschaltung fassen wir in einem Byte zusammen:
Bit Nr. 7 6 5 4 3 2 1 0
 Wert Aktiv So Sa Fr Do Mi Di Mo
  • Stunden: Werte 0-23
    • 1 Byte
  • Minuten: Werte 0-59
    • 1 Byte

Also benötigen wir an Daten

  • pro Zeitpunkt 1+1+1 = 3 Bytes
  • pro Timer 2 Zeitpunkte = 2*3 Bytes = 6 Bytes
  • pro Zeitschaltuhr 16 Timer = 16*6 Bytes = 96 Bytes

Summe Ausgangsdaten: 96 Bytes

Umsetzung RAP Datei

Die fertige Datei unseres RevPiTimers findest du auf deinem RevPi unter:

  • /var/www/pictory/resources/data/rap/VirtTimer_20170208_1_0.rap

Hier ist ein Auszug aus dieser Datei:

{
    "id": "VirtTimer",
    "version": "1.0",
    "comment": [
        "=1= If -range- is empty, original datatype range is used",
        "=2= -edit- maps whether name and/or value can be edited:",
        "0: no editing, 1: value editable, 2: name editable, 3: both editable "
    ],
    "screencomment": "This is a weekly based timer",
    "size": "1",
    "devicetype": "VIRTUAL",
    "producttype": 28673,
    "output": [
        {
            "name": "T1_ON_active_day",
            "type": "BYTE",
            "offset": 2,
            "range": {
                "type": "tooltip_loop",
                "values": [
                    0,
                    255,
                    1
                ]
            },
            "default": "0",
            "unit": "",
            "tags": "output, byte",
            "edit": "3",
            "order": 10,
            "description": "weekdays and activeflags",
            "active": true,
            "export": true
        },
        {
            "name": "T1_ON_hour",
            "type": "BYTE",
            "offset": 3,
            "range": {
                "type": "tooltip_loop",
                "values": [
                    0,
                    23,
                    1
                ]
            },
            "default": "0",
            "unit": "",
            "tags": "output, byte",
            "edit": "3",
            "order": 11,
            "description": "hour",
            "active": true,
            "export": true
        },
        {
            "name": "T1_ON_minute",
            "type": "BYTE",
            "offset": 4,
            "range": {
                "type": "tooltip_loop",
                "values": [
                    0,
                    59,
                    1
                ]
            },
            "default": "0",
            "unit": "",
            "tags": "output, byte",
            "edit": "3",
            "order": 12,
            "description": "minute",
            "active": true,
            "export": true
        },
        {
            "name": "T1_OFF_active_day",
            "type": "BYTE",
            "offset": 5,
            "range": {
                "type": "tooltip_loop",
                "values": [
                    0,
                    255,
                    1
                ]
            },
            "default": "0",
            "unit": "",
            "tags": "output, byte",
            "edit": "3",
            "order": 13,
            "description": "weekdays and activeflags",
            "active": true,
            "export": true
        },
        {
            "name": "T1_OFF_hour",
            "type": "BYTE",
            "offset": 6,
            "range": {
                "type": "tooltip_loop",
                "values": [
                    0,
                    23,
                    1
                ]
            },
            "default": "0",
            "unit": "",
            "tags": "output, byte",
            "edit": "3",
            "order": 14,
            "description": "hour",
            "active": true,
            "export": true
        },
        {
            "name": "T1_OFF_minute",
            "type": "BYTE",
            "offset": 7,
            "range": {
                "type": "tooltip_loop",
                "values": [
                    0,
                    59,
                    1
                ]
            },
            "default": "0",
            "unit": "",
            "tags": "output, byte",
            "edit": "3",
            "order": 15,
            "description": "minute",
            "active": true,
            "export": true
        },
        [...]
    ],
    "input": [
        {
            "name": "TimerStatus",
            "type": "WORD",
            "offset": 0,
            "range": {
                "type": "tooltip_loop",
                "values": [
                    0,
                    255,
                    1
                ]
            },
            "default": "0",
            "unit": "",
            "tags": "input, word",
            "edit": "2",
            "order": 5,
            "description": "Timer active flags",
            "active": true,
            "export": true
        }
    ],
    "memory": [],
    "lang": {
        "de": {
            "INPUT": "Eingang",
            "OUTPUT": "Ausgang"
        },
        "en": {
            "INPUT": "Input",
            "OUTPUT": "Output"
        }
    }
}

Weitere Links

In diesem Tutorial zeigen wir Dir, wie du deine eigene RAP Datei erstellen kannst:

Hier eine Übersicht über die Struktur einer RAP Datei: