CISCO xAPI - HTTP Get Requests from a Hockey Fan

CISCO recently launched support for HTTP GET and PUT as commands that can be run from macros running on their CISCO Room systems. I love the idea of being able to expand the use of the CISCO Room System and Touch 10 panel to put APIs on connected systems to use. There are plenty of valid use cases for this - room booking systems, integration of enterprise applications and obviously integration with other AV systems in the room.

For me - I thought it would be great to have the latest scores of my favourite hockey team right on the Touch 10! GO SENS GO!

Below is a rough outline of how I completed this little project.

hockey-panel.png

Create the Panel

So - I started with a new panel on the Touch 10. The panel has 2 pages (tabs) - one for my Ottawa Senators - the other for the Montreal Canadians (boo). Each tab has 4 rows with textboxes that will contain information about the last game and the next upcoming game. In the table below - each data field is listed, as well as, the Widgit id’s on each panel page.

Field Ottawa Senators Tab
Widgit id
Boston Bruins Tab
Widgit id
Last Game Opponent OttawaLastOpponent MTLLastOpponent
Last Game Score OttawaLastScore MTLLastScore
Next Game Date OttawaNextDate MTLNextDate
Next Game Opponent OttawaNextOpponent MTLNextOpponent

So - my new panel on the Touch 10 looks like this:

Panel-dev.JPG

Add the Macro

Now - I need the macro with the fancy HTTP GET request to get the NHL Game Info. Good thing the NHL has an open REST API where you can get all kinds of data about the NHL - games, locations, player, etc…. I will not get into how the API works because it can be found on the internet.

So - we now flip over to the Macro editor and click the Create new macro button. Give the macro the name HOCKEY and turn it on. You can then paste the following code into the editor:

const xapi = require('xapi');

//Created by Colin Bush - BUSHTEK INC
//2019-10-31

function NextGameInfo(TeamID,TeamIDforPANEL) {
  var NextGameDay;
  var NextGameOpponent;
  var NextGameObj;
  var HockeyUrl = 'https://statsapi.web.nhl.com/api/v1/teams/' + TeamID + '?expand=team.schedule.next';

    //Get Next Game Info
    xapi.command('HttpClient Get', { 'Header': ["Content-Type: application/json"] , 'Url':HockeyUrl, 'AllowInsecureHTTPS': 'True'}).then((result) => {
    console.log(result.body);
    NextGameObj = JSON.parse(result.Body);
    NextGameDay = NextGameObj.teams[0].nextGameSchedule.dates[0].date;
    console.log (NextGameDay);
    if (NextGameObj.teams[0].nextGameSchedule.dates[0].games[0].teams.home.team.id == TeamID) {
      NextGameOpponent = NextGameObj.teams[0].nextGameSchedule.dates[0].games[0].teams.away.team.name;
    } else {
      NextGameOpponent = NextGameObj.teams[0].nextGameSchedule.dates[0].games[0].teams.home.team.name;
    }
    console.log ('NEXT GAME OPPONENT ' + NextGameOpponent);
    xapi.command('UserInterface Extensions Widget SetValue', { 'WidgetId': TeamIDforPANEL+'NextDate', 'Value' :  NextGameDay});
    xapi.command('UserInterface Extensions Widget SetValue', { 'WidgetId': TeamIDforPANEL+'NextOpponent', 'Value' :  NextGameOpponent});
    }).catch((error) => { console.error('NextGame ERROR - ' + error); });
}

