Sorry, I do not (yet?) use HABPanel or Velbus.
A virtual button would just be an Item that can be referenced and/or set in a Rule.Just create an Item with no linked channel to create a virtual button. I assume the Item would be a Switch?
What have you tried? This forum is geared more to help somebody resolve their issues and learn. It is not a Help Desk just providing solutions.
It is no different in habpanel!!.
What you need is to create a virtual item first. And then link it in Habpanel.
Whatever you do with this item, could be as well as a trigger in a rule.
They can, and it´s pretty easy… But you need to understand how to create the item… This is where you seem to have gone stucked. Try searc for vitual items. As wel as channel triggers, (velbus button IS the channel trigger).
Most people read documentation before embarking on this journey.
First, study the concepts of OH.
The configuration Guide is a good next step.
Rules are described here.
Please read this information and return after you have tried to implement something. You could surprise yourself.
1 Like
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
21
I understand the confusion, especially if you’re thinking about ‘virtual items’.
You’d use the State of a virtual Item in a similar way to how you’d use a trigger Channel of a Velbus Thing
(Note the Title case usage there)
An Item and a trigger Channel are both something that can be used in the When section of a rule.
With the added bonus that Item States can also be queried during the Then section of a rule. (As you’ve done with your Sonos Volume)
For example
rule "example triggers and queries"
when
Item Virtual_Switch_Item changed
or
Channel 'velbus:VMBGP2:xxxxxxxx:XX:ch1' triggered LONG_PRESSED
then
Virtual_Switch_Item.sendCommand(OFF)
If ( Another_Item.state == ON ) {
New_Item.sendCommand(ON)
Another_Item.sendCommand(OFF)
}
else {
New_Item.sendCommand(OFF)
Something_Volume.sendCommand(0)
}
end
Or do you mean in the Experimental Rules Engine of PaperUI.
(The hint might be in the name)
That said, can you clarify what you mean by ‘Thermostats can’
Because the Velbus thermostat functionality is made up of Trigger Channels (that can’t be linked to Items) and normal (state based) channels that can be linked to Items and thus used in all the rules / logic solutions available to openHAB2.
Yes, I am (was) using the Experimental Rules Engine of PaperUI.
I thought you could make this rule:
when ‘velbus:vmb8pbu:bc2e9d45:28:input#CH1’ triggered PRESSED then do something…
But this is impossible with he Experimental Rules Engine of PaperUI, but now it works with a DSL rule, so me happy.
But there is no way so I can simulate a key-press in velbus so a scene (stored in velbus) is recalled. In my living room I have 6 velbus dimmers, and I hope that I must not to copy all the settings (values and dim times stored in my velbus modules) in the rules in openhab.
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
26
Hello
Happy new year to you.
I’m glad to hear that the DSL rules are working for you.
As far as sending “Button events” back into Velbus from openHAB2, that isn’t possible right now.
At least, not through the Velbus binding.
I have worked out how to send a mimicking packet from NodeRed using a TCP node.
If that is something you’d like to play with ?
I would assume that there is a way to send a TCP packet to VelServ using the TCP / UDP binding in openHAB2, but I haven’t got my head around that yet.
What I do know is that you may need to send just a “Button Pressed” packet, but ideally follow it with a “Button Released” packet (just for compliance with the protocol)
Or you may need to send a “Button Pressed” packet, followed by “Button Long Pressed” packet, later followed with a “Button Released” packet, depending on how you have setup your scenes in VelbusLink.,
I have tested the following with a button from a VMB8PBU, which was programmed in VelbusLink with a “Up/Down” action on a VMB2BLE motor controller.
Just issuing a “Button Pressed” packet was enough to start and stop the VMB2BLE.
What happens with other modules will be a matter for you to explore.
Here is what I did.
I opened VelbusLink logging and isolated the VMB8PBU packets by using the filter
packet.addr==$A0
Then I Pressed, Long Pressed and Released Button 7 of the VMB8PBU (I did it from within VelbusLink, using the Operate function)
Which gave me this
The first Button Status is the “Press”
Second Button Status is the “Long Press”
Third Button Status is the “Released”
You’ll note that H40 pops up in all three strings, at different places.
H40 is derived from Bin 01000000, which indicated that Button 7 is in play.
So equally, H01 would mean Button 1, from Bin 00000001
By highlighting the first Button Status and clicking on “USE”, followed by “Check Sum”
The BIG issue I found (and it may be possible to bypass this step if you know more about NodeRed than I do) is that I couldn’t simply paste in the HEX string into the Inject node.
I had to convert the HEX packet into something that NodeRed would convert (correctly) back into exactly the same HEX string.
I used a Google Drive sheet to convert the HEX string from VelbusLink into a formatted TEXT string.
I’ve put that spreadsheet in a ZIP file here in Open Document and Excel formats.
The flow I used in NodeRed is this, which you can simply import into your own NodeRed instance, assuming that you have VelServ running on the same machine, on port 6000
Looking into this further, I discovered that it is possible to use a Function node to format the VelServ packet, and get triggered by different Payload content.
For example, I created a Function node that can output the 3 different button events, based on a payload containing matching text.
Which means that by using a couple of Delay nodes and Change nodes, you could automate the sending of the correct sequence of Button events to correctly match your requirements.
IE
Pressed
Long_Pressed
Released
You will just have to work out the correct sequence of Button Events to trigger your scene and release all modules (IE, Don’t Leave them waiting for a “Button Released” event)
Please note that I have added 2 variables to the Function node so that you can easily adapt it for your use.
address
button
These need to the the Decimal version of the HEX command you wish to send, whereas the rest of the string you see in the function is made up of HEX .
Hi stuart, also a happy 2020 for you and family,
Thank you for your help.
I was thinking also to send IP commands to the velserv directly via the tcp/udp binding, but I gonna give node-red a try.
Is it correct you have openhab, velserv and node-red on the same raspberry pi?
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
28
Hello
You can put the software on as many different machines as you like / want / need.
I guess it comes down to performance and speed, my personal opinion of SBCs is well documented on this forum.
In theory, yes, you can run all three on the same Pi.
There’s no reason why you couldn’t use the TCP binding and just send out the packets you need to.
In fact, there is a method of interacting with Velbus networks from openHAB2 that doesn’t use Cédric’s binding at all.
Hi,
I have now velserv, openhab and node-red working
I think there is a little error in your hex codes the 9th hex value is changing depending the adress, or something else (checksum ?).
I 'm now trying to send the press and release command with one press of a button, do you know the correct comand for the delay. (I’m using now “timeout(1000)”)
here you have my node-red export file:
[{"id":"ccfd159f.c0e418","type":"function","z":"d86de69f.3d1a48","name":"Send Button Events to VelServ","func":"var button3 = 4; // Decimal of Hex 40, which is button No 7 only (Different numbers are generated if multiple buttons are pressed). Note Dec 64 is derived from the Binary state 01000000 indicating button 7\nvar address3 = 34; // Decimal of Hex A0\n\nvar incoming = String(msg.payload);\nvar buffer = \"\"\n\nif (incoming == \"Pressed3\" ) {\n// Format Pressed event\nbuffer = Buffer.from( [0x0F, 0xF8, address3, 0x04, 0x00, button3, 0x00, 0x00, 0xCF, 0x04] );\n//Timeout(1000)\nbuffer = Buffer.from( [0x0F, 0xF8, address3, 0x04, 0x00, 0x00, button3, 0x00, 0xCF, 0x04] );\n\nreturn {payload:buffer};\n\t}\n\t\nreturn [msg];\n","outputs":1,"noerr":0,"x":650,"y":640,"wires":[["440b7389.4d954c","adf0b974.f17448"]]}]
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
30
Hello
Yes, the one before last byte is always a checksum and I’ll confess I completely forgot to account for that.
It’s probably best at this stage to see how VelbusLink creates the checksum, by using the steps I showed above.
As for sending a Pressed AND Released msg from the same function call, I suggest you have a read of this page on the NodeRed site, specifically the section marked “Multiple Messages”
in openhab I made virtual items and I use in habpanel this widget
When you push the button, the ON command is send and after a few ms OFF is send to velbus.
It is very nice that every scene can be programmed within velbus, and recalled directly from the habpanel. (with fade times, etc)
I still do not find a reason why stef coene didn’t programmed the item “simulate this button” (you can find this in velbuslink to test your actions)
i just have to find a way that all my monstable buttons are in selection button(i have put my buttons in a group), like I have with my sonos fav.
I have problems with running the lastest binding of velbus (witch recognises vmb1ts) and velserv (dsm rules doesn’t work anymore till I shut down velserv).
But I need velserv for my nodered, any idea how to talk to the velbus (usb) via the velbus raw byte node ?
If that is not possible a try a second pi with velserv seperated from openhab
I’m not using both at the same time (I disable one when I use the other way), It was for testing because the velbus binding was giving problems via velserv. I think when the binding is working perfect with velserv all my problems will be solved !
1 Like
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
36
If anyone is interested, I have got a Function node working now that will start a timer for up to 63532 seconds on a Velbus Relay channel.
I assume it would be possible to adapt this for a dimmer?
All you should need to do is change the HEX address of the Module and the Channel number
I’m certain I’ll not win an award for this mess, but it is working.
If you’re curious, the JavaScript inside the NodeRed Function looks like this
var address = "74"; // Hex address of Relay
var channel = "04"; // Hex value of Channel No 3 of relay, derived from a bit array = 00100 (as in =bin2hex(00100) in a spreadsheet )
// 01 = OFF, 02 = ON, 03 = Timer start
var eop = "04";
var a = '0f', b = 'f8', c = address, d = '02', e = '02', f = channel, g = '00', h ="00", i = "00", y = 'ff';
var ndigits = 2, x, carry = 0, z, checksum = "";
var incoming = String(msg.payload);
var buffer = ""
var newMsg = { payload:incoming };
if (incoming == "ON" ) {
command = "02"; // ON
c = address;
e = command;
f = channel;
for (x = ndigits - 1; x >= 0; x--) {
z = parseInt(a[x], 16) + parseInt(b[x], 16)+ parseInt(c[x], 16)+ parseInt(d[x], 16)+ parseInt(e[x], 16)+ parseInt(f[x], 16) + carry;
carry = z >> 4;
checksum = (z & 15).toString(16) + checksum;
}
checksum = ((parseInt(y, 16) - parseInt(checksum, 16))+1).toString(16)
newMsg.payload = checksum;
// Format Pressed event
// buffer = Buffer.from( [0x0F,0xF8,0x74,0x05,0x03,0x04,0x00,0x00,0x05,0x74,0x04] );
buffer = Buffer.from(["0x"+a.toString(16),"0x"+b.toString(16),"0x"+c.toString(16),"0x"+d.toString(16),"0x"+e.toString(16),"0x"+f.toString(16),"0x"+checksum,0x04])
return [{payload:buffer},newMsg];
}
if (incoming == "OFF" ) {
command = "01"; // OFF
c = address;
d = size;
e = command;
f = channel;
for (x = ndigits - 1; x >= 0; x--) {
z = parseInt(a[x], 16) + parseInt(b[x], 16)+ parseInt(c[x], 16)+ parseInt(d[x], 16)+ parseInt(e[x], 16)+ parseInt(f[x], 16) + carry;
carry = z >> 4;
checksum = (z & 15).toString(16) + checksum;
}
checksum = ((parseInt(y, 16) - parseInt(checksum, 16))+1).toString(16)
newMsg.payload = checksum;
buffer = Buffer.from(["0x"+a.toString(16),"0x"+b.toString(16),"0x"+c.toString(16),"0x"+d.toString(16),"0x"+e.toString(16),"0x"+f.toString(16),"0x"+checksum,0x04])
return [{payload:buffer},newMsg];
}
// Timer value less than 255 seconds
if (incoming >= 0 ) { if (incoming <=255) {
command = "03"; // Start Timer
c = address;
d = "05"; // Size
e = command;
f = channel;
i = incoming.toString(16) // Duration of timer in seconds
checksum = parseInt(a, 16) + parseInt(b, 16)+ parseInt(c, 16)+ parseInt(d, 16)+ parseInt(e, 16)+ parseInt(f, 16)+ parseInt(g, 16)+ parseInt(h, 16)+ parseInt(i, 16);
checksum = checksum.toString(16);
checksum = (parseInt("FFFF",16) - parseInt(checksum,16));
checksum = (parseInt(checksum,10)) + 257;
checksum = checksum.toString(16);
checksum = checksum.slice(-2);
newMsg.payload = checksum;
buffer = Buffer.from(["0x"+a.toString(16),"0x"+b.toString(16),"0x"+c.toString(16),"0x"+d.toString(16),"0x"+e.toString(16),"0x"+f.toString(16),"0x"+g.toString(16),"0x"+h.toString(16),"0x"+i.toString(16),"0x"+checksum,0x04])
return [{payload:buffer},newMsg];
}}
// Timer value more than 255 seconds and less than 63535 seconds
if (incoming >= 255 ) { if (incoming <=63535) {
command = "03"; // Start Timer
c = address;
d = "05"; // Size
e = command;
f = channel;
h = incoming - 255
i = (incoming - h).toString(16) // Duration of timer in seconds
checksum = parseInt(a, 16) + parseInt(b, 16)+ parseInt(c, 16)+ parseInt(d, 16)+ parseInt(e, 16)+ parseInt(f, 16)+ parseInt(g, 16)+ parseInt(h, 16)+ parseInt(i, 16);
checksum = checksum.toString(16);
checksum = (parseInt("FFFF",16) - parseInt(checksum,16));
checksum = (parseInt(checksum,10)) + 257;
checksum = checksum.toString(16);
checksum = checksum.slice(-2);
newMsg.payload = checksum;
buffer = Buffer.from(["0x"+a.toString(16),"0x"+b.toString(16),"0x"+c.toString(16),"0x"+d.toString(16),"0x"+e.toString(16),"0x"+f.toString(16),"0x"+g.toString(16),"0x"+h.toString(16),"0x"+i.toString(16),"0x"+checksum,0x04])
return [{payload:buffer},newMsg];
}}
if (incoming >= 63535 ) {
newMsg.payload ="";
msg.payload ="";
return;
}
return [msg,newMsg];