1.1.8 • Published 6 days ago

@deeplocal/gumband-node-sdk v1.1.8

Weekly downloads
-
License
ISC
Repository
bitbucket
Last release
6 days ago

Gumband Node.js SDK

The Gumband SDK takes care of all communication between an Exhibit and Gumband servers in the Cloud. It handles authentication, establishes a websocket connection for live updates, and also optionally spawns an MQTT broker to handle communcation with Gumband-compatible hardware.

Check out our public documentation here.

How to Prepare your exhibit to use the Gumband SDK

Step 0: Install the SDK

Install the Gumband SDK to your Node.js project using the npm registry with the command $ npm install @deeplocal/gumband-node-sdk.

Step 1: Create an exhibit

Log into the Gumband dashboard in a web browser and then select an organization and site. Create a new exhibit or select an existing exhibit. Select the "Auth" tab for that exhibit and note the ID and token, you'll need this when initializing the Gumband SDK. Some users may not have permission to create exhibits in the Gumband dashboard.

Step 2: Create a manifest

The exhibit manifest is a way to describe the real time signals (statuses, settings, and controls) available for an exhibit. The manifest is a local JSON file that is included in the Gumband SDK constructor. It has a main key manifest that contains three required keys - statuses, controls, and settings - that each contain the necessary Gumband schema.

Here is an example of a manifest file:

{
  "manifest": {
    "statuses": [
      {
        "id": "ip_address",
        "type": "String",
        "display": "IP Address",
        "default": "127.0.0.1", // Optional
        "order": 0 // Optional
      },
      {
        "id": "count",
        "type": "Integer",
        "display": "Count",
        "default": 0, // Optional
        "order": 1 // Optional
      },
      {
        "id": "last_interaction",
        "type": "Date",
        "display": "Last Interaction",
        "order": 2 // Optional
      },
      {
        "id": "primary_color",
        "type": "Color",
        "display": "Color",
        "default": "#abc123" // Optional
      }
    ],
    "controls": [
      {
        "id": "reload",
        "type": "Single",
        "display": "Reload",
        "order": 0 // Optional
      },
      {
        "id": "skip",
        "type": "Single",
        "display": "Skip Interaction",
        "enabledOpMode": "On" // Optional
      },
      {
        "id": "restart_cameras",
        "type": "Group",
        "display": "Restart Cameras",
        "items": [
          {
            "id": "camera_1",
            "display": "Camera 1"
          },
          {
            "id": "camera_2",
            "display": "Camera 2"
          }
        ]
      }
    ],
    "settings": [
      {
        "id": "kiosk_name",
        "type": "TextInput",
        "display": "Kiosk Name",
        "default": "(not set)" // Optional
      },
      {
        "id": "idle_timeout_secs",
        "type": "IntegerInput",
        "display": "Idle Timeout (secs)",
        "default": 60 // Optional
      },
      {
        "id": "prod_api",
        "type": "Toggle",
        "display": "Production API",
        "default": false // Optional
      },
      {
        "id": "audio_file",
        "type": "Dropdown",
        "display": "Audio File",
        "default": "a_type_1", // Optional
        "items": [
          {
            "id": "a_type_1",
            "display": "Audio 1"
          },
          {
            "id": "a_type_2",
            "display": "Audio 2"
          },
          {
            "id": "a_type_3",
            "display": "Audio 3"
          }
        ]
      },
      {
        "id": "ux_mode",
        "type": "SingleButtonGroup",
        "display": "UX Mode",
        "default": "ux_mode_ambient", // Optional
        "items": [
          {
            "id": "ux_mode_silent",
            "display": "Silent"
          },
          {
            "id": "ux_mode_ambient",
            "display": "Ambient"
          },
          {
            "id": "ux_mode_offline",
            "display": "Offline"
          }
        ]
      },
      {
        "id": "date",
        "type": "Date",
        "display": "Date"
      },
      {
        "id": "named_images",
        "type": "SettingsList",
        "display": "Named Images",
        "schema": [
          {
            "type": "TextInput",
            "id": "image_group_title",
            "display": "Image Group Title"
          },
          {
            "type": "SettingsList",
            "id": "images_list",
            "display": "Images",
            "schema": [
              {
                "type": "FileSelection",
                "id": "image_file",
                "display": "Image"
              }
            ]
          }
        ]
      },
      {
        "id": "operator_info",
        "type": "SettingsGroup",
        "display": "Operator Info",
        "schema": [
          {
            "type": "TextInput",
            "id": "operator_name",
            "display": "Operator Name",
            "order": 0
          },
          {
            "type": "TextInput",
            "id": "operator_location",
            "display": "Operator Location",
            "order": 1
          }
        ]
      }
    ]
  }
}

