Skip to Main Content

PLEX Insights Dashboard

Sometimes you want to share your collection without the hassle.  This Plex dashboard is a playful attempt to pull some intriguing statistics from a Plex library without launching the Plex app or webpage.  Created using a combination of Web API and PowerShell tiles targeting Plex’s REST AP

John Knowles, SquaredUp

Challenge

As with most hobbies, Plex users want to show off their collection to friends and family! Understandably Plex is a very security-conscious application. That means if a user wants to share statistics about their library, they need to provide the user with credentials. That makes sharing a little tricky when you “only” want to share the statistics, not the actual content. Even more of a challenge, the native Plex dashboard uses a REST API that is not publicly documented.

Solution

I decided to build a Plex insights dashboard in SquaredUp that I could share with anyone.

To display anything, we first needed to identify where our data resides. After a bit of investigation, it was determined that the Plex Media Server stores data in two locations. The first location is in the cloud, and the second is a local SQLite database. 

We won’t go into the details, but the Plex Media Server creates a unique HTTPS URL for every Plex Media Server installation (in a rather genius way, actually). Since we know the username and password, our requests should piggyback on the same URL once we know what to send. Once we identified our unique URL (using the browsers debugging tools), we also captured the necessary API calls to replicate the default status dashboards. 

While using the debugging tools, we also discovered our second data source with some data that originated from a local SQLite database.

Now that we’ve identified our two data sources and with a bit of creativity, we can now share our Plex statistics dashboard via SquaredUp’s Open Access feature! 

Dashboard walk-through

The Plex insights dashboard is a mix of REST API calls using SquaredUp’s Web API and PowerShell tiles. For example, the CPU Utilization tile is a Web API tile that calls the Plex endpoint “statistics/resources,” which returns a JSON payload that is then graphed.

Using a donut graph, we can see how many TV episodes versus movies have been watched. The Most Viewed bar graph shows me what the favourite films are in this household and the right-hand donut shows which of the Plex libraries are the most popular.

PLEX media server insights dashboard - Total watched and most viewed

Line graphs help monitor CPU Utilization and Bandwidth Usage so we can spot if there are any issues.

PLEX media insights dashboard - CPU utilization and Bandwidth Usage, also friends with access

Also, a grid list of friends is a great reminder of who has access and what their usernames are.

We can also keep an eye on what's being watched currently with the grid list of Last Watched.

PLEX media insights dashboard - most watched by library and last watched

Scripts and data sets to steal

Here is an example Web API (line graph) tile.

The bandwidth usage tile needs the PowerShell tile to format the values that are returned from the SQLite database. The Switch statement accepts SquaredUp’s page timeframe variable to allow the tile to adjust.

switch ($timeFrame) { 
    "last1Hour" { $timeSpan = '-1 hours' } 
    "last12Hours" { $timeSpan = '-12 hours' } 
    "last24Hours" { $timeSpan = '-24 hours' } 
    "last7Days" { $timeSpan = '-7 days' } 
    "last30Days" { $timeSpan = '-30 days' } 
    "last3Months" { $timeSpan = '-3 months' } 
    "last6Months" { $timeSpan = '-6 months' } 
    "last12Months" { $timeSpan = '-12 months' } 
} 

#Plex records everythign in UTC time, so adjust accordingly! 
$Query = " 
SELECT [at] as timestamp 
      ,CASE  
        WHEN [lan] = 1 THEN 'Local' 
        WHEN [lan] = 0 THEN 'Remote' 
        else [lan] 
        END [label] 
      ,sum([bytes])/1024 as value 
      ,datetime(datetime('now','-10 hours'),'$timeSpan') as ctime 
  FROM [statistics_bandwidth]  
  WHERE [at] >= datetime(datetime('now','-10 hours'),'$timeSpan')   
  GROUP BY [at],[label] 
  ORDER BY [at] DESC,[label] 
"

# Timezone adjustment 
$ts = New-TimeSpan -Days 0 -Hours 5 -Minutes 00

$results = Invoke-SqliteQuery -Query $Query -DataSource $Database 
$results | Select-Object @{ N = 'timestamp'; E = { $_.timestamp + $ts } }, label, value, ctime

GET STARTED TODAY

Zero to dashboard hero in 60 seconds

Start now with hundreds of customizable dashboards.