How to Create a RAP File Exemplified by RevPiTimer (Compact)

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
Bit 7 6 5 4 3 2 1 0
Timer No. Timer8 Timer7 Timer6 Timer5 Timer4 Timer3 Timer2 Timer1
Bit 15 14 13 12 11 10 9 8
Timer No. Timer16 Timer15 Timer14 Timer13 Timer12 Timer11 Timer10 Timer9

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 time Timer 1: Switch off time
Timer 2: Switch on time Timer 2: Switch off time
Timer 16: Switch on time Timer 16: Switch off time

A time consists of

  • Weekday and active switching can be combined in one byte.
Bit No. 7 6 5 4 3 2 1 0
 Value Active Sun Sat Fri Thu Wed Tue Mon
  • 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: