Skip to content

Commit 2c1b442

Browse files
Initial version
* Added `package.json` with dependencies * Added `macro-tutorial.pdf` * Added `.vscode/launch.json` configured for macro debugging * Added `_bootstrap.js` for macro debugging * Added `.env` to configure connection to a device * Added sample macros to `/macros`
0 parents  commit 2c1b442

File tree

9 files changed

+238
-0
lines changed

9 files changed

+238
-0
lines changed

.env

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
JSXAPI_DEVICE_URL=10.10.20.158:22
2+
JSXAPI_USERNAME=admin
3+
JSXAPI_PASSWORD=ciscopsdt

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package-lock.json
2+
node_modules/
3+
.env
4+
.vscode/

.vscode/launch.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "node",
9+
"request": "launch",
10+
"name": "Debug macro",
11+
"skipFiles": [
12+
"<node_internals>/**"
13+
],
14+
"program": "${workspaceFolder}\\_bootstrap.js",
15+
"args": ["${file}"],
16+
}
17+
]
18+
}

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2017 Cisco Systems
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

_bootstrap.js

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
//
2+
// Copyright (c) 2018 Cisco Systems
3+
// Licensed under the MIT License
4+
//
5+
6+
/**
7+
* Listen to realtime events via xAPI's feedback function
8+
* In this example, we display people count changes as they happen
9+
*
10+
* This script only works when run against a 'RoomKit' type of device
11+
*/
12+
13+
// Load necessary modules
14+
15+
const dotenv = require('dotenv');
16+
const jsxapi = require('jsxapi');
17+
const Module = require('module');
18+
19+
// Load environment variables from '.env' file
20+
dotenv.config()
21+
22+
// Ensure must-have environment variables
23+
ensureEnvVariable('JSXAPI_DEVICE_URL');
24+
ensureEnvVariable('JSXAPI_USERNAME');
25+
ensureEnvVariable('JSXAPI_PASSWORD'); // Empty passwords are not supported
26+
27+
// Check env variables
28+
if (!process.env.JSXAPI_DEVICE_URL || !process.env.JSXAPI_USERNAME) {
29+
console.warn("Please specify info to connect to your device as JSXAPI_DEVICE_URL, JSXAPI_USERNAME, JSXAPI_PASSWORD env variables");
30+
console.warn("You can set the variables using '.env' file");
31+
process.exit(1);
32+
}
33+
34+
// Connect to the device
35+
console.log("Connecting to the device...");
36+
console.log(process.env.JSXAPI_DEVICE_URL);
37+
console.log(`Username: ${process.env.JSXAPI_USERNAME}`);
38+
const xapi = jsxapi.connect(
39+
process.env.JSXAPI_DEVICE_URL,
40+
{
41+
username: process.env.JSXAPI_USERNAME,
42+
password: process.env.JSXAPI_PASSWORD,
43+
});
44+
45+
46+
// Hacking the `Module._load` to ignore require in the macro that is being debugged
47+
48+
// Saving a reference to an original `Module._load` function
49+
const moduleLoad = Module._load;
50+
// Hacking `Module._load` function
51+
Module._load = function(request, parent, isMain) {
52+
// If `require('xapi')` is called,
53+
if (request === 'xapi') {
54+
// Return existing reference to `xapi`
55+
return xapi;
56+
}
57+
58+
// Otherwise, use original `Module._load` function
59+
return moduleLoad(request, parent, isMain);
60+
};
61+
62+
// File that is being debugged should be passed as a command-line argument
63+
// node 0-bootstrap.js <file-being-debugged.js>
64+
const fileBeingDebugged = process.argv[2];
65+
if (!fileBeingDebugged) {
66+
console.error("File to debug is not specified");
67+
console.warn("Path to the file is expected to be a third command-line argument");
68+
console.warn("Example:");
69+
console.warn("node _bootstrap.js <file-to-debug.js>");
70+
71+
console.log();
72+
console.log("If you are using Visual Studio Code, switch to file that you would like to debug and press 'F5'");
73+
74+
console.log();
75+
console.log("In any other case, run the debugging session by command:");
76+
console.log("node _bootstrap.js <file-to-debug.js>");
77+
78+
process.exit(1);
79+
}
80+
81+
82+
xapi.on('error', err => {
83+
console.error(`Connection failed: ${err}`);
84+
process.exit(1);
85+
});
86+
87+
xapi.on('ready', () => {
88+
console.log("Connection successful");
89+
90+
console.log(`File being debugged: ${fileBeingDebugged}`);
91+
92+
// Load the file that is being debugged.
93+
// First line 'const <...> = require('xapi');' will return `xapi` which is already loaded in current script
94+
require(fileBeingDebugged);
95+
});
96+
97+
// Ensure environment variable is set
98+
function ensureEnvVariable(varName) {
99+
if (!process.env[varName]) {
100+
console.error(`Environment variable '${varName}' is not set`);
101+
102+
console.warn("Please specify info to connect to your device as JSXAPI_DEVICE_URL, JSXAPI_USERNAME, JSXAPI_PASSWORD env variables");
103+
console.warn("You can set the variables using '.env' file");
104+
process.exit(1);
105+
}
106+
}

