GyroPalm JavaScript SDK

JavaScript SDK for GyroPalm Developers

Overview

The GyroPalm JavaScript software development kit (SDK) enables developers to wirelessly connect to one or more GyroPalm Encore wearables without any additional dependencies. This JS library includes methods to enable developers in establishing bi-directional communication with GyroPalm devices for creating unlimited hands-free web interactions. This repository also contain an example HTML page that demonstrates typical use.

This library exposes the GyroPalm object, which encapsulates secure websockets (WSS) with our real-time low latency server. Using enhanced methods and function callbacks, gestures, commands, and other data can be retrieved from the wearable in milliseconds. Using the GyroPalm object, developers can write applications that retrieve information about a user as well as their wearables.

The GyroPalm JavaScript SDK also provides a supplemental browser-based graphical user interface (GUI) which makes it easier to code with the GyroPalm JavaScript class. Essentially, this GUI enables users to not only map gesture communications with various websites and apps, but also have them synced to the cloud and shared with other colleagues. This GUI, code-named GyroPalm Vertex, can be run in a Chrome browser extension, Firefox plugin, smartphone app, etc. Developers can write and publish compatible interfaces using JavaScript and SDK based functions.

Requirements

To implement this SDK for its intended use, it is highly recommended that the developer has a GyroPalm Developer Kit or equivalent GyroPalm package to do proper testing. To order one or more wearables, visit the GyroPalm Online store.

In addition, both the end-user must use a modern web browser such as Chrome, Firefox, Edge, or Safari with HTML5 capabilities. The developer may choose to use jQuery or equivalent library alongside this SDK for convenience, but it is not required.

Installation

There are three simple ways to include this library: By referencing our CDN hosted version, using GyroPalm's hosted version, or downloading the latest release from GyroPalm's GitHub repository.

To use the CDN Hosted Link, include the following in your HTML:

<script src="https://cdn.jsdelivr.net/gh/GyroPalm/GyroPalm-JavaScript-SDK@latest/gyropalm.min.js"></script>

To use the GyroPalm Hosted Link, include the following in your HTML:

<script src="https://app.gyropalm.com/api/sdk/javascript/gyropalm.min.js"></script>

Download Release from GitHub

Download the latest release of gyropalm.min.js on the GitHub releases page. Place the file relative to your script path and include it as follows:

<script src="gyropalm.min.js"></script>

Release Notes

Version 1.0.0.4 - Release on 12/21/2022
- Added GyroPalm SDK GUI (GyroPalm Vertex)
- Improved attachment of callback functions (can attach multiple callbacks)
- Updated Developer docs
- Automatic loading of jQuery
- JavaScript Code Editor

Version 1.0.0.3 - Release on 5/21/2022
- Added ability to Request for Device Online/Offline status
- Educational demo page for using GyroPalm JavaScript SDK

Version 1.0.0.2 - Release on 5/21/2022
- Realtime object accepts both masterToken and API key
- Able to connect to wearable
- Able to auto-reconnect if connection fails
- Able to attach event and connection callback functions
- Able to send JSON payloads to the wearable
- Able to receive verbose messages via separate callback
- Educational demo page for using GyroPalm JavaScript SDK

Version 1.0.0.0 - Beta release on 11/3/21
- Initial release candidate
- Primary objects initiated
- Able to list account info
- Able to list wearables
- Able to establish connection and reconnect

Demo and Documentation

This README serves as a basic guide to setting up the SDK. For detailed explanations, code samples, and object references, please see the full documentation on GyroPalm SDK Docs.

Basic Usage

To instantiate a GyroPalm object, first include the gyropalm.min.js library. Then instantiate the object as follows:

<script>
    function printData(obj) {   //example callback
        console.log(obj);
    }

    var gp = new GyroPalm();    //basic instantiation
    gp.enableVerbose(); //enable console messages
    gp.getAccountInfo("c188888888", printData); //show account info object
    gp.getWearables("", printData); //no need to respecify the API key
    gp.connect("gp123123123");  //connect to wearableID

    // OR you can choose to declare wearableID and API key first
    var gp = new GyroPalm("gp123123123", "c188888888"); //advanced instantiation
    gp.enableVerbose(); //enable console messages
    gp.getAccountInfo("", printData);   //show account info object
    gp.connect();   //connect to wearableID above
