RfLink binding - Sending to multiple devices unreliable

Hi there! My first post here. Newly migrated to openhab from Pimatic. Spent lots of time setting up my system and loving openhab.

I use the rflink binding to control various switches and sockets and it works very nicely. The issue I am having is when sending commands to multiple devices it doesnt activate all the switches / sockets. Checking the logs reveals nothing as the commands seem to send properly.

I have added the “repeats=x” variable to the binding config for each thing and tested higher values but it seems to make no difference.

I have a feeling it is to do with the interval between commands. I think they are processed too quickly to be sent correctly. But as i said, the logs reveal nothing to me.

Can anyone help? Below is my setup

Things:

Bridge rflink:bridge:usb0 "RFLink Bridge" [ serialPort="/dev/ttyACM0", baudRate=57600, disableDiscovery=false ] {
        switch          ChristmasLight1         "Christmas Light 1"             [deviceId="Unitec-9159-01", repeats=15]
        switch          ChristmasLight2         "Christmas Light 2"             [deviceId="Unitec-9159-02", repeats=15]
        switch          ChristmasLight3         "Christmas Light 3"             [deviceId="Unitec-9159-03", repeats=15]
        switch          ChristmasLight4         "Christmas Light 4"             [deviceId="Unitec-9159-04", repeats=15]
        switch          ChristmasLightALL       "Christmas Lights ALL"          [deviceId="Unitec-9159-00", repeats=15]
        switch          LoungeLight1            "Lounge Light 1"                [deviceId="TriState-8a22a1-10", repeats=15]
        switch          LoungeLight2            "Lounge Light 2"                [deviceId="TriState-8a22a4-10", repeats=15]
        switch          LoungeLight3            "Lounge Light 3"                [deviceId="TriState-8a2290-10", repeats=15]
        switch          PIR1                    "Downstairs PIR"                [deviceId="NewKaku-0000007b-3"]
        switch          PIR2                    "Upstairs PIR"                  [deviceId="NewKaku-0000007b-2"]
        temperature     TempSensor1             "Temp Sensor 1"                 [deviceId="AlectoV4-5018"]
        temperature     TempSensor2             "Temp Sensor 2"                 [deviceId="AlectoV4-5028"]
        humidity        Humidity1               "Humidity Sensor 1"             [deviceId="AlectoV4-5018"]
        humidity        Humidity2               "Humidity Sensor 2"             [deviceId="AlectoV4-5028"]
        switch          BedroomLight            "Bedroom Light"                 [deviceId="Conrad-5a10ef-06", repeats=15]
   }

Items:

Switch  AllLights                               "All Lights"                    ["Lighting"]
Dimmer  3KitchenLights_Level                    "3 Kitchen Lights Level"
Color   3KitchenLights_Hue                      "3 Kitchen Lights Hue"          ["Lighting"]
Switch  ChristmasLight1                         "Christmas Light 1"             ["Lighting"]    {channel="rflink:switch:usb0:ChristmasLight1:command"}
Switch  ChristmasLight2                         "Christmas Light 2"             ["Lighting"]    {channel="rflink:switch:usb0:ChristmasLight2:command"}
Switch  ChristmasLight3                         "Christmas Light 3"             ["Lighting"]    {channel="rflink:switch:usb0:ChristmasLight3:command"}
Switch  ChristmasLight4                         "Christmas Light 4"             ["Lighting"]    {channel="rflink:switch:usb0:ChristmasLight4:command"}
Switch  ChristmasLightALL                       "Christmas Light ALL"           ["Lighting"]    {channel="rflink:switch:usb0:ChristmasLightALL:command"}
Contact ChristmasLight1_Contact                 "Christmas Light 1 Contact"                     {channel="rflink:switch:usb0:ChristmasLight1:contact"}
Contact ChristmasLight2_Contact                 "Christmas Light 2 Contact"                     {channel="rflink:switch:usb0:ChristmasLight2:contact"}
Contact ChristmasLight3_Contact                 "Christmas Light 3 Contact"                     {channel="rflink:switch:usb0:ChristmasLight3:contact"}
Contact ChristmasLight4_Contact                 "Christmas Light 4 Contact"                     {channel="rflink:switch:usb0:ChristmasLight4:contact"}
Contact ChristmasLightALL_Contact               "Christmas Light ALL Contact"                   {channel="rflink:switch:usb0:ChristmasLightALL:contact"}
Switch  LoungeLight1            "Lounge Light 1"                ["Lighting"]    {channel="rflink:switch:usb0:LoungeLight1:command"}
Switch  LoungeLight2            "Lounge Light 2"                ["Lighting"]    {channel="rflink:switch:usb0:LoungeLight2:command"}
Switch  LoungeLight3            "Lounge Light 3"                ["Lighting"]    {channel="rflink:switch:usb0:LoungeLight3:command"}
Contact LoungeLight1_Contact    "Lounge Light 1 Contact"                        {channel="rflink:switch:usb0:LoungeLight1:contact"}
Contact LoungeLight2_Contact    "Lounge Light 2 Contact"                        {channel="rflink:switch:usb0:LoungeLight2:contact"}
Contact LoungeLight3_Contact    "Lounge Light 3 Contact"                        {channel="rflink:switch:usb0:LoungeLight3:contact"}
Switch  BedroomLight            "Bedroom Light"                 ["Lighting"]    {channel="rflink:switch:usb0:BedroomLight:command"}
Contact BedroomLight_Contact    "Bedroom Light Contact"                         {channel="rflink:switch:usb0:BedroomLight:contact"}
Switch  PIR1                    "Downstairs PIR"        {channel="rflink:switch:usb0:PIR1:command"}
Switch  PIR2                    "Upstairs PIR"          {channel="rflink:switch:usb0:PIR2:command"}
Number          TempSensor1             "Temp Sensor 1"         {channel="rflink:temperature:usb0:TempSensor1:temperature"}
Number          TempSensor2             "Temp Sensor 2"         {channel="rflink:temperature:usb0:TempSensor2:temperature"}
Number          Humidiy1                "Humidity Sensor 1"     {channel="rflink:humidity:usb0:Humidity1:humidity"}
Number          Humidiy2                "Humidity Sensor 2"     {channel="rflink:humidity:usb0:Humidity2:humidity"}

