Hello,
I have scratched a simple binding for listening to incoming http requests.
What problem does it solve?
There are quite a few devices which are able to perform http requests on a given webhook (like Synology Surveillance Station in rules or some intercoms/ip doorphones like akuvox). Those httprequest cannot be simple utilized in openhab straight away. You could translate it at nginx level from the simple form of http get/post those devices can perform to openhab REST APIs or create a simple server which passes mentioned request to mqtt.
However those methods requires third party software to be involved. With this binding you can expose an url to be called by your devices and handle it in the openhab directly.
How this binding works?
When you create a thing you can configure it with only one parameter - JSON like string. Example
{
"channels": [
{
"key":"action",
"kind": "STATE",
"state": "req.parameters.action[0]"
},{
"key": "card",
"kind": "STATE",
"state": "req.parameters.card[0]"
}
]
}
In this parameter you define channels that will be exposed by the thing. key means the id of the channel. Kind is either STATE or TRIGGER (both are implemented) type of a channel. state is an expression based on apache jexl expression language.
As for now in the expression there is only a simple object req which has only two properties:
- parameters - under this property all query parameters and form-encoded post parameters are placed. So you can define in your http requests query params and extract it to channels.
2 body - unders this property the body of the POST requests is stored. body has two properties text and json. With this you can post a json file to you openhab and use an expression to extract an value from the json and place it into channel. See further examples.
Context for expressions can be enriched with more than one req object in future.
Examples
Handling an card input to my doorphone.
I have configured my doorphone to call following url when someone use the mifare tag on it.
http://oh/httplistener/intercomhook?action=cardaction&card=$card_sn
Then I have configured a thing with following json snippet
{
"channels": [
{
"key":"action",
"kind": "STATE",
"state": "req.parameters.action[0]"
},{
"key": "card",
"kind": "STATE",
"state": "req.parameters.card[0]"
}
]
}
Result:
Extracting posted JSON
Following call
curl -H "Content-Type: application/json" -X POST -d '{"username":"test-username"}' http://localhost:8080/httplistener/af71afd830/
With configured thing:
{
"channels": [
{
"key":"testowy",
"kind": "STATE",
"state": "req.parameters.ekologia[0]"
},{
"key": "testjson",
"kind": "STATE",
"state": "req.body.json.username"
}
]
And result:
That’s all. Any suggestions are welcomed. I do not call it early alpha or something - I wouldn’t recommend to use it on production (though I have deployed in on my openhab). However maybe some of you would be interested and have some hints how evolve it to a useful binding.
Binaries and a source code is here.
Regards,
Piotr