Real-time Monitor Notifications

I hacked together a dirty bash script that sends notifications when new stream are started. It monitors the channels-dvr.log for connections to live tv and recorded tv.

Requirements need:
jq is a lightweight and flexible command-line JSON processor
Boxcar Universal Push Notification Platform Or other cmdlline based notification service
Bash Shell runtime environment

Basically I just kicked the script off and let it run.

#!/bin/bash

activitydb=$(curl -s http://LOCAL_IP_TO_DVR:8089/dvr | jq '.activity|keys[]')
echo ${activitydb}

tail -Fn0 "/PATH-TO/data/channels-dvr.log" | \
while read line ; do
   echo "$line" | egrep -s "Opened connection to | Starting transcoder for file"
   if [ $? = 0 ]
   then
      sleep 1
      tempKeys=$(curl -s http://LOCAL_IP_TO_DVR:8089/dvr | jq '.activity|keys[]')
      #echo ${tempKeys}

      for key in ${tempKeys}
      do
         if [[ ! ${activitydb[@]} =~ ${key} && ( ${key} =~ "6-stream-" || ${key} =~ "7-file" || ${key} =~ "0-job-" ) ]]; then
           #echo ${key}
           activitydb+=" ${key}"
           TITLE="$(curl -s http://LOCAL_IP_TO_DVR:8089/dvr | jq '.activity['${key}']')"
           TITLE=${TITLE//\"}
           MESSAGE=""
           BOXCAR_SOUND=echo
           BOXCAR_ACCESS_TOKEN=*******

           /usr/bin/curl -d "user_credentials=${BOXCAR_ACCESS_TOKEN}" \
                         -d "notification[title]=${TITLE}" \
                         -d "notification[long_message]=${MESSAGE}" \
                         -d "notification[source_name]=Channels DVR" \
                         -d "notification[sound]=${BOXCAR_SOUND}" \
                         https://new.boxcar.io/api/notifications > /dev/null 2>&1
         fi
      done
   #echo ${activitydb}
   fi
 
    echo "$line" | egrep -s "Closed connection to | Stopping transcoder session file"
    if [ $? = 0 ]
    then
       sleep 1
       activitydb=$(curl -s http://LOCAL_IP_TO_DVR:8089/dvr | jq '.activity|keys[]')
       #echo ${activitydb}
    fi
 done
1 Like

Cool.

Another way to do this without tailing the log is via the dvr's event api. See Feature request : do "stuff" on recording started

1 Like

Looks interesting. I will take a look at this. Thanks.

@carterbunch
Interested in how jq might be able to handle a task for me, since I don't want to become a full-time programmer and learn a new language to do it.

I would like an EPG Guide pivot view for everything showing on a certain channel that ChannelsDVR has EPG data for.
i.e. What's on DiscoveryHD (or other channels) that ChannelsDVR knows about

I currently do this by creating a paused advanced pass that just selects the channel#, then use my web browser inspector to capture the response (json) and paste it into Notepad++ to edit. It's limited to 500 entries currently.

I eliminate duplicates so only unique movies/show episodes appear. I eliminate dups so I don't see the same repeated 28 episodes of Sharks Eating People...

This is basically a filter to see what movies & show episodes are appearing on a channel.

I would like to pull certain fields from the json so I can see Moviename, ShowTitle, EpisodeTitle, summary, etc.

Is that possible with jq?

Should be. You can use jq to extract individual fields from the JSON. Here’s an example from a thermostat control script I wrote:

echo $currentFollowMeStateResponse | jq -r '.thermostatList[0].settings.followMeComfort'

Note the first reference is an array, so you indicate which item within the brackets (zero-based)

Absolutely. jq is a JSON command line parser. I am sure you can feed the JSON file you saved to Notepad++. It might take you a couple of passes through the file to get what you want.

Also, you could try looking at the JSON data from here, http://local_dvr_ip:8089/dvr/jobs Maybe you could get more of what your need by doing just one pass.

Here is my stab at using your API. I did notice that from iOS, tvOS is okay, when it connects directly, not transcoding, that events aren't logged, but the HDHomeRun Tuner Status page says tuner is in use. All other events, recording jobs, transcoding and direct streaming are logged.

Also, this script needs to be restarted after the DVR server is restarted. Tailing the log file script does not have the problem.

#!/bin/bash

activitydb=""

curl -Ns http://LOCAL_DVR_IP:8089/dvr/events/subscribe | \

while read line ; do
   if [[ ${line} =~ "activities.set" && ( $(echo ${line} | jq .Name) =~ ^\"7- || $(echo ${line} | jq .Name) =~ ^\"6- || $(echo ${line} | jq .Name) =~ ^\"0- ) ]]
   then
      data=$(echo ${line} | jq .Value)
      key=$(echo ${line} | jq .Name)
      if [[ ! ${data} =~ null && ! ${activitydb[@]} =~ ${key} ]]
      then
         echo ${data}
         activitydb+=${key}
         echo Adding, ${key}, to activity DB: ${activitydb}
         TITLE=${data//\"}
         MESSAGE=""
         BOXCAR_SOUND=echo
         BOXCAR_ACCESS_TOKEN=******

         /usr/bin/curl -d "user_credentials=${BOXCAR_ACCESS_TOKEN}" \
                       -d "notification[title]=${TITLE}" \
                       -d "notification[long_message]=${MESSAGE}" \
                       -d "notification[source_name]=Channels DVR" \
                       -d "notification[sound]=${BOXCAR_SOUND}" \
                       https://new.boxcar.io/api/notifications > /dev/null 2>&1
      fi

      if [[ ${data} =~ null && ${activitydb[@]} =~ ${key} ]]
      then
         activitydb=${activitydb/$key/}
         echo Deleting, ${key}, from activity DB: ${activitydb}
      fi
   fi
done

If the app connects directly to the HDHR then the DVR has no idea. If Tuner Sharing is enabled you should see Activity.

You can wrap the whole thing in a while loop like my original example.

1 Like

Here are some examples: Link to json guide.json file

cat guide.json | jq '.[0].Airings[0] | .Channel, .Title, .Summary, .Raw.ratings[0].code'
"2.1"
"General Hospital"
"Shiloh is too comfortable for Jason's liking; Kim has a suggestion; Nina welcomes a houseguest."
"TV14"

cat guide.json | jq '.[36].Airings[0] | .Channel, .Title, .Summary, .Raw.ratings[0].code'
"6010"
"The Cleveland Show"
"Cleveland discovers that Donna is still attending a support group for single mothers."
"TV14"

cat guide.json | jq '.[36].Airings[0] | .Title, .Summary, .Channel, .Categories[], .Genres[], .Raw.ratings[0].code'
"The Cleveland Show"
"Cleveland discovers that Donna is still attending a support group for single mothers."
"6010"
"Episode"
"Series"
"Sitcom"
"Animated"
"TV14"

What determines how the iOS connects directly to Tuner vs going via server? My AppleTV always seem to go to the DVR, but my phone seems to be random where it connects. This is the behavior when my phone is connected to WiFi.

Tuner sharing. If enabled in the client, the streams go through the DVR server to allow the tuner to be shared. If not enabled, then clients stream directly from the tuners, bypassing the DVR server.

I am unable to get the iOS client to register connections through the DVR on a regular basis. The tvOS app consistently logs activity through the DVR. Both apps have tuner sharing on and I am starting multiple connections on different channels.

Recorded shows behave the same way. I have tried on both the production and beta versions of the iOS apps.

Can you submit diagnostics from the iOS app?

Just played a station and submitted diagnostics.

Thanks. It looks like you used "Connect to DVR > At Home" and then entered a hostname instead of IP address, so tuner sharing is failing. Only IPs are supported for direct connect.

So, to fix I would log out in the app and connect again and choose the dvr IP addr?

Just click Connect to DVR > At Home and then either leave it empty and hit save (which will fallback to auto-discovery), or enter the IP of your mac there and hit save.

That worked! Thanks.

1 Like

I need to reopen this as I am seeing some weird behavior from the activity stream.

If I start a recording on the local network it get multiple repeating activities like this:

{"Type":"hello", "Version":"2019.12.06.0248"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 192.168.7.182."}
{"Type":"files.updated","Name":"9441","UpdatedAt":1575681226362}
{"Type":"files.updated","Name":"9441","UpdatedAt":1575681226374}
{"Type":"groups.updated","Name":"12308123","UpdatedAt":1575681226385}
{"Type":"activities.set","Name":"6-file-9441-192.168.7.182"}

But if I start the same recording from remote network I get the expected output of only a few lines of activity.

{"Type":"hello", "Version":"2019.12.06.0248"}
{"Type":"activities.set","Name":"7-file9441-23278ccdc69d","Value":"Streaming recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg."}
{"Type":"activities.set","Name":"7-file9441-23278ccdc69d","Value":"Watching recording NBC Nightly News With Lester Holt 2019-12-06-1830.mpg from 166.177.184.18 (Transcoder Running at 904kbps: 3s @ 0.97x (197.76fps))."}
{"Type":"activities.set","Name":"7-file9441-23278ccdc69d"}

This seems to still be happening with tvOS and iOS Clients only when you are connected to the local network. When you try this from remote or cellular it does not happen. I could only test remote iOS Client. I am assuming it will happen with remote tvOS client as well.