Scaling an IoT deployment? Join our webinar on May 28th where we dive into real-world scaling pain points and how to overcome them.

Blues Developers
What’s New
Resources
Blog
Technical articles for developers
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Developer Certification
Get certified on wireless connectivity with Blues
Webinars
Listing of Blues technical webinars
Blues.comNotehub.io
Shop
Docs
Button IconHelp
Notehub StatusVisit our Forum
Button IconSign In
Sign In
Sign In
Docs Home
What’s New
Resources
Blog
Technical articles for developers
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Developer Certification
Get certified on wireless connectivity with Blues
Webinars
Listing of Blues technical webinars
Blues.comNotehub.io
Shop
Docs
Notecard
Notecard API Reference
Notecard Guides
Notecard Firmware Releases
Notecard Walkthrough
Overview
Notecard Product Family
Notecard Requests & Responses
JSON Fundamentals
Notecard Interfaces
Essential Requests
Time & Location Requests
Inbound Requests & Shared Data
Sending Data Through NotehubHandling Inbound NotesUsing Database Files for Replicated StateUsing Change Trackers with Inbound DataHandling Notecard InterruptsMiscellaneous File Requests
Web Transactions
Low Power Design
Low Bandwidth Design
Working with the Notecard AUX Pins
Updating Notecard Firmware
Advanced Notecard Configuration
Notecard Error and Status Codes
Notecard Certifications
homechevron_rightDocschevron_rightNotecardchevron_rightNotecard Walkthroughchevron_rightInbound Requests & Shared Data

Inbound Requests & Shared Data

All of the scenarios discussed so far in this guide are focused on performing requests directly against the Notecard from a host, and synching data from the Notecard to Notehub. This type of data is called "outbound data" because it is data that starts on the Notecard and is synchronized to Notehub. In other words it is "outbound" from the perspective of the Notecard.

Many solutions, however, will need to initiate data or requests from a cloud app or external service, and propagate that request down to the Notecard. This data is called "inbound data" because it is data that originates somewhere else and is synchronized to the Notecard. In other words, it is "inbound" from the perspective of the Notecard.

Using the API requests detailed below, you can perform inbound requests to:

  • Share state between the Notecard and Notehub.
  • Notify the host that new data is available.

Once available, a host can retrieve inbound data from the Notecard, and respond accordingly.

Sending Data Through Notehub

Inbound requests are requests that originate somewhere other than the Notecard, and are sent to the Notecard from Notehub. These requests are created either directly in the Notehub UI or by using the Notehub API.

Adding Inbound Notes in Notehub

To add a Note that will sync to the Notecard from the Notehub UI, navigate to the Devices dashboard, select your device, and click the "+ Note" button. In the modal, select the Notefile for your Note (the default is data.qi) and add the Note body as a JSON object.

note

This approach only supports adding inbound queue files with the .qi or .qis extensions. If you need to add Notes to a DB file, use the Notehub API, as described below.

Also, inbound Notes MUST use Note Templates (defined on the Notecard) if using with Notecard LoRa or NTN mode with Starnote.

adding an inbound note with the notehub ui

Adding Notes for Secure Transport

If you want to ensure that Notes are sent over encrypted TLS to the Notecard, use the .qis extension when specifying the Notefile. .qis signifies that the Notefile is a secure inbound queue.

adding a secure inbound note with the notehub ui

Adding Inbound Notes with the Notehub.io API

Alternatively, you may use the Notehub API to add inbound notes to Notehub. This approach works for both .qi/.qis and .db Notefiles.

For example, here's how to add a Note to the default data.qi file using curl.

curl -X POST
    -L 'https://api.notefile.net/v1/projects/<projectUID>/devices/<deviceUID>/notes/data.qi'
    -H 'Authorization: Bearer <access_token>'
    -d '{"body":{"key-1":"val-1"}}'

Here's an example for adding a new Note named sync-settings to a DB file named my-settings.db:

