We need a structured list of all messages and commands

I think you deserve it :slight_smile: Having the OpenHab interface adds quite some value to Velbus.

It’s a good start. A lot of commands can still be added. We just have to think on how the community can help with that. Because once values are added manually we can not regenerate it anymore.

Adding them manually is not that easy either because of the linked sections.
We might create a dedicated editor for it, including data validations and revisions… Hmm, that might work…

The purpose of having a JSON like this is to simplify sending/receiving bus messages in whatever language, by having that higher-level, structured metadata.

It should be simple to

  • Use this metadata to filter out modules and messages to easily generate the right Velbus packet data. This can then be translated to whatever underlaying programming language.
  • Add new modules and messages to the JSON file when Velbus releases new modules. So versioning is important.

With that in mind, I should make a ‘simple’ test app that integrates the JSON to see how this structure works out. But as I said, it looks promising.

More commands and detailed data byte info are of course welcome, but that’s a hell of a job. Not sure if more can be parsed out of the PDFs? That’s why we need to think about a community driven way to do this.

Looking forward to both the opinions of @Stef_Coene and @VEL524 about this.

I can’t give any hardware, but you’re both welcome to remotely connect to my networks to test your solutions.

I’m only a couple of modules short of the full ( current ) range.

1 Like

I just wrote some scripts for fun :slight_smile:
And published them on github because an ex-collegae was interested in them.

The json file is just the end result.
The information comes from the protocol files, but mostly from the files in the data directory. These *.pm files are in perl format. But they contain the most important data and some logic to reuse some code.
Don’t be scared about the perl format, it’s actually not really perl code, but a mult-hash definition. I can convert them to json, but I think the perl code is easier to read then json code.

I recommend to not change the json file itself, but the *.pm files and regenerate the json file.

With format I didn’t mean json. But more the way the data is stored in the json file.

I tried to explain how I use the data in the json in README-StefCoene.md, but that’s not finished yet.
For instance, the ‘Get’ and ‘Set’ are hard to explain, even for me :slight_smile:
I need to reread my code to find out how the data in the json file is used.

It’s easier to just read the pdf’s, update the *.pm files and regenerate the json file.
But I think most of the interested stuff is already in my code. I’m pretty sure I can parse all channel update messages and control all channels with my scripts.

I skipped everything related to alarms and programs because I don’t use them in my setup. I don’t know if there is any need for it?

Stef

This is indeed a great start, or even an awsome start.

the only thing what i miss is that in some definitions there are no modules listed, is this a bug?
about the basedon, i think if we want to make this generally avilable (an only generate the json) it would be better to just duplicate the data.

And would it be possible to add the modulename to the ‘ModuleTypes’ object?

the buttoncounter type is missing some info :slight_smile:

1 Like

This is an odd one.

There seems to be a clear 50 / 50 divide.

Some people don’t seem to want any kind of timed events within Velbus and use some other kind of scheduler or just manual adjustment.

Then the other people (once they discover the Velbus alarm times) use them for full control of their property.

Changing program groups is again something that isn’t asked for until people get very comfortable with the advanced configuration.

The Alarm Clock widget I’ve adapted for openHAB2 HabPanel certainly makes it easier to interact with them.

So the info in the files in the data folder is not parsed from the PDFs?
For instance to add a new command message it should be added in Velbus_data_protocol_messages.pm manually?
Probably not all info can be parsed automatically from the PDFs (like on how to convert), but like you said, I also think most of it can be parsed. Eg: the info from the tables, like I did here.
I’d like to help here, but not sure what’s the best way to keep this easy.

Like @MDAR said, everybody has his own interests. I’m now working on Node-RED nodes to update colors of Edge-lit buttons. I also want to send memo texts to them…
So we have to find a way to for any developer to easily add these niche commands, so everybody can benefit from it.

1 Like

Indeed, that’s a manual step. The effort to parse the protocol file 100% correctly does not outweighs the time needed to read the pdf and put in the needed data manually.

Parsing the pdf and putting the text in a json is something different then what I did. I don’t care about the text

“databyte2”:“0 =disabled / 1 = enabled”

No, I want something like

{
“0” = “disabled”,
“1” = “enabled”
}

And this needs to 100% accurate and for all the possible cases in all the protocol files the same.
So I prefer to this manually for the few places where the content of the databyte is relevant.

Stef

I don’t care about alarms and programs because I use OpenHAB for automation.
But if the demand is there, can always take a look at the messages and see if I can understand them and add them to the json and my scripts.

Stef

1 Like

Thanks Stef for making that JSON available. There’s a lot of information in that. :slight_smile:


I don’t think that Stef’s JSON should be responsible to know the whole structure of every command and their databytes. If you need that, I would wait for our own revision of the protocol manuals and parse that.

