Help needed: HTTP binding, JSON and basic authentification for CCU825 controller

Hi there!

I have got a PLC CCU825 running home automation. Working well. This controller has it web portal and API at ccu.sh. Instruction says that to access controller state the following request may be done:
h ttps://ccu.sh:8080/data.cgx?cmd={“Command”:“GetStateAndEvents”}
Also it is written that “Basic HTTP-authentification is used”. The server will return JSON answer.

Currenly I cannot get proper request, web server logs says that I am providing “illegal uri”.

Please help me to configure OpenHAB: HTTP binding, items and example of sitemap.

Example of the JSON:

{
" I n p u t s " : [
{" Ac ti ve ": 1 , " Vol tage “: 0 } ,
{” Ac ti ve ": 0 , " Vol tage “: 2 0 } ,
{” Ac ti ve ": 1 , " Vol tage “: 3 0 } ,
{” Ac ti ve ": 0 , " Vol tage “: 4 0 } ,
{” Ac ti ve ": 1 , " Vol tage “: 5 0 } ,
{” Ac ti ve ": 1 , " Vol tage “: 6 0 } ,
{” Ac ti ve “: 0 , " Vol tage “: 7 0 } ,
{” Ac ti ve “: 1 , " Vol tage “:4095}
] ,
“Outputs " : [ 1 , 0 , 1 , 1 , 1 , 0 , 1 ] ,
" P a r t i t i o n s " : [ " Arm” ,” Disarm " ,” Disarm " ,” Disarm " ] ,
"Case " : 1 ,
"Power " : 1 2 . 3 ,
" Ba t te r y “:{” S ta t e “: “OK” ,” Charge ": 2 0 } ,
“Temp”: 2 5 ,
" Balance “: " NotValid " ,
" Events " : [
{” ID ": 2 4 , " Type ": " I n p u tPa s si v e " ,"Number “: 1 } ,
{” ID ": 2 5 , " Type ": " I n p u tA c ti v e " ,"Number “: 1 6 , " P a r t i t i o n s " : [ 1 , 2 , 3 , 4 ] } ,
{” ID ": 2 6 , " Type ": " PowerRecovery “} ,
{” ID ": 2 7 , " Type ": " PowerFault “} ,
{” ID ": 2 8 , " Type ": " BatteryLow1 “} ,
{” ID ": 2 9 , " Type ": " BatteryLow2 “} ,
{” ID ": 3 0 , " Type ": " BalanceLow “} ,
{” ID ": 3 1 , " Type “: “TempLow”} ,
{” ID “: 3 2 , " Type “: " TempNormal”} ,
{” ID “: 3 3 , " Type “: " TempHigh”} ,
{” ID ": 3 4 , " Type ": " CaseOpen “} ,
{” ID ": 3 5 , " Type ": " Test “} ,
{” ID ": 3 6 , " Type ": " I n f o “} ,
{” ID ": 3 7 , " Type ": " P r o f i l e A p p l i e d " ,"Number “: 1 } ,
{” ID ": 3 8 , " Type ": " DeviceOn “} ,
{” ID ": 3 9 , " Type ": " D e vi c eR e s ta r t “} ,
{” ID ": 4 0 , " Type ": “Arm” ,
" Sou rce “:{” Type ": " Button “}} ,
{” ID ": 4 1 , " Type “: “Arm” ,” P a r t i t i o n " : 1 ,
" Sou rce “:{” Type ": " Inpu t “}} ,
{” ID “: 4 2 , " Type “: “Arm” ,” P a r t i t i o n " : 2 ,
" Sou rce “:{” Type “: " S c h e d ul e r “}} ,
{” ID “: 4 3 , " Type “: “Arm” ,” P a r t i t i o n " : 3 ,
" Sou rce “:{” Type “: “Modbus”}} ,
{” ID “: 4 4 , " Type “: “Arm” ,” P a r t i t i o n " : 4 ,
" Sou rce “:{” Type “: " TouchMemory” ,
“Key”:“0001020304050607” ,“KeyName”: " Vasya “}} ,
{” ID “: 4 5 , " Type “: “Arm” ,” P a r t i t i o n " : 1 ,
" Sou rce “:{” Type “: “DTMF” ,” Phone “:”+71231234567”}} ,
{” ID “: 4 6 , " Type “: " Disarm " ,” P a r t i t i o n " : 2 ,
" Sou rce “:{” Type “: “SMS” ,” Phone “:”+71231234567”}} ,
{” ID “: 4 7 , " Type “: " Disarm " ,” P a r t i t i o n " : 3 ,
" Sou rce “:{” Type “: “CSD” ,” Phone “:”+71231234567”}} ,
{” ID “: 4 8 , " Type “: " Disarm " ,” P a r t i t i o n " : 4 ,
" Sou rce “:{” Type “: " Call " ,” Phone “:”+71231234567”}} ,
{” ID ": 4 9 , " Type “: “Arm” ,” P a r t i t i o n " : 1 ,
" Sou rce “:{” Type “: “GTNet”}} ,
{” ID ": 5 0 , " Type “: " Disarm " ,” P a r t i t i o n " : 2 ,
" Sou rce “:{” Type “: " uGuardNet " ,” UserName “: “Name”}} ,
{” ID ": 5 1 , " Type “: " Disarm " ,” P a r t i t i o n " : 3 ,
" Sou rce “:{” Type “: " S h e l l " ,” UserName “: “Name”}} ,
{” ID ": 5 2 , " Type ": " FirmwareUpgrade “} ,
{” ID ": 5 3 , " Type “: " ExtRuntimeError " ,” ErrorCode ":1}
]
}

If this is copy and paste then the space in https needs to be removed.

You may need to URL encode the request. https://www.w3schools.com/tags/ref_urlencode.asp

I intentionally inserted this space to avoid direct URL placing. In the code there is no space or other non-ASCII sinmbols.

In the http.cfg I placed line:
CCU825_State.url=https://ccu.sh:8080/data.cgx?cmd={“Command”:“GetStateAndEvents”}
CCU825_State.updateInterval=60000

in the default.items:
String CCU825_Response “CCU825_Response” { http=CCU825_State{Authorization=Basic bG9naW46cGFzc3dvcmQ=":60000:JSONPATH($.Balance)]" }

base64 is fake here…

Is it correct?!

I am getting the following in logs:

23:21:43.805 [INFO ] [del.core.internal.ModelRepositoryImpl] - Loading model ‘default.items’
23:21:43.809 [INFO ] [ab.core.service.AbstractActiveService] - HTTP Refresh Service has been started
23:30:13.182 [ERROR] [org.openhab.io.net.http.HttpUtil ] - Fatal transport error: java.net.ConnectException: Connection timed out (Connection timed out)
23:30:13.183 [ERROR] [hab.binding.http.internal.HttpBinding] - No response received from ‘CCU825_State’

Can you ping the host name ccu.sh? Try using the IP address instead. The error means it can’t find the computer or the computer hosting this web service didn’t respond to the connection request.

Hostname CCU825_State doesn’t sound right.

You need:

{ http="<[https://ccu.sh:8080/data.cgx?cmd=..." }

And you need to properly encode the URL, as Rich already stated.

Could you advise what type of coding is required?

ccu.sh reply to ping…

In the protocol discription it is written that: GET or POST are used for data exchange. Requesting URL is data.cgx. The only one parameter cmd presents, containing text commands in JSON format.

How to make proper url encoding, http binding and item for request execution and following data receiving?

Look at the link I provided above and replace any character in your URL that appears in the table with the encoded version of that character. For example, replace all the { with %7B.

It doesn’t help. 8(

Dear all,

I tried to bind the following:
CCU825_State.url=https://ccu.sh:8080/data.cgx?cmd=%7b“Command”:“GetStateAndEvents”%7d{BAuthorization=Basic bG9naW46cGFzcw=}

In logs:

18:24:19.939 [ERROR] [ab.core.service.AbstractActiveService] - Error while executing background thread HTTP Refresh Service
java.lang.IllegalArgumentException: Invalid uri 'https://ccu.sh:8080/data.cgx?cmd=%7b“Command”:“GetStateAndEvents”%7d': Invalid query
        at org.apache.commons.httpclient.HttpMethodBase.<init>(HttpMethodBase.java:222) ~[195:org.apache.servicemix.bundles.commons-httpclient:3.1.0.7]
        at org.apache.commons.httpclient.methods.GetMethod.<init>(GetMethod.java:89) ~[195:org.apache.servicemix.bundles.commons-httpclient:3.1.0.7]
        at org.openhab.io.net.http.HttpUtil.createHttpMethod(HttpUtil.java:314) ~[196:org.openhab.core.compat1x:2.4.0]
        at org.openhab.io.net.http.HttpUtil.executeUrl(HttpUtil.java:167) ~[196:org.openhab.core.compat1x:2.4.0]
        at org.openhab.io.net.http.HttpUtil.executeUrl(HttpUtil.java:130) ~[196:org.openhab.core.compat1x:2.4.0]
        at org.openhab.binding.http.internal.HttpBinding.getCacheData(HttpBinding.java:423) ~[?:?]
        at org.openhab.binding.http.internal.HttpBinding.execute(HttpBinding.java:169) ~[?:?]
        at org.openhab.core.binding.AbstractActiveBinding$BindingActiveService.execute(AbstractActiveBinding.java:144) ~[196:org.openhab.core.compat1x:2.4.0]
        at org.openhab.core.service.AbstractActiveService$RefreshThread.run(AbstractActiveService.java:166) [196:org.openhab.core.compat1x:2.4.0]

You’re still using illegal characters in your URL.

This provides some help, including links to the RFCs (formal specifications).

Dear all,

I reworked my code. Now I got:
In Items:
Number CCUPowerVoltage <energy> String CCU_JSON
In Rules
rule "CCU825_StateRead" when Time cron "0 0/5 * 1/1 * ? *" then CCU825_JSON=sendHttpPutRequest("https://ccu.sh:443/data.cgx?cmd=%7bBAuthorization=Basic%20BASE64LOGINPASS%7d","text/plain","%7B%22Command%22%3A%20%22GetStateAndEvents%22%7D") end

In log I am getting the following every 5 mins:

12:05:00.353 [ERROR] [untime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'CCU825_StateRead': An error occurred during the script execution: Couldn't invoke 'assignValueTo' for feature JvmVoid: (eProxyURI: default.rules#|::0.2.0.2.0.0::0::/1)

It does not change if I use 8080 or 443 ports. I also changed “text/plain” with “application/json”- no difference. What does this error message means? Does the sendHttpPutRequest() works?

How is CCU825_JSON declared? Is it a global variable? It needs to be declared as var String CCU825_JSON.

It is just mentioned in the items file as I wrote. I added “var” to the rules file before “CCU825_JSON” and currently log has changed to:

17:15:00.442 [ERROR] [untime.internal.engine.ExecuteRuleJob] - Error during the execution of rule "CCU825_StateRead": json string can not be null or empty

This probably means that request returns nothing. Correct? Is it possible to make sure that request was accepted by server ccu.sh?

But you didn’t mention it in your .items file. You have CCUPowerVoltage and CCU_JSON in your .items file, not CCU825_JSON.

The error is what is being returned from ccu.sh. Looking at your call in the Rule shows you need to escape the double quotes in the content you pass in the PUT.

"{\“Command\”%3A%20\"GetStateAndEvents\"}”

NOTE, please follow How to use code fences

Now it looks like:

rule "CCU825_StateRead"
    when
	Time cron "0 0/5 * 1/1 * ? *"`
    then
	var CCU825_JSON=sendHttpPutRequest("https://ccu.sh:443/data.cgx?cmd=%7bBAuthorization=Basic%20Base64LoginAndPass=%7d","text/plain","%7B%5CCommand%5C%3A%5C%22GetStateAndEvents%5C%22%7D")
	CCUPowerVoltage=transform("JSONPATH", "$.Power", CCU825_JSON)
end

But in logs I got:

18:15:00.442 [ERROR] [untime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'CCU825_StateRead': json string can not be null or empty

Don’t use URL encoding on the contents. Use the string just like I have above.