curl -X PUT
    -L 'https://api.notefile.net/v1/projects/<projectUID>/devices/<deviceUID>/notes/my-settings.db/sync-settings'
    -H 'Authorization: Bearer <access_token>'
    -d '{"body": {"interval": 60 }}'
note

Notehub API requests are authorized via OAuth bearer tokens. Consult the Notehub API documentation for more information.

Using Inbound Notefiles with Starnote

As a data-constrained satellite communication device, using NTN mode with Starnote requires the user to specifically request a check for inbound Notefiles from Notehub to minimize data usage. This is handled with the "in":true argument in the hub.sync API:

{
  "req": "hub.sync",
  "in": true
}

Also, as mentioned above, inbound Notefiles must use Note Templates that are pre-defined on the Notecard when using NTN mode with Starnote.

Handling Inbound Notes

After a successful sync, inbound Notes and Notefiles are available to your Notecard. To get an overview of new data across all of your files, use the file.changes request with no arguments.

{
  "req": "file.changes"
}
J *req = NoteNewRequest("file.changes");

NoteRequest(req);
req = {"req": "file.changes"}

rsp = card.Transaction(req)

When passed with no arguments, file.changes returns an object with the total number of new notes across all files, and the totals for each file, by name.

{
 "total": 2,
 "info": {
  "my-settings.db": {
   "total": 2
  },
  "data.qi": {
   "total": 1
  }
 }
}

To obtain a summary of changes across a subset of available files, use the files argument and an array containing the file or files you're interested in.

{
  "req": "file.changes",
  "files": ["data.qi"]
}
J *req = NoteNewRequest("file.changes");

J *files = JAddArrayToObject(req, "files");
JAddItemToArray(files, JCreateString("data.qi"));

NoteRequest(req);
req = {"req": "file.changes"}
req["files"] = ["data.qi"]

rsp = card.Transaction(req)

The response object is similar to the previous request, but returns only data for the files you specified.

{
 "total": 1,
 "info": {
  "data.qi": {
   "total": 1
  }
 }
}

Once you've confirmed that inbound Notes are available, use the note.get request to retrieve them. Use the file argument to specify the name of the Notefile, or omit it to fetch a single Note from the data.qi Notefile.

{
  "req": "note.get",
  "file": "requests.qi"
}
J *req = NoteNewRequest("note.get");
JAddStringToObject(req, "file", "requests.qi");

NoteRequest(req);
req = {"req": "note.get"}
req["file"] = "requests.qi"

rsp = card.Transaction(req)

Following queuing semantics, this request will return oldest available Note in the requests.qi Notefile, and the time it was created in Notehub.

{
 "body": {
  "api-key1": "api-val1"
 },
 "time": 1598909219
}

note.get does not, by default, remove a Note when you request it, so repeated calls will return the same Note, even if multiple Notes are available in the Notefile. To delete a Note after retrieval, use the delete argument. Subsequent requests will return and delete successive Notes in the Notefile.

{
  "req": "note.get",
  "file": "requests.qi",
  "delete": true
}
J *req = NoteNewRequest("note.get");
JAddStringToObject(req, "file", "requests.qi");
JAddBoolToObject(req, "delete", true);

NoteRequest(req);
req = {"req": "note.get"}
req["file"] = "requests.qi"
req["delete"] = True

rsp = card.Transaction(req)

Using Database Files for Replicated State

Queued Notefiles (.qo, .qos, .qi, and .qis) are uni-directional in nature, and are not ideal for replicating state or settings between the Notecard and Notehub. For replicated state, use DB Notefiles. These files, which have a .db or .dbs extension, are synchronized between the Notecard and Notehub, and contain Notes that can be individually read and updated.

Adding and Updating Notes in DB Notefiles

Add Notes to a DB file with the note.add request. In addition to a Notefile ID (file), adding Notes to a DB file requires a Note ID (note). The Note ID is used to manage the Note directly, because DB Notefiles hold shared state that is synchronized between the Notecard and Notehub.

