[OH3] HowTo perform sendHttpGetRequest and sendHttpPutRequest in order to read/write through REST API

you have to enable basic auth first since it’s disabled by default

Edit:
Also I recommend creating a new user for every device.

1 Like

Ups!
Switched it on and tried again. Now it’s a

Fatal transport error: java.util.concurrent.TimeoutException: Total timeout 5000 ms elapsed

BTW : A new used for each device? I’m trying to get data to and from the REST API, so it is the device which runs openHAB which tries to get something from itself.

It is a service on the device ( & executed by a user) trying to get information from the openHAB service, outside of openHAB. The fact it is running on the same device does not matter to OH.

Using the commands like:

val systemstatus_thing =sendHttpGetRequest("http://opus:******@127.0.0.1:8080/rest/things/systeminfo%3Acomputer%3Aopuspi", 10000)
        val returnvalue = sendHttpPutRequest("http://opus:*****@127.0.0.1:8080/rest/things/systeminfo%3Acomputer%3Aopuspi","application/json",systemstatus_thing.replaceAll('"pid":([0-9]+)','"pid":' + openHAB_PID), 15000)

Can’t say if it would work with smaller timeouts. My testing-system got a bit unresponsive yesterday, that caused the problems. Now it is working, THANKS!

1 Like

Hello,

i have a related problem with an thing i want to disable / enable per rule.

The url i got from API explorer, basic auth is enabled and added to url

var String url = "restuser:restpass@https://openhab.srv.local/rest/things/onkyo%3ATX-NR636%3A18b0a1bd-65a1-bdb9-70a8-bd0965b96cd5/enable"
var put = sendHttpPutRequest(url, "application/json", 'enabled', 5000)

failed: Invalid URI host: null (authority: null)

this is the original thing id
onkyo:TX-NR636:18b0a1bd-65a1-bdb9-70a8-bd0965b96cd5

what i am missing here?

It’s like this:

var String url =" https://restuser:restpass@openhab.srv.local/rest/things/onkyo%3ATX-NR636%3A18b0a1bd-65a1-bdb9-70a8-bd0965b96cd5/enable"

Oh no :disappointed:, i should get more sleep, thank you.

Hi All,

how to use sendHttpGetRequest with a API token instead of Basic Auth?

I’m struggling from a while, trying almost all possible options … unlucky.

Any clue?

thanks
Andrea

Did you have a look to this thread [JavaScript] Syntax to insert API Token into SendHTTPGetRequest - #4 by alexxio

1 Like

I’ve seen that topic, but not sure how to change my rule

sendHttpPutRequest("http://user:password@127.0.0.1:8080/rest/things/openuv:uvreport:local:home/enable", "application/json", 'true')

Questions:

  1. the user created via Karaf is common user (not admin) … is the normal user able to send a Put Request? to me, it sounds like a “write” permission, and it should be an admin characteristic

  2. how to modify the user:pass structure with the API token?

btw if I need an admin user to send put requests, also the API token should be generated by an admin account right?

thanks
Andrea

found and tested the solution :slight_smile:

val headers = newHashMap("Authorization" -> "Bearer <put_your_token_here>", "WWW-Authenticate"-> "Basic")
sendHttpPutRequest("http://127.0.0.1:8080/rest/things/openuv:uvreport:local/enable", "application/json", 'false', headers, 1000)

thanks @Wolfgang_S for the input :slight_smile:

Andrea

5 Likes

I searched for how to send requests to OH3 with API tokens in Jython/Python and found this thread, but no immediate answer on how to do it in Python.

It’s quite easy to deduct it from how @ariela ist doing it in JS.
Nevertheless here is an example, as it might be helpful for someone else:

from core.actions import HTTP

api_token = "oh.name.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
auth_headers = {
    "Authorization": "Bearer {}".format(api_token),
    "WWW-Authenticate": "Basic",
}

HTTP.sendHttpPutRequest(
    "http://my-oh.local/rest/things/max:bridge:IEQ0547745/config", # your OH domain & path in the REST-API
    "application/json",
    "{action-cubeReboot:1234}",
    auth_headers, # here is where the auth-info is handed over to the HTTP action
    9000) # a timeout value
