Pulling Multiple JSON Queries From a Single HTTP POST

I am in the process of building a DirecTV remote using HTTP requests. I got all of the remote buttons mapped and working correctly. However, now I am working with receiving the JSON data back from the DirecTV receiver and displaying it correctly.

What I am trying to accomplish is every minute OpenHAB will send the HTTP request to display what is playing on the TV.

Here is the JSON response from the DirecTV Reciever:

{
  "callsign": "ESPNHD",
  "date": "20170916",
  "duration": 10800,
  "isOffAir": false,
  "isPclocked": 3,
  "isPpv": false,
  "isRecording": false,
  "isVod": false,
  "major": 206,
  "minor": 65535,
  "offset": 10521,
  "programId": "64781638",
  "rating": "No Rating",
  "startTime": 1505566800,
  "stationId": 2220255,
  "status": {
    "code": 200,
    "commandResult": 0,
    "msg": "OK.",
    "query": "/tv/getTuned"
  },
  "title": "College GameDay"
}

Here is an example of my Rules file:

// DirecTV
rule “DirecTV Watching”
when Time cron "0 0/1 0 ? * * *"
then
  String DirecTV_Status = { http="<[http://192.168.1.10:8080/tv/getTuned:60000:REGEX((.*))]" }
  var String DIRECTV_POST = DirecTV_Status.state.toString
  var String DirecTV_Show = transform("JSONPATH","$.title", DIRECTV_POST)
  var String DirecTV_Ch = transform("JSONPATH","$.major", DIRECTV_POST)
  var String DirecTV_Chan = transform("JSONPATH","$.callsign", DIRECTV_POST)
  var String EPISODE = transform("JSONPATH","$.episodeTitle", DIRECTV_POST)
end

Here is my Items file:

String DirecTV_Show "Watching: [%s]"
String DirecTV_Ch "Current Channel [%s]"
String DirecTV_Chan "Channel: [%s]"
String EPISODE "Episode: [%s]"

Any help would be greatly appreciated! Also, If anyone would like to see my .items file for the rest of my DirecTV configuration, just let me know. I’m thinking of writing a guide on it if there is enough interest.

Thanks,

Trevor

I would start with the Beginner’s Tutorial and the Rules section in the docs followed by the HTTP binding readme.

You are using a binding config in a rule which makes no sense.

Personally what I would do is config a cached request (see the binding readme) to get the info once a minute then use the proper binding config with the transforms for your items. See the Comprehensive Wunderground with HTTP for an example.

Rich,

Thank you for your response. I guess I should have prefaced with I already have it working by using what I learned in the HTTP documentation. Here is my current items file with it working:

String DirecTV_Show "Watching: [%s]" { http="<[http://192.168.1.10:8080/tv/getTuned:30000:JSONPATH($.title)]" }
String DirecTV_Ch "Current Channel [%s]" { http="<[http://192.168.1.10:8080/tv/getTuned:30000:JSONPATH($.major)]" }
String DirecTV_Chan "Channel: [%s]" { http="<[http://192.168.1.10:8080/tv/getTuned:30000:JSONPATH($.callsign)]" }
String EPISODE "Episode: [%s]" { http="<[http://192.168.1.10:8080/tv/getTuned:30000:JSONPATH($.episodeTitle)]" }

The issue I have with this is that it sends 4 different HTTP requests at the same time to collect data, that in my opinion, should be able to collected by a single request. The true reason for this, is it seems to extremely saturate the receiver when the requests are sent, so if I’m trying to change the channel at the same time it will take a long time to respond.

So if you have a better idea then what my thought was, above, I would love to hear it!

Thanks again.

…and because all those requests (except one) are not needed you were advised to read the documentation of the http-binding, which allows to do a single request, scheduled in an adjustable timeschedule , in order to reuse it until all information has been used.

I’m an idiot!

I was too worried about the JSON transformation part of it instead of looking at the simple config part!

Thank you both for your help.

Trevor

Rich,

I took your advice and implemented the HTTP cache method and read your guide on Weather Underground, which I will most likely play with next. I read the HTTP guide and my syntax matches yours and the HTTP readme but I am getting an error in my items file. Can someone please tell my where my syntax error is?

http.cnf


# timeout in milliseconds for the http requests (optional, defaults to 5000)
timeout=5000

# the interval in milliseconds when to find new refresh candidates
# (optional, defaults to 1000)
granularity=5000

# whether to substitute the current time or state value into the URL
# (optional, defaults to true)
#format=

# configuration of the first cache item
directvCache.url=http://192.168.1.10:8080/tv/getTuned
directvCache.updateInterval=60000

Items file:

