HTTP binding - Dynamic URL


so I created an item with the http binding which gets me information from my work calendar via REST API.
The request URL looks like this:

Now, what I want is to use the current date for “interval-start” and for interval-end +2 hours from interval start.
Can I do this with variables within the item file? Do variables work within the http binding syntax?

I also found this:

But I have no clue how to use it,
so if anybody can help or give me an example I would be thankful!

Have a nice day!

Figured it out I think, but I got a problem:
My calendar shows entries in GMT, while I am at UTC +2.

Can I do some simple math (subtraction -2) within this whole thing?

There is no such thing as variables in a .items file. And there is definitely no way to perform logic like “add two hours” in the .items file. You need Rules to do that. I recommend using a Rule and dynamically build the URL in the Rules code and call the sendHttpGetRequest Action to pull the data down from the web site.

Can you give me a minimum working example here maybe?
I am a bit overcharged what exactly to do in the rules file.

rule "make a url"
    Item myParam changed
    // construct a string
    val base = ""
    val arg = myParam.toString
    logInfo("http rule", "Sending argument " + arg)
    sendHttpGetRequest(base + arg)

Okay so my problem seems more complicated than I thought:

I could create the rule and form a dynamic url with the timestamps.
The problem is:
My HTTP request requieres basic auth as well as a token, therefore I can not use sendHttpGet, am I right?

I tried to use the HTTP-binding, but afaik, the binding works only within the ITEM file.
I thought about creating a rule which updates the item channel of the HTTP item but this seems impossible too…

Is there any way I can archieve this?

You can. http://username:password@<rest of URL>

1 Like

and where do I add the second command, my token?
Its like
product key : AAAA-BBBB-CCCC

and needs to be sent with in every request, otherwise my server gives me an error.

I know that I can use the auth with user:pw or base64, but I dont know if I can add other header parameters.

That’s not basic auth then.

You can’t change the header using the binding nor the actions.

If you need to set something in the header, you either need to go to a lower level and code the HTTP request using the Java classes (see OAuth2 using just OH Rules and for an example).

Or what would probably be easier to use executeCommandLine or the exec binding and use curl.

Thats what I thought, thanks for confirming!
My approches so far look like this:

var String test = executeCommandLine(curl --request GET \  --url link \ --header 'accept: application/json' \ --header 'authorization: Basic ABCDE' \ --header 'product-key: 12345')
logInfo("Test", test)

Do I have to get rid of the quotes within the execute line? Or replace the --?

Have a look at this topic:

Thanks again Marcel!
My curl command works after replacing everything with @@.
The next issue:
The command gives me an output like this:

How can I get rid of the Dload Uload Total etc. information?
For now, I can’t use JSONPATH because of the information which gets send with.

Try adding -s or --silent to your curl command. That should remove the statistics from the output.

Thanks again for the fast help!

Me again, another day another problem ^^

The curl gives me an JSON which different information.
Until now, I used JSONpath to get the value “Keywords” out of the JSON.
Since today, I may be possible that there are >1 keywords in the JSON, and JSONpath cant return 0 or >1 values.

So I tried to create a while loop, which creates an array and checks for every single keyword and writes that keyword in the array.
The problem is, how can I stop the loop? Can I fetch the WARN or ERROR logs to use as a break?

Who can say. Got a problem with a rule, show the rule.
In general, while loops are unwise in rules due to risk of endless looping. Perhaps a for-each would be a better approach.

Heres the rule so far:



 var i = 0
    val wert = newArrayList()
    while (true){
        val currentval = (transform("JSONPATH", "$."+i+"*.fields.KEYWORD",test.toString)) 
        if(currentval == NULL) {
        wert.add(transform("JSONPATH", "$."+i+"*.fields.KEYWORD",test.toString))
    logInfo("Test", wert)

As you say, the problem is that I need something to break the loop. I can get each item from the JSON and bring it into the array, but as soon as i > #ofitems in array,
I get an error because JSONpath cant handle a NULL.

Is there any way to do this?

NULL is a valid state for Items, as in myItem.state == NULL

null is a java style keyword used in rules to indicate an empty variable
if (currentval == null)
Of course it’ll only work if your transform does return null and not empty string etc., I don’t know.

I guess this is trying to extract JSON keywords that may or may not be present.
That’s interesting … but if you find a keyword you haven’t seen before, what are you going to do with it?
I’m just saying that looking for known keywords that may or may not be present is a slightly different task to listing all keywords.

Okay so a bit background information so it may be more clear what I am trying to archieve:

I am using a company calendar and want to check if I have vacation at the current time.
My curl returns a JSON with all current appointments (with all information) in my calendars. I want to extract the “KEYWORD”-part of the JSON to see if one of the keywords is vacation.

So I am looking for a existing keyword, which may be present or not. The problem here is, on top of that, I dont know if I have other (reoccuring) appointments parallel to the vaccation.

Is there a easier way to archieve this?

I don’t know enough about JSON to suggest. I’d have thought you could directly search for “vacation” or whatever, maybe get a null result, maybe get a list/array in return.

But as you seem to be saying you can get other unexpected entries that you are interested in, then processing all from a blank canvas may be best for you.

Thats true,
it would be enough to search the array for the string “vacation” and if its found or not return true or null or whatever. I will research if this is possible and come back if Ive found a solution!

if (test.toString.contains(“vacation”)){

seems to work.