SageTV Community  

Go Back   SageTV Community > SageTV BETA Release Products > SageTV Beta Test Software
Forum Rules FAQs Community Downloads Today's Posts Search

Notices

SageTV Beta Test Software Discussion related to BETA Releases of the SageTV application produced by SageTV. Questions, issues, problems, suggestions, etc. regarding SageTV Beta Releases should be posted here.

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 07-06-2010, 10:41 PM
shadeblue.com's Avatar
shadeblue.com shadeblue.com is offline
Sage Aficionado
 
Join Date: Jun 2008
Posts: 435
Question SageTV V7 - API: FindWidgetBySymbol on remote UI context

Hello, I am working on the InfoPopup/Caller ID plugin for SageTV V7 and have run into an issue that I need a little help with.

The release notes for Version 7.0.10 included this little GEM:

1. Added support for using SageTVClient context names to execute API calls on a SageTVClient from the SageTV server. The sage.SageTV.apiUI() call is used to do this; and the context names can be retrieved using the API call GetConnectedClients().


Using this new feature, my goal is to be able to send the popup instructions to SageTV clients and the local instance of SageTV UI running on a server where SageTV is running as a service.

I was able to successfully get a UI Context for the remote connected client using the GetConnectedClients() call. On my system it returns this value "/127.0.0.1:64556".

Next, I need to find a widget by ID and then execute the widget chain on this remote UI context. Here is a snippet of the current code. (This logic is currently working for HD Extenders, just not the remote UI context)

Code:
// find shadeBlue-InfoPopup dialog widget in SageTV            
String ui = "/127.0.0.1:64556";
Object widget1 = sage.SageTV.apiUI(ui, "FindWidgetBySymbol", new Object[] {"SBINFOPOPUP-START"});

if(widget1 == null)
{
    // debug
    logger.warn("WIDGET '"+configuration.getWidgetID()+"' NOT FOUND IN UI CONTEXT : "+ui);
    logger.warn("Unable to deliver YAC message to UI context: "+ui);
}
else
{
    // invoke shadeBlue-InfoPopup dialog widgets in SageTV
    sage.SageTV.apiUI(ui, "ExecuteWidgetChain", new Object[] {widget1});
}
(Technically speaking the ui context is not hard coded as shown here, but rather obtained dynamically at runtime using the "GetConnectedClients()" call. I illustrated it here as fixed, because I did not want to over complicate the example.)

The following failure info text is returned in the log file:

Code:
INFO - YAC caller ID message received: Caller=YAC Test Call / Number=(425) 555-1212 / Image=telephone.png
INFO - creating SageTV API and Global objects...
INFO - updating InfoPopup global context variables...
INFO - querying SageTV for list of UI contexts...
INFO - Processing message for SageTV UI context: /127.0.0.1:65220
INFO - Sending message 'Incoming Caller:
 
YAC Test Call
(425) 555-1212
 
' to SageTV UI context: /127.0.0.1:65220
WARN - WIDGET 'SBINFOPOPUP-START' NOT FOUND IN UI CONTEXT : /127.0.0.1:65220
WARN - Unable to deliver YAC message to UI context: /127.0.0.1:65220
So the "FindWidgetBySymbol" does not seem to be working when attempting to call this on a remote connected UI Context? I did open the STV on the running local client instance and it does contain the Widget ID. In fact, if I shut down the SageTV service and disable the service and run SageTV standalone (not as a service) then this code works fine.

Please help .. I'm stuck :-)
Thanks - SB
__________________
Server Hardware: Intel Core 2 Quad Q6700 2.66GHz CPU, 4GB DDR2 RAM, NVIDIA nForce 780i SLI Motherboard, GeForce 8600 GT, Seagate Barracuda 7200.11 2.5TB
Operating System: Windows XP Professional
HTPC/DVR Software: SageTV 7
Capture Devices: 2 @ Hauppauge HD-PVR (1212), Hauppauge WinTV-HVR-1600 ATSC/QAM, HD Homerun
Media Extenders: 2 @ Sage HD100 & 1 @ Sage HD200
Signals/Providers: AT&T UVerse, OTA ATSC
Set-Top-Box: 2 @ Motorola Box VIP 1200