note

See the Bash tabs in the note Requests API docs for examples on adding/managing Notefiles with the Notehub API.

{
  "req": "note.add",
  "file": "my-settings.db",
  "note": "measurements",
  "body": {"interval": 10}
}
J *req = NoteNewRequest("note.add");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "note", "measurements");

J *body = JCreateObject();
JAddNumberToObject(body, "interval", 10);
JAddItemToObject(req, "body", body);

NoteRequest(req);
req = {"req": "note.add"}
req["file"] = "my-settings.db"
req["note"] = "measurements"
req["body"] = {"interval": 10 }

rsp = card.Transaction(req)

As with other note.add requests, a payload can be provided instead of, or in addition to, a body.

{
  "req": "note.add",
  "file": "my-settings.db",
  "note": "measurements",
  "payload": "ewogICAgInRlbXAiOiAyMy4xMzQKfQ=="
}
J *req = NoteNewRequest("note.add");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "note", "measurements");
JAddStringToObject(req, "payload", "ewogICAgInRlbXAiOiAyMy4xMzQKfQ==");

NoteRequest(req);
req = {"req": "note.add"}
req["file"] = "my-settings.db"
req["note"] = "measurements"
req["payload"] = "ewogICAgInRlbXAiOiAyMy4xMzQKfQ=="

rsp = card.Transaction(req)

To update a Note in a DB Notefile, use the note.update request. Provide a new body or payload to replace the existing Note content.

{
  "req": "note.update",
  "file": "my-settings.db",
  "note": "measurements",
  "body": {"interval": 60 }
}
J *req = NoteNewRequest("note.update");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "note", "measurements");

J *body = JCreateObject();
JAddNumberToObject(body, "interval", 60);
JAddItemToObject(req, "body", body);

NoteRequest(req);
req = {"req": "note.update"}
req["file"] = "my-settings.db"
req["note"] = "measurements"
req["body"] = {"interval": 60 }

card.Transaction(req)

Fetching Notes from DB Notefiles

To retrieve a Note from a DB Notefile, use the note.get request and provide the file and note arguments with the Notefile ID and Note ID, respectively.

{
  "req": "note.get",
  "file": "my-settings.db",
  "note": "measurements"
}
J *req = NoteNewRequest("note.get");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "note", "measurements");

NoteRequest(req);
req = {"req": "note.get"}
req["file"] = "my-settings.db"
req["note"] = "measurements"

rsp = card.Transaction(req)

The request above will return the measurements Note in the my-settings.db Notefile and the time of creation or the most recent update (shown below).

{
 "note": "measurements",
 "body": {
  "interval": 60
 },
 "time": 1598916085
}

Deleting Notes from a DB Notefile

To delete a DB Note after retrieval, use the delete argument.

{
  "req": "note.get",
  "file": "my-settings.db",
  "note": "measurements",
  "delete": true
}
J *req = NoteNewRequest("note.get");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "note", "measurements");
JAddBoolToObject(req, "delete", true);

NoteRequest(req);
req = {"req": "note.get"}
req["file"] = "my-settings.db"
req["note"] = "measurements"
req["delete"] = True

rsp = card.Transaction(req)

Alternatively, if you do not need to retrieve the Note, delete the Note with the note.delete request. If successful, this request will return an empty JSON object ({}).

{
  "req": "note.delete",
  "file": "my-settings.db",
  "note": "measurements"
}
J *req = NoteNewRequest("note.delete");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "note", "measurements");

NoteRequest(req);
req = {"req": "note.delete"}
req["file"] = "my-settings.db"
req["note"] = "measurements"

card.Transaction(req)

Because DB Notefiles are shared between the Notecard and Notehub, updates and deletions made by either are reconciled during each sync.

Using Database Notefiles for Local-Only State