Here’s an example of what we have in mind (at this moment):

{
 "id": "02-2",
 "name": "'Switch relay on' command received",
 "modules": [
   "VMB4RYLD",
   "VMB4RYNO"
 ],
 "type": "Request",
 "priority": {
   "name": "Highest priority",
   "value": 0
 },
 "addressRequired": "Module address",
 "rtr": false,
 "databytes": [
   {
     "description": "Command Type",
     "displayAs": "hex",
     "options": [
       {
         "description": "COMMAND_SWITCH_RELAY_ON",
         "pattern": "02"
       }
     ]
   },
   {
     "description": "Relay bit number",
     "displayAs": "bin",
     "options": [
       {
         "description": "Channel 1",
         "pattern": "00000001"
       },
       {
         "description": "Channel 2",
         "pattern": "00000010"
       },
       {
         "description": "Channel 3",
         "pattern": "00000100"
       },
       {
         "description": "Channel 4",
         "pattern": "00001000"
       },
       {
         "description": "Virtual channel 5",
         "pattern": "00010000"
       }
     ]
   }
 ]
}

{
"id": "FB-3",
"name": "Transmits the relay status",
"remarks": [
  "[DATABYTE6][DATABYTE7][DATABYTE8] contain a 24-bit time in seconds"
],
"modules": [
  "VMB4RYLD",
  "VMB4RYNO"
],
"type": "Response",
"priority": {
  "name": "Lowest priority",
  "value": 11
},
"addressRequired": "Module address",
"rtr": false,
"databytes": [
  {
    "description": "Command Type",
    "displayAs": "hex",
    "options": [
      {
        "description": "COMMAND_RELAY_STATUS",
        "pattern": "FB"
      }
    ]
  },
  {
    "description": "Relay bit number",
    "displayAs": "bin",
    "options": [
      {
        "description": "Channel 1",
        "pattern": "00000001"
      },
      {
        "description": "Channel 2",
        "pattern": "00000010"
      },
      {
        "description": "Channel 3",
        "pattern": "00000100"
      },
      {
        "description": "Channel 4",
        "pattern": "00001000"
      },
      {
        "description": "Virtual Channel 5",
        "pattern": "00010000"
      }
    ]
  },
  {
    "description": "Disable/inhibit/Forced on setting",
    "displayAs": "bin",
    "options": [
      {
        "description": "Channel normal",
        "pattern": "xxxxxx00"
      },
      {
        "description": "Channel inhibited",
        "pattern": "xxxxxx01"
      },
      {
        "description": "Channel forced on",
        "pattern": "xxxxxx10"
      },
      {
        "description": "Channel disabled",
        "pattern": "xxxxxx11"
      }
    ]
  },
  {
    "description": "Relay status",
    "displayAs": "bin",
    "options": [
      {
        "description": "Relay channel off",
        "pattern": "xxxxxx00"
      },
      {
        "description": "Relay channel on",
        "pattern": "xxxxxx01"
      },
      {
        "description": "Relay channel interval timer on",
        "pattern": "xxxxxx11"
      }
    ]
  },
  {
    "description": "Led status",
    "displayAs": "bin",
    "options": [
      {
        "description": "LED off",
        "pattern": "00000000"
      },
      {
        "description": "LED on",
        "pattern": "10000000"
      },
      {
        "description": "LED slow blinking",
        "pattern": "01000000"
      },
      {
        "description": "LED fast blinking",
        "pattern": "00100000"
      },
      {
        "description": "LED very fast blinking",
        "pattern": "00010000"
      }
    ]
  },
  {
    "description": "high byte of current delay time",
    "displayAs": "none"
  },
  {
    "description": "mid byte of current delay time",
    "displayAs": "none"
  },
  {
    "description": "low byte of current delay time",
    "displayAs": "none"
  }
 ]
}

We have plans to generate a HTML based on this, eventually replacing the PDFs. Please note that the above structure is not final and subject to change.

In this example, you can find the needed packets for VMB4RYLD and VMB4RYNO allowing to turn the relay on. ( That’s a simple example, I know :slight_smile: )

For example, to turn relay 1 on:

  • Send out one packet with command type: 0x02 (Turn relay on) 0x01 (Relay 1).
  • Wait for one packet with command type: 0xFB (Relay status) and check the second databyte to be 1 and check if the first 2 bits of the third databyte to be 01.

I can find what is needed to turn on a relay in Stef’s JSON.


I think we should not define channel types to a channel, since you have a lot of channel types and chances are big that it will be extended with new channel types quite soon. :wink:

To give an example, some of our (newer) relay modules support inhibited, forced on, forced off and normal state. If we extend the JSON to support that, I assume you need to make a new channel type.

