HTTP IO Relay Module (BEM107 BrickElectric) - help reading inputs and using Regex

Hi all,

I’m trying to set-up a BEM107 IO Relay module from BrickElectric. So far I am able to control the output from openHAB using the HTTP binding no problem however I’m struggling to figure out how to map the input to a contact item. Here’s a link to the product.

The module has one relay and one input and can be controlled using HTTP requests.

Output Contol
The relay can be switched using the following URLs, http://device-ip:80/k01=1 is ON and http://device-ip:80/k01=0 is OFF. I’ve implemented this via the following:

Item:
Switch BrickRelay1 { http=">[ON:GET:http://192.168.0.40:80/k01=1] >[OFF:GET:http://192.168.0.40:80/k01=0]" }

This works fine.

Input Status
You can request the status of the input using the following URL, http://device-ip:80/getpara[189]=1 which will return GETPARA[189] = 1; if the input contacts are bridged or GETPARA[189] = 0; if they’re open. This works fine in my browser and returns a blank page with just the text GETPARA[189] = 1; or GETPARA[189] = 0; depending on the status of the input.

I’ve attempted to implement this using the following:

Item:
String Input "Input Status" { http="<[http://device-ip:80/getpara%%5B189%%5D=1:10000:REGEX((.*))]" }

Note I’ve used %%5B and %%5D instead of [ ] as the closed brackets caused an error.

In the logs this returns “Input changed from html>body>/body>/html> to html>body>/body>/html>”
The sitemap item displays no text.

This also only returns a response the first few times, after this I think multiple websockets are being opened and it causes a “Fatal transport error: java.net.SocketTimeoutException: Read timed out” error.

Is anyone able to advise on how I can read the input of this device and map it to a contact item? There are also other functions such as get device type which I would like to map to a string.

Thank you

Hardware: Raspberry Pi 4 Model B Rev 1.2
OS: openhabian 2.5.9-1 release build

I would use the exec Binding together with a curl command:

curl -q -o - http://device-ip:80/getpara[189]=1

Can you provide how the exact output of the curl command looks like ? The output then needs to parsed by an additional command to return the status of the relais.

This is the Putty output of the curl command:

<html><body>GETPARA[189] = 1;</body></html>

Reading up on the exec binding now, thanks

With this command executed by the exec binding

curl -q -o - http://device-ip:80/getpara[189]=1 | sed -e 's/.*= //' |sed -e 's/;.*//'

it should be possible to get back the status of the switch.

This works in Putty, but I may be using the exec binding incorrectly.

I’ve added the command to the /etc/openhab2/misc/exec.whitelist file as
curl -q -o - http://192.168.0.40:80/getpara[189]=1 | sed -e 's/.*= //' |sed -e 's/;.*//'

Configured the rest as follows:

Thing
Thing exec:commmand:brickinput [command="curl -q -o - http://192.168.0.40:80/getpara[189]=1 | sed -e 's/.*= //' |sed -e 's/;.*//'", interval=15, timeout=5]

Items
String InputStatus {channel="exec:command:brickinput:output"}
Switch InputRead {channel="exec:command:brickinput:run"}

When I flick the switch in the sitemap the following is returned in the logs:

2020-10-16 08:26:48.529 [ome.event.ItemCommandEvent] - Item ‘InputRead’ received command ON

2020-10-16 08:26:48.542 [nt.ItemStatePredictedEvent] - InputRead predicted to become NULL

The InputStatus string remains blank in the sitemap.

This is a clue the channel is broken.
Things file loaded correctly? (see your openhab.log)
Exec binding installed?

Just had a look and confirmed that the binding is installed, when I save the exec.things file I get the following message in the logs with no errors:

2020-10-16 10:14:28.569 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'exec.things'

I assume this means the things file is being loaded correctly?

Could there potentially be illegal characters in the Thing channel? Such as [ ]

Yes indeed, as the channel is defined using [ ] those would certainly need escaping in the content. I would expect the things file parser to grizzle about that really.

Ok so I’ve managed to get it working…sort of.

The curl command only works in the executeCommandLine() function or inside a .sh script due to the closed brackets [ ] seemingly causing problems. The filtering you suggested @Wolfgang_S unfortunately doesn’t seem to work in a script or in the executeCommandLine() function.

I can now read the status of the switch, pull the 0 or 1 out of the return string and map this to a contact state using the following rule.

rule "Brick Input"

when Time cron "0 0/1 * * * ?" //run every minute