</script>

Advanced Usage

Advanced usage of the GyroPalm JS object is as follows.

Object Instantiation

var gp = new GyroPalm(); // declare later
var gp = new GyroPalm(apiKey); // declare just apiKey
var gp = new GyroPalm(apiKey, wearableID); // declare apiKey and wearableID

Event Callbacks

// Declared event callback functions
function eventCallback(obj) {    //example callback
    console.log(obj);
}
function connectionCallback(obj) {    //example callback
    console.log(obj);
}
function verboseCallback(obj) {    //example callback
    console.log(obj);
}

// Attach event callback functions
gp.addEventCallback(eventCallback); // get a callback function from the wearable when an action is performed
gp.addConnectionCallback(connectionCallback); // when connected or disconnected get a callback function
gp.addVerboseCallback(verboseCallback); // get verbose messages for debugging

// Remove event callback functions (optional)
gp.removeEventCallback(eventCallback); // get a callback function from the wearable when an action is performed
gp.removeConnectionCallback(connectionCallback); // when connected or disconnected get a callback function
gp.removeVerboseCallback(verboseCallback); // get verbose messages for debugging

Connection And Disconnecting

// Choose one of 3 ways to connect to a wearable
gp.connect(wearableID, eventCallback, connectionCallback); // connect with all information
gp.connect(wearableID); // connect with only wearable
gp.connect(); // connect if you have connected in the past

gp.disconnect(); // disconnect from wearableID

Sending Messages to Wearable

var myObject = {"action": "control", "wearableID": "gp00000", "outputVal": "{\"thisKey\": \"thatKey\"}"};

// Information from wearable
gp.sendDataObj(myObject); // send a JSON string OR object to the wearable
gp.sendStatusRequest(); // request the status of the device (Time active, Output value json, current status, wearableID)

Receiving Messages

Parsing Device Data

Assuming the event callback has been established by running gp.addEventCallback(eventCallback), the callback function eventCallback(obj) will be called whenever the wearable sends out a message. The obj variable contains a JSON object that will typically include a key called "action" with the value as "data", while the actual data received will be contained in a key that is the name of your wearableID (starting with gp). The following function may be used to parse the received obj variable:

function extractDeviceData(obj) {
  if (obj.action !== 'data') {
    return null;
  }

  const deviceKey = Object.keys(obj).find(key => key.startsWith('gp') && key.length > 4);

  if (!deviceKey) {
    return null;
  }

  return obj[deviceKey];
}

This is an example of how the extractDeviceData function can be used:

function eventCallback(obj) {    //example callback
    // Parse data from wearable
    var wearableData = extractDeviceData(obj);
}

gp.addEventCallback(eventCallback); // get a callback function from the wearable when an action is performed

Robot Driving Use-Case

When the GyroPalm Encore is being used for driving robots, vehicles, or drones, the device emits "drive commands" to GyroPalm Realtime while it is connected and activated. Generally, the user performs an activation command (i.e. a double-snap, or holding an "Activation" button). Objects containing "drive commands" are inside the device data received, but have to be parsed. In addition, "aux commands" (i.e. dock, undock, uturn, etc) are received in a manner that is contained inside a key called "request".

To process data for drive and aux commands, include these two functions in your code:

// Checks if jsonStr is valid drive command.
// If drive command, then returns x and y values. Otherwise returns null.
function handleDriveCommand(jsonStr) {
  try {
    const json = JSON.parse(jsonStr);
    if (json.request !== 'drive') {
      return null;
    }
    if (!('x' in json) || !('y' in json)) {
      return null;
    }
    return { x: json.x, y: json.y };
  } catch (error) {
    return null;
  }
}