Sometimes, your host may wish to use the Notecard to store application state or configuration, but you do not want that state to be synchronized to Notehub. For these cases, you can use the .dbx extension to create a Local-only Notefile. The semantics for adding, updating, and deleting local-only Database Notefiles is the same as detailed above for replicated Database files.

{
  "req": "note.add",
  "file": "local-config.dbx",
  "note": "sensor-types",
  "body": {"temp": "si7201", "gas": "bme680"}
}
J *req = NoteNewRequest("note.add");
JAddStringToObject(req, "file", "local-config.dbx");
JAddStringToObject(req, "note", "sensor-types");

J *body = JCreateObject();
JAddStringToObject(body, "temp", "si7201");
JAddStringToObject(body, "gas", "bme680");
JAddItemToObject(req, "body", body);

NoteRequest(req);
req = {"req": "note.add"}
req["file"] = "local-config.dbx"
req["note"] = "sensor-types"
req["body"] = {"temp": "si7201", "gas": "bme680"}

rsp = card.Transaction(req)

Using Change Trackers with Inbound Data

If your host needs to work with inbound data on a regular basis within and across Notefiles, you can use a change tracker to incrementally work with inbound data. A change tracker is identified by a developer-defined string, like my_inbound_requests, and used to associate additions and deletions to Notefiles.

note

Change trackers are associated with their respective files. Once a change tracker is created, it will consume resources until the changes have been queried. As a result, change trackers should not be created without a plan to consume the accumulated changes, and should be removed when no longer needed.

warning

Change trackers are not supported on Notecard LoRa.

Configuring a Change Tracker for a Notefile

To set-up a change tracker for a single file, use the note.changes request with the Notefile ID as file, and a change tracker ID in the tracker argument.

{
  "req": "note.changes",
  "file": "my-settings.db",
  "tracker": "my_inbound_requests"
}
J *req = NoteNewRequest("note.changes");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "tracker", "my_inbound_requests");

NoteRequest(req);
req = {"req": "note.changes"}
req["file"] = "my-settings.db"
req["tracker"] = "my_inbound_requests"

rsp = card.Transaction(req)

This request returns an object with the total number of Notes in the Notefile, the total number of Notes changed since the change tracker was started, and an object containing each Note body, organized by ID.

{
  "changes": 4,
  "total": 4,
  "notes": {
    "setting-one": { "body": { "foo": "bar" }, "time": 1598918235 },
    "setting-two": { "body": { "foo": "bat" }, "time": 1598918245 },
    "setting-three": { "body": { "foo": "baz" }, "time": 1598918225 },
    "setting-four": { "body": { "foo": "foo" }, "time": 1598910532 }
  }
}

On the first call, a tracker is instantiated, and the inbound tracker lists all existing Notes in a Notefile. When a tracker is instantiated, the state changes from zero Notes being tracked, to all the Notes in a Notefile being tracked. As a result, the list of changes, or all notes, are displayed.

Change trackers on inbound queue Notefiles (.qi/.qis)

Using a change tracker on an inbound queue .qi./.qis is not recommended.

Notes in queues are expected to be consumed completely, making change trackers unnecessary. When used in such a manner, you may perform a note.get to check whether the queue is empty to detect if a change has occurred.

If you find you need long-lived data and your usage pattern does not align with the pattern outlined above, then your application by be better suited for use with a DB Notefile or environment variables.

However, if you elect to use a change tracker with .qi/.qis Notefiles, then be aware the Note ID is a system-generated, internal ID. Whereas in DB Notefiles, the Note ID is developer-specified.

.qi/.qis Tracker Response Example:

{
 "changes": 1,
 "total": 1,
 "notes": {
  "1:495": {...}
 }
}

Continuing with the example above, assume three more settings have been added to the DB Notefile, my-settings.db.

Use the max argument to limit the number of notes returned when querying a change tracker.

{
  "req": "note.changes",
  "file": "my-settings.db",
  "tracker": "my_inbound_requests",
  "max": 2
}
J *req = NoteNewRequest("note.changes");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "tracker", "my_inbound_requests");
JAddNumberToObject(req, "max", 2);

