cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1063
Views
0
Helpful
1
Replies

Virtual input API / Watchdog Macro

thombrooks
Level 1
Level 1

If a third-party control system uses the API to:

  1. Provide a heartbeat, per best practices, (xCommand Peripherals HeartBeat) and
  2. Register 'virtual inputs' to overload one physical input on the codec (xFeedback register Event/UserInterface/Presentation/ExternalSource) using a third-party video switcher, then:
  3. What happens when the control system and codec lose communication with one another for an extended period? All of those overloaded/virtual inputs break. Even if there's sync detected on the overloaded input, the codec doesn't know which of those virtual inputs to light up as 'available.'
  • Can a Macro run as a 'watchdog' and detect if the heartbeat from the control system has been lost? I don't see an xStatus specifically for this; the best I can figure is to watch 'xstatus Peripherals ConnectedDevice 100[x] status' but then I need to use a stateful variable to track this; I know the codec is keeping track already. Can I tap into that?
    • Or... can I have the macro 'subscribe' to the 'xStatus Peripherals ConnectedDevice 100x status' and do an event based off of that? Does the status only change to Disconnected after a certain threshold has passed, i.e. the same one when the codec starts reporting that it has lost communication with the control system? (Or, would I still have to 'debounce' that signal by making sure its state was consistently disconnected for more time?)
  • If not, is there a best practice for this to not hog processor resources? (i.e. using appropriate 'sleep' or 'nice', using a built-in event scheduler, etc? Just use setInterval?)
  • Either way, could that Macro delete the 'overloaded' (virtual) interfaces and make the codec present that interface using its default name?
  • The idea is that the control system would maintain a similar watchdog on its end and if communication is lost, would change the third-party video switching behavior to auto-switch last detected input, or implement priorities, etc. 
  • Then if communication is restored, the control system would recreate the virtual inputs and change back to 'normal' behavior.

Thank you!

1 Reply 1

Magnus Ohm
Cisco Employee
Cisco Employee

Hi Thom,

You can subscribe to the lost connection status for the connected device. The ID does not change even though the control system disappears which is normal after a certain time (1 minute or so with no connection). Sending the heartbeat will revive the registered peripheral (even after a boot). I have not looked into closely but finding a way of dynamically keeping track of the id number should not be that difficult.

 

You can use the macro as a watchdog based on this, please see the simplified example:

 

When the peripheral loses the connection it removes all the inputs (here you can insert other actions as well). When the control device reconnects, it recreates the inputs (as you say the creation of sources would come from the control device, but I let the macro do this as a proof of concept). The macro can also do this but that should only remove upon lost connection and handle the "offline" scenario to improve the user experience.

 

UPDATED:

 

const xapi = require('xapi');

function createInputs() {
  var inputs = [
    {
      'ConnectorId':'2',
      'SourceIdentifier':'s1',
      'Name':'PC Input',
      'Type':'PC'    
    },
    {
      'ConnectorId':'2',
      'SourceIdentifier':'s2',
      'Name':'AppleTV',
      'Type':'mediaplayer'    
    }
  ];
  for (var i = 0; i < inputs.length; i++) {
    xapi.command('UserInterface Presentation ExternalSource Add', inputs[i]);
  }
}

function removeInputs() {
  xapi.command('UserInterface Presentation ExternalSource RemoveAll');
}

xapi.status.on('Peripherals ConnectedDevice', event => {
  if (!("ghost" in event)) {
    xapi.status.get('Peripherals ConnectedDevice ' + event.id).then((device) => {
      if (device.Type == 'ControlSystem') {
        switch (device.Status) {
          case 'LostConnection':
            //Do stuff here
            removeInputs();
            break;
          case 'Connected':
            //Do stuff here
            console.log('Connected');
            createInputs();
            break;
        }
      }
    }).catch(error => {
      console.log(JSON.stringify(error));
    });
  }
});

So here is the example flow:

 

 

xCommand UserInterface Presentation ExternalSource List

OK
*r ExternalSourceListResult (status=OK): #No sources
** end
xcommand Peripherals HeartBeat id: 1 timeout: 10 #Send heartbeat OK *r PeripheralsHeartBeatResult (status=OK): ** end *s Peripherals ConnectedDevice 1010 HardwareInfo: "" *s Peripherals ConnectedDevice 1010 ID: "1" *s Peripherals ConnectedDevice 1010 Name: "Control" *s Peripherals ConnectedDevice 1010 SoftwareInfo: "" *s Peripherals ConnectedDevice 1010 Status: Connected #Device connects again *s Peripherals ConnectedDevice 1010 Type: ControlSystem *s Peripherals ConnectedDevice 1010 UpgradeStatus: None ** end xCommand UserInterface Presentation ExternalSource List #See if the macro has done its job OK *r ExternalSourceListResult (status=OK): *r ExternalSourceListResult Source 1 ConnectorId: 2 *r ExternalSourceListResult Source 1 Name: "AppleTV" *r ExternalSourceListResult Source 1 SourceIdentifier: "s2" *r ExternalSourceListResult Source 1 State: NotReady *r ExternalSourceListResult Source 1 Type: mediaplayer *r ExternalSourceListResult Source 2 ConnectorId: 2 *r ExternalSourceListResult Source 2 Name: "PC Input" *r ExternalSourceListResult Source 2 SourceIdentifier: "s1" *r ExternalSourceListResult Source 2 State: NotReady *r ExternalSourceListResult Source 2 Type: PC ** end *s Peripherals ConnectedDevice 1010 Status: LostConnection #Lost connection *s Diagnostics Message 12 Description: "Expected a Control System, none is connected." *s Diagnostics Message 12 Level: Error *s Diagnostics Message 12 References: "" *s Diagnostics Message 12 Type: ControlSystemConnection ** end
xCommand UserInterface Presentation ExternalSource List #Check if the macro has removed the sources OK *r ExternalSourceListResult (status=OK): #No sources ** end

Hope this helps you.

 

/Magnus