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;
}
}
}