Requests always fail

I recently upgraded to OH3 and am porting everything I can to the more modern methodology. One of these things is my garage door opener, which has a very simple HTTP protocol:

GET http://address/?status returns “Open” or “Closed” as the body.
GET http://address/?open opens the door.
GET http://address/?close closes the door.

There is no authentication.

In OH2 I bound the controls like this:

rule "Forward garage door commands"
when
Item LF_Garage_Door received command
then
    switch(receivedCommand) {
        case UP : 
        {
            logInfo("Garage door", "Requesting open")
            sendHttpGetRequest("http://address?open")
        }
        case DOWN : 
        {
            logInfo("Garage door", "Requesting close")
            sendHttpGetRequest("http://address?close")
        }
    }
end

The receiver was set up in the item definition, calling a JS transformation to translate the response into valid values for the item type.

I’m trying to refactor this into an HTTP Binding thing with read and write channels. The new definition looks like this:

UID: http:url:GarageDoor
label: Garage door
thingTypeUID: http:url
configuration:
  ignoreSSLErrors: false
  baseURL: http://10.183.50.80/?
  refresh: 5
  commandMethod: GET
  contentType: text/plain
  timeout: 1000
  bufferSize: 2048
location: Garage
channels:
  - id: OpenClose
    channelTypeUID: http:rollershutter
    label: Open close
    description: ""
    configuration:
      mode: WRITEONLY
      downValue: close
      upValue: open
  - id: ReadState
    channelTypeUID: http:contact
    label: Read state
    description: ""
    configuration:
      onValue: Open
      mode: READONLY
      offValue: Closed
      openValue: Open
      stateExtension: status
      closedValue: Closed

The documentation is not very explicit about how the GET string is built and how the values are incorporated, so this was my best guess.

After some experimentation, I left with two problems:

  1. According to the log, every request ever sent results in:
    [WARN ] [tp.internal.http.HttpResponseListener] - Requesting 'http://address/?status' (method='GET', content='null') failed: Total timeout 1000 ms elapsed
  2. When I a message is sent to the writeable channel, I see messages saying that that status of the channel is changed, but it never seems to send anything by HTTP. I don’t see any INFO or WARN messages in the log. I also looked in the DEBUG version, but it’s obviously quite hard to find a needle in that haystack.

Any troubleshooting or usage information would be welcome. Of course, typing any of these strings into my desktop browser works perfectly!

Increase the timeout. Maybe 1s is not enough. URL looks good.

Yeah I started with the default of 5000ms, but behaviour is the same. My desktop browser connects and receives the response within 165ms. I presume the time to connection is a fraction of that.

I forgot to mention before that each time the thing inititialises, I get this in the log:
No authentication configured for thing 'http:url:GarageDoor'
That is deliberate since no authentication is needed. There is no option for “none” in authentication type, so I presume it infers that by the fact that no username or password are configured.

The auth message is not your problem. Are you sure the browser is using http and not https? Did you copy the request from the log to the browser? Are you sure the request is not blocked by some firewall rule?

Issue 1 appears to have fixed itself. I worked around a separate problem where rules defined through the UI caused a memory leak. My best guess is that there was not enough memory available for the request to execute until I worked around this.

Once issue 1 was fixed I was able to fix issue 2 with a bit of trial and error. For the record, this is what I ended up with:

UID: http:url:GarageDoor
label: Garage door
thingTypeUID: http:url
configuration:
  authMode: BASIC
  ignoreSSLErrors: false
  baseURL: http://address/?
  refresh: 5
  commandMethod: GET
  contentType: text/plain
  timeout: 500
  bufferSize: 2048
location: Garage
channels:
  - id: OpenClose
    channelTypeUID: http:rollershutter
    label: Open close
    description: ""
    configuration:
      mode: WRITEONLY
      commandExtension: "%2$s"
      downValue: close
      upValue: open
  - id: ReadState
    channelTypeUID: http:contact
    label: Read state
    description: ""
    configuration:
      onValue: Open
      mode: READONLY
      offValue: Closed
      openValue: OPEN
      stateExtension: status
      closedValue: CLOSED
      stateTransformation: JS:ParseGarageStatus.js

I needed the transformations because the response strings included carriage returns. Maybe there’s a simpler way to handle this, but I didn’t find it.