function LastGameInfo(TeamID,TeamIDforPANEL) {
   //Get Last Game Info
    var LastGameObj;
    var LastGameDay;
    var LastGameOpponent;
    var MyScore;
    var OtherScore;
    var Score;
    var HockeyUrl = 'https://statsapi.web.nhl.com/api/v1/teams/' + TeamID + '?expand=team.schedule.previous';
    
    //Get LastGameInfo
    xapi.command('HttpClient Get', { 'Header': ["Content-Type: application/json"] , 'Url':HockeyUrl, 'AllowInsecureHTTPS': 'True'}).then((result) => {
    var body = result.Body;
    LastGameObj = JSON.parse(body);
    LastGameDay = LastGameObj.teams[0].previousGameSchedule.dates[0].date;
    console.log (LastGameDay);
    if (LastGameObj.teams[0].previousGameSchedule.dates[0].games[0].teams.home.team.id == TeamID) {
      LastGameOpponent = LastGameObj.teams[0].previousGameSchedule.dates[0].games[0].teams.away.team.name;
      MyScore =  LastGameObj.teams[0].previousGameSchedule.dates[0].games[0].teams.home.score;
      OtherScore = LastGameObj.teams[0].previousGameSchedule.dates[0].games[0].teams.away.score;
      } else {
      LastGameOpponent = LastGameObj.teams[0].previousGameSchedule.dates[0].games[0].teams.home.team.name;
      MyScore =  LastGameObj.teams[0].previousGameSchedule.dates[0].games[0].teams.away.score;
      OtherScore =  LastGameObj.teams[0].previousGameSchedule.dates[0].games[0].teams.home.score;
    }
    if (MyScore > OtherScore) {
      Score = 'WIN ' + MyScore +'-'+OtherScore;
    } else {
      Score = 'LOST '+ MyScore +'-'+OtherScore;
    }
    var LastOpp = TeamIDforPANEL + 'LastOpponent';
    var LastScore = TeamIDforPANEL + 'LastScore';
    xapi.command('UserInterface Extensions Widget SetValue', { 'WidgetId': TeamIDforPANEL + 'LastOpponent', 'Value' :  LastGameOpponent});
    xapi.command('UserInterface Extensions Widget SetValue', { 'WidgetId': TeamIDforPANEL + 'LastScore', 'Value' :  Score});
    console.log (MyScore + "-" + OtherScore);
    }).catch((error) => { console.error('LastGame ERROR - ' + error); });
}

function onGui(event) {
  if (event.PanelId == 'Hockey') {
    xapi.command('UserInterface Extensions Widget SetValue', { 'WidgetId': 'OttawaLastOpponent', 'Value' :  ''});
    xapi.command('UserInterface Extensions Widget SetValue', { 'WidgetId': 'OttawaLastScore', 'Value' :  ''});
    xapi.command('UserInterface Extensions Widget SetValue', { 'WidgetId': 'OttawaNextDate', 'Value' :  ''});
    xapi.command('UserInterface Extensions Widget SetValue', { 'WidgetId': 'OttawaNextOpponent', 'Value' :  ''});
    LastGameInfo(9,'Ottawa');
    NextGameInfo(9,'Ottawa');
    LastGameInfo(8,'MTL');
    NextGameInfo(8,'MTL');
  }
}

xapi.event.on('UserInterface Extensions Panel Clicked', onGui);

Decoding the code a bit…

EVENT - xapi.event.on('UserInterface Extensions Panel Clicked', onGui);

  • Last line in the code above

  • It essentially says trigger the code in the onGui function whenever someone clicks on a panel

FUNCTION - onGui

  • This function is run when the event above is triggered

  • It checks to see if the Hockey Panel was clicked and, if so, it runs the functions to update the textboxes on the panel pages, specifically LastGameInfo and NextGameInfo

FUNCTION - LastGameInfo and NextGameInfo

  • These function makes the HTTP Get requests to the NHL API for the info about the last/next games played by both teams

  • The 1st parameter is the NHL API Team Code - 9 for Ottawa, 8 for Montreal

  • The 2nd parameter is the team identifier in the Widgit id of the panel pages

  • The functions are called twice within the onGui function - once for Ottawa and once for Montreal

xAPI Commands

  • xapi.command('HttpClient Get',…

    • Used within the LastGameInfo and NextGameInfo functions to make the HTTP Get request to the NHL API

    • The TEAM id which is the 1st parameter in function calls is inserted into the URL that is requested with the HTTP Get (HockeyUrl variable)

    • The blob that is returned is parsed using JSON.parse so that it can be easily read

    • Once you understand the NHL API - you can use a JSON parser test site to read what is returned.

  • xapi.command('UserInterface Extensions Widget SetValue',…

    • Used within the LastGameInfo and NextGameInfo functions to update the textboxes on the panels

    • The team identifier (2nd parameter) is used to build the name of the Widget to be updated on the panel pages

THAT IS IT!

That is the end of my attempt at using the CISCO Touch 10 to help me keep on top of my Hockey Pool. I am not a professional javascript coder so this was just a fun project to see what is possible. Below is a link to my panel xml file - if you would like to see what mine looked like (it is easier than recreating it). Make sure you merge it into your configuration or you may lose what you had before.

CISCO Touch10 Panel - Hockey.xml

Looking forward to my next adventure into the world of HTTP Put! I am thinking about trying to write Room Analytics data to a GOOGLE SHEET…

Enjoy this project and keep your fingers crossed for the Ottawa Senators - it is going to be a tough year!

GO SENS GO!