How to Create a RAP File Exemplified by RevPiTimer

What are RAP files and why do you need them? Surely you were wondering this when you clicked on the headline.

RAP stands for RevolutionPi Adapter Profile. These files are used by PiCtory to describe devices.

Using the example of the “RevPiTimer” we would like to show you how to create your own RAP files and what you have to consider.

Define your goals

Before hitting the keys, you should give some thought to your project and define a goal.

 

What do you need?

  • I need a timer clock.

What should this timer clock do?

  • Should manage switch-on and switch-off times on a weekly basis.
  • Should support multiple switching times.
  • Switching times should be exact to the minute.
  • Switching times should be able to be turned on and off.

What shouldn’t this timer clock do?

  • Send emails.

Can you give a few examples?

I want…

  • to switch on something from Monday to Friday at 7:15 and switch off 16:45.
  • to switch on something every Tuesday at 0:00, but I don’t want to turn it off.
  • to be able to disable switching times
  • to turn off something at noon on Saturdays.

Requirements

In the next step, we derive the requirements resulting from the objectives.

  • Create a timer clock on a weekly basis
  • Timer clock should have 16 switching times
  • Each switching time consists of a turn-on instant and a turn-off moment.
  • Turn-on instant and a turn-off moment consist of
    • weekdays
    • hours and minutes
    • Enabling/Disabling
  • The status of the 16 switching times (On or Off) can be queried.

Realisation

Okay, now that we have the requirements together, now comes the implementation. First of all, we must ask ourselves what data we need. These data will then appear in the process image. The more compact they are, the more efficiently our RevPi can process them.

First of all, we need to know what input and output data we need.

  • Input data

    • Timer status of the 16 switching times
  • Output data

    • 16 switching times

That sounds a bit odd at first, because you might think that it should be the other way around. But it’s not. From the point of view of the process chain, the timer status serves as an input for further processing.

Data modelling

Which data types do we need?  Bit fields, Bytes, etc…

Input data

  • Timer Status
    • 16 binary values
    • 1 : Timer has the status On
    • 0 : Timer has the status Off
Bit76543210
Timer No.Timer8Timer7Timer6Timer5Timer4Timer3Timer2Timer1
Bit15141312111098
Timer No.Timer16Timer15Timer14Timer13Timer12Timer11Timer10Timer9

Total input data: 2 Bytes

Output data

For each timer we have two events (switch-on and switch-off time). In the process image, this is what it looks like::

Timer 1: Switch on timeTimer 1: Switch off time
Timer 2: Switch on timeTimer 2: Switch off time
Timer 16: Switch on timeTimer 16: Switch off time

A time consists of

  • Weekday and active switching can be combined in one byte.
Bit No.76543210
 ValueActiveSunSatFriThuWedTueMon
  • Hours: Values 0-24
    • 1 Byte
  • Minutes: Values 0-59
    • 1 Byte

So we need the following data:

  • each time 1+1+1 = 3 Bytes
  • 2 times per timer = 2*3 Bytes = 6 Bytes
  • 16 cycle times per timer = 16*6 Bytes = 96 Bytes

Total Output data: 96 Bytes

Realisation of RAP file

The finished file of our RevPiTimer can be found on your RevPi at:

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

Here is an excerpt from this file:

{
    "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,
                    255,
                    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,
                    255,
                    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,
                    255,
                    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,
                    255,
                    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"
        }
    }
}

Further links

In this tutorial we will show you how to create your own RAP file:

Overview of the structure of a RAP file: