Webhooks usage?


#1

Hi all,

Has anyone used webhooks successfully?

I currently poll kegbot for changes in volumes every 15 seconds and then play a message over alexa to “enjoy (beer name)”. Works great but would prefer to push it from kegbot to save traffic on the wifi.

Cheers,

Moad


#2

That sounds awesome!! I would love to get more details around the Alexa thing, did you develop a skill that actually does an Alexa notification?

As far as webhooks, that’s sort of what the Node server is doing (kind of) by monitoring the Redis pub/sub and then sending the live updates to the front-end via sockets. But you could definitely do something similar on-board where Node/Python whatever monitors that Redis feed and if it notices volume changes make a request outbound to trigger the message.

EDIT: Sorry I’m an idiot! As soon as I sent that message I remembered seeing a WebHooks item in the Admin page for Kegbot, so maybe something already built in! I have not messed with it but this Alexa thing sounds like a fun project to try to mess around with the Webhooks.


#3

I’m using openhab for home automation.

Curl scripts pull the tap volumes and names back into variables in openhab and when there is a change it sends the message to alexa via the binding.

It uses the openhab “binding” (add ons that transform data for various services) which connects to an alexa web page for control (I think the German page allows this). I also use it to start playing a song when I get home, I use my iPhone location with the iCloud binding to trigger “dad is almost home” over alexa etc etc

I’m sure you could hack it together without openhab, if you’d like more info on it I’d be happy to share

Yeah I tried pointing the webhook URL to a “webhook test” page but it didn’t connect. That was step one before I tried parsing the json data into the variables in
Openhab

Edit: bed time here in aus so will reply tomorrow if you do have questions! Cheers


#4

Will talk tomorrow, but I just took a second to test by setting up a mock endpoint and it did actually work when I started a drink (10:30am here so I started a fake one in the UI :wink:). JSON looks like the pattern you see if you hit the /api/events endpoint so there’s definitely some actions you can take on that!

Awesome find and I’ll have to play with OpenHab next!


#5

Awesome so it works!

I setup a test webhook server and just put the URL in to webhook but it didn’t receive anything. Is there a particular format for the URL?


#6

I’ve been working a lot recently with Azure Functions, so I spun up a new Azure Function project in Visual Studio and used Ngrok.io to create a forwarding route to the function running locally on my development machine in the VS debugger. I put the Ngrok HTTPS URL in the webhook configuration (followed by a new line) and then manually logged a new drink. It came through and I was able to capture the event(s) in the debugger.

Not doing anything special with it yet but going that route I was able to at least see that it was firing off a POST request for each Kegbot event.


#7

any chance you could point at this for me?

https://webhook.site/#!/71188c2e-1790-43c3-82c0-7753a5bddc14

Just to check if its the webhook test or my kegbot install?


#8

Hey I just tried it, and while the automatic detection did not work, when I refreshed the page (actually just clicked on the Webhook.site logo in the top-left) it successfully pulled up the request details from Kegbot.