// Checks if jsonStr is a valid aux request.
// If its valid, then returns request string. Otherwise returns null.
function handleAuxCommand(jsonStr) {
  try {
    const json = JSON.parse(jsonStr);
    if ('request' in json && json.request != 'drive') {
      return json.request;
    } else {
      return null;
    }
  } catch (error) {
    return null;
  }
}

This is an example of how to use all these functions together for a robot driving use-case:

function eventCallback(obj) {    //example callback
    // Parse data from wearable
    var wearableData = extractDeviceData(obj);
    // Handle drive commands (if we receive those)
    var driveComm = handleDriveCommand(wearableData);
    var auxComm = handleAuxCommand(jsonStr);

    // If we have a drive command
    if (driveComm !== null) {
        // handle driveComm.x and driveComm.y values
        console.log(driveComm);
    }

    // If we have an aux command
    if (auxComm !== null) {
        // handle value from auxComm
    }
}

gp.addEventCallback(eventCallback); // get a callback function from the wearable when an action is performed

Additional Helper Functions

Developers who are familiar with Arduino or Processing IDE may appreciate these additional functions which are equivalents in Javascript. Usage of these functions is entirely optional.

// Sets an input range slider with a specific ID to any value
function setSlider(elementID, sliderVal) {
    const slider = document.getElementById(elementID);
    slider.value = sliderVal;
    slider.dispatchEvent(new Event('input'));
}

// Maps a variable to a new min and max value
function map(value, fromLow, fromHigh, toLow, toHigh) {
  return (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
}

// Returns number of milliseconds since page started
function millis() {
  return Math.floor(performance.now());
}

// Constrains a variable between min and max values
function constrain(value, min, max) {
  if (value < min) {
    return min;
  } else if (value > max) {
    return max;
  } else {
    return value;
  }
}

Using GyroPalm JS SDK on other websites

The GyroPalm SDK is capable of running JavaScript on other websites to enhance accessibility and provide a hands-free interface. By using this functionality, you agree to use the SDK at your own risk. You also agree to comply with local and international laws and regulations.

The GyroPalm JS SDK is a powerful tool that enables authorized users to run, trigger, and fetch data on websites and web apps that they have access to. With a few lines of JavaScript, you can implement a Chrome or Firefox extension that can make GyroPalm work with virtually any website or platform. For example, users can perform gestures on a GyroPalm wearable to scroll, trigger buttons, fill forms, etc.

Load GyroPalm JS SDK on a site using jQuery

$.getScript('https://cdn.jsdelivr.net/gh/GyroPalm/GyroPalm-JavaScript-SDK@latest/gyropalm.min.js')

Load GyroPalm JS SDK on a site without jQuery

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://cdn.jsdelivr.net/gh/GyroPalm/GyroPalm-JavaScript-SDK@latest/gyropalm.min.js';
document.head.appendChild(script);

Load GyroPalm Vertex on a modern website

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://app.gyropalm.com/api/sdk/javascript/gui/gyropalmgui.js';
document.head.appendChild(script);

GyroPalm Vertex vs. GyroPalm JS SDK

GyroPalm Vertex is a JavaScript-based GUI that wraps around the GyroPalm JS SDK. In GyroPalm Vertex, the GyroPalm() object is automatically instantiated as gpObj for convenient usage. Vertex handles the authentication and wearable ID selection automatically so developers no longer have to worry about obtaining the user's apiKey or wearableID. Instead, developers can focus on creating compelling gesture-based experiences on virtually any website they choose.

You can choose to load the code above using a Chrome extension such as Run JavaScript or by writing your own custom Chrome extension. Alternatively, you can run the code in the browser's Developer Console. Once the SDK is loaded, you can create a new instance of the GyroPalm() class and attach the event callbacks as needed. Again, developers who choose to use GyroPalm Vertex (gyropalmgui.js) do not need to instantiate the GyroPalm() class as it has been instantiated already as gpObj.

By writing additional code in the event callbacks, you can make different websites respond to your various GyroPalm gestures by parsing the JSON objects before and after the data is sent to the wearable.

The MIT License (MIT) Copyright (c) 2015-2024 by GyroPalm, LLC. Code written by Dominick Lee for GyroPalm.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.