Real Time Signal Types

Statuses: Integer, String, Date, Color Controls: Single, Group Settings: TextInput, IntegerInput, Toggle, Dropdown, SingleButtonGroup, FileSelection, Date, SettingsList, SettingsGroup

Step 3: Configuring the Gumband SDK via the constructor

After the previous steps, you can start using Gumband in your Node.js application. The Gumband constructor requires the exhibit ID, exhibit Token, and the path to the manifest file that you previously created.

Upon creation, the Gumband class will attempt to authenicate itself with the Gumband API and establish a Websocket connection to listen to Real-Time signals relevant to the exhibit. Here's an example:

const { Gumband, Sockets } = require("@deeplocal/gumband-node-sdk");

const gb = new Gumband(
  "a986dc223cc137xxxxxxxxxxxxxxx", // exhibit token
  "6", // exhibit ID
  "/path/to/manifest.json" // manifest path
);

// Register callback for when Gumband is ready to be used
// No Gumband SDK functions should be called before this event fires
gb.on(Sockets.READY, async () => {
  console.log("Gumband Exhibit Initialization Successful!");
});

Optional Constructor Parameters

You can initialize the Gumband SDK with a few parameters:

  • version (string): What API version to use. Value should be v1.
  • endpoint (string): What Gumband environment to operate with. Value can be local, dev,stag, app, or custom.
  • customServerIp (string): If endpoint=custom, what DNS name or IP address is the Gumband environment at. Value should be similar to test.gumband.com or 192.168.1.1.
  • contentLocation (string || null): Assets uploaded to Gumband will be synced to the specified folder. Active user must have write permission for this directory. It is advised use an absolute instead of relative path. This value can be set to null to explicitly not sync any files.
  • skipOrganizationFileSync (boolean): Set to false to sync organization level files. Defaults to true.
// optional contructor parameters example
const gb = new Gumband(
  "a986dc223cc137xxxxxxxxxxxxxxx", // exhibit token
  "6", // exhibit ID
  "/path/to/manifest.json", // manifest path
  {
    endpoint: "custom", // local, dev, stag, app, or custom (set to 'app' by default)
    customServerIP: "test.gumband.com", // or an IP address such as '192.168.1.1' (ignored unless endpoint=custom)
    version: "v1", // api version
    contentLocation: "/path/to/content", // a directory to sync files in or null to not sync content
    skipOrganizationFileSync: false, // whether or not to skip the org level file syncing
  }
);

Using the SDK

The Gumband class provides you with methods to make requests to our API and Surfaces Websocket and Hardware events as an EventEmitter. Combining our example manifest.json and our example exhibit code above, here is an example of how to interact with Gumband with a properly configured instance of the Gumband class.

The js example below and manifest.json example above have been included in the npm package as files example.js and manifest.json as a place to start. For a more in depth example of interacting with these methods, events, and a walkthrough of building something out from scratch, check out our Quick Start Guide.

const { Gumband, Sockets } = require("@deeplocal/gumband-node-sdk");

const gb = new Gumband(
  "a986dc223cc137xxxxxxxxxxxxxxx", // exhibit token
  "6", // exhibit ID
  "/path/to/manifest.json" // manifest path
);

// Register callback for when Gumband is ready to be used
// No Gumband SDK functions should be called before this event fires
gb.on(Sockets.READY, async () => {
  // Get and set statuses
  await gb.setStatus("ip_address", "0.0.0.0");
  const status = await gb.getStatus("ip_address");
  console.log(status);

  // Get and set settings
  await gb.setSetting("kiosk_name", "a new value");
  const setting = await gb.getSetting("kiosk_name");
  console.log(setting);

  // Get and set operating mode
  await gb.setOperatingMode(true);
  const opMode = await gb.getOperatingMode();
  console.log(opMode);

  // Send logs
  await gb.logger.info("Log info text.");
  await gb.logger.debug("Log debug text.");
  await gb.logger.warn("Log warn text.");
  await gb.logger.error("Log error text.");

  // Report an analytics event (second param can be key-value pairs)
  await gb.event.create("HardwareFailure", {
    data: "The hardware has failed",
    value: 1,
  });

  // Send an event to hardware
  await gb.hardware.set("17/switch1/switch", 1);
});