macro-tutorial.pdf

111 KB
Binary file not shown.

macros/0-emptyMacro.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const xapi = require('xapi');
2+
3+
// Put your code instead of "// Put your code here". Don't change the rest of the code.
4+
5+
// Check out mini-courses on YouTube:
6+
// "Writing xAPI Macros 101" [Playlist]
7+
// "JavaScript for xAPI Macros 101" [Playlist]
8+
9+
// To debug this file from your local machine:
10+
// 1. Follow setup instructions described in `README.md`.
11+
// 2. Simply press 'F5' in current tab.
12+
13+
// All `xapi` commands return promises. That's why you have to use `.then(<...>)`.
14+
// To learn more about promises basics check out: https://javascript.info/promise-basics
15+
16+
// It's much easier to use `await` syntax to work with promises.
17+
// `await` helps to await promises to avoid `.then(x => { <...>.then(<...>)})` nesting.
18+
// `async` enables `await` usage.
19+
// Check out for more info: https://javascript.info/async-await
20+
21+
// Define the `async` function
22+
const macro = (async () => {
23+
24+
// Put your code here
25+
// const volume = await xapi.status.get('Audio Volume');
26+
// console.log(volume);
27+
28+
});
29+
30+
// // In case of wokring with events, you need to use `async` function as well
31+
// xapi.on('ready', async () => {
32+
// const volume = await xapi.status.get('Audio Volume');
33+
// console.log(volume);
34+
// });
35+
36+
// Execute
37+
macro();

macros/1-showVolume.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const xapi = require('xapi');
2+
3+
// Put your code instead of "// Put your code here". Don't change the rest of the code.
4+
5+
// Check out mini-courses on YouTube:
6+
// "Writing xAPI Macros 101" [Playlist]
7+
// "JavaScript for xAPI Macros 101" [Playlist]
8+
9+
// To debug this file from your local machine:
10+
// 1. Follow setup instructions described in `README.md`
11+
// 2. Simply press 'F5' in current tab
12+
13+
// All `xapi` commands return promises. That's why you have to use `.then(<...>)`.
14+
// To learn more about promises basics check out: https://javascript.info/promise-basics
15+
16+
// It's much easier to use `await` syntax to work with promises.
17+
// `await` helps to await promises to avoid `.then(x => { <...>.then(<...>)})` nesting.
18+
// `async` enables `await` usage.
19+
// Check out for more info: https://javascript.info/async-await
20+
21+
// Define the `async` function
22+
const macro = (async () => {
23+
24+
// Put your code here
25+
const volume = await xapi.status.get('Audio Volume');
26+
console.log(volume);
27+
28+
});
29+
30+
// // In case of wokring with events, you need to use `async` function as well
31+
// xapi.on('ready', async () => {
32+
// const volume = await xapi.status.get('Audio Volume');
33+
// console.log(volume);
34+
// });
35+
36+
// Execute
37+
macro();

package.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "xapi-roomkit-macro-debugger",
3+
"version": "0.0.1",
4+
"description": "Debug your macros in Visual Studio Code using the Node.js and `jsxapi`",
5+
"scripts": {},
6+
"author": "Vlad DX <[email protected]>",
7+
"license": "MIT",
8+
"dependencies": {
9+
"dotenv": "^8.2.0",
10+
"jsxapi": "^4.1.3"
11+
}
12+
}

0 commit comments

Comments
 (0)