Thanks in advance!

Probably correct
See:

This looks very complicated. Not sure how to start with my setup.

EDIT:

This is my attempt at a rule:

import java.util.concurrent.locks.ReentrantLock
var lock = new ReentrantLock
var lastCommand = now.millis
val commandDelay = 100 // experiment to find the lowest number that works

rule "433Delay"

when

    // We can't trigger the rule using WirelessDevices received update because there is no good way to handle the multiple rule triggers
    Item LoungeLight1  received command or
    Item LoungeLight2  received command or
    Item LoungeLight3  received command
then

    // Get the controller ID and device ID
    val split = triggeringItem.name.split("_")
    val device = split.get(0)
    val command = if(receivedCommand == ON) "ON" else "OFF"

    // Ensures only one instance of the Rule can run at a time
    // We do this after the lines above so the delay below does not interfear with the Rule's ability to
    // determine which Item triggered the Rule
    lock.lock
    try {

        // Sleep if the last command happened too close to now, but only sleep just long enough
        val deltaTime = now.millis - lastCommand // how long since the last call to executeCommandLine
        if(deltaTime <= commandDelay) Thread::sleep(deltaTime)

        val results = sendCommand("" + device + ", " + command)
        lastCommand = now.millis

        logDebug("RFLINKDELAY", results)
    }
    catch(Exception e) {
        logError("rflinkDelay", "Error handling RfLink command: " + e)
    }
    finally {
        lock.unlock
    }

end

Cant really see anything in the logs to confirm it is working or not. Maybe I have entered something wrong? Time will tell when I use the devices.

Im struggling with this. Having ditched the above attempt as it wasnt working for lots of reasons I am now working on this:


import java.util.concurrent.ConcurrentLinkedQueue

val Queue<String> commands = new ConcurrentLinkedQueue()
val Queue<String> items = new ConcurrentLinkedQueue()
var Timer timer = null
var lastCommand = now.minusSeconds(1)

rule "Delay"

when
        Item LoungeLight1 received command or
        Item LoungeLight2 received command or
        Item LoungeLight3 received command

then

        val device = RfLink.members.sortBy[lastUpdate].last
        items.add(device.toString)
        commands.add(receivedCommand.toString)
        logInfo("RFLINKDELAY", "Send Device: " + device + ", Command: " + receivedCommand)
        if(timer === null) {
                timer = createTimer(now.plusMillis(0), [ |
                        if(items.peek !== null) {
                                val cmd = commands.poll
                                val sendDevice = items.poll

                                logInfo("RFLINKDELAY", "Send Device: " + sendDevice + ", Command: " + cmd)

                                val results = sendCommand(sendDevice, cmd)
                                logDebug("RFLINKDELAY", results)
                                lastCommand = now.millis
                                }
                val deltaTime = now.millis - lastCommand
                logInfo("RFLINKDELAY", deltaTime)
                timer.reschedule(now.plusMillis(if(deltaTime<100) deltaTime else 100))

                        ])
        }
end

Still working on it… any help is appreciated.

Hi @Phil_Mottershead!
Have you been successful? I’m looking for exactly this kind of rule.

Wouldn’t it be an idea to avoid putting the devices and commands in separate queues? What if the queues gets out of sync for some reason? Isn’t it possible to put both the device and command in the same queue and then perform some string operations?
I’ll give this some thought unless you already have a working rule syntax.

I’m having problems with running out of threads, probably (rules stop working), and this is a good way to avoid locks and sleep.

Hi,

I dont have this working as yet. A bit stuck if im honest. I dont have enough grasp of it yet.

Hi @Phil_Mottershead,
I had same same problem and fixed it in changing the constant Send_Delay in the file RfLinkSerialConnector.java. It is part of the source files of the binding. I changed it from 50 to 500 (ms). After saving the file you need to package the binding. Just follow the instructions at the end of the page https://github.com/cyrilcc/org.openhab.binding.rflink. The packaging worked nicely for me under Linux after installing Maven (apt maven install).

I hope this helps.

Best,
Thomas

Thomas,

I edited the rflinkserialconnector.java. Packaged to .jar file but it seems that it is not working. When i look in the tail log the switch times are less than 500 millisecs (average between 20-30). I did check rflinkserialconnector.java and the 500 millisec is in the right place.

I did restart OH2 and did remove the original binding from the addon dir. The binding is working as far as I can see correctly!

Any ideas why this delay is not working?