// You can listen for events and importantly register multiple listeners!
// It is OK to do this prior to the Sockets.READY event

// Do something when the exhibit is turned on or off in the dashboard
gb.on(Sockets.OP_MODE_RECEIVED, (payload) => {
  console.log(payload);
});

// Do something when a setting is updated
gb.on(Sockets.SETTING_RECEIVED, (payload) => {
  console.log(payload);
});

// Do something when a control is triggered
gb.on(Sockets.CONTROL_RECEIVED, (payload) => {
  console.log(payload);
});

// Sync files when a file is uploaded
// Assumes a contentLocation directory is specified in the constructor
gb.on(Sockets.FILE_UPLOADED, async (data) => {
  console.log(`User uploaded ${data.fileName} to exhibit`);
  await gb.content.sync();
  console.log("Downloaded new files!");
});

// Notify when a file is deleted
// Assumes a contentLocation directory is specified in the constructor
gb.on(Sockets.FILE_DELETED, (data) => {
  console.log(`User deleted ${data.fileName} from exhibit`);
  // The SDK does not automatically delete files so potentially delete the file here
});

// Do something when receiving data from hardware
// Assumes a Gumband Hardware is connected to this exhibit.
gb.on(Sockets.HARDWARE_PROPERTY_RECEIVED, (payload) => {
  console.log(payload);
});

Optional Environment Variables

You can set a few environment variables to control functionality of the Gumband SDK:

  • GB_LOCAL_LOG_LEVEL (string): what level of logs to be displayed, options { debug, info, warn, error }, defaults to warn
  • GB_MUTE_HEARTBEAT (boolean): whether or not to mute the heartbeat logs, defaults to false

Settings Groups Usage

As shown in the above example, you can define a setting of type SettingsGroup. This is different from other settings, in that it allows you to define a schema for a group unit of settings. Settings created within a group follow the naming schema settingsGroupId/settingID. You are also able to nest settings groups within other settings groups, and the nested groups also follow the above naming schema (ie. settingsGroupId/nestedGroupId/settingID). When the settings within a group are updated, they follow the same communication pipelines as normal settings.

Setting Lists Usage

As shown in the above example, you can define a setting of type SettingsList. This is different from other settings, in that it allows you to define a schema for a group unit of settings. Once you define this group unit of settings, you can add (and remove) an arbitrary number of these setting units through the gumband web interface. Settings created within a group follow the naming schema settingsListId/groupName/settingID. You are also able to nest settings lists within other settings lists, and the nested groups also follow the above naming schema (ie. settingsListId/groupName/nestedListId/nestedGroupName/settingID). When the settings nested within a group are updated, they follow the same communication pipelines as normal settings.

A note for parsing Settings Lists:

When fetching settings lists and their values, via the getAllSettingLists call, your return will be formatted with all top level settings groups in an array (ie. ImageGroups, Employees, ...) where each item is a group Object. This object contains information about the group, and contains all the groups sub-settings under the settinglistitems field. If the settings list contains a nested settings list, that nested list will appear in the settinglistitems field as well.

Locally stored values

Another feature of the Gumband class is that it locally stores setting and status values from the Websocket events and 'set' methods in the SDK. This improves the responsiveness of the 'get' methods because your exhibit won't have to wait for an http request while the websocket connection is active. In our testing, we've found our websocket connection to be reliable. However, if the websocket ever fails to catch and surface an event, the locally stored values may be outdated. To force the locally stored values to update with the Gumband web services' values, you can restart your exhibit or run syncManifest().