2 Likes

Does anyone know how this works with a hosted private OH3 cloud service with Alexa, the Alexa API makes a request but gets the HTTP error

 - onComplete: 2030
21:22:55.104 [DEBUG] [.io.openhabcloud.internal.CloudClient] - Jetty request 2030 failed: HTTP protocol violation: Authentication challenge without WWW-Authenticate header
21:22:55.104 [DEBUG] [.io.openhabcloud.internal.CloudClient] - Response Failure: HTTP protocol violation: Authentication challenge without WWW-Authenticate header

Basic Auth is turned on, but the Alexa skill integrates using OAUTH, so I figured i just needed a matching username on OH3 (same as the OH3 Cloud or the Alexa skill) - still no joy

I’m having trouble getting this to work with OH 3.2. I have the same code above but it’s NOT re-enabling a few THINGs that are disabled. Am I missing something?

val 	headers = newHashMap("Authorization" -> "Bearer oh.RESTAPI.PrhuIqPGkhU8Sxy8DbXcQgMtYezcUR7yNWwmpnpehS25MV7akeDcFzr6Qf11mPsKmTFBDi49hZ9uf9kXXXX", "WWW-Authenticate"-> "Basic")

sendHttpPutRequest("http://127.0.0.1:8080/rest/things/sonos:CONNECTAMP:RINCON_XXXXFDE1B88801400/enable", "application/json", 'true', headers, 1000)				// Enable SonosThingOnWall
  Thread::sleep(500)  
sendHttpPutRequest("http://127.0.0.1:8080/rest/things/sonos:CONNECTAMP:RINCON_XXXXFDEA6E1E01400/enable", "application/json", 'true', headers, 1000)				// Enable SonosThingGround	

Best, Jay

1 Like

what does the log say?

Here’s my logger for HTTP but I’m not seeing any errors. Am I missing something OR should I just put INFO status on a specific logger?

		<!-- HTTP -->		
		
		<Logger additivity="false" level="WARN" name="org.openhab.core.model.script.actions.HTTP">		
			<AppenderRef ref="HTTP"/>
		</Logger>			
	
		<Logger additivity="false" level="WARN" name="java.util.concurrent.ExecutionException">		
			<AppenderRef ref="HTTP"/>
		</Logger>		
		
		<Logger additivity="false" level="WARN" name="java.util.concurrent.TimeoutException">		
			<AppenderRef ref="HTTP"/>
		</Logger>	

		<Logger additivity="false" level="WARN" name="org.openhab.core.io.http">		
			<AppenderRef ref="HTTP"/>
		</Logger>	

		<Logger additivity="false" level="WARN" name="org.openhab.core.io.http.auth">		
			<AppenderRef ref="HTTP"/>
		</Logger>	

		<Logger additivity="false" level="WARN" name="org.apache.cxf.cxf-rt-transports-http">		
			<AppenderRef ref="HTTP"/>
		</Logger>		
		
		<Logger additivity="false" level="WARN" name="java.io.EOFException">		
			<AppenderRef ref="HTTP"/>
		</Logger>		
		
		<Logger additivity="false" level="WARN" name="org.openhab.binding.http">		
			<AppenderRef ref="HTTP"/>
		</Logger>

Best, Jay

sorry, I meant openhab events and openhab log

Nothing is shown for the sendHttpPutRequest’s in those logs.

Best, Jay

Can’t say if it makes a difference, however I’m creating my headers like:

var headers = [];
headers["Authorization"] = "Bearer oh.RESTCall.xyz123";
headers["WWW-Authenticate"] =  "Basic";

I do see no difference beside that. Using this sendHttpPutRequest you should get a returned value, log the contents of that one and post it here.

Finally found the issue, it was the MIME type.

Examples on the forum showed “application/json” which worked for OH2.x.

I switched it to → “text/plain”

Now it’s working perfectly!

Best, Jay

2 Likes