2010-06-16, 05:58
Guys as requested how to integrate to Crestron:
This was tested with Xbmc for Windows and XbmcLive (Ubunutu)
First set Xbmc Settings:
1. Set Xbmc System--Settings--Network--Services--"Allow control via Http"
2. Set the Port to high number (I use 48880)
3. Username and password not used.
4. Set "AllowPrograms on other systems ...
Crestron Simpl+ :
1. Parameter Fields:
STRING_PARAMETER XbmcIp[20], XbmcPort[5], PcMacAddress[17];
2. Services / Sockets:
TCP_CLIENT XbmcTcp[2048];
UDP_SOCKET FbUdp[1024], WolSck[10], EventServerUpd[255];
TcpClient "XbmcTcp" is for the HttpApi
UdpSocket "FbUdp" is for receiving "Xbmc UPD Broadcast"
UdpSocket "WolSck" is for "MagicPacket" to wakeup / turnon the Xbmc host pc
UdpSocket "EventServerUpd" is for Navigation commands thru Event Server
3. "Main" function:
//*******************************************************************************************/
Function Main()
{
WaitForInitializationComplete();
MacId = ""; //Convert MacId to Packet
ValCount = 0;
For(i = 1 to 17)
{
If(i mod 3 <> 0)
{
ValCount = ValCount + 1;
Val[ValCount] = Byte(PcMacAddress,i);
If(Val[ValCount] > 96) Val[ValCount] = Val[ValCount] - 87;
Else
{
If(Val[ValCount] > 64) Val[ValCount] = Val[ValCount] - 55;
Else Val[ValCount] = Val[ValCount] - 48;
}
}
}
For(i = 1 to 11 Step 2)
{
MacId = MacId + Chr((Val[i]*16) + Val[i+1]);
}
WolPacket = "\xFF\xFF\xFF\xFF\xFF\xFF";
For(i = 1 to 16) WolPacket = WolPacket + MacId;
//Startup Sockets
UdpPort = Atoi(XbmcPort)+1;
Makestring(Temp, "SetBroadcast(130;%u)", UdpPort);
Call Connect(Temp, 2);
Status = SocketUDP_Enable(FbUdp, XbmcIp, UdpPort);
Status = SocketUDP_Enable(EventServerUpd, XbmcIp, 9777);
}
4. Http Connect Function:
//*******************************************************************************************/
FUNCTION Connect(String SendInfo, Integer CmdSeq)
{
INTEGER i;
STRING Sbuffer[1024];
// Print("Connect= CurrentSckStatus %u SendInfo %s ,%u\n", CurrentSckStatus, SendInfo, CmdSeq);
CommBusy = 1;
Wait(200, CommBusyWait) { CommBusy = 0; }
CommandToSend = SendInfo;
CurrCmdSeq = CmdSeq;
If(CurrentSckStatus <> 2)
{
SOCKETDISCONNECTCLIENT(XbmcTcp);
i = 0;
SOCKETCONNECTCLIENT(XbmcTcp, XbmcIp, Atoi(XbmcPort), 0);
Do{ Delay(2); i = i + 1; } Until(CurrentSckStatus = 2 || i>100);
}
MAKESTRING(Sbuffer,"GET /xbmcCmds/xbmcHttp?command=%s\x0D\x0A\x0D\x0A", CommandToSend);
If(Enable) SOCKETSEND(XbmcTcp, Sbuffer);
// Print("CommandToSend = %s\n", CommandToSend);
Wait(200, XbmcCloseConnection) { SOCKETDISCONNECTCLIENT(XbmcTcp); CommBusy = 0; BusyTcp = 0;}
}
//*******************************************************************************************/
SOCKETRECEIVE XbmcTcp
{
STRING Sbuffer[16392], CurrInfo[40][40], Fifo[1][10000], UdpTemp[1024];
INTEGER RcvLength, PrevByte, i, j, k, l, Ind[2];
// Print("RcvAction\n");
If(BusyTcp) Terminateevent;
BusyTcp = 1;
IF(len(XbmcTcp.SocketRxBuf) = 0) { BusyTcp = 0; Terminateevent; }
Do { Delay(2); i=i+1; } Until(i>50 || Find("</html>", Right(XbmcTcp.SocketRxBuf, 20)) > 0);
Sbuffer = XbmcTcp.SocketRxBuf;
i=0; j=0; Ind[0] = 1;
ClearBuffer(XbmcTcp.SocketRxBuf);
While(Ind[0])
{
Ind[1] = Find("<li>", Sbuffer, Ind[0]);
If(Ind[1])
{
Ind[2] = Find(":", Sbuffer, Ind[1]);
If(Ind[2])
{
Ind[0] = Find("<", Sbuffer, Ind[2]);
If(Ind[0])
{
CurrInfo[j] = Mid(Sbuffer, Ind[1]+4, (Ind[2]-Ind[1]-4));
If(Byte(Sbuffer, Ind[0]+1) = 47) l=Ind[0]-Ind[2]-1; Else l=Ind[0]-Ind[2]-2;
MakeString(Info[j], "%s", Mid(Sbuffer, Ind[2]+1, l));
j=j+1;
Delay(1);
}
}
Else Ind[0] = 0;
}
Else Ind[0] = 0;
}
CommBusy = 0;
BusyTcp = 0;
//For(i = 1 to 20)
//{
//if(len(Sbuffer)>200) Print("%s\n", Removebylength(200, Sbuffer));
//else i = 20;
//}
//Print("%s\n", Sbuffer);
For(i = 1 to j)
{
If(CurrInfo[i] = "ActiveWindow")
{
ActiveWindow=Atoi(Info[i]);
Print("ActiveWindow = %s\n", Info[i]);
CurrXbmcWindow = ActiveWindow;
If(ActiveWindow = 12005)
{
Switch(CurrType)
{
Case(1): CurrXbmcWindow = 5;
Case(2): CurrXbmcWindow = 6;
Case(3): CurrXbmcWindow = 7;
}
}
}
Else If(CurrInfo[i] = "ControlId")
{
ControlId=Atoi(Info[i]);
Print("ControlId = %s\n", Info[i]);
If(ControlId<>60 && ActiveWindow=10025) VideoNavHighlightFb = 1;
Else If(ControlId=60 && ActiveWindow=10025) VideoNavHighlightFb = 0;
}
Else If(CurrInfo[i] = "PlayStatus") CurrPlay$[1] = Info[i];
Else If(CurrInfo[i] = "Type" && Info[i] <> "Botton") CurrPlay$[2] = Info[i];
Else If(CurrInfo[i] = "Title") CurrPlay$[3] = Info[i];
Else If(CurrInfo[i] = "Genre") CurrPlay$[4] = Info[i];
Else If(CurrInfo[i] = "Studio") CurrPlay$[5] = Info[i];
Else If(CurrInfo[i] = "Director") CurrPlay$[6] = Info[i];
Else If(CurrInfo[i] = "Rating") CurrPlay$[7] = Info[i];
Else If(CurrInfo[i] = "Year") CurrPlay$[8] = Info[i];
Else If(CurrInfo[i] = "Track") CurrPlay$[9] = Info[i];
Else If(CurrInfo[i] = "Album") CurrPlay$[10] = Info[i];
Else If(CurrInfo[i] = "Artist") CurrPlay$[11] = Info[i];
Else If(CurrInfo[i] = "Lyrics")
{
// Print("Lir-%u\n", Len(Info[i]));
SetArray(Fifo, " ");
PrevByte=0; l=0;
For(k = 1 to Len(Info[i]))
{
If(Byte(Info[i],k)<32 || Byte(Info[i],k)>127)
{
If(PrevByte=0)
{
l=l+1; PrevByte=1;
If(Byte(Info[i],k)<32) Setstring("\xFE",l,Fifo[1]);
Else Setstring("'",l,Fifo[1]);
}
}
Else { l=l+1; Setstring(Mid(Info[i],k,1),l,Fifo[1]); PrevByte=0; }
}
Info[i] = Left(Fifo[1],l);
// Print("Lend-%u\n", Len(Info[i]));
LyricsNumOfLines=1;
For(k = 1 to 500)
{
IF(Find("\xFE", Info[i]))
{
Lyrics[LyricsNumOfLines] = Remove("\xFE", Info[i]);
If(len(Lyrics[LyricsNumOfLines])>2)
{
Lyrics[LyricsNumOfLines] = Left(Lyrics[LyricsNumOfLines], Len(Lyrics[LyricsNumOfLines])-1);
LyricsNumOfLines=LyricsNumOfLines+1;
}
}
Else
{
If(len(Info[i])>1)
{
LyricsNumOfLines=LyricsNumOfLines+1; Lyrics[LyricsNumOfLines] = Info[i];
}
k = 500;
}
}
If(LyricsNumOfLines > 2)
{
If(Len(Lyrics[1]) > 0) CurrPlay$[12] = Lyrics[1];
If(Len(Lyrics[2]) > 0) CurrPlay$[13] = Lyrics[2];
If(Len(Lyrics[3]) > 0) CurrPlay$[14] = Lyrics[3];
LyricsIndex = 1;
LyricsXbmcIndex = 1;
}
}
}
SOCKETDISCONNECTCLIENT(XbmcTcp);
CancelWait(XbmcCloseConnection);
Switch(CurrCmdSeq)
{
Case(1): { Call Connect("getGUIStatus", 0); }
Case(2): { Call Connect("SetResponseFormat(WebHeader;False)", 3); }
Case(3): { Call Connect("SetVolume(100)", 4); }
Case(4): { Call Connect("ExecBuiltIn(ActivateWindow(12600))", 5); }
Case(5): { Call Connect("ExecBuiltIn(Action(Stop))", 1); }
}
}
/
/*******************************************************************************************
SOCKETSTATUS XbmcTcp
{
CurrentSckStatus = SOCKETGETSTATUS();
//Print("CurrentSckStatus=%d\n",CurrentSckStatus);
}
//*******************************************************************************************
SOCKETCONNECT XbmcTcp
{
STRING Sbuffer[1024];
ReTimeWait(200, XbmcCloseConnection);
}
This was tested with Xbmc for Windows and XbmcLive (Ubunutu)
First set Xbmc Settings:
1. Set Xbmc System--Settings--Network--Services--"Allow control via Http"
2. Set the Port to high number (I use 48880)
3. Username and password not used.
4. Set "AllowPrograms on other systems ...
Crestron Simpl+ :
1. Parameter Fields:
STRING_PARAMETER XbmcIp[20], XbmcPort[5], PcMacAddress[17];
2. Services / Sockets:
TCP_CLIENT XbmcTcp[2048];
UDP_SOCKET FbUdp[1024], WolSck[10], EventServerUpd[255];
TcpClient "XbmcTcp" is for the HttpApi
UdpSocket "FbUdp" is for receiving "Xbmc UPD Broadcast"
UdpSocket "WolSck" is for "MagicPacket" to wakeup / turnon the Xbmc host pc
UdpSocket "EventServerUpd" is for Navigation commands thru Event Server
3. "Main" function:
//*******************************************************************************************/
Function Main()
{
WaitForInitializationComplete();
MacId = ""; //Convert MacId to Packet
ValCount = 0;
For(i = 1 to 17)
{
If(i mod 3 <> 0)
{
ValCount = ValCount + 1;
Val[ValCount] = Byte(PcMacAddress,i);
If(Val[ValCount] > 96) Val[ValCount] = Val[ValCount] - 87;
Else
{
If(Val[ValCount] > 64) Val[ValCount] = Val[ValCount] - 55;
Else Val[ValCount] = Val[ValCount] - 48;
}
}
}
For(i = 1 to 11 Step 2)
{
MacId = MacId + Chr((Val[i]*16) + Val[i+1]);
}
WolPacket = "\xFF\xFF\xFF\xFF\xFF\xFF";
For(i = 1 to 16) WolPacket = WolPacket + MacId;
//Startup Sockets
UdpPort = Atoi(XbmcPort)+1;
Makestring(Temp, "SetBroadcast(130;%u)", UdpPort);
Call Connect(Temp, 2);
Status = SocketUDP_Enable(FbUdp, XbmcIp, UdpPort);
Status = SocketUDP_Enable(EventServerUpd, XbmcIp, 9777);
}
4. Http Connect Function:
//*******************************************************************************************/
FUNCTION Connect(String SendInfo, Integer CmdSeq)
{
INTEGER i;
STRING Sbuffer[1024];
// Print("Connect= CurrentSckStatus %u SendInfo %s ,%u\n", CurrentSckStatus, SendInfo, CmdSeq);
CommBusy = 1;
Wait(200, CommBusyWait) { CommBusy = 0; }
CommandToSend = SendInfo;
CurrCmdSeq = CmdSeq;
If(CurrentSckStatus <> 2)
{
SOCKETDISCONNECTCLIENT(XbmcTcp);
i = 0;
SOCKETCONNECTCLIENT(XbmcTcp, XbmcIp, Atoi(XbmcPort), 0);
Do{ Delay(2); i = i + 1; } Until(CurrentSckStatus = 2 || i>100);
}
MAKESTRING(Sbuffer,"GET /xbmcCmds/xbmcHttp?command=%s\x0D\x0A\x0D\x0A", CommandToSend);
If(Enable) SOCKETSEND(XbmcTcp, Sbuffer);
// Print("CommandToSend = %s\n", CommandToSend);
Wait(200, XbmcCloseConnection) { SOCKETDISCONNECTCLIENT(XbmcTcp); CommBusy = 0; BusyTcp = 0;}
}
//*******************************************************************************************/
SOCKETRECEIVE XbmcTcp
{
STRING Sbuffer[16392], CurrInfo[40][40], Fifo[1][10000], UdpTemp[1024];
INTEGER RcvLength, PrevByte, i, j, k, l, Ind[2];
// Print("RcvAction\n");
If(BusyTcp) Terminateevent;
BusyTcp = 1;
IF(len(XbmcTcp.SocketRxBuf) = 0) { BusyTcp = 0; Terminateevent; }
Do { Delay(2); i=i+1; } Until(i>50 || Find("</html>", Right(XbmcTcp.SocketRxBuf, 20)) > 0);
Sbuffer = XbmcTcp.SocketRxBuf;
i=0; j=0; Ind[0] = 1;
ClearBuffer(XbmcTcp.SocketRxBuf);
While(Ind[0])
{
Ind[1] = Find("<li>", Sbuffer, Ind[0]);
If(Ind[1])
{
Ind[2] = Find(":", Sbuffer, Ind[1]);
If(Ind[2])
{
Ind[0] = Find("<", Sbuffer, Ind[2]);
If(Ind[0])
{
CurrInfo[j] = Mid(Sbuffer, Ind[1]+4, (Ind[2]-Ind[1]-4));
If(Byte(Sbuffer, Ind[0]+1) = 47) l=Ind[0]-Ind[2]-1; Else l=Ind[0]-Ind[2]-2;
MakeString(Info[j], "%s", Mid(Sbuffer, Ind[2]+1, l));
j=j+1;
Delay(1);
}
}
Else Ind[0] = 0;
}
Else Ind[0] = 0;
}
CommBusy = 0;
BusyTcp = 0;
//For(i = 1 to 20)
//{
//if(len(Sbuffer)>200) Print("%s\n", Removebylength(200, Sbuffer));
//else i = 20;
//}
//Print("%s\n", Sbuffer);
For(i = 1 to j)
{
If(CurrInfo[i] = "ActiveWindow")
{
ActiveWindow=Atoi(Info[i]);
Print("ActiveWindow = %s\n", Info[i]);
CurrXbmcWindow = ActiveWindow;
If(ActiveWindow = 12005)
{
Switch(CurrType)
{
Case(1): CurrXbmcWindow = 5;
Case(2): CurrXbmcWindow = 6;
Case(3): CurrXbmcWindow = 7;
}
}
}
Else If(CurrInfo[i] = "ControlId")
{
ControlId=Atoi(Info[i]);
Print("ControlId = %s\n", Info[i]);
If(ControlId<>60 && ActiveWindow=10025) VideoNavHighlightFb = 1;
Else If(ControlId=60 && ActiveWindow=10025) VideoNavHighlightFb = 0;
}
Else If(CurrInfo[i] = "PlayStatus") CurrPlay$[1] = Info[i];
Else If(CurrInfo[i] = "Type" && Info[i] <> "Botton") CurrPlay$[2] = Info[i];
Else If(CurrInfo[i] = "Title") CurrPlay$[3] = Info[i];
Else If(CurrInfo[i] = "Genre") CurrPlay$[4] = Info[i];
Else If(CurrInfo[i] = "Studio") CurrPlay$[5] = Info[i];
Else If(CurrInfo[i] = "Director") CurrPlay$[6] = Info[i];
Else If(CurrInfo[i] = "Rating") CurrPlay$[7] = Info[i];
Else If(CurrInfo[i] = "Year") CurrPlay$[8] = Info[i];
Else If(CurrInfo[i] = "Track") CurrPlay$[9] = Info[i];
Else If(CurrInfo[i] = "Album") CurrPlay$[10] = Info[i];
Else If(CurrInfo[i] = "Artist") CurrPlay$[11] = Info[i];
Else If(CurrInfo[i] = "Lyrics")
{
// Print("Lir-%u\n", Len(Info[i]));
SetArray(Fifo, " ");
PrevByte=0; l=0;
For(k = 1 to Len(Info[i]))
{
If(Byte(Info[i],k)<32 || Byte(Info[i],k)>127)
{
If(PrevByte=0)
{
l=l+1; PrevByte=1;
If(Byte(Info[i],k)<32) Setstring("\xFE",l,Fifo[1]);
Else Setstring("'",l,Fifo[1]);
}
}
Else { l=l+1; Setstring(Mid(Info[i],k,1),l,Fifo[1]); PrevByte=0; }
}
Info[i] = Left(Fifo[1],l);
// Print("Lend-%u\n", Len(Info[i]));
LyricsNumOfLines=1;
For(k = 1 to 500)
{
IF(Find("\xFE", Info[i]))
{
Lyrics[LyricsNumOfLines] = Remove("\xFE", Info[i]);
If(len(Lyrics[LyricsNumOfLines])>2)
{
Lyrics[LyricsNumOfLines] = Left(Lyrics[LyricsNumOfLines], Len(Lyrics[LyricsNumOfLines])-1);
LyricsNumOfLines=LyricsNumOfLines+1;
}
}
Else
{
If(len(Info[i])>1)
{
LyricsNumOfLines=LyricsNumOfLines+1; Lyrics[LyricsNumOfLines] = Info[i];
}
k = 500;
}
}
If(LyricsNumOfLines > 2)
{
If(Len(Lyrics[1]) > 0) CurrPlay$[12] = Lyrics[1];
If(Len(Lyrics[2]) > 0) CurrPlay$[13] = Lyrics[2];
If(Len(Lyrics[3]) > 0) CurrPlay$[14] = Lyrics[3];
LyricsIndex = 1;
LyricsXbmcIndex = 1;
}
}
}
SOCKETDISCONNECTCLIENT(XbmcTcp);
CancelWait(XbmcCloseConnection);
Switch(CurrCmdSeq)
{
Case(1): { Call Connect("getGUIStatus", 0); }
Case(2): { Call Connect("SetResponseFormat(WebHeader;False)", 3); }
Case(3): { Call Connect("SetVolume(100)", 4); }
Case(4): { Call Connect("ExecBuiltIn(ActivateWindow(12600))", 5); }
Case(5): { Call Connect("ExecBuiltIn(Action(Stop))", 1); }
}
}
/
/*******************************************************************************************
SOCKETSTATUS XbmcTcp
{
CurrentSckStatus = SOCKETGETSTATUS();
//Print("CurrentSckStatus=%d\n",CurrentSckStatus);
}
//*******************************************************************************************
SOCKETCONNECT XbmcTcp
{
STRING Sbuffer[1024];
ReTimeWait(200, XbmcCloseConnection);
}