NoteRequest(req);
req = {"req": "note.changes"}
req["file"] = "my-settings.db"
req["tracker"] = "my_inbound_requests"
req["max"] = 2

rsp = card.Transaction(req)

Subsequent calls to note.changes will display changed files only, while hiding previously viewed changes.

// First Request
{
  "changes": 3,
  "total":   7,
  "notes":   {
    "setting-five": {"body":{"bim": "bam"},"time":1598912838},
    "setting-six": {"body":{"bing": "bong"},"time":1598923484}
  }
}

// Second Request
{
  "changes": 1,
  "total":   7,
  "notes":   {
    "setting-seven": {"body":{"zip": "zap"},"time":1598927365}
  }
}

// Third Request
{"total":7}

Notes will be retrieved incrementally until all Notes are returned, at which point an object with only the total field is returned.

By default, Notes returned in note.changes are not deleted. If you want to delete them from the Notefile set the delete argument to true.

{
  "req": "note.changes",
  "file": "my-settings.db",
  "tracker": "my_inbound_requests",
  "delete": true
}
J *req = NoteNewRequest("note.changes");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "tracker", "my_inbound_requests");
JAddBoolToObject(req, "delete", true);

NoteRequest(req);
req = {"req": "note.changes"}
req["file"] = "my-settings.db"
req["tracker"] = "my_inbound_requests"
req["delete"] = True

rsp = card.Transaction(req)

Resetting a Change Tracker

If changes need to be reprocessed for any given reason, the reset parameter allows you to reset the change counter and tracker to their original states.

To reset a change tracker, perform a request to note.changes with the Notefile and change tracker id, and set the reset argument to true.

{
  "req": "note.changes",
  "file": "my-settings.db",
  "tracker": "my_inbound_requests",
  "reset": true
}
J *req = NoteNewRequest("note.changes");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "tracker", "my_inbound_requests");
JAddBoolToObject(req, "reset", true);

NoteRequest(req);
req = {"req": "note.changes"}
req["file"] = "my-settings.db"
req["tracker"] = "my_inbound_requests"
req["reset"] = True

rsp = card.Transaction(req)

Deleting a Change Tracker

Change trackers are meant to be long-lived and enable you to easily scan for changes on the Notecard at any time. As such, you won't often need to delete a change tracker unless the needs of your application change.

To delete a change tracker, perform a request to note.changes with the Notefile and change tracker id, and set the stop argument to true.

{
  "req": "note.changes",
  "file": "my-settings.db",
  "tracker": "my_inbound_requests",
  "stop": true
}
J *req = NoteNewRequest("note.changes");
JAddStringToObject(req, "file", "my-settings.db");
JAddStringToObject(req, "tracker", "my_inbound_requests");
JAddBoolToObject(req, "stop", true);

NoteRequest(req);
req = {"req": "note.changes"}
req["file"] = "my-settings.db"
req["tracker"] = "my_inbound_requests"
req["stop"] = True

rsp = card.Transaction(req)

Using Change Trackers Across Multiple Notefiles

To use a change tracker with multiple files, use the tracker argument with the file.changes request, and provide a list of files to track.

Analogous to note.changes, the first request will create trackers of the same name on each of the Notefiles listed, and each subsequent request will query those existing trackers and return the results as a single response.

{
  "req": "file.changes",
  "tracker": "multi-file-tracker",
  "files": ["my-settings.db", "other-settings.db"]
}
J *req = NoteNewRequest("file.changes");
JAddStringToObject(req, "tracker", "multi-file-tracker");

J *files = JAddArrayToObject(req, "files");
JAddItemToArray(files, JCreateString("other-settings.db"));
JAddItemToArray(files, JCreateString("my-settings.db"));

NoteRequest(req);
req = {"req": "file.changes"}
req["tracker"] = "multi-file-tracker"
req["files"] = ["my-settings.db", "other-settings.db"]