String DirecTV_Show { http=“<[directvCache:10000:JSONPATH($.title)]" }
String DirecTV_Ch { http=“<[directvCache:10000:JSONPATH($.major)]" }
String DirecTV_Chan { http=“<[directvCache:10000:JSONPATH($.callsign)]" }
String EPISODE { http=“<[directvCache:10000:JSONPATH($.episodeTitle)]" }

openhab.log

2017-09-17 14:33:45.234 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'directv.items' has errors, therefore ignoring it: [44,28]: mismatched input '“' expecting RULE_STRING
[44,31]: missing '}' at 'directvCache'
[44,43]: extraneous input ':' expecting RULE_ID

The error refers to the stated .items file and also states the exact position (line, character) of the problem. Since you did not show all contents we can’t what is wrong in line 41 character 28.
It could be the usage of a tilted " character !

If you did a direct copy and paste the problem is probably your use of smart quotes.

You just use only " and never

@rlkoshak That was exactly the issue. I copied and pasted directly from the forum and it used the wrong quotes. I retyped everything out and it is working as expected.

Thank you @rlkoshak and @opus for both of your help!

Also @rlkoshak , I started on your Weather Underground using HTTP and its working so much better already than the old weather binding, so thanks for that also.

Thanks,

Trevor

Trevor, do you have a complete working DirecTV set of items and rules now? I am starting that path, so it would be great if you could share…

@david I do have a complete set of items and it’s been working for me for quite some time. I will admit the code is quite sloppy and could use some cleanup, but it was my first time ever writing my own “code”.

Here is my items file. Now realize that its calling the IP of your DirecTV Box. You should be able to alias the IP of your box in a .cfg file instead of typing it out 43 times.

String HDDVR_Show { http="<[HDDVRCache:10000:JSONPATH($.title)]" }
String HDDVR_Ch { http="<[HDDVRCache:10000:JSONPATH($.major)]" }
String HDDVR_Chan_Name { http="<[HDDVRCache:10000:JSONPATH($.callsign)]" }
String HDDVR_EPISODE { http="<[HDDVRCache:10000:JSONPATH($.episodeTitle)]" }
Switch HDDVR_GUIDE { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=guide&hold=keyPress:default]" }
Switch HDDVR_MUTE { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=mute&hold=keyPress:default]" }
Switch HDDVR_RED { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=red&hold=keyPress:default]" }
Switch HDDVR_GREEN { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=green&hold=keyPress:default]" }
Switch HDDVR_YELLOW { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=yellow&hold=keyPress:default]" }
Switch HDDVR_BLUE { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=blue&hold=keyPress:default]" }
Switch HDDVR_EXIT { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=exit&hold=keyPress:default]" }
Switch HDDVR_PREV { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=prev&hold=keyPress:default]" }
Switch HDDVR_MENU { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=menu&hold=keyPress:default]" }
Switch HDDVR_LIST { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=list&hold=keyPress:default]" }
Switch HDDVR_RECORD { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=record&hold=keyPress:default]" }
Switch HDDVR_BACK { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=back&hold=keyPress:default]" }
Switch HDDVR_ACTIVE { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=active&hold=keyPress:default]" }
Switch HDDVR_INFO { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=info&hold=keyPress:default]" }
Switch HDDVR_ZERO { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=0&hold=keyPress:default]" }
Switch HDDVR_ONE { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=1&hold=keyPress:default]" }
Switch HDDVR_TWO { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=2&hold=keyPress:default]" }
Switch HDDVR_THREE { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=3&hold=keyPress:default]" }
Switch HDDVR_FOUR { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=4&hold=keyPress:default]" }
Switch HDDVR_FIVE { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=5&hold=keyPress:default]" }
Switch HDDVR_SIX { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=6&hold=keyPress:default]" }
Switch HDDVR_SEVEN { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=7&hold=keyPress:default]" }
Switch HDDVR_EIGHT { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=8&hold=keyPress:default]" }
Switch HDDVR_NINE { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=9&hold=keyPress:default]" }
Switch HDDVR_DASH { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=dash&hold=keyPress:default]" }
Switch HDDVR_ENTER { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=enter&hold=keyPress:default]" }
Switch HDDVR_POWER { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=power&hold=keyPress:default]" }
Switch HDDVR_POWERON { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=poweron&hold=keyPress:default]" }
Switch HDDVR_POWEROFF { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=poweroff&hold=keyPress:default]" }
Switch HDDVR_PLAY { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=play&hold=keyPress:default]" }
Switch HDDVR_PAUSE { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=pause&hold=keyPress:default]" }
Switch HDDVR_REW { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=rew&hold=keyPress:default]" }
Switch HDDVR_REPLAY { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=replay&hold=keyPress:default]" }
Switch HDDVR_STOP { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=stop&hold=keyPress:default]" }
Switch HDDVR_ADVANCE { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=advance&hold=keyPress:default]" }
Switch HDDVR_FFWD { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=ffwd&hold=keyPress:default]" }
Switch HDDVR_UP { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=up&hold=keyPress:default]" }
Switch HDDVR_DOWN { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=down&hold=keyPress:default]" }
Switch HDDVR_LEFT { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=left&hold=keyPress:default]" }
Switch HDDVR_RIGHT { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=right&hold=keyPress:default]" }
Switch HDDVR_SELECT { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=select&hold=keyPress:default]" }
Switch HDDVR_CHANUP { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=chanup&hold=keyPress:default]" }
Switch HDDVR_CHANDOWN { http=">[*:GET:http://10.0.0.6:8080/remote/processKey?key=chandown&hold=keyPress:default]" }

Here is my HTTP config file:

HDDVRCache.url=http://10.0.0.6:8080/tv/getTuned
HDDVRCache.updateInterval=30000

Hope this helps!

Also here is where I got most of my information from when I was getting all of the JSON requests:DirecTV IP Commands

Thanks for posting this, I’ve been able to get everything working except I get an error when the “episodeTitle” isn’t returned. Not all shows have an episode title so that object is left out of the results from the JSON query. When this happens, the “EPISODE” item shows the entire JSON response. The JsonPath documentation states: "When creating your Configuration there are a few option flags that can alter the default behaviour.
DEFAULT_PATH_LEAF_TO_NULL
This option makes JsonPath return null for missing leafs… "
I haven’t been able to find any documentation on how to set these flags or if it’s even an option with the JSONPATH transformation. Have you run into this issue and come up with any solution?