Thanks, that has at least kept the designer happy. By experimentation I discovered that the server would accept
{“acState”:{“on”:true,“mode”:“heat”,“fanLevel”:“auto”,“targetTemperature”:24}} so I set that into the string.
However now I get "14:24:40.900 [ERROR] [g.openhab.io.net.http.HttpUtil:233 ] - Fatal transport error: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Yup, there’s a bunch of cases that can cause this including:
Bad/expired site cert
Self-signed cert, with no trust relationship and/or;
No mechanism to validate the cert’s CA
At this point you’ve entered into the realm of “There are cases where the server is more rigid on the caller…”, and the options for disabling cert validation (etc) are wider when using CURL.
If you run the Google search criteria above it’ll give you a great set of pointers for next steps.
Oh dear… further into the rabbit hole we go
Is there some obscure hidden away procedure for adding / editing / general playing with certificates that has to be done before openhab will talk SSL? I seem to remember I had a similar problem somewhere else in the deep and distant past taking to the IFTTT maker channel and got around it by dropping the SSL which I can’t do with this one.
I’ve routinely scratched my head with (browser) SSL issues only to find that it’s happening because my clock is out of whack… And the list of those gotchas is long
For SSL/TLS, the connection establishment sequence validates the [HTTPS Server] Certificate in a number of ways. If any of these fail, then you’ll get the type of error your seeing.
A few quick checks:
ensure the clock on your openHAB device is current.
check the Root CA (the issuer Organization) and validate that it’s in the list of Root CA’s Java is configured for.
This latter list can be extracted with keytool using something akin to:
If these things sounds foreign, then you’re not alone, it’s a complex subject
This is why some people play very loose security-wise, and end up disabling certificate validation. In tools like curl this is a simple command line option (eg. --insecure).
You may also find that running curl, at the command line, will give you more details on the Certificate issue (although it validates against a different list of CA’s, not the Java list referenced above)
As an example, here’s what curl says about the certificate shipped with my Router:
root@openhab:~$ curl https://192.xxx.xxx.xxx
curl: (60) SSL certificate problem: self signed certificate
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
It sounds like avoiding all the SSL complication is the way to go, if this goes to the wrong place my AC doesn’t turn on, hardly the end of the world!
I’ll take a look tomorrow, apologies in advance for any dumb questions, I know absolutely nothing about Curl which is why so far I’ve used IFTTT to do this. Unfortunately a couple of complimentary bugs mean I need to go direct to get the reliability I need.
keytool -list -v -keystore /usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts
keytool error: java.lang.Exception: Keystore file does not exist: /usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts
java.lang.Exception: Keystore file does not exist: /usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts
at sun.security.tools.keytool.Main.doCommands(Main.java:742)
at sun.security.tools.keytool.Main.run(Main.java:340)
at sun.security.tools.keytool.Main.main(Main.java:333)
I’ve given up on getting SSL to work, the debug flag did nothing that I could find even after turning on the debug logging so I’m now trying to get Curl to work in the hope of translating this into a commandline.
Needless to say it doesn’t work so I guess a fresh set of obscure hoops is in order. Can you give me a clue as to what options I need to add?
From the google chrome Advanced Web Client I put in the URL: https://myurl?apiKey=myapikey
click the post dot
put in payload {“acState”:{“on”:true,“mode”:“heat”,“fanLevel”:“auto”,“targetTemperature”:20}}
and leave the content-type set as the default application/x-www-form-urlencoded
After clicking send this gives me back a status of 200 OK and turns the AC On which is what I’m after.
After a lucky google strike it appears I may have answered my own question. This seems to work
curl -H “Content-Type: application/x-www-form-urlencoded” -X POST -d ‘{“acState”:{“on”:true,“mode”:“heat”,“fanLevel”:“auto”,“targetTemperature”:21}}’ https://myURL?apiKey=myAPI
Which in a rule becomes:
executeCommandLine('curl@@-H@@Content-Type: application/x-www-form-urlencoded@@-X@@POST@@-d@@{“acState”:{“on”:false,“mode”:“heat”,“fanLevel”:“auto”,“targetTemperature”:22}}@@https://myURL’@apiKey=myAPI)
Now I need to work out how I can link this to an Switch item using whether I got back a status of 200 or not as its status.
This sends a JSON string. MYPODID is replaced with the correct POD ID and MYAPIKEY is replaced with the correct API Key. The command above I think does send the “”
From memory the whole command line needs to be enclosed in (’ ') and @@ is used in place of a space on the command line so to run in a command prompt the command “Ping MyHost” would be written as
executeCommandline('Ping@@MyHost')
assuming it behaves the same in Windows as it does in Linux.
Looking further in my rules, to move a file in Linux is written as
which is slightly different as it doesn’t have “@@” in place of a command line space and there are no brackets around it all, so perhaps both are interchangable in a rule file. This example is a simple command line with no feedback from the command.
In your case it may be simpler to just call the windows batch file with a timelimit on the end to ensure nothing is left hanging if something unexpected happens.
I ended up using BAT file and send the text as paramater INside I have curl command. Also one critical thing in each BAT including the one for starting OH is to have
chcp 65001
at the start. This force unicode and I can send Cyrilic now.
Your curl example strips the " but maybe the server does not care, I tested lot of combination using a small http server for debugging the requests and it was not working.
I think you cannot add the HTTP header when using item configuration/HTTP binding
(anyone to prove me wrong is welcome, it’s long ago I tried so things may well have changed).
Here’s an example to do it with a rule:
rule "Landroid command"
when
Item Landroid_Command received command
then
val String URL = "http://admin:0000@landroid/jsondata.cgi"
var String jsondata = 'data=[[\"settaggi\",' + Landroid_Command.state.toString + ',1]]'
logInfo("rules", "Sending Command " + Landroid_Command.state + " to Landroid.")
sendHttpPostRequest(URL, "application/x-www-form-urlencoded", jsondata)
end