rsp = card.Transaction(req)

The response returns the number of changes per file, as well as the total changes across all files.

{
  "changes": 5,
  "total": 5,
  "info": {
    "my-settings.db": { "changes": 3, "total": 3 },
    "other-settings.db": { "changes": 2, "total": 2 }
  }
}

Using the file.changes tracker syntax provides an efficient way to quickly query several files and determine which files have changed. Once the changed files are known, you can process those individual Notefiles using the note.changes API outlined above.

Handling Notecard Interrupts

Host applications that interface with the Notecard often need to determine if the Notecard has received inbound data for the host to process. This can be achieved through periodic polling and the use of change trackers, as described in Using Change Trackers with Inbound Data. However, this approach can be power-intensive on the host and difficult to optimize for low-power applications. As such, the Notecard exposes a hardware pin called ATTN (referred to as the "attention pin"), which is used to notify the host that the Notecard has detected an event of interest. The card.attn request is used to configure the behavior of the ATTN pin.

Depending upon its configuration, the Notecard can notify the host MCU in one or more of the following scenarios:

  • When the Notecard receives a Note in specified Notefiles.
  • When the Notecard connects to Notehub.
  • When the Notecard detects motion.
  • When the Notecard detects a location change.
  • When the Notecard detects a change to its network state.
  • When the Notecard is configured as a Watchdog timer.

Interrupt behavior

Arming the interrupt causes the Notecard to pull the ATTN pin LOW. When armed, the GPIO connected to the Notecard attention pin will also read LOW, unless one of the monitored events occurs, in which case the pin will read HIGH. The interrupt is a latching interrupt. This means once it is armed, it will stay LOW until it has been disarmed or fired, and conversely, once fired it will remain HIGH until it has been rearmed.

note

In order to take full advantage of this behavior, you must correctly configure your host microcontroller. The two most common configurations, are attaching the Notecard's ATTN pin to an interrupt capable GPIO pin or to the chip enable (EN) pin on the host MCU. In either case, your host MCU should respond by obtaining inbound file changes, rearming the interrupt, or performing other application specific actions.

Configuring the Attention Pin

In a card.attn request, the mode argument is the primary interface for configuring the attention configurations described below. In addition, this argument is used to arm and disarm the attention pin, ATTN. The mode argument accepts both single arguments, and a comma-separated list of keywords that enable the configurations described below.

Disarming the Attention Pin

To disarm the pin, pass disarm into the mode argument. Disarming the attention pin pulls the pin HIGH.

{
  "req": "card.attn",
  "mode": "disarm"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "disarm");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "disarm"

card.Transaction(req)

As of Notecard firmware v3.2.1, if you have multiple attention modes configured as detailed below, you can disarm all of these at once with the -all flag.

{
  "req": "card.attn",
  "mode": "disarm,-all"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "disarm,-all");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "disarm,-all"

card.Transaction(req)

Arming the Attention Pin

To arm the attention pin, pass arm into the mode argument of a card.attn request, along with the optional keywords or parameters that correspond with your desired configuration.

Setting an Attention Timeout

The simplest attention mode configuration is to arm the pin, and instruct the Notecard to bring the pin HIGH after a timeout of n seconds. You can do this with the seconds argument, and by setting mode to arm.

{
  "req": "card.attn",
  "mode": "arm",
  "seconds": 10
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "arm");
JAddNumberToObject(req, "seconds", 10);

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "arm"
req["seconds"] = 10

card.Transaction(req)

This request will return an empty JSON object ({}). Then, after the timeout has elapsed, the attention pin will be pulled HIGH by the Notecard. You can confirm that the attention pin has fired by making a request to card.attn with no arguments.

{
  "req": "card.attn"
}
J *req = NoteNewRequest("card.attn");

NoteRequest(req);
req = {"req": "card.attn"}

card.Transaction(req)

