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.
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:
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!