I just entered the URL from the page (the one without the ‘#!’ in it) in the Webhook box on my Kegbot server and then just pressed ‘ENTER’ to move to the next line. I then just click Update Settings and started a new drink. Seemed to work fine, but again, the “automatic” feature of that site does not seem to be working as advertised.


#9

OK, I tried from my work kegbot install and it does fire off.

Not sure why it isn’t working at home and no idea how to troubleshoot :frowning:


#10

hmmm, it started working now. I wonder if my polling has messed it up.

Time to try and get this stuff parsed in to the variables I have in open hab now


#11

Awesome! This looks amazing and I got OpenHAB installed yesterday with the Echo Controls and the Amazon Account Thing. Still a little confused as to how to setup rules/actions and trigger them with an api call but when I get a little more free time I’ll dive into it!


#12

So webhooks are definitely the way to go so we don’t have to poll.

My current setup is to use the http binding, add a “thing” which has the command path to the script.

sh /home/openhabian/kegbot1.sh

The Output channel maps to the “volume remaining” item which is essentially the variable.

In the script is

#!bash
curl -sS http://192.168.1.22/api/taps/?api_key=xxxxxxx | \jq ‘.objects[0].current_keg.volume_ml_remain’

so the script is called by the http binding (it essentially is just used to poll stuff I think), the script hits the krgbot API and pulls back the volume remaining.

Similarly I pull back the keg name using a separate script.

#!bash
curl -sS http://192.168.1.22/api/taps/?api_key=xxxxxxx | \jq ‘.objects[0].current_keg.type.name’

I have the two scripts for each tap.

Now how we get openhab to receive the webhook I am unsure

Items are

//Takes the output from the “thing” - the thing executes the script bash file that runs the curl command with the jq filter

String tap1_vol_remaining {channel=“exec:command:kegbot_poll1:output”}

String tap2_vol_remaining {channel=“exec:command:kegbot_poll2:output”}

String tap3_vol_remaining {channel=“exec:command:kegbot_poll3:output”}

//String tap4_vol_remaining {channel=“exec:command:kegbot_poll4:output”}

//String tap5_vol_remaining {channel=“exec:command:kegbot_poll5:output”}

//String tap6_vol_remaining {channel=“exec:command:kegbot_poll6:output”}

Group gAllTapRemain

Group gAllTapName

//will be converted from string above to a number

Number tap1_vol_remaining_num “Tap1 [%d]” (gAllTapRemain)

Number tap2_vol_remaining_num “Tap2 [%d]” (gAllTapRemain)

Number tap3_vol_remaining_num “Tap3 [%d]” (gAllTapRemain)

//Names of kegs

String tap1_name “Tap1 [%s]” (gAllTapName) {channel=“exec:command:kegbot_name1:output”}

String tap2_name “Tap2 [%s]” (gAllTapName) {channel=“exec:command:kegbot_name2:output”}

String tap3_name “Tap3 [%s]” (gAllTapName) {channel=“exec:command:kegbot_name3:output”}\

then my rules are:

//converts string to number
rule “convert tap1 to number”
when
Item tap1_vol_remaining received update
then
tap1_vol_remaining_num.postUpdate(Double::parseDouble(tap1_vol_remaining.state.toString) / 1000)
end

//converts string to number
rule “convert tap2 to number”
when
Item tap2_vol_remaining received update
then
tap2_vol_remaining_num.postUpdate(Double::parseDouble(tap2_vol_remaining.state.toString) / 1000)
end

//converts string to number
rule “convert tap3 to number”
when
Item tap3_vol_remaining received update
then
tap3_vol_remaining_num.postUpdate(Double::parseDouble(tap3_vol_remaining.state.toString) / 1000)
end

rule “Tap pour”
when
Member of gAllTapRemain changed // one Tap was changed
then
if(previousState === null) return; // startup, so stop rule
var String strTap = triggeringItem.name.split("_").get(0) // get Index
var iTapName = gAllTapName.members.filter[i | i.name.contains(strTap)].head // get Name as Item
if ((previousState as Number) > (triggeringItem.state as Number)) { // if level has fallen
Garage_Speak.sendCommand('Enjoy '+ iTapName.state) // say the Name…
sendNotification("[email protected]","Beer Poured - "+ iTapName.state)
}
end


#13

@johnnyruz

https://community.openhab.org/t/receiving-and-parsing-webhook-post/81848/4


#14

Hey @johnnyruz , I’ve got a small node server accepting the webhook from Kegbot and parsing the keg name. I just need to work out how to post it to an item through the openhab API.

I am no dev so please excuse me if this is messy/rubbish hahah

var express = require(‘express’)
var bodyParser = require(‘body-parser’)
var port = 81
require(“util”).inspect.defaultOptions.depth = null;

var app = express()

// parse application/json
app.use(express.json({extended: true}))

app.use(function (req, res, next) {
console.log(req.body) // populated!
var beer=req.body.data.drink.keg.beverage.name
console.log(beer)
next()
})

console.log(‘Web server listening on port: %s’, port);

//Start the server and make it listen for connections on port
app.listen(port);

EDIT:

Here we go - “Garage_Speak” is my alexa channel for speak

var express = require(‘express’)
var bodyParser = require(‘body-parser’)
var port = 81
require(“util”).inspect.defaultOptions.depth = null;
var request = require(‘request’);
var app = express()
var headers = {
‘Content-Type’: ‘text/plain’,
‘Accept’: ‘application/json’
};

// parse application/json
app.use(express.json({extended: true}))

app.use(function (req, res, next) {
console.log(req.body) // populated!
var beer=req.body.data.drink.keg.beverage.name
console.log(beer)
var options = {
url: ‘http://192.168.1.21:8079/rest/items/Garage_Speak’,
method: ‘POST’,
headers: headers,
body: “enjoy” + beer
};
next(request(options, callback))
})

console.log(‘Web server listening on port: %s’, port);

//Start the server and make it listen for connections on port
app.listen(port);

function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}