This request will return an object with a boolean, set, reflecting the state of the ATTN pin and a files array. The files array contains the timeout keyword, reflecting a timeout has occurred.

{
  "files": ["timeout"],
  "set": true
}

If the attention pin has not fired, a request to card.attn will return an empty JSON object ({}).

note

The files parameter is used as an input/output parameter with a list of files to watch for changes, and also to receive a list of Notefile IDs that have changed when using files mode.

Watching for File Changes

If you want your host to be notified when the Notecard detects file changes, use files in the mode argument, as well as the files argument to provide an array of one or more Notefiles to watch.

{
  "req": "card.attn",
  "mode": "arm,files",
  "files": ["data.qi", "my-settings.db"]
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "arm, files");

J *files = JAddArrayToObject(req, "files");
JAddItemToArray(files, JCreateString("data.qi"));
JAddItemToArray(files, JCreateString("my-settings.db"));

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "arm, files"
req["files"] = ["data.qi", "my-settings.db"]

card.Transaction(req)

Alternatively, pass an empty string array to the files argument to watch all Notefiles on the Notecard.

{
  "req": "card.attn",
  "mode": "arm,files",
  "files": [""]
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "arm, files");

J *files = JAddArrayToObject(req, "files");
JAddItemToArray(files, JCreateString(""));

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "arm, files"
req["files"] = [""]

card.Transaction(req)

The interrupt fires when the Notecard detects a change to a watched file. You can use a no argument card.attn request to determine which file has changed. The response object will contain the name of the modified file, so you can issue a note.changes request to get new or modified Notes.

{
  "files": ["data.qi", "modified"],
  "set": true
}

To disable file mode, issue another card.attn request, and add a dash before the files string in the mode argument to indicate that it should be disabled.

{
  "req": "card.attn",
  "mode": "-files"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "-files");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "-files"

card.Transaction(req)

Watching for Service Connections

The attention pin can be set to fire whenever the Notecard successfully connects to Notehub with the connected string in the mode argument.

{
  "req": "card.attn",
  "mode": "arm,connected"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "arm,connected");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "arm,connected"

card.Transaction(req)

The interrupt fires the next time the Notecard connects. You can use a no argument, card.attn request to confirm the reason. In connection mode, the files array in a card.attn response object will include the connected string.

{
  "files": ["connected"],
  "set": true
}

To disable connection mode, issue another card.attn request, and add a dash before the connected string in the mode argument to indicate that it should be disabled.

{
  "req": "card.attn",
  "mode": "-connected"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "-connected");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "-connected"

card.Transaction(req)

Watching for Notecard Motion

The attention pin can be set to fire whenever the Notecard accelerometer detects motion with the motion string in the mode argument.

{
  "req": "card.attn",
  "mode": "arm,motion"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "arm,motion");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "arm,motion"

card.Transaction(req)

The interrupt fires when the accelerometer detects movement. You can use a no argument card.attn request to confirm the reason. In motion mode, the files array in a card.attn response object will include the motion string.

{
  "files": ["motion"],
  "set": true
}

To disable motion mode, issue another card.attn request, and add a dash before the motion string in the mode argument to indicate that it should be disabled.

{
  "req": "card.attn",
  "mode": "-motion"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "-motion");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "-motion"

card.Transaction(req)

Watching for Notecard Location Updates

The attention pin can be set to fire whenever the Notecard GPS/GNSS module detects a location update with the location string in the mode argument.

{
  "req": "card.attn",
  "mode": "arm,location"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "arm,location");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "arm,location"

card.Transaction(req)

The interrupt fires when a location change is detected. You can use a no argument card.attn request to confirm the reason. In location mode, the files array in a card.attn response object will include the location string.

{
  "files": ["location"],
  "set": true
}

To disable location mode, issue another card.attn request, and add a dash before the location string in the mode argument to indicate that it should be disabled.

{
  "req": "card.attn",
  "mode": "-location"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "-location");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "-location"

card.Transaction(req)

Watching for Environment Variable Changes