then

    var result = executeCommandLine("curl -q -o - http://192.168.0.40/getpara[189]=1",10000)

    logInfo("Input Test", result.toString)

    var String newstring = result.substringBetween("=",";")

    logInfo("String",newstring)

    InputString.postUpdate(newstring)

    if (newstring==" 0"){

        InputStatusContact.postUpdate(OPEN) 

    }

    else if (newstring==" 1"){

        InputStatusContact.postUpdate(CLOSED) 

    }

    logInfo("Contact Status",InputStatusContact.toString)

end

Is there a better way of doing this? This solution seems pretty clunky.

Does this work ( untested ) with the executeCommandLine ?

executeCommandLine = "curl@@-q@@-o@@-@@http://device-ip:80/getpara[189]=1|sed@@-e@@'s/.*=.//'|sed@@-e@@'s/;.*//'"

Returns the following error:

2020-10-17 19:56:01.208 [INFO ] [se.smarthome.model.script.Input Test] - % Total % Received % Xferd Average Speed Time Time Time Current

                             Dload  Upload   Total   Spent    Left  Speed

0 0 0 0 0 0 0 0 --:–:-- --:–:-- --:–:-- 0curl: (6) Could not resolve host: device-ip

I took the hostname device-ip from your initial post. Did you replace it with the hosts real IP/name in the curl command ?

ah yes that was silly of me! Ok the correct ip address is in there now and this is the output:

> 2020-10-17 21:17:30.232 [INFO ] [se.smarthome.model.script.Input Test] -   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
> 
>                                  Dload  Upload   Total   Spent    Left  Speed
> 
>   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
> 
> 100    47  100    47    0     0   1305      0 --:--:-- --:--:-- --:--:--  2136
> 
> <html><body>GETPARA[189] = 1;</body></html>

The substringBetween("=",";") seems to be working well though in pulling out the 0 or 1.

Are there any drawbacks of constantly running this rule and polling the device?

Well, it uses resource but no more than any other rule.
The worst that can happen is that the curl hangs up a rule thread for ten seconds, until timeout. Keep the executeCommandLine timeout as short as you dare.

You’ll probably get bored of the logging and comment that out :wink:

Before you set the completed rule aside, now is the time to bullet proof it … or at least have it tell you about surprises.

var result = executeCommandLine( ...
if (result === null) {
   logWarn("Input Test", "Failure to retrieve param 189")
   InputString.postUpdate(UNDEF)   // optional
} else {
   // the rest of your rule
}

and maybe

if (newstring==" 0"){
   // blah
} else if (newstring==" 1") {
   // bleh
} else {
   logWarn("Input Test", "Unexpected content param 189 " + newstring)
   InputString.postUpdate(UNDEF)   // optional
}
1 Like

That’s something the manufacturer of the device needs to answer :wink:
One item you could add to the curl command is the -s switch ( sorry I forgot that one ). Adding it will not show the download progress bar in the output.

Appreciate all the help, it seems to be working quite well so far!

@rossko57 I’ve reduced the timeout to 5000 and added your first suggestion to the rule, I was already getting sick of the logging so have commented out most of my loginfos haha

@Wolfgang_S I’ve actually just emailed the manufacturer so fingers crossed I’m not slowly killing the device :sweat_smile:

Here’s the finished rule:

rule "Brick Input"
when Time cron "0/30 * * * * ?" //run every 30 seconds
then
    var result = executeCommandLine("curl -s -q -o - http://192.168.0.40/getpara[189]=1",5000)
    if (result === null) {
        logWarn("BrickElectric Relay", "Failure to retrieve param 189")
    } else {
    var String newstring = result.substringBetween("=",";")
    logInfo("Brick String",newstring)
    InputString.postUpdate(newstring)
    if (newstring==" 0"){
        InputStatusContact.postUpdate(OPEN) 
    }
    else if (newstring==" 1"){
        InputStatusContact.postUpdate(CLOSED) 
    }
    }
end

Just one further update in case anyone stumbles across this and wants to use their products, the supplier got back to me saying there’s no issue with continuously polling the device. Here’s the email/response.

Hi,

I’m using the BEM 107 with openHAB (open-source home automation software).
In order to read the input, I’ve written a rule that issues a curl command every 30 seconds.
Are there any drawbacks in continuously issuing commands to the device in this way?

Their response:

Dear Jack,

There is no issue for this, actually it’s designed for this kind of application.

If you have any further questions, feel free to contact us.

Best Regards,
Andreas
Technical support team

Manufacturers website:
https://www.brickelectric.com/