I think a list of possible “features” (switch relay on, force relay on, inhibit, switch to program 1, switch programs off, …) should be defined per module. An integration, supporting a relay, can look in the feature list if the required features are available and make the mapping.

Food for thought.

2 Likes

Hi,

There is a difference in making a json file from the protocol file and making a json file to implement the velbus protocol.

I know that I had a lot of trouble in converting the message data to a channel number. I will have to dig in my code to document it. But it was messy sometimes!

There should be a mapping between the message and channel number, not channel name. I don’t care if it’s a virtual channel, or an alarm or a button.

What I miss in your code is a channel number that’s always consistent for all messages and all modules:

And it can even simplified, instead of giving a sum of mappings, just say this:

When Content=Channel the byte contains the channel number. And we can find the channel number by converting it from ‘counting bit’ notation to decimal (I cal this ChannelBit in my code).
I did this for every message that I needed to parse so I can get the Channel number in a consistent way.

Stef

@VEL524
The biggest problem i face is that the same command codes are used with different data inside of it for certain modules.
How would this be represented in the velbus json?
Do you have an eta on when this would be available?

And to be honest i like the format from vel524 a bit more then the format from Stef_Coene as it has less logic inside

I have per module type and per message the configuration on how to interpret the command.
I try to reuse as much code as possible, that’s why I generate the json file based on (in my case) perl code that contains that logic.

It depends.
If you want to know the content of a message, then yes. But if you want to do something with message, then you need the logic to understand the message.
An example is channel numbering. Make it always the same. No in text like ‘Relay 1’. But in real numbering.

And we also need to change or add information. Example:

“description”: “Relay channel on”,

But for a programmer, this needs to be translate in a state he can use and not in some text:

“state”: “ON”

And for a programmer, this code:

"options": [
  {
    "description": "Channel 1",
    "pattern": "00000001"
  },
  {
    "description": "Channel 2",
    "pattern": "00000010"
  },
  {
    "description": "Channel 3",
    "pattern": "00000100"
  },
  {
    "description": "Channel 4",
    "pattern": "00001000"
  },
  {
    "description": "Virtual Channel 5",
    "pattern": "00010000"
  }
]

Should be:

"Map": {

“00000001”: “CH01”,
“00000010”: “CH02”,
“00000100”: “CH03”,
“00001000”: “CH04”,
“00010000”: “CH05”,
}

Stef

The more I think about it, the more I’m sure that my json layout is what I need.
The layout started very basic and step by step I added what I needed.
I’m sure that some parts can be done better, but at the end it is what I need.

I will try to document my json layout and how my scripts are using the json file.
I will also try to document the workaround I needed to implement at some places.

Stef

Maybe i don’t really understand your json, but i think its way to complex …

@Stef_Coene maybe it would be usefull to give us a walkthrough about how you use it?
for example:

1- how to use it for a scan
2- how to know what message to generate for turning a realy channel on
3- if we receive a couterStatus message for a vmb7in channel

Finding the right balance is hard; universal reusabe code versus detailed described readable…
If I may choose, I prefer the actual JSON format with wide application.

Thanks for all your valuable input, guys. :ok_hand:

I think we need both and I don’t see a reason why we can’t merge both needs in one JSON.
Eg:

"options": [
  {
    "channelNumber": 1,
    "description": "Channel 1",
    "pattern": "00000001"
  },
  {
    "channelNumber": 2,
    "description": "Channel 2",
    "pattern": "00000010"
  },
  {
    "channelNumber": 3,
    "description": "Channel 3",
    "pattern": "00000100"
  },
  {
    "channelNumber": 4,
    "description": "Channel 4",
    "pattern": "00001000"
  },
  {
    "channelNumber": 5,
    "description": "Virtual Channel 5",
    "pattern": "00010000"
  }

Personally I think that having an array of objects (as the above example) is better than using an object with keys: You have more freedom to find an item based on whatever key/value, as with an object you are stuck with the fixed key. The only downside is a little bit more verbose code. Speed is neglectable as long as you don’t have thousansds of items.

Example in JS code (ES6):

options.find(object => object.pattern === "00000010") //returns the second object

But you can also search on channelNumber:
options.find(object => object.channelNumber === 2) //also returns the second object

So you are not stuck on a predefined key to find an item.

@Stef_Coene do you see a downside of using arrays of objects?

Some examples might help, indeed.

In case someone is still following this discussion and is interested in some more information about how my scripts are parsing messages, see this document:

Stef

3 Likes

@Stef_Coene ik denk dat volgende lijst nog niet verwerkt is in uw json

My mistake. I generated a new json file but I forgot to push it to github.

Stef

1 Like

now the json is much better :slight_smile: