Receiving `Content-Type=application/json` payload on REST API

Hi there,

I am trying to integrate my new Nuki smart lock with openHAB and they have just released a beta version of their firmware that allows you to specify a callback URL which is called whenever the lock changes state.

The payload of the callback is JSON and the request is made with a header containing Content-Type=application/json. I have a virtual item setup in openHAB for receiving this payload and testing with Postman shows my item and rules (for decoding the JSON payload) is working great…

…as long as the request is made with Content-Type=text/plain.

The requests coming from the lock itself are failing, due to the Content-Type. Just wondering if there is a trick for getting the openHAB REST API to handle these types of requests?

Or am I going to need to code up a little proxy server to receive the lock callback requests and transpose to the appropriate format acceptable by the openHAB REST API?

Cheers,
Ben

1 Like

I use a script to call my wireless sensor tag data and have to specify the content type as json. I haven’t had any trouble with this in OH2. Maybe something in what i’ve done will help.

Script:

curl -s -X POST -H "Content-Type: application/json; charset=utf-8" -H "Authorization: bearer xxxx-xxxx-xxxx-xxxx-xxxx" -d "" "http://mytaglist.com/ethClient.asmx/GetTagList"

Rule transform:

rule WirelessSensorRule
when
    Item wirelesstagPayload received update
then
    logInfo("Sensor", "Wireless Sensor Payload arrived...")
     val String payload = (wirelesstagPayload.state as StringType).toString
    var i = -1
    while ((i=i+1) < 11){
        //extract the values we care about...
        val String xSlaveId = transform("JSONPATH", "$.d["+i+"].slaveId", payload)
        val String xTemperature = transform("JSONPATH", "$.d["+i+"].temperature", payload)
        val String xHumidity = transform("JSONPATH", "$.d["+i+"].cap", payload)
        val String xBatteryRemaining = transform("JSONPATH", "$.d["+i+"].batteryRemaining", payload)
        //logInfo("Sensor", "Wireless Tag Payload (name: " + xName + ", slaveId: " + xSlaveId + ", temp: " + xTemperature + ", cap: " + xHumidity + ", batt: "+ xBatteryRemaining + ")")

        switch xSlaveId {
            case "0":{
                postUpdate(sensor_ShedTemp,new DecimalType(xTemperature)*1)
                  postUpdate(sensor_ShedHumidity,new DecimalType(xHumidity)*1)
                  postUpdate(sensor_ShedBattery,new DecimalType(xBatteryRemaining)*100)
              }
....
        }
    }
end

Hi Paul,

Thanks for that. How is wirelesstagPayload being updated via the REST API?

Regards,
Ben

Sorry, in an item via:

String    wirelesstagPayload    { exec="<[/etc/openhab2/scripts/getTagList.sh:900000:REGEX((.*?))]" }

Ah ok - so you are not actually using the REST API. I can’t poll the lock (as it kills the battery) so have to rely on these callback urls which is fine, just the REST API seems to bork when the Content-Type is not text/plain.

Yeah, missed the REST part of the question.

Thanks for the response tho! I am sure there is a simple flag/setting I am missing here…

Have you tried Content-Type=application/javascript rather than json?

No - the issue is the Nuki lock is generating the request/payload (and I have no control over that). So I have configured the locks callback URL to be http://openhab:8080/rest/items/NukiCallback and it is then sending a POST request to that URL with application/json in the header.

I ended up knocking together a quick and dirty proxy using python/bottle which the lock publishes the JSON updates to, and it decodes and forwards the update to openHAB via the REST API (in the format it can accept).

Do you mind sharing the proxy setup you did? I have the same problem…
Or did the Nuki folks change something in the mean time?

Bye, Frido.

Sure - https://github.com/sumnerboy12/nukiproxy

Thank you very much Ben, will try it out!

Bye, Frido.