Connecting to hardware (optional)

  1. Go to the Gumband Dashboard and make sure Hardware is created. If not, assuming you have the necessary permissions, create a Hardware device. Make sure the Hardware is in the same Organization and Site as your Exhibit.
  2. Under the "Overview" tab in the Hardware page, select "Connect to Exhibit" and select the desired Exhibit to connect to.
  3. Next time you run the Exhibit SDK, it will automatically pull in the Hardware information and wait for an incomming Hardware registration through GBTT.
  4. Verify that the Hardware device points to the Exhibit's GBTT endpoint (default port: 8883) and that it is sending the correct Hardware ID and Hardware Authentication Token.

Optional Constructor Parameters for hardware

  • gbttEnabled (boolean): Set to true to run the MQTT broker for hardware communication, defaults to false.
  • gbttPort (number): What port to run the MQTT broker, defaults to 1883.
  • noInternetConnection (boolean): Whether the exhibit will run in offline mode. Default is false. This is mostly useful for when an exhibit is going to run without an internet connection but still wants to communicate with Gumband hardware through MQTT.
  • noInternetHardwareIds (string[]): Specify an array of Gumband hardware IDs to allow to connect to this exhibit. Used in conjunction with noInternetConnection=true. Warning: this will allow any hardware with the specified IDs to send and receive data from the exhibit without authentication.
// optional construct parameters for hardware example
const gb = new Gumband(
  "a986dc223cc137xxxxxxxxxxxxxxx", // exhibit token
  "6", // exhibit ID
  "/path/to/manifest.json", // manifest path
  {
    gbttEnabled: false, // or true to enable the hardware MQTT broker (set to false by default)
    gbttPort: 8884, // port for the MQTT broker, defaults to 1883
    noInternetConnection: false, // true if the SDK needs to run in offline mode (set to false by default)
    noInternetHardwareIds: [], // array of offline hardware IDs to accept messages from (without auth)
  }
);

Developing the SDK

  1. To initialize the SDK for local development, run the command git submodule update --recursive --remote to pull in all necessary submodules.
  2. To develop the SDK, create a copy of the template-test-scripts/ folder and name it local-test/ (the naming is important because it is git-ignored).
  3. Modify the Exhibit token and Exhibit ID to point to an exhibit in your local environment.
  4. Test exhibit while editing the SDK source folder in lib/.
1.1.8

6 days ago

1.1.7

1 month ago

1.1.6

2 months ago

1.1.5

2 months ago

1.1.4

2 months ago

1.1.3

2 months ago

1.1.2

2 months ago

1.1.0-alpha-0

8 months ago

1.1.0-alpha-1

8 months ago

1.1.0-beta-0

8 months ago

1.0.58-beta.1

8 months ago

1.0.58-beta.0

8 months ago

1.1.1

7 months ago

1.0.48

10 months ago

1.0.49

10 months ago

1.0.51

10 months ago

1.0.50

10 months ago

1.0.55

10 months ago

1.0.54

10 months ago

1.0.53

10 months ago

1.0.52

10 months ago

1.0.57

8 months ago

1.0.56

9 months ago

1.0.44

1 year ago

1.0.47

11 months ago

1.0.46

11 months ago

1.0.45

12 months ago

1.0.43

1 year ago

1.0.39

1 year ago

1.0.40

1 year ago

1.0.42

1 year ago

1.0.41

1 year ago

1.0.38

1 year ago

1.0.37

2 years ago

1.0.36

2 years ago

1.0.33

2 years ago

1.0.32

2 years ago

1.0.35

2 years ago

1.0.34

2 years ago

1.0.31

2 years ago

1.0.30

2 years ago

1.0.29

2 years ago

1.0.28

2 years ago

1.0.26

2 years ago

1.0.27

2 years ago

1.0.25

2 years ago

1.0.24

2 years ago

1.0.23

3 years ago

1.0.22

3 years ago

1.0.21

3 years ago

1.0.20

3 years ago

1.0.19

3 years ago

1.0.18

3 years ago

1.0.17

3 years ago

1.0.16

4 years ago

1.0.15

4 years ago

1.0.14

4 years ago

1.0.13

4 years ago

1.0.12

4 years ago

1.0.11

4 years ago

1.0.10

4 years ago

1.0.9

4 years ago

1.0.8

4 years ago

1.0.7

4 years ago

1.0.6

4 years ago

1.0.5

4 years ago

1.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago