Kodi Media Sensors - need Python help with an upgrade idea!

Hi there.
I am trying to roll everything in my home into one app to rule them all. Naturally I’m using Home Assistant for this, but I hit a snag when working on my Kodi integration…

I recently installed the (excellent) Kodi Media Sensors add-on via HACS.

Rather than use the Upcoming Media Card I’ve opted to roll my own for a bit more control.

I’ve got it looking nice with my minimalist mushroom UI, and have been able to tweak a few lines of code so the sensor retrieves file names that I can pass to script to play the specific episodes/movies directly from HA.

There is just one thing that bugs me…

The Recently Added Episodes sensor returns a pretty basic list of, well… recently added episodes…

What I actually want is a list of the recently added episodes, compressed into the last unwatched episode of each series.

Now… after a bit of Google-fu I was able to locate this script which I was able to modify to output exactly what I want:

#!/usr/bin/env python
import requests
import json
import time, datetime
from datetime import date
import sys

kodi_ip = 'YOUR KODI IP HERE'
kodi_port = '8080'
kodi_url = 'http://' + kodi_ip + ':' + kodi_port + '/jsonrpc'

#setup the JSON request parameters to use for the next request to Kodi
#we poll the video library for the list of TV shows, sorted by last added
kodi_params = json.dumps({"jsonrpc":"2.0","method":"VideoLibrary.GetTVShows","params":{"properties":["playcount"],"limits":{"end":50,"start":0},"sort":{"ignorearticle":True,"method":"dateadded","order":"descending","useartistsortname":True}},"id":28})
kodi_response = requests.post(kodi_url, data=kodi_params)

#we format the JSON response so it can be read
json_data = json.dumps(kodi_response.json(), indent=4, sort_keys=True)
json_object  = json.loads(json_data)

#Below are some examples of how to get data back out of the json_object, limits are the number of inprogress shows.
#print(json_object['result']['limits']['start'])
#print(json_object['result']['limits']['end'])
#print(json_object['result']['tvshows'][0])
#json_object = json.loads(json.dumps(json_object['result'], indent=4, sort_keys=True))
#print(kodi_data.get('tvshows'))
#print(json_object['tvshows'])

#next we begin a loop to build the query which will poll the episodes of the latest shows to get the first 6 that have unwatched episodes
#we need to empty the kodi_params as we will use this to store the multi show query, we put the JSON request for each tvshowid on a line and braket it [ ] once #complete. For each inprogress show Kodi returns - ["season", "episode", "playcount", "firstaired", "tvshowid", "lastplayed"]
kodi_params = ''
showcount = 0
for k in json_object['result']['tvshows']:
    #print (k['tvshowid'])
    #print (k['label'])
#Only handle unwatched or in progress shows
    if k['playcount'] < 1:
        showcount = showcount + 1
        if kodi_params == '':
            kodi_params = ('{"jsonrpc":"2.0","id":1,"method":"VideoLibrary.GetEpisodes","params":{"tvshowid": ' + str(k['tvshowid']) + ', "properties": ["playcount"],"sort":{"ignorearticle":true,"method":"episode","order":"ascending","useartistsortname":true}}}')
        else:
            kodi_params = kodi_params + ","+ "\n" + ('{"jsonrpc":"2.0","id":1,"method":"VideoLibrary.GetEpisodes","params":{"tvshowid": ' + str(k['tvshowid']) + ', "properties": ["playcount"],"sort":{"ignorearticle":true,"method":"episode","order":"ascending","useartistsortname":true}}}')
#once we have found 6 items we can stop
    if showcount >= 6: break

kodi_params = "[" + kodi_params + "]"
#print(kodi_params)
kodi_response = requests.post(kodi_url, data=kodi_params)
json_data = json.dumps(kodi_response.json(), indent=4, sort_keys=True)
#print(json_data)
json_object  = json.loads(json_data)

#Kodi has now returned all the information for the episodes of the inprogress tvshows which we will need to process to determine the first unwatched episode.
kodi_params = ''

#we loop through the results for each show.
idcount = 0;
for k in json_object:
#we then loop through the episodes in each show, and take the first unwatched episode
    for x in k['result']['episodes']:
        if x['playcount'] < 1:
#then if the particular episode is the next unwatched for a show it will start writing the multiple "GetEpisodeDetails" 
            if kodi_params == '':
                kodi_params = ('{"jsonrpc":"2.0","id":' + str(idcount) + ',"method":"VideoLibrary.GetEpisodeDetails","params":{"episodeid":' + str(x['episodeid']) + ', "properties": ["title","firstaired","playcount","runtime","season","episode","showtitle","file","dateadded","art","fanart","rating"]}}')
            else:
                kodi_params = kodi_params + ","+ "\n" + ('{"jsonrpc":"2.0","id":' + str(idcount) + ',"method":"VideoLibrary.GetEpisodeDetails","params":{"episodeid":' + str(x['episodeid']) + ', "properties": ["title","firstaired","playcount", "runtime","season","episode","showtitle","file","dateadded","art","fanart","rating"]}}')
#                print(str(x['firstaired']) + ' ' + str(x['tvshowid'])+ ' ' + str(x['episodeid']))
#once we have found the first unwatched episode for a show we can break the loop and move onto the next show.
            idcount = idcount + 1
            break


#once the loop is complete we write the multiple requests and bound with [] and send to kodi
kodi_params = "[" + kodi_params + "]"
#print(kodi_params)

#kodi_response = requests.post(kodi_url, headers=kodi_header, data=kodi_params)
kodi_response = requests.post(kodi_url, data=kodi_params)
json_data = json.dumps(kodi_response.json(), indent=4, sort_keys=True)
print(json_data)

The above script spits out a JSON list of the first unwatched episodes from any recently added TV shows - perfect!

This, unfortunately, is where I hit the limits of my technical expertise. I need help integrating the above script into the entitiies.py file of the Kodi Sensors add-on. Any Python pros able to help with this?

Thanks in advance for your assistance!
:smiley:

After a lot of fiddling around, I was able to get this up and running using PyScript, which is a great add-on for running Python. :smiley:

Much better…