The attention pin can be set to fire whenever the Notecard detects an Environment Variable update with the env string in the mode argument.

{
  "req": "card.attn",
  "mode": "arm,env"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "arm,env");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "arm,env"

card.Transaction(req)

The interrupt fires when an Environment Variable change is detected. You can use a no argument card.attn request to confirm the reason. In env mode, the files array in a card.attn response object will include the env string.

{
  "files": ["env"],
  "set": true
}

To disable env mode, issue another card.attn request, and add a dash before the env string in the mode argument to indicate that it should be disabled.

{
  "req": "card.attn",
  "mode": "-env"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "-env");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "-env"

card.Transaction(req)

Watching for Notecard Network Status Changes

The attention pin can be set to fire whenever the Notecard detects a change in the network status it communicates via the card.wireless request.

{
  "req": "card.attn",
  "mode": "arm,wireless"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "arm,wireless");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "arm,wireless"

card.Transaction(req)

The interrupt fires when a network status change is detected. You can use a no argument card.wireless request to inspect the change. In wireless mode, the files array in a card.attn response object will include the wireless string.

{
  "files": ["wireless"],
  "set": true
}

To disable wireless mode, issue another card.attn request, and add a dash before the wireless string in the mode argument to indicate that it should be disabled.

{
  "req": "card.attn",
  "mode": "-wireless"
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "-wireless");

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "-wireless"

card.Transaction(req)

Using Multiple Modes Together

The modes described above are not mutually-exclusive, and can be used together. Simply provide a comma between each watch mode when calling card.attn:

{
  "req": "card.attn",
  "mode": "arm,files,connected,location",
  "files": ["data.qi"]
}
J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "arm,files,connected,location");

J *files = JAddArrayToObject(req, "files");
JAddItemToArray(files, JCreateString("data.qi"));

NoteRequest(req);
req = {"req": "card.attn"}
req["mode"] = "arm,files,connected,location"
req["files"] = ["data.qi"]

card.Transaction(req)

When multiple modes are used together, no argument calls to card.attn will identify all of the modes and files that caused the pin to fire.

{
  "files": ["data.qi", "motion", "connected"],
  "set": true
}

Miscellaneous File Requests

To obtain information about local Notefiles on the Notecard, use the file.stats request.

{
  "req": "file.stats"
}

This request returns a total number of notes across all Notefiles, a count of the number of Notes pending sync to Notehub (changes), if any, and a sync field of true if a sync is recommended based on the number of pending Notes. This field should be considered false, if not present.

{
 "changes": 1,
 "total": 4
}

For details on Notes pending sync, use the file.changes.pending request.

{
  "req": "file.changes.pending"
}

This request returns a pending boolean indicating whether any Notes are pending sync, total notes and changes across all files, as well as a per-file listing of pending changes.

{
 "changes": 2,
 "total": 2,
 "pending": true,
 "info": {
  "sensors.qo": {
   "changes": 1,
   "total": 1
  },
  "data.qo": {
   "changes": 1,
   "total": 1
  }
 }
}

Finally, to delete a Notefile and all of the Notes contained within, use the file.delete request. This request accepts a single argument files, which is an array of Notefiles to delete. If successful, this request will return an empty JSON object ({}).

{
  "req":  "file.delete",
  "files" ["sensors.qo"]
}
Time & Location Requests Web Transactions
Can we improve this page? Send us feedback
© 2025 Blues Inc.
© 2025 Blues Inc.
TermsPrivacy
Notecard Disconnected
Having trouble connecting?

Try changing your USB cable as some cables do not support transferring data. If that does not solve your problem, contact us at support@blues.com and we will get you set up with another tool to communicate with the Notecard.

Advanced Usage

The help command gives more info.

Connect a Notecard
Use USB to connect and start issuing requests from the browser.
Try Notecard Simulator
Experiment with Notecard's latest firmware on a Simulator assigned to your free Notehub account.

Don't have an account? Sign up