Last edited by shadeblue.com; 07-07-2010 at 09:20 AM.
Reply With Quote
  #2  
Old 07-07-2010, 01:28 AM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
My guess is that not all object types are serialized correctly across remote API calls. Things like MediaFiles and Airings are, since the client needs to access those anyway. But there's no precedent for accessing remote widgets, so that's probably what's biting you. The call is executing correctly on the remote client (I'm guessing), but the returned widget is not making it back across the wire intact. Not sure if that counts as a bug or a known design limitation. There may just be too many interconnections between Widget objects to make serialization practical.
__________________
-- Greg
Reply With Quote
  #3  
Old 07-07-2010, 04:44 AM
tmiranda's Avatar
tmiranda tmiranda is offline
SageTVaholic
 
Join Date: Jul 2005
Location: Central Florida, USA
Posts: 5,851
Odd timing. I actually tried serializing an Airing last night and from what I can tell they are not serializable at all. (Of course I'm a java noob so I may have been doing something wrong.)
__________________

Sage Server: 8th gen Intel based system w/32GB RAM running Ubuntu Linux, HDHomeRun Prime with cable card for recording. Runs headless. Accessed via RD when necessary. Four HD-300 Extenders.
Reply With Quote
  #4  
Old 07-07-2010, 06:05 AM
stuckless's Avatar
stuckless stuckless is offline
SageTVaholic
 
Join Date: Oct 2007
Location: London, Ontario, Canada
Posts: 9,713
It's been my experience that not many, if any, of the native sage objects are java serializable. That's part of the reason why I ended up writing my sagex-apis, that support access to sage remote objects without needing them to be java serializable. (although is used primarily for testing purposes)

What is interesting about your situation is that your code works when running the sagetv client stand-alone, but not when it's running as a service. I don't know enough about SageTV and Windows to be helpful, but that would seem to me that this is not really a serialization issue, since why would the serialization fail simply because of how you ran the executable?
Reply With Quote
  #5  
Old 07-07-2010, 08:05 AM
shadeblue.com's Avatar
shadeblue.com shadeblue.com is offline
Sage Aficionado
 
Join Date: Jun 2008
Posts: 435
Quote:
Originally Posted by stuckless View Post
It's been my experience that not many, if any, of the native sage objects are java serializable. That's part of the reason why I ended up writing my sagex-apis, that support access to sage remote objects without needing them to be java serializable. (although is used primarily for testing purposes)

What is interesting about your situation is that your code works when running the sagetv client stand-alone, but not when it's running as a service. I don't know enough about SageTV and Windows to be helpful, but that would seem to me that this is not really a serialization issue, since why would the serialization fail simply because of how you ran the executable?
There is one main difference between when I run it standalone versus running it as as local client connecting to a SageTV service that I was not very clear on. In the standalone mode, the UI context is obtained via the call to SageApi.Api("GetUIContextNames") whereas when running as local instance connecting to SageTV service, the UI context is obtained via SageApi.Api("GetConnectedClients").

The UI context is also a different value either "SAGETV_PROCESS_LOCAL_UI" when running standalone or something like "/127.0.0.1:64556" when running as a service.


Quote:
protected String[] GetUIContextNames() {
// support backward compatibility for Sage 2.2
String[] UiContexts = new String[] {};
String[] localUiContexts = new String[] {};
String[] remoteUiContexts = new String[] {};
try
{
// 4.1
localUiContexts = (String[]) SageApi.Api("GetUIContextNames");
remoteUiContexts = (String[]) SageApi.Api("GetConnectedClients");

// combine arrays
UiContexts = new String[localUiContexts.length + remoteUiContexts.length];
System.arraycopy(localUiContexts, 0, UiContexts, 0, localUiContexts.length);
System.arraycopy(remoteUiContexts, 0, UiContexts, localUiContexts.length, remoteUiContexts.length);

} catch (InvocationTargetException e) {
// 4.1 API failed, try 2.2 API
try {
Object[] widgets = (Object[]) SageApi.Api("GetAllWidgets");
if (SageApi.Size(widgets) > 0) {
UiContexts = new String[] { LOCAL_UI_CONTEXT };
}
} catch (InvocationTargetException e2) {
// 2.2 API failed - no UI contexts
}
}
return UiContexts;
}
__________________
Server Hardware: Intel Core 2 Quad Q6700 2.66GHz CPU, 4GB DDR2 RAM, NVIDIA nForce 780i SLI Motherboard, GeForce 8600 GT, Seagate Barracuda 7200.11 2.5TB
Operating System: Windows XP Professional
HTPC/DVR Software: SageTV 7
Capture Devices: 2 @ Hauppauge HD-PVR (1212), Hauppauge WinTV-HVR-1600 ATSC/QAM, HD Homerun
Media Extenders: 2 @ Sage HD100 & 1 @ Sage HD200
Signals/Providers: AT&T UVerse, OTA ATSC
Set-Top-Box: 2 @ Motorola Box VIP 1200
Reply With Quote
  #6  
Old 07-07-2010, 08:09 AM
shadeblue.com's Avatar
shadeblue.com shadeblue.com is offline
Sage Aficionado
 
Join Date: Jun 2008
Posts: 435
If only there were a "ExecuteWidgetChainBySymbol" API method that would accept the widget ID as a parameter, then I would not need to perform the find call and marshall objects back and forth .....
__________________
Server Hardware: Intel Core 2 Quad Q6700 2.66GHz CPU, 4GB DDR2 RAM, NVIDIA nForce 780i SLI Motherboard, GeForce 8600 GT, Seagate Barracuda 7200.11 2.5TB
Operating System: Windows XP Professional
HTPC/DVR Software: SageTV 7
Capture Devices: 2 @ Hauppauge HD-PVR (1212), Hauppauge WinTV-HVR-1600 ATSC/QAM, HD Homerun
Media Extenders: 2 @ Sage HD100 & 1 @ Sage HD200
Signals/Providers: AT&T UVerse, OTA ATSC
Set-Top-Box: 2 @ Motorola Box VIP 1200
Reply With Quote
  #7  
Old 07-07-2010, 10:30 AM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
Quote:
Originally Posted by tmiranda View Post
I actually tried serializing an Airing last night and from what I can tell they are not serializable at all.
Quote:
Originally Posted by stuckless View Post
It's been my experience that not many, if any, of the native sage objects are java serializable.
I'm not talking about Java serialization; I'm talking about whatever serialization the Sage core does internally to make Wiz.bin accessible from SageTV Client. Clearly it's doing something since you can call methods in the MediaFileAPI, AiringAPI, FavoriteAPI, etc from SageTV Client and get sensible answers. However I surmise that WidgetAPI does not work since up to now there's been no requirement for remote WidgetAPI calls, so no support exists in the core to serialize Widget objects properly.
__________________
-- Greg
Reply With Quote
  #8  
Old 07-07-2010, 12:01 PM
Narflex's Avatar
Narflex Narflex is offline
Sage
 
Join Date: Feb 2003
Location: Redondo Beach, CA
Posts: 6,349
Greg hit this one on the head. The protocol used for passing objects between the client & the server does NOT use Java based serialization. It uses its own protocol that supports a limited number of object types. This was never an issue previously; because any method that was remoted to a server automatically only used objects of a supported type. But now that you can call arbitrary methods on a client...not all of those methods will be able to pass values correctly.

We do not plan on extending the protocol so that all methods work remotely since many use Collections and other items that can store arbitrary Java objects; some of which may not be java.io.Serializable and they may also use SageTV DB objects which need to be passed by ID and are not compatible with java.io.Serializable. However, we can add support for more object types as needed in order to assist developers with specific problems.

For this issue; we just made an update so that any of the Widget API methods that take a 'Widget' as a parameter will also accept a symbol. And in that case, the symbol will be looked up and converted to a Widget. We also added support for converting a Widget to a symbol automatically when it's sent over the protocol. This means the client will send the Widget symbol back to the server for the OP's API call of "FindWidgetBySymbol". You'd then be able to use that same result in a remote call to "ExecuteWidgetChain" since the client would then automatically convert that symbol string back into a Widget. The server would never actually get a Widget object in this case.

This update should actually allow full usage of the Widget API in a remote context (at least I *think* so).

There was another bug that came up; which is that in the current implementation of servers executing API calls on clients, the local UI context was never set which prevented the Widget API calls from returning any value at all (that's why you got null instead of the default toString() representation of a Widget). This was also fixed for 7.0.12. So in actuality; there were two bugs here.
__________________
Jeffrey Kardatzke
Google
Founder of SageTV
Reply With Quote
  #9  
Old 07-07-2010, 12:18 PM
shadeblue.com's Avatar
shadeblue.com shadeblue.com is offline
Sage Aficionado
 
Join Date: Jun 2008
Posts: 435
Hi Jeff,

Thank you so much for addressing this issue. And let me send a big THANK YOU on behalf of all users of the InfoPopup / Caller ID plugin. With support for these remote client calls it will greatly simplify the implementation of the caller id listener. Prior to this an instance of the listener plugin had to be installed and running at each client and for the local SageTV client instance running on the SageTV server, you would have to setup the listener plugin in the SageClient.properties file with a different port, and thus the YAC sender had to send to each listener on each port. While all this makes sense, it was a bit intimidating for some non-networking savvy users :-)

Love the new plugin architecture, plugin manager, and the remote UI context calls!

Thanks, SB
__________________
Server Hardware: Intel Core 2 Quad Q6700 2.66GHz CPU, 4GB DDR2 RAM, NVIDIA nForce 780i SLI Motherboard, GeForce 8600 GT, Seagate Barracuda 7200.11 2.5TB
Operating System: Windows XP Professional
HTPC/DVR Software: SageTV 7
Capture Devices: 2 @ Hauppauge HD-PVR (1212), Hauppauge WinTV-HVR-1600 ATSC/QAM, HD Homerun
Media Extenders: 2 @ Sage HD100 & 1 @ Sage HD200
Signals/Providers: AT&T UVerse, OTA ATSC
Set-Top-Box: 2 @ Motorola Box VIP 1200
Reply With Quote
  #10  
Old 07-07-2010, 03:04 PM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
Quote:
Originally Posted by Narflex View Post
For this issue; we just made an update so that any of the Widget API methods that take a 'Widget' as a parameter will also accept a symbol. And in that case, the symbol will be looked up and converted to a Widget. We also added support for converting a Widget to a symbol automatically when it's sent over the protocol.
I read that and I thought, great solution, but yikes! How the heck am I going to wrap that? But you know what, I think it will just work transparently, since my wrappers don't actually care about the underlying type of the object being wrapped; they just unwrap it and pass it back in as needed.
__________________
-- Greg
Reply With Quote
  #11  
Old 07-17-2010, 12:45 AM
shadeblue.com's Avatar
shadeblue.com shadeblue.com is offline
Sage Aficionado
 
Join Date: Jun 2008
Posts: 435
Just upgraded to 7.0.12 and tested this. It all seems to be working great! The InfoPopup / Caller ID plugin has been updated to support this feature.

This is so much nicer where the running plugin can send out instructions to all the connected extenders and clients. No more need to run multiple YAC listeners on custom ports for SageTV clients!

Thanks Again,
SB
__________________
Server Hardware: Intel Core 2 Quad Q6700 2.66GHz CPU, 4GB DDR2 RAM, NVIDIA nForce 780i SLI Motherboard, GeForce 8600 GT, Seagate Barracuda 7200.11 2.5TB
Operating System: Windows XP Professional
HTPC/DVR Software: SageTV 7
Capture Devices: 2 @ Hauppauge HD-PVR (1212), Hauppauge WinTV-HVR-1600 ATSC/QAM, HD Homerun
Media Extenders: 2 @ Sage HD100 & 1 @ Sage HD200
Signals/Providers: AT&T UVerse, OTA ATSC
Set-Top-Box: 2 @ Motorola Box VIP 1200
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Context/ThreadLocal data jphipps SageTV Studio 2 12-11-2009 12:26 PM
Obtaining correct UI context dflachbart SageTV Studio 3 07-17-2006 07:10 AM
Are you good with the SageTV API? roofus The SageTV Community 10 11-25-2005 01:11 PM


All times are GMT -6. The time now is 10:49 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.
Copyright 2003-2005 SageTV, LLC. All rights reserved.