JSON parsing
PhreaK
Posts: 966
Similar to other people, I'm increasingly working with JSON based API's for various devices and services these days and looking for neater ways to parse this. Currently I'm using a pretty rudimentary parser I rolled that enables me to pull out specific items based on a key. It works, but it gets clunky when you're working with larger objects more complex structures.
One option I'm thinking of is a parser that will ingest a JSON string and spit out a string encoded in the NetLinx Binary Marshalling Protocol. This will then allow you to take advantage of the in internal string_to_variable(..) method to load this directly into a variable (including structures) of arbitrary type. From what I can see, the only limitation is that the members of any structure you are decoding into will need to be ordered identically to members of the original JSON. An alternative is to parse into the XML format ingested by xml_to_variable(..). Again, this will enable you to decode into arbitrary types. In exchange for the slightly increased overhead of building that out to XML, the ordering caveat will be removed as the XML marshalling protocol contains reference to members by name.
Has anyone else tried this approach yet, or have another approach that works well for them?
One option I'm thinking of is a parser that will ingest a JSON string and spit out a string encoded in the NetLinx Binary Marshalling Protocol. This will then allow you to take advantage of the in internal string_to_variable(..) method to load this directly into a variable (including structures) of arbitrary type. From what I can see, the only limitation is that the members of any structure you are decoding into will need to be ordered identically to members of the original JSON. An alternative is to parse into the XML format ingested by xml_to_variable(..). Again, this will enable you to decode into arbitrary types. In exchange for the slightly increased overhead of building that out to XML, the ordering caveat will be removed as the XML marshalling protocol contains reference to members by name.
Has anyone else tried this approach yet, or have another approach that works well for them?
0
Comments
I've never used the string to variable or the XML, but I bet Json implementations are going to vary widely, more flexibility would be better, and I'm assuming you could drop the fields you are not interested in in the xml and just get what you want.
on a related note, do you see the JSON ID field being used as a sequential identifier, or unique to a particular type of command?
[USER="3082"]DFroberg[/USER] JSONID field? I'm assuming you're talking about something protocol specific.
I've only tried this on one device but I think the parsing routine would be fairly portable but my function here would have to change to process the specific tags:
[code]
DEFINE_FUNCTION fnJSON_Process_FB(_FB iFB)
{
STACK_VAR _FB sMyFB;
STACK_VAR INTEGER i;
STACK_VAR INTEGER nLVL;
STACK_VAR INTEGER nFBS;
STACK_VAR INTEGER nIndx;
STACK_VAR INTEGER nFBIndx;
//STACK_VAR INTEGER nLoopRunIndx;
STACK_VAR INTEGER nPlugin;
STACK_VAR INTEGER nRecognized;
STACK_VAR INTEGER nSearchPerformed;
sMyFB = iFB;
nLVL = sSBS.sBrowseState.nLevel;
fnJSON_Debug("'Process_FB, **, START-->'",1);
fnJSON_Debug("'Process_FB, **, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], TAGCNT-, ORIGINDX-, LVL- :DEBUG<',ITOA(__LINE__),'>'",1);
sLevel[nLVL].cTypeRet = sMyFB.cTag;
nPlugin = fnCheck_if_Plugin(sMyFB.cTag);//see if app or radio
{
if(nPlugin == 1)
{
sMyFB.cTopTag = 'apps';
sLevel[sSBS.sBrowseState.nLevel].nType = SBS_infoApps;
}
else if(nPlugin == 2)//radio
{
sMyFB.cTopTag = 'radios';
sLevel[sSBS.sBrowseState.nLevel].nType = SBS_infoRadios;
}
}
for(i=1;i<=sMyFB.nTagCnt;i++)
{
//fnJSON_Debug("'Process_FB, **TOP**, CNT-, FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_VAL[i],' ], FB_INDX-),'] :DEBUG<',ITOA(__LINE__),'>'",1);
nRecognized = 1;
if(sMyFB.nFB_Indx)
{
nFBIndx = sMyFB.nFB_Indx;
}
else if(!nFBIndx)
{
nFBIndx = 1;
}
SWITCH(sMyFB.cTopTag)
{
CASE 'apps':
CASE 'artists':
CASE 'genres':
CASE 'albums':
CASE 'radios':
CASE 'playlists':
//CASE 'loop':
CASE 'favorites':
CASE 'titles':
CASE 'playlisttracks':
{
if(nFBIndx && find_string(sMyFB.cObjTag,'_loop',1))
{
STACK_VAR CHAR cCopyVal[4096];
if(i==1 && nFBIndx==1)
{
STACK_VAR _sLevelList sZeroLevellist;
sLevelList[nLVL] = sZeroLevellist;
}
SWITCH(sMyFB.cTag)
{
CASE 'artists':
CASE 'albums':
CASE 'genres':
CASE 'titles':
{
if("sMyFB.cFB_Tag,'s'" == sMyFB.cTag)//sLevel[nLVL].cTypeRet)
{
sLevelList[nLVL].cItem[nFBIndx] = sMyFB.cFB_VAL;
}
if(sMyFB.cTag == 'titles')
{
sLevelList[nLVL].nHasItems[nFBIndx] = 0;
sLevelList[nLVL].nIsAudio[nFBIndx] = 1;
}
else
{
sLevelList[nLVL].nHasItems[nFBIndx] = 1;
sLevelList[nLVL].nIsAudio[nFBIndx] = 1;
}
}
CASE 'playlists':
{
if("sMyFB.cFB_Tag,'s'" == sMyFB.cTag)//sLevel[nLVL].cTypeRet)
{
sLevelList[nLVL].cItem[nFBIndx] = sMyFB.cFB_VAL;
}
else if(sMyFB.cFB_Tag == 'title')
{
sLevelList[nLVL].cItem[nFBIndx] = sMyFB.cFB_VAL;
sLevelList[nLVL].nHasItems[nFBIndx] = 0;
sLevelList[nLVL].nIsAudio[nFBIndx] = 1;
}
}
//CASE 'pandora':
// CASE 'apps':
// CASE 'favorites':
// CASE 'radios':
DEFAULT:
{
if(sMyFB.cFB_Tag == 'name')
{
sLevelList[nLVL].cItem[nFBIndx] = sMyFB.cFB_VAL;
if(nFBIndx == 1)//copy in case needed later
{
cSBS_TxtBox = sMyFB.cFB_VAL;
}
}
}
//DEFAULT:
// {
// nRecognized = 0;
// fnJSON_Debug("'Process_FB, !!, TAG-[ ',sMyFB.cTag,' ], no value assigned sLevelList.xXXXX, INDX- :DEBUG<',ITOA(__LINE__),'>'",1);
// }
}
SWITCH(sMyFB.cFB_Tag)
{
CASE 'album' :{sLevelList[nLVL].cAlbum[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'artist' :{sLevelList[nLVL].cArtist[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'cmd' :{sLevelList[nLVL].cListCmd[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'command' :{}//pandora button command arrays
CASE 'genre' :{sLevelList[nLVL].cGenre[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'playlist' :{sLevelList[nLVL].cPlaylist[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'title' :{sLevelList[nLVL].cTitle[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'id' :
{//spotify has spaces with %20 for some id's, these are needed in string sent back but the DecodeURL func removes them so we add an escape %--
//and modified the DecodeURL func to recognize it
sLevelList[nLVL].cItem_ID[nFBIndx] = fnStrReplace(sMyFB.cFB_VAL,'%20','%--%20');
}//sLevelList[nLVL].nHasItems[nFBIndx] = 1;
CASE 'icon' :{sLevelList[nLVL].cIconURL[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'name' :{sLevelList[nLVL].cName[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'type' :{sLevelList[nLVL].cType[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'weight' :{sLevelList[nLVL].cWeight[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'url' :{sLevelList[nLVL].cURL[nFBIndx] = sMyFB.cFB_VAL;}
CASE 'isaudio' :{sLevelList[nLVL].nIsAudio[nFBIndx] = atoi(sMyFB.cFB_VAL);}
CASE 'hasitems' :{sLevelList[nLVL].nHasItems[nFBIndx] = atoi(sMyFB.cFB_VAL);}
CASE 'duration' :{sLevelList[nLVL].nDuration[nFBIndx] = atoi(sMyFB.cFB_VAL);}
CASE 'tracknum' :{sLevelList[nLVL].nTrackNum[nFBIndx] = atoi(sMyFB.cFB_VAL);}
CASE 'remote' :{sLevelList[nLVL].nRemote[nFBIndx] = atoi(sMyFB.cFB_VAL);}
CASE 'image' :{sLevelList[nLVL].cImageURL[nFBIndx] = sMyFB.cFB_VAL;}//found in radios, pandora
CASE 'playlist index' :{sLevelList[nLVL].nIndxNum[nFBIndx] = atoi(sMyFB.cFB_VAL);}//playlist tracks zap song
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
else
{
SWITCH(sMyFB.cObjTag)
{
CASE 'artists':
CASE 'albums':
CASE 'genres':
CASE 'playlists':
CASE 'titles':
{
SWITCH(sMyFB.cFB_Tag)
{
CASE 'networkerror': {fnFB_SendVTMessage(UI_UPDATE_ACTIVE,"'Network Error!, ',sMyFB.cFB_Val",15);CANCEL_WAIT'SBS_PROGRESS_WAIT_DELAYOFF';fnSet_ProgressBar(FALSE);}
CASE 'command': {}//pandora button command arrays
CASE 'search': {nSearchPerformed = 1;}
CASE 'rescan': {fnSBS_SetRescan(atoi(sMyFB.cFB_Val));}
CASE 'count': {sLevel[nLVL].nMaxCountItem = atoi(sMyFB.cFB_VAL);}
CASE 'context': {sSBS.sBrowseState.nContextSession = atoi(sMyFB.cFB_VAL);}
CASE '__playlistTitle':
CASE '_playlistTitle': {sLevel[nLVL].cTitle = sMyFB.cFB_Val;}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'favorites':
{
LOCAL_VAR INTEGER nExists;
LOCAL_VAR INTEGER nExists_Indx;
SWITCH(sMyFB.cFB_Tag)
{
CASE 'networkerror': {fnFB_SendVTMessage(UI_UPDATE_ACTIVE,"'Network Error!, ',sMyFB.cFB_Val",15);CANCEL_WAIT'SBS_PROGRESS_WAIT_DELAYOFF';fnSet_ProgressBar(FALSE);}
CASE 'title':{}
CASE 'count':{sLevel[nLVL].nMaxCountItem = atoi(sMyFB.cFB_VAL);CANCEL_WAIT'SBS_PROGRESS_WAIT_DELAYOFF';fnSet_ProgressBar(FALSE);}
CASE 'exists':
{
if(atoi(sMyFB.cFB_Val))
{
nExists = 1;
if(nExists)
{
fnFB_SendVTMessage(UI_UPDATE_ACTIVE,'Item already in favorites',15);
}
}
else
{
STACK_VAR CHAR cCopyURL[SBS_LEN_ITEM];
nExists = 0;
if(nSBS_Fav_Selected)
{
if(length_string(sSBS.sCurQList[nSBS_Fav_Selected].cURL) && length_string(sSBS.sCurQList[nSBS_Fav_Selected].cTitle))
{
cCopyURL = sSBS.sCurQList[nSBS_Fav_Selected].cURL;
if(find_string(cCopyURL,'file://',1))
{
REMOVE_STRING(cCopyURL,'file://',1);
}
fnQueue_QCmd("'favorites add url:',fnEncodeURL(cCopyURL)(*fnEncodeURL()*),' title:',fnEncodeURL(sSBS.sCurQList[nSBS_Fav_Selected].cTitle)");
nSBS_Fav_Selected = 0;
}
}
else
{
if(length_string(sSBS.sNowPlaying.cURL) && length_string(sSBS.sNowPlaying.cTitle))
{
cCopyURL = sSBS.sCurQList[nSBS_Fav_Selected].cURL;
if(find_string(cCopyURL,'file://',1))
{
REMOVE_STRING(cCopyURL,'file://',1);
}
fnQueue_QCmd("'favorites add url:',fnEncodeURL(cCopyURL)(*fnEncodeURL()*),' title:',fnEncodeURL(sSBS.sNowPlaying.cTitle)");
}
}
}
}
CASE 'add':
{
}
CASE 'index':
{
if(nExists)
{
nExists_Indx = atoi(sMyFB.cFB_Val);
fnFB_SendVTMessage(UI_UPDATE_ACTIVE,"'Item already in favorites, index:',itoa(nExists_Indx +1)",15);
}
else
{
nExists_Indx = 0;
}
}
CASE 'delete':
{
STACK_VAR _sLevelList sZeroList;
sLevelList[nLVL] = sZeroList;
nIndx = atoi(sMyFB.cFB_Val);
fnFB_SendVTMessage(UI_UPDATE_ACTIVE,"'Favorite index:',itoa(nIndx+1),', deleted'",15);
fnQueue_QCmd("'favorites items ',itoa(sLevel[nLVL].nStartItem),' ',itoa(sLevel[nLVL].nCountItem),' want_url:1'");
}
CASE 'changed':{}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'pandora':
{
if(sMyFB.cFB_Val == 'null'){fnFB_SendVTMessage(UI_UPDATE_ACTIVE,sMyFB.cFB_Tag,15);}
else
{
SWITCH(sMyFB.cFB_Tag)
{
CASE 'networkerror': {fnFB_SendVTMessage(UI_UPDATE_ACTIVE,"'Network Error!, ',sMyFB.cFB_Val",15);CANCEL_WAIT'SBS_PROGRESS_WAIT_DELAYOFF';fnSet_ProgressBar(FALSE);}
CASE 'title': {}
CASE 'count': {sLevel[nLVL].nMaxCountItem = atoi(sMyFB.cFB_VAL);fnSet_ProgressBar(FALSE);}//CANCEL_WAIT'SBS_PROGRESS_WAIT_DELAYOFF';
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
//CASE 'jazzfm':
// {
// SWITCH(sMyFB.cFB_Tag)
// {
// CASE 'networkerror': {fnFB_SendVTMessage(UI_UPDATE_ACTIVE,"'Network Error!, ',sMyFB.cFB_Val",15);CANCEL_WAIT'SBS_PROGRESS_WAIT_DELAYOFF';fnSet_ProgressBar(FALSE);}
// CASE 'count': {sLevel[nLVL].nMaxCountItem = atoi(sMyFB.cFB_VAL);fnSet_ProgressBar(FALSE);}
// DEFAULT:
// {
// nRecognized = 0;
// fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
// }
// }
// }
DEFAULT://catch all apps, radios, etc
{
SWITCH(sMyFB.cFB_Tag)
{
CASE 'networkerror': {fnFB_SendVTMessage(UI_UPDATE_ACTIVE,"'Network Error!, ',sMyFB.cFB_Val",15);CANCEL_WAIT'SBS_PROGRESS_WAIT_DELAYOFF';fnSet_ProgressBar(FALSE);}
CASE 'title':{}
CASE 'count':{sLevel[nLVL].nMaxCountItem = atoi(sMyFB.cFB_VAL);CANCEL_WAIT'SBS_PROGRESS_WAIT_DELAYOFF';fnSet_ProgressBar(FALSE);}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
}
CASE 'players':
CASE 'serverstatus':
{
STACK_VAR _sServer sServerClear;
SWITCH(sMyFB.cObjTag)
{
CASE 'serverstatus':
{
if(i==1)
{
sServer = sServerClear;
}
SWITCH(sMyFB.cFB_Tag)
{
CASE 'rescan': {sServer.sStats.nRescan = atoi(sMyFB.cFB_Val);}
CASE 'lastscan': {sServer.sStats.cLastscan = sMyFB.cFB_Val;}
CASE 'lastscanfailed': {sServer.sStats.nLastscanfailed = atoi(sMyFB.cFB_Val);}
CASE 'progressname': {sServer.sStats.cProgressName = sMyFB.cFB_Val;}
CASE 'progressdone': {sServer.sStats.nProgressDone = atoi(sMyFB.cFB_Val);}
CASE 'progresstotal': {sServer.sStats.nProgressTotal = atoi(sMyFB.cFB_Val);}
CASE 'version': {sServer.sStats.cVersion = sMyFB.cFB_Val;}
CASE 'uuid': {sServer.sStats.cUuid = sMyFB.cFB_Val;}
CASE 'info total albums': {sServer.sStats.nInfo_total_albums = atoi(sMyFB.cFB_Val);}
CASE 'info total artists': {sServer.sStats.nInfo_total_artists = atoi(sMyFB.cFB_Val);}
CASE 'info total genres': {sServer.sStats.nInfo_total_genres = atoi(sMyFB.cFB_Val);}
CASE 'info total songs': {sServer.sStats.nInfo_total_songs = atoi(sMyFB.cFB_Val);}
CASE 'player count': {sServer.sStats.nPlayers_Count = atoi(sMyFB.cFB_Val);}
CASE 'sn player count': {sServer.sStats.nSn_Players_Count = atoi(sMyFB.cFB_Val);}
CASE 'other player count': {sServer.sStats.nOther_Players_Count = atoi(sMyFB.cFB_Val);}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'players_loop':
{
//nIndx = sMyFB.nFB_Indx;
SWITCH(sMyFB.cFB_Tag)
{
CASE 'playerid': {sServer.sPlayers[nFBIndx].cPlayer_MAC = LOWER_STRING(sMyFB.cFB_Val);}
CASE 'uuid': {sServer.sPlayers[nFBIndx].cUuid = LOWER_STRING(sMyFB.cFB_Val);}
CASE 'ip': {sServer.sPlayers[nFBIndx].cIP = sMyFB.cFB_Val;}
CASE 'name':
{
sServer.sPlayers[nFBIndx].cName = sMyFB.cFB_Val;
if(sServer.sPlayers[nFBIndx].cPlayer_MAC == sSBS.sPlayer.cStrMAC)
{
sSBS.sStatus.cPlayerName = sMyFB.cFB_Val;
}
}
CASE 'seq_no': {sServer.sPlayers[nFBIndx].nSeq_No = atoi(sMyFB.cFB_Val);}
CASE 'model': {sServer.sPlayers[nFBIndx].cModel = sMyFB.cFB_Val;}
CASE 'displaytype': {sServer.sPlayers[nFBIndx].cDisplayType = sMyFB.cFB_Val;}
CASE 'canpoweroff': {sServer.sPlayers[nFBIndx].nCanPowerOff = atoi(sMyFB.cFB_Val);}
CASE 'connected': {sServer.sPlayers[nFBIndx].nConnected = atoi(sMyFB.cFB_Val);}
CASE 'isplayer': {sServer.sPlayers[nFBIndx].nIsplayer = atoi(sMyFB.cFB_Val);}
CASE 'power': {sServer.sPlayers[nFBIndx].nPower = atoi(sMyFB.cFB_Val);}
CASE 'player_needs_upgrade': {sServer.sPlayers[nFBIndx].nPlayer_needs_upgrade = atoi(sMyFB.cFB_Val);}
CASE 'player_is_upgrading': {sServer.sPlayers[nFBIndx].nPlayer_is_upgrading = atoi(sMyFB.cFB_Val);}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'playlist':
{
SWITCH(sMyFB.cFB_Tag)
{
CASE 'shuffle' :{sSBS.sStatus.nPlylistShuffle = atoi(sMyFB.cFB_VAL);}//fnFB_Shuffle(UI_UPDATE_ACTIVE,NOFORCE);
CASE 'repeat' :{sSBS.sStatus.nPlylistRepeat = atoi(sMyFB.cFB_VAL);}//fnFB_Repeat(UI_UPDATE_ACTIVE,NOFORCE);
CASE 'rew' :{}
CASE 'fwd' :{}
CASE 'buttons' :{}//subobj includes shuffle, repeat, take all and process seperately
CASE 'jiveStyle' :{}
CASE 'command' :{}
CASE 'remote' :{}
CASE 'url' :{sSBS.sNowPlaying.cURL = sMyFB.cFB_VAL;}
CASE 'duration' :{}
CASE 'artist' :{}
CASE 'album' :{}
//CASE 'playlist_index':{}
CASE 'playlist index' :{}
CASE 'id' :{}
CASE 'title' :{sSBS.sNowPlaying.cTitle = fnStrReplace(sMyFB.cFB_VAL,'|',' * ');}
CASE '_title' :{sSBS.sNowPlaying.cTitle = fnStrReplace(sMyFB.cFB_VAL,'|',' * ');}//sSongInfo.cTitle = sSBS.sNowPlaying.cTitle;}
CASE '_path':
{
if(sMyFB.cFB_VAL != '?')
{
sSBS.sNowPlaying.cURL = sMyFB.cFB_VAL;
//fnGet_SongInfo(sSBS.sNowPlaying.cURL,'');
}
}
CASE '_index':
{
if(fnIsNumber(sMyFB.cFB_VAL[1]))
{
if(!sSBS.sStatus.nPlylistTracks)
{
//fnGet_PlaylistTracks();
sSBS.sStatus.nPlylistCurIndx = 0;
}
else
{
sSBS.sStatus.nPlylistCurIndx = (atoi(sMyFB.cFB_VAL) + 1);
//fnQueue_QCmd("fnGet_PlayerMAC(),' playlist path ',sMyFB.cFB_VAL,' ?'");
}
//fnFB_DoSend_UI_CMD(UI_UPDATE_ACTIVE,"'^SHO-',itoa(SBS_BTN_ZAP_IT),',1'");
}
else if(sMyFB.cFB_VAL != '?')//if echo don't respond with the same thing
{
//fnQueue_QCmd("fnGet_PlayerMAC(),' playlist path ?'");
}
}
CASE '_duration':
{
if(fnIsNumber(sParam.cParam[3][1]) && sParam.cParam[2] == 'duration' && sParam.cParam[1] == 'playlist')
{
STACK_VAR LONG nRxIndx;
nRxIndx = atoi(sParam.cParam[3]);
if(sSBS.sCurQ.nTrackCounter)
{
if(nRxIndx == (sSBS.sCurQ.nTrackCounter))//this is the one we just queried
{
if(sSBS.sCurQ.nAddorDelete == SBS_DEL_TRKS)//delete
{
sSBS.sCurQ.nTotalDuration = (sSBS.sCurQ.nTotalDuration - atof(sMyFB.cFB_VAL));
}
else //0 or 1 = add
{
sSBS.sCurQ.nTotalDuration = (sSBS.sCurQ.nTotalDuration + atof(sMyFB.cFB_VAL));
}
}
else
{
fnJSON_Debug("'Process_FB, TRACKS ERROR! RX TRK-[ ',itoa(nRxIndx),' ] BUT REQUESTED TRK-[ ',itoa(sSBS.sCurQ.nTrackCounter),' ] :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRxIndx == sSBS.sNowPlaying.nIndx )
{
sSBS.sNowPlaying.nDuration = atoi(sMyFB.cFB_VAL);
}
}
}
CASE '_tracks':
{
if(fnIsNumber(sMyFB.cFB_VAL[1]))
{
sSBS.sStatus.nPlyListTracks = atoi(sMyFB.cFB_VAL);
if(!sSBS.sStatus.nPlyListTracks && sSBS.sStatus.nPlyListTracks)
{//also performed in playlistcontrol cmd:add or delete
fnBtn_DoCommand(SBS_PlayMode_Play);
}
if(sSBS.sStatus.nPlyListTracks)
{
//fnGet_PlaylistIndex();
}
else
{
fnPlayer_ClearPlyList();
//sSBS.sStatus.nPlylistCurIndx = 0;
}
if(sSBS.sCurQ.nTrackCount < sSBS.sStatus.nPlyListTracks)
{
//CANCEL_WAIT 'GET_TOTAL_TIME';
// WAIT 100 'GET_TOTAL_TIME'
// {
// fnJSON_Debug("'Process_FB, TRACKS initiating fnGet_TotalPlayTime(',itoa(sSBS.sStatus.nPlyListTracks),') :DEBUG<',ITOA(__LINE__),'>'",1);
// fnGet_TotalPlayTime(sSBS.sStatus.nPlyListTracks,SBS_ADD_TRKS,TYPE_CAST(sSBS.sStatus.nPlyListTracks - sSBS.sCurQ.nTrackCount));
// }
}
else
{
sSBS.sCurQ.nTrackCount = sSBS.sStatus.nPlyListTracks;
}
fnFB_CurPlyListIndx(UI_UPDATE_ACTIVE,NOFORCE);
}
}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'data':
CASE 'status':
{
SWITCH(sMyFB.cObjTag)
{
CASE 'command':
{
SWITCH(sMyFB.cFB_Tag)
{
CASE 'icon'://"pandora","rate",1 or 0
{
SWITCH(sObj[sMyFB.nOrigIndx].cTag)
{
CASE 'repeat':
{
sSBS.sNowPlaying.cBtnRepeatCmdIcon = sMyFB.cFB_Val;
if(sSBS.sStatus.nPlylistRepeat){fnBtn_DoCommand(SBS_BTN_PLYLST_REPEAT_0);}
//fnFB_Repeat(UI_UPDATE_ACTIVE,NOFORCE);
}
CASE 'shuffle':
{
sSBS.sNowPlaying.cBtnShuffleCmdIcon = sMyFB.cFB_Val;
if(sSBS.sStatus.nPlylistShuffle){fnBtn_DoCommand(SBS_BTN_PLYLST_SHUFFLE_0);}
//fnFB_Shuffle(UI_UPDATE_ACTIVE,NOFORCE);
}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'buttons':
{
SWITCH(sMyFB.cFB_Tag)
{
CASE 'fwd':{sSBS.sNowPlaying.nBtnFFwd = atoi(sMyFB.cFB_Val);}//1 is available, 0 is not available for use
CASE 'rew':{sSBS.sNowPlaying.nBtnRew = atoi(sMyFB.cFB_Val);}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'repeat'://thumbsup on pandora
{
SWITCH(sMyFB.cFB_Tag)
{
CASE 'icon': {sSBS.sNowPlaying.cBtnRepeatIcon = sMyFB.cFB_Val;}
CASE 'jiveStyle': {sSBS.sNowPlaying.cBtnRepeatJiveStyle = sMyFB.cFB_Val;fnFB_Repeat(UI_UPDATE_ACTIVE,NOFORCE);}//tumbsup
CASE 'tooltip': {sSBS.sNowPlaying.cBtnRepeatToolTip = sMyFB.cFB_Val;}//I like this song in pandora
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'shuffle'://tumbsdown on pandora
{
SWITCH(sMyFB.cFB_Tag)
{
CASE 'icon': {sSBS.sNowPlaying.cBtnShuffleIcon = sMyFB.cFB_Val;}
CASE 'jiveStyle': {sSBS.sNowPlaying.cBtnShuffleJiveStyle = sMyFB.cFB_Val;fnFB_Shuffle(UI_UPDATE_ACTIVE,NOFORCE);}//tumbsdown
CASE 'tooltip': {sSBS.sNowPlaying.cBtnShuffleToolTip = sMyFB.cFB_Val;}//I don't like this song in pandora
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'data':
CASE 'status':
{
if(i==1)// && sMyFB.cObjTag == 'status')
{
STACK_VAR _sStatusInfo sStatusClear; // Status block to receive current status 1427637377.0878
sSBS.sStatus = sStatusClear;
}
SWITCH(sMyFB.cFB_Tag)
{
CASE 'player_ip': {sSBS.sStatus.cPlayerIP = sMyFB.cFB_Val;}
CASE 'play time': {sSBS.sStatus.cPlayTime = sMyFB.cFB_Val;}
CASE 'id': {sSBS.sStatus.cItem_ID = sMyFB.cFB_Val;}
CASE 'can_seek': {sSBS.sStatus.cCanSeek = sMyFB.cFB_Val;}
CASE 'playlist_timestamp': {sSBS.sStatus.cPL_TmStamp = sMyFB.cFB_Val;}
CASE 'playlist mode': {sSBS.sStatus.cPL_Mode = sMyFB.cFB_Val;}
CASE 'seq_no': {sSBS.sStatus.cSeqNo = sMyFB.cFB_Val;}
CASE 'title': {sSBS.sNowPlaying.cTitle = fnStrReplace(sMyFB.cFB_Val,'|',' * ');}
CASE 'genre': {sSBS.sNowPlaying.cGenre = sMyFB.cFB_Val;}
CASE 'artist': {sSBS.sNowPlaying.cArtist = sMyFB.cFB_Val;}
CASE 'album': {sSBS.sNowPlaying.cAlbum = sMyFB.cFB_Val;}
CASE 'current_title': {sSBS.sNowPlaying.cCurrentTitle = fnStrReplace(sMyFB.cFB_Val,'|',' * ');}
CASE 'player_name': {sSBS.sStatus.cPlayerName = sMyFB.cFB_Val;}
CASE 'player_connected': {sSBS.sStatus.nPlayer_Connected = atoi(sMyFB.cFB_Val);}
CASE 'power': {sSBS.sStatus.nPower = atoi(sMyFB.cFB_Val);sSBS.sPlayer.nPort = sSBS.sStatus.nPower;}
CASE 'signalstrength': {sSBS.sStatus.nSignalStrength = atoi(sMyFB.cFB_Val);}
CASE 'rescan': {fnSBS_SetRescan(atoi(sMyFB.cFB_Val));}
CASE 'mode':
{
SWITCH(sMyFB.cFB_Val)
{
CASE 'play': {sSBS.sStatus.nMode = SBS_PlayMode_Play;fnPlayer_Play();}
CASE 'pause': {sSBS.sStatus.nMode = SBS_PlayMode_Pause;fnPlayer_Pause();}
CASE 'stop': {sSBS.sStatus.nMode = SBS_PlayMode_Stop;fnPlayer_Stop();}
CASE 'off': {sSBS.sStatus.nMode = SBS_PlayMode_Off;fnPlayer_Stop();}
DEFAULT:
{
sSBS.sStatus.nMode = SBS_PlayMode_Unknown;
fnPlayer_Stop();
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'artwork_url': {sSBS.sNowPlaying.cArtworkURL = sMyFB.cFB_Val;}
CASE 'rate': {sSBS.sStatus.nRate = atol(sMyFB.cFB_Val);}
CASE 'time': {sSBS.sSongTime.nSongTime = atoi(sMyFB.cFB_Val);}
CASE 'duration': {sSBS.sNowPlaying.nDuration = atoi(sMyFB.cFB_Val);}
CASE 'sleep': {sSBS.sStatus.nSleepTime = atoi(sMyFB.cFB_Val);}
CASE 'will_sleep_in': {sSBS.sStatus.nSleepRemaining = atoi(sMyFB.cFB_Val);}
CASE 'mixer volume':
{
STACK_VAR FLOAT volume;
sSBS.sStatus.nMixVolume = atoi(sMyFB.cFB_Val);
// Convert to I/R scale as well (as shown on Squeezebox display)
volume = atof(sMyFB.cFB_Val);
volume = (volume + 0.1) / 2.5;
sSBS.sStatus.nIRVolume = type_cast(volume);
}
CASE 'mixer balance': {sSBS.sStatus.nMixBalance = atoi(sMyFB.cFB_Val);}
CASE 'mixer bass': {sSBS.sStatus.nMixBass = atoi(sMyFB.cFB_Val);}
CASE 'mixer treble': {sSBS.sStatus.nMixTreble = atoi(sMyFB.cFB_Val);}
CASE 'mixer pitch': {sSBS.sStatus.nMixPitch = atoi(sMyFB.cFB_Val);}
CASE 'playlist repeat': {sSBS.sStatus.nPlylistRepeat = atoi(sMyFB.cFB_Val);}//fnFB_Repeat(UI_UPDATE_ACTIVE,NOFORCE);
CASE 'playlist shuffle': {sSBS.sStatus.nPlylistShuffle = atoi(sMyFB.cFB_Val);}//fnFB_Shuffle(UI_UPDATE_ACTIVE,NOFORCE);
CASE 'remote': {sSBS.sNowPlaying.nRemote = atoi(sMyFB.cFB_Val);}
CASE 'remote_title': {sSBS.sNowPlaying.cRemoteTitle = fnStrReplace(sMyFB.cFB_Val,'|',' * ');}
CASE 'remoteMeta': {sSBS.sStatus.cRemoteMeta = sMyFB.cFB_Val;}
CASE 'playlist_cur_index': {sSBS.sStatus.nPlylistCurIndx = atoi(sMyFB.cFB_Val)+1;}
//fnQueue_QCmd("fnGet_PlayerMAC(),'playlist path ',sMyFB.cFB_Val,' ?'");
//Zero based
//myCurQ.nPlylistCurIndx = sStatus.nPlylistCurIndx;
CASE 'playlist_tracks':
{
sSBS.sStatus.nPlylistTracks = atoi(sMyFB.cFB_Val);
if(!sSBS.sStatus.nPlylistTracks)
{
sSBS.sStatus.nPlylistCurIndx = 0;
}
//sSBS.sCurQ.nPlylistTracks = sStatus.nPlylistTracks;
if(sSBS.sCurQ.nTrackCount < sSBS.sStatus.nPlyListTracks)
{
CANCEL_WAIT 'GET_TOTAL_TIME';
WAIT 100 'GET_TOTAL_TIME'
{
//fnDevMod_DeBug("'Parse_Playlist: TRACKS initiating fnGet_TotalPlayTime(',itoa(sSBS.sStatus.nPlyListTracks),') :DEBUG<',ITOA(__LINE__),'>'",2);
//recent fnGet_TotalPlayTime(sSBS.sStatus.nPlyListTracks,SBS_ADD_TRKS,TYPE_CAST(sSBS.sStatus.nPlyListTracks - sSBS.sCurQ.nTrackCount));
}
}
}
CASE 'waitingToPlay':
{
//what to do with this????????????
}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'playlist_loop':
{
if(i==1 && sMyFB.cTopTag == 'status')
{
STACK_VAR _sCurQList sCurQListClear[MAX_NUM_BROWSE_LINES];
sSBS.sCurQList = sCurQListClear;
if(!nFBIndx){nFBIndx=1;}
}
else if(i==1 && sMyFB.cTopTag == 'data')
{
STACK_VAR _sNowPlaying sNowPlayingClear;
sSBS.sNowPlaying = sNowPlayingClear;
if(!nFBIndx){nFBIndx=1;}
}
SWITCH(sMyFB.cFB_Tag)
{
CASE 'playlist index':
{
if(sMyFB.cTopTag == 'status')
{
if(sSBS.sCurQList[nFBIndx].nIndx){nFBIndx++;}
sSBS.sCurQList[nFBIndx].nIndx = (atoi(sMyFB.cFB_Val)+1);
if(nFBIndx == 1){sSBS.sCurQ.nStartQItem = sSBS.sCurQList[nFBIndx].nIndx;}
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.nIndx = (atoi(sMyFB.cFB_Val)+1);
}
}
CASE 'id':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cItem_ID)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cItem_ID = sMyFB.cFB_Val;
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cItem_ID = sMyFB.cFB_Val;
}
}
CASE 'coverid':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cCoverID)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cCoverID = sMyFB.cFB_Val;
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cCoverID = sMyFB.cFB_Val;
}
}
CASE 'url':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cURL)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cURL = sMyFB.cFB_Val;
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cURL = sMyFB.cFB_Val;
nFBS = find_string(sMyFB.cFB_Val,"':'",1);
if(nFBS) //just want file or app name
{
sSBS.sNowPlaying.cSource = LEFT_STRING(sMyFB.cFB_Val,nFBS-1);
}
}
}
CASE 'type':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cType)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cType = sMyFB.cFB_Val;
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cType = sMyFB.cFB_Val;
}
}
CASE 'tracknum':
{
if(sMyFB.cTopTag == 'status')
{
if(sSBS.sCurQList[nFBIndx].nTrackNum){nFBIndx++;}
sSBS.sCurQList[nFBIndx].nTrackNum = atoi(sMyFB.cFB_Val);
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.nTrackNum = atoi(sMyFB.cFB_Val);
}
}
CASE 'artwork_url':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cArtworkURL)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cArtworkURL = sMyFB.cFB_Val;
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cArtworkURL = sMyFB.cFB_Val;
//will need to further parse out leading junk to use this
//nFBS = find_string(sMyFB.cFB_Val,"':'",1);
// if(nFBS) //just want file or app name
// {
// sSBS.sNowPlaying.cSource = LEFT_STRING(sMyFB.cFB_Val,nFBS-1);
// }
}
}
CASE 'year':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cYear)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cYear = sMyFB.cFB_Val;
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cYear = sMyFB.cFB_Val;
}
}
CASE 'genre':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cGenre)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cGenre = sMyFB.cFB_Val;
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cGenre = sMyFB.cFB_Val;
}
}
CASE 'artist':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cArtist)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cArtist = sMyFB.cFB_Val;
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cArtist = sMyFB.cFB_Val;
}
}
CASE 'album':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cAlbum)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cAlbum = sMyFB.cFB_Val;
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cAlbum = sMyFB.cFB_Val;
}
}
CASE 'title':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cTitle)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cTitle = fnStrReplace(sMyFB.cFB_Val,'|',' * ');
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cTitle = fnStrReplace(sMyFB.cFB_Val,'|',' * ');
}
}
CASE 'duration':
{
if(sMyFB.cTopTag == 'status')
{
if(sSBS.sCurQList[nFBIndx].nDuration){nFBIndx++;}
sSBS.sCurQList[nFBIndx].nDuration = atoi(sMyFB.cFB_Val);
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.nDuration = atoi(sMyFB.cFB_Val);
}
}
CASE 'remote':
{
if(sMyFB.cTopTag == 'status')
{
if(sSBS.sCurQList[nFBIndx].nRemote){nFBIndx++;}
sSBS.sCurQList[nFBIndx].nRemote = atoi(sMyFB.cFB_Val);
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.nRemote = atoi(sMyFB.cFB_Val);
}
}
CASE 'remote_title':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cRemoteTitle)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cRemoteTitle = fnStrReplace(sMyFB.cFB_Val,'|',' * ');
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cRemoteTitle = fnStrReplace(sMyFB.cFB_Val,'|',' * ');
}
}
CASE 'replay_gain':
{
if(sMyFB.cTopTag == 'status')
{
if(length_string(sSBS.sCurQList[nFBIndx].cReplayGain)){nFBIndx++;}
sSBS.sCurQList[nFBIndx].cReplayGain = sMyFB.cFB_Val;
}
else if(sMyFB.cTopTag == 'data')
{
sSBS.sNowPlaying.cReplayGain = sMyFB.cFB_Val;
}
}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'remoteMeta':
{
SWITCH(sMyFB.cFB_Tag)
{
CASE 'id': {sSBS.sNowPlaying.cItem_ID = sMyFB.cFB_Val;}
CASE 'title': {sSBS.sNowPlaying.cTitle = fnStrReplace(sMyFB.cFB_Val,'|',' * ');}
CASE 'artist': {sSBS.sNowPlaying.cArtist = sMyFB.cFB_Val;}
CASE 'duration': {sSBS.sNowPlaying.nDuration = atoi(sMyFB.cFB_Val);}
CASE 'artwork_url':
{
sSBS.sNowPlaying.cArtworkURL = sMyFB.cFB_Val;
nFBS = find_string(sMyFB.cFB_Val,"':'",1);
//if(nFBS) //just want file or app name
// {
// sSBS.sNowPlaying.cSource = LEFT_STRING(sMyFB.cFB_Val,nFBS-1);
// }
}
CASE 'album': {sSBS.sNowPlaying.cAlbum = sMyFB.cFB_Val;}
CASE 'type': {sSBS.sNowPlaying.cType = sMyFB.cFB_Val;}
CASE 'url':
{
sSBS.sNowPlaying.cURL = sMyFB.cFB_Val;
nFBS = find_string(sMyFB.cFB_Val,"':'",1);
if(nFBS) //just want file or app name
{
sSBS.sNowPlaying.cSource = LEFT_STRING(sMyFB.cFB_Val,nFBS-1);
}
}
CASE 'remote': {sSBS.sNowPlaying.nRemote = sMyFB.cFB_Val;}
CASE 'year': {sSBS.sNowPlaying.cYear = sMyFB.cFB_Val;}
CASE 'replay_gain': {sSBS.sNowPlaying.cReplayGain = sMyFB.cFB_Val;}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
}
DEFAULT:
{
nRecognized = 0;
fnJSON_Debug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",1);
}
}
if(nRecognized)
{
fnJSON_Debug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX- :DEBUG<',ITOA(__LINE__),'>'",3);
nRecognized = 0;
}
}
CASE 'songinfo':
{
//STACK_VAR _sNowPlaying myNowPlaying;
//STACK_VAR INTEGER nNowPlaying;
SWITCH(sMyFB.cFB_Tag)
{
CASE 'album' :{sSongInfo.cAlbum = sMyFB.cFB_VAL;}
CASE 'album_id' :{sSongInfo.cAlbum_ID = sMyFB.cFB_VAL;}
CASE 'artist' :{sSongInfo.cArtist = sMyFB.cFB_VAL;}
CASE 'artist_id' :{sSongInfo.cArtist_ID = sMyFB.cFB_VAL;}
CASE 'genre' :{sSongInfo.cGenre = sMyFB.cFB_VAL;}
CASE 'genre_id' :{sSongInfo.cGenre_ID = sMyFB.cFB_VAL;}
//CASE 'cmd' :{sSongInfo.cCMD = atoi(sMyFB.cFB_VAL);}
CASE 'artwork_url' :{sSongInfo.cArtworkURL = sMyFB.cFB_VAL;}
CASE 'count' :{sSongInfo.nCount = atoi(sMyFB.cFB_VAL);}
CASE 'cover_id' :{sSongInfo.cCoverID = sMyFB.cFB_VAL;}
CASE 'title' :{sSongInfo.cTitle = fnStrReplace(sMyFB.cFB_VAL,'|',' * ');}
CASE 'id' :{sSongInfo.cItem_ID = sMyFB.cFB_VAL;}
CASE 'disc' :{sSongInfo.nDisc = atoi(sMyFB.cFB_VAL);}
CASE 'disccount' :{sSongInfo.nDiscCount = atoi(sMyFB.cFB_VAL);}
CASE 'tagversion' :{sSongInfo.cTagVersion = sMyFB.cFB_VAL;}
CASE 'filesize' :{sSongInfo.cFileSize = sMyFB.cFB_VAL;}
CASE 'coverart' :{sSongInfo.nCoverArtAvail = atoi(sMyFB.cFB_VAL);}
CASE 'replay_gain' :{sSongInfo.cReplayGain = sMyFB.cFB_VAL;}
CASE 'compilation' :{sSongInfo.nCompilation = atoi(sMyFB.cFB_VAL);}
CASE 'samplerate' :{sSongInfo.cSampleRate = sMyFB.cFB_VAL;}
CASE 'samplesize' :{sSongInfo.cSampleSize = sMyFB.cFB_VAL;}
CASE 'rating' :{sSongInfo.cRating = sMyFB.cFB_VAL;}
CASE 'bpm' :{sSongInfo.nBPM = atoi(sMyFB.cFB_VAL);}
CASE 'type' :{sSongInfo.cType = sMyFB.cFB_VAL;}
CASE 'duration' :{sSongInfo.nDuration = atoi(sMyFB.cFB_VAL);}
CASE 'tracknum' :{sSongInfo.nTrackNum = atoi(sMyFB.cFB_VAL);}
CASE 'bitrate' :{sSongInfo.cBitRate = sMyFB.cFB_VAL;}
CASE 'year' :{sSongInfo.cYear = sMyFB.cFB_VAL;}
CASE 'remote' :{sSongInfo.nRemote = atoi(sMyFB.cFB_VAL);}
CASE 'remote_title' :{sSongInfo.cRemoteTitle = fnStrReplace(sMyFB.cFB_VAL,'|',' * ');}
CASE 'url' :
{
sSongInfo.cURL = sMyFB.cFB_VAL;
nFBS = find_string(sSongInfo.cURL,"':'",1);
if(nFBS)
{
sSongInfo.cSource = LEFT_STRING(sSongInfo.cURL,nFBS-1);
if(sSongInfo.cSource = 'http')
{
sSongInfo.cSource = 'Internet Radio';
}
else if(sSongInfo.cSource = 'file')
{
sSongInfo.cSource = 'Hard Drive';
}
}
}
CASE 'track_id' :{sSongInfo.cItem_ID = sMyFB.cFB_VAL;}
CASE 'album_replay_gain' :{sSongInfo.cAlbum = sMyFB.cFB_VAL;}
CASE 'modificationTime' :{sSongInfo.cAlbum = sMyFB.cFB_VAL;}