Attaching Events To "Now Playing"

Hello

Im going to develop an application that will dim the lights in my living room if a movie is played on my tv.

Does anyone know if there is a port i can connect to on my pms to listen for events or if there is another way of attaching myself to the server without polling it.

 

Thanks

Levi

PlexWatch can trigger notifications when a video is started or stopped. So you can get a notification from pushover or pushbullet etc. you can also configure it to run a script so if you have a script that will dim your lights plexwatch will trigger the script for you.

Hi

Thanks for getting back to me.

I’ve had a look at the program - installed and had a play.

It works however uses the method I was trying to avoid - polling the server. I want instant results which would mean continuously polling the server 24/7 evey 5 seconds or less and that’s not great… And still not really quick… Ideally the lights would dim the instant you click play…

I have next week of - I will devote a morning to resolving this problem.

Thanks again for your reply

I've been looking at the trakt scrobbler code recently.

Apparently there's a websocket you can use to get notifications. Maybe only if you have plex pass?

ws://127.0.0.1:32400/:/websockets/notifications

https://github.com/trakt/Plex-Trakt-Scrobbler/blob/master/Trakttv.bundle/Contents/Code/pts/activity_websocket.py

You star!

Thank you very much - works perfect!

Anyone else going down the same path may find the below url useful to resolve the sessionKey to some useful info!

http://localhost:32400/status/sessions

I will put together a little C# library and post my finished work here probably monday

Thanks again!  :D

Hi

For anyone interested - got my service finished - code below - there is a lot of info available from plex - i dont parse it neatly to a class - i just pick out the information i need (given more time this would be a neater way of writing) - the plex half of this application took approx 30 mins however getting it to work with my light switches was a little more involved and troublesome so took me bout 3 hours in total.

This is running as a service on my fileserver. the lights are controlled in real time with no polling.

Please excuse slightly messy code - works 100% perfectly though.

Enjoy

Thanks

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

using WebSocketSharp;
using System.Net;
using System.Net.Sockets;
using System.Web;

namespace PlexNotificationCatcher.Classes
{
class Application
{
static string PlexRootUrl = “192.168.100.50:32400”;
WebSocket ws;

    public Application() { }

    public void Start()
    {
        ws = new WebSocket("ws://" + PlexRootUrl + "/:/websockets/notifications");
        ws.OnMessage += (sender, e) => OnNotificationRecieved(e.Data);
        ws.Connect();
    }

    public void Stop()
    {
        ws.Close();
        lightwaveSender.Close();
    }

    private void OnNotificationRecieved(string Notification)
    {
        //"_elementType":"NotificationContainer","type":"playing","size":1,"_children":[{"_elementType":"PlaySessionStateNotification","sessionKey":"2340","guid":"com.plexapp.agents.thetvdb://193131/1/5?lang=en","ratingKey":"70948","url":"","key":"/library/metadata/70948","viewO
        // Only get the notificatinos in interested in
        if (Notification.Contains("\"type\":\"playing\""))
        {
            string SessionKey = Notification.Split(new string[] { "\"sessionKey\":\"" }, StringSplitOptions.None)[1].Split('"')[0];
            string State = Notification.Split(new string[] { "\"state\":\"" }, StringSplitOptions.None)[1].Split('"')[0];

            string sessionXml = new WebClient().DownloadString("http://" + PlexRootUrl + "/status/sessions");
            if (State == "stopped")
                PlayingEventFired("", "", State, SessionKey);
            else
            {
                // Pull deviceName and film name from above xml (only stuff i care bout)
                string[] sessions = sessionXml.Split(new string[] { "<Video " }, StringSplitOptions.None);
                for (int i = 1; i < sessions.Length; i++)
                {
                    if (sessions*.Contains("sessionKey=\"" + SessionKey + "\""))
                    {
                        string PlayerName = HttpUtility.HtmlDecode(sessions*.Split(new string[] { "<Player " }, StringSplitOptions.None)[1].Split(new string[] { "title=\"" }, StringSplitOptions.None)[1].Split('"')[0]);
                        string VideoTitle = sessions*.Split(new string[] { "title=\"" }, StringSplitOptions.None)[1].Split('"')[0];
                        PlayingEventFired(PlayerName, VideoTitle, State, SessionKey);
                        break;
                    }
                }
            }
        }
    }

    private void PlayingEventFired(string PlayerName, string VideoTitle, string State, string SessionKey)
    {
        if (GetPrevSessionState(SessionKey) == State)
            return;
        PlayerName = SetPrevSessionState(SessionKey, State, PlayerName);

        if (PlayerName.ToLower().Contains("living room") || PlayerName.ToLower().Contains("livingroom") || PlayerName.ToLower().Contains("chromecast"))
        {
            if (State == "playing")
                SendLightwaveRFCommand("!R1D1F0", PlayerName, "Playing " + VideoTitle);
            else if (State == "paused")
                SendLightwaveRFCommand("!R1D1F1", PlayerName, "Paused");
            else if (State == "stopped")
                SendLightwaveRFCommand("!R1D1F1", PlayerName, "Stopped");
        }
    }

    UdpClient lightwaveSender = new UdpClient(9761);
    IPEndPoint ip = new IPEndPoint(IPAddress.Broadcast, 9760);
    private void SendLightwaveRFCommand(string Command, string PlayerName, string Description)
    {
        byte[] bytes = Encoding.ASCII.GetBytes("100,!F*p

");
lightwaveSender.Send(bytes, bytes.Length, ip);

        System.Threading.Thread.Sleep(200);

        bytes = Encoding.ASCII.GetBytes("568," + Command + "|Plex - " + PlayerName + "|" + Description + "

");
lightwaveSender.Send(bytes, bytes.Length, ip);
}

    List<object[]> SessionStates = new List<object[]>();
    private string GetPrevSessionState(string SessionKey)
    {
        for (int i = 0; i < SessionStates.Count; i++)
            if (SessionStates*[0].ToString() == SessionKey)
                return SessionStates*[1].ToString();
        return string.Empty;
    }
    private string SetPrevSessionState(string SessionKey, string State, string PlayerName)
    {
        bool Set = false;
        for (int i = 0; i < SessionStates.Count; i++)
        {
            if (SessionStates*[0].ToString() == SessionKey)
            {
                if (!string.IsNullOrEmpty(PlayerName))
                    SessionStates*[2] = PlayerName;
                SessionStates*[1] = State;
                Set = true;
                return SessionStates*[2].ToString();
            }
        }
        if (!Set)
            SessionStates.Add(new object[] { SessionKey, State, PlayerName });
        return PlayerName;
    }
}

}

You star!

Thank you very much - works perfect!

Anyone else going down the same path may find the below url useful to resolve the sessionKey to some useful info!

http://localhost:32400/status/sessions

I will put together a little C# library and post my finished work here probably monday

Thanks again!  :D

Hi, ive been using this url for a while to get the state of my plex and using that to change light scenes, but the url is down. i get a "Unauthorized" page.

is this related to updates on plex home?

id really like to know if this gets resolved, or if theres another url i can read out with python.

i hope to get some help!

Hi

Go to settings, server - show advance

do you have the below checked? if so try unchecking it

Thanks

  Require authentication on local networks

Sets the allowed networks setting to 127.0.0.1/255.255.255.255. This requires other computers on a local network to authenticate before accessing the server.

i already had that unchecked. any other tips?

i already had that unchecked. any other tips?

It is a result of Home mode been enabled.

You'll need to use a token to authenticate

See this thread:

https://forums.plex.tv/topic/129340-getting-a-token-from-plextv/?p=775682

/T

Hello

Spent a little time last night making some improvements

Ive attached V2

Now suitable for others to use

Loads Application variables from XML file

Supports multiple rooms - each room has properties:

  • Name
  • Devices (Array)
  • Users (Array)
  • Play Command
  • Pause Command
  • Stop Command
  • Include Music (Will run commands if music is played)
  • Is Dark (Will only run commands between sunset and sunrise)
  • Lat and Long (used for Is Dark)

Example config files are included

Need to be installed as a service.

Thanks

Now accepts player unique ids as it wasn’t distinguishing between my chromecasts


I won’t upload another copy yet in case I make more changes


Thanks

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.