Time & Location Requests
Once the Notecard has connected to Notehub, there are a number of requests available for obtaining the time, location, and (on cellular-based Notecards) using the onboard GPS module for location tracking.
Obtaining the Current Time and Date
To obtain the current time, expressed as a Unix epoch value, use the card.time
request.
Upon power-up, the Notecard must complete a sync to Notehub in order to obtain time and location data.
{
"req": "card.time"
}
J *req = NoteNewRequest("card.time");
NoteRequest(req);
req = {"req": "card.time"}
rsp = card.Transaction(req)
Sending this request yields a response that includes the current UNIX Epoch
time
, local time zone
, minutes
East of GMT, latitude (lat
), longitude
(lon
), and country
.
{
"time": 1598478570,
"area": "Beverly, MA",
"zone": "CDT,America/New York",
"minutes": -300,
"lat": 42.577600,
"lon": -70.871340,
"country": "US",
}
Tower Location vs. Notecard Location
It's important to note that the location values returned by a card.time
request correspond to the cellular tower to which the Notecard
last connected. This may differ widely from the physical location of the
Notecard. For greater accuracy of location, you'll want to use
card.location
APIs described below.
Until the Notecard has connected to Notehub, it does not know the time. In those
cases, card.time
requests respond with a zone
value of UTC,Unknown
.
{"zone":"UTC,Unknown"}
Using Cell Tower & Wi-Fi Triangulation
For improved location accuracy without using GPS, the Notecard provides optional triangulation capabilities that can gather information about surrounding cell towers and/or local Wi-Fi access points to ascertain a location upon each new Notehub session.
Due to the low-power nature of the Notecard, triangulation-derived location data
is only available if the Notecard has detected motion with its onboard
accelerometer (unless overridden by card.triangulate
arguments).
Cell tower triangulation is available on the Notecard Cellular and Notecard Cell+WiFi. Cell tower triangulation should be used sparingly if your device is battery-powered, as it can add 1-2 minutes of connection time whenever the Notecard powers on the cellular modem to establish a connection with Notehub. Cell tower triangulation is disabled by default on all Notecards.
Wi-Fi triangulation is available on any Notecard that has access to a Wi-Fi module (either on the Notecard or on a connected host). Unlike cell tower triangulation, Wi-Fi triangulation adds only 1-2 seconds of processing time, uses minimal power, and can be nearly as accurate as a GPS-derived location. Wi-Fi triangulation is enabled by default on the Notecard WiFi and Notecard Cell+WiFi, and is disabled by default on the Notecard Cellular.
Wi-Fi triangulation is an experimental, technical preview feature that is free for use today, but may use Consumption Credits in the future. Blues reserves the right to rate limit excessive Wi-Fi triangulation requests at our discretion.
Enabling Triangulation
To enable triangulation, use the card.triangulate
request with the mode
argument set to wifi
, cell
, or both, separated by a comma:
{
"req": "card.triangulate",
"mode": "wifi,cell"
}
J *req = NoteNewRequest("card.triangulate");
JAddStringToObject(req, "mode", "wifi,cell");
NoteRequest(req);
req = {"req": "card.triangulate"}
req["mode"] = "wifi,cell"
rsp = card.Transaction(req)
This request will return an object confirming that triangulation is enabled with
the mode provided, and a motion
field indicating the last time device movement
was detected.
{
"mode": "wifi,cell",
"motion": 1606761044
}
Depending on your requirements, you may also need to change the frequency at
which triangulation data is processed on Notehub. The default is "Daily", which
means at most triangulation data will be processed once per day. This option is
available in the Settings of your Notehub project and also updatable as the
_tri_mins
environment variable:
The card.triangulate
request does not itself perform triangulation with the
Notecard. Rather, it gathers cell tower and/or Wi-Fi access point data that
Notehub uses to perform device triangulation. You'll see this information appear
in Notehub as _geolocate.qo
Notes.
Notehub performs triangulation requests at the start of new Sessions. Once a Session begins, the triangulated location for that Session will appear in all Notehub events that occur during that Session.
All triangulated location fields are prepended with tri_
and may be routed. For example:
"tri_when": 1656011112,
"tri_lat": 43.07113895,
"tri_lon": -89.43272533,
"tri_location": "Shorewood Hills WI",
"tri_country": "US",
"tri_timezone": "America/Chicago",
"tri_points": 16,
By default, the Notecard will not perform triangulation requests if the device is in motion
(as determined by the Notecard's onboard accelerometer). You can change this behavior with the
card.triangulate
request's on
and set
arguments.
Providing Wi-Fi Information to the Notecard
The Notecard WiFi and Notecard Cell+WiFi have onboard Wi-Fi modules that automatically scan access points and provide the appropriate information to Notehub to perform Wi-Fi triangulation requests.
If you are using a Notecard Cellular and would like to leverage Notehub's Wi-Fi
triangulation requests, you must manually retrieve this access-point information from
a connected host, and provide it to the card.triangulation
request's text
argument.
The format of the text
field must be a newline-terminated list of Wi-Fi access
points that follows a pattern similar to the
ESP32's AT+CWLAP
command output.
{
"req": "card.triangulate",
"text": "+CWLAP:(4,\"Blues\",-51,\"74:ac:b9:12:12:f8\",1)\n+CWLAP:(3,\"AAAA-62DD\",-70,\"6c:55:e8:91:62:e1\",11)\n+CWLAP:(4,\"Blues\",-81,\"74:ac:b9:11:12:23\",1)\n+CWLAP:(4,\"Blues\",-82,\"74:ac:a9:12:19:48\",11)\n+CWLAP:(4,\"Free Parking\",-83,\"02:18:4a:11:60:31\",6)\n+CWLAP:(5,\"GO\",-84,\"01:13:6a:13:90:30\",6)\n+CWLAP:(4,\"AAAA-5C62-2.4\",-85,\"d8:97:ba:7b:fd:60\",1)\n+CWLAP:(3,\"DIRECT-a5-HP MLP50\",-86,\"fa:da:0c:1b:16:a5\",6)\n+CWLAP:(3,\"DIRECT-c6-HP M182 LaserJet\",-88,\"da:12:65:44:31:c6\",6)\n\n"
}
J *req = NoteNewRequest("card.triangulate");
JAddStringToObject(req, "text", "+CWLAP:(4,\"Blues\",-51,\"74:ac:b9:16:15:f8\",1)\n+CWLAP:(3,\"CBCI-62DD\",-70,\"6c:55:e8:91:62:e1\",11)\n+CWLAP:(4,\"Blues\",-81,\"74:ac:b9:16:16:80\",1)\n+CWLAP:(4,\"Blues\",-82,\"74:ac:b9:16:19:48\",11)\n+CWLAP:(4,\"Free Parking\",-83,\"02:18:4a:13:90:31\",6)\n+CWLAP:(5,\"GO\",-84,\"02:18:4a:13:90:30\",6)\n+CWLAP:(3,\"\",-84,\"7a:8a:20:51:da:c7\",6)\n+CWLAP:(4,\"CBCI-5C62-2.4\",-85,\"d8:97:ba:7b:fd:60\",1)\n+CWLAP:(3,\"PBW\",-85,\"78:8a:20:51:da:c7\",6)\n+CWLAP:(3,\"DIRECT-a5-HP MLP50\",-86,\"fa:da:0c:1b:16:a5\",6)\n+CWLAP:(3,\"DIRECT-c6-HP M182 LaserJet\",-88,\"da:12:65:44:31:c6\",6)\n\n");
NoteRequest(req);
req = {"req": "card.triangulate"}
req["text"] = "+CWLAP:(4,\"Blues\",-51,\"74:ac:b9:12:12:f8\",1)\n+CWLAP:(3,\"AAAA-62DD\",-70,\"6c:55:e8:91:62:e1\",11)\n+CWLAP:(4,\"Blues\",-81,\"74:ac:b9:11:12:23\",1)\n+CWLAP:(4,\"Blues\",-82,\"74:ac:a9:12:19:48\",11)\n+CWLAP:(4,\"Free Parking\",-83,\"02:18:4a:11:60:31\",6)\n+CWLAP:(5,\"GO\",-84,\"01:13:6a:13:90:30\",6)\n+CWLAP:(4,\"AAAA-5C62-2.4\",-85,\"d8:97:ba:7b:fd:60\",1)\n+CWLAP:(3,\"DIRECT-a5-HP MLP50\",-86,\"fa:da:0c:1b:16:a5\",6)\n+CWLAP:(3,\"DIRECT-c6-HP M182 LaserJet\",-88,\"da:12:65:44:31:c6\",6)\n\n"
rsp = card.Transaction(req)
This request will return an object with the current triangulation configuration
parameters, and a length
field indicating the size of the text
buffer
provided in the request.
{
"usb": true,
"mode": "wifi",
"length": 398,
"on": true,
"time": 1606770857,
"motion": 1606770581
}
The Notecard Auxiliary Wi-Fi Arduino library provides an easy way to programmatically pull a list of Wi-Fi access points from a Wi-Fi enabled host MCU in the required format.
Configuring USB Power and Motion-based Triangulation
The card.triangulate
request provides options for configuring the Notecard
based on its power state and movement. Set the usb
argument to true
to instruct the Notecard to only perform triangulation when connected to USB
power, and set on
to true
if you want the Notecard to triangulate even when
the device has not moved. Both flags require the set
argument in order to
take effect.
{
"req": "card.triangulate",
"mode": "wifi,cell",
"on": true,
"usb": true,
"set": true
}
J *req = NoteNewRequest("card.triangulate");
JAddStringToObject(req, "mode", "wifi,cell");
JAddBoolToObject(req, "on", true);
JAddBoolToObject(req, "usb", true);
JAddBoolToObject(req, "set", true);
NoteRequest(req);
req = {"req": "card.triangulate"}
req["mode"] = "wifi,cell"
req["on"] = True
req["usb"] = True
req["set"] = True
rsp = card.Transaction(req)
This request will return an object with the current triangulation configuration
parameters, a motion
field indicating the time of the last device movement,
and time
field indicating the time of the last triangulation scan.
{
"mode": "wifi,cell",
"usb": true,
"on": true,
"time": 1606758961,
"motion": 1606761044
}
Ascertaining an Approximate Device Location
When card.location.mode
is set to "mode":"off"
, which is the default
behavior of the Notecard WiFi, Notehub will automatically download to the
Notecard its "best guess" as to the general location of the device. This
location is either the Wi-Fi triangulation result (preferred), cell tower
triangulation result, or nearest cell tower.
When subsequently issuing a card.location
request, the Notecard will return
the approximate location (which is updated every time a new Notehub
session is created).
{"req":"card.location"}
{
"status": "GPS is off {gps-inactive}",
"mode": "off",
"lat": 43.07426250000001,
"lon": -89.442609375,
"dop": 20,
"time": 1709312128
}
This functionality is not available on the Notecard LoRa.
Disabling Triangulation
To turn triangulation off, set the mode
argument to -
:
{
"req": "card.triangulate",
"mode": "-"
}
J *req = NoteNewRequest("card.triangulate");
JAddStringToObject(req, "mode", "-");
NoteRequest(req);
req = {"req": "card.triangulate"}
req["mode"] = "-"
rsp = card.Transaction(req)
This request will return an object with no mode
argument, indicating that
triangulation is disabled. The motion
and time
fields may still be present
after triangulation is disabled.
{ "motion": 1606761044 }
Working with GPS on the Notecard
The Notecard Cellular and Notecard Cell+WiFi include an onboard GPS module that can be used for location tracking, when paired with an appropriate antenna.
The Notecard's cellular radio and GPS module cannot be enabled at the same time.
When building a location-aware product, be sure one or both are in periodic
mode and that you allot enough time for the Notecard to switch between cellular
and GPS functions, which can take 1-2 minutes depending on the strength of the
cellular connection and/or the visibility of GPS satellites.
To conserve power, the GPS module on the Notecard is off, by default. You can
confirm this with the card.location
request:
{
"req": "card.location"
}
J *req = NoteNewRequest("card.location");
NoteRequest(req);
req = {"req": "card.location"}
rsp = card.Transaction(req)
Which will return the following:
{
"status": "GPS is off {gps-inactive}",
"mode": "off"
}
When using GPS mode, you'll want to decide whether your application should enable GPS periodically to conserve battery at the cost of accuracy between readings, or continuously in real-time.
The Notecard will not turn on the GPS module until it has made a successful cellular connection upon startup to obtain the current time. Once the Notecard has the time, GPS is available for use, regardless of the state of a cellular connection.
There are also other functions on the Notecard that require the time to be set.
As of Notecard firmware v6.1.1,
if a GPS location is not available the card.location
request returns the lat
and lon
from
the device's most recent cell tower location or
triangulated location.
When a GPS location is available you'll see a "GPS updated"
message in the status
of your
card.location
request, and the lat
and lon
that appear in the response will be from the
onboard GPS module.
Sampling GPS Readings with Periodic Mode
If you prefer to enable GPS readings on an interval, use periodic
mode. In
this mode, the Notecard enables GPS at a frequency you define using either a set
number of seconds or using a voltage-variable value.
In both cases, regardless of the periodic value, the GPS module will only turn
on to update the location if the Notecard has moved since the last time GPS was
enabled. The seconds
value sets the minimum interval at which the Notecard
will enable its GPS.
{
"req": "card.location.mode",
"mode": "periodic",
"seconds": 3600
}
J *req = NoteNewRequest("card.location.mode");
JAddStringToObject(req, "mode", "periodic");
JAddNumberToObject(req, "seconds", 3600);
NoteRequest(req);
req = {"req": "card.location.mode"}
req["mode"] = "periodic"
req["seconds"] = 3600
rsp = card.Transaction(req)
Sampling at Predefined Intervals
To activate the GPS module on the Notecard every 600 seconds (at most, and only
if motion is detected), set mode
to periodic
and use the seconds
argument
in a card.location.mode
request:
{
"req": "card.location.mode",
"mode": "periodic",
"seconds": 600
}
J *req = NoteNewRequest("card.location.mode");
JAddStringToObject(req, "mode", "periodic");
JAddNumberToObject(req, "seconds", 600);
NoteRequest(req);
req = {"req": "card.location.mode"}
req["mode"] = "periodic"
req["seconds"] = 600
rsp = card.Transaction(req)
This will return an object confirming that the Notecard is in periodic mode and that GPS should be enabled no more frequently than once every 600 seconds:
{
"mode": "periodic",
"seconds": 600
}
Once enabled, use the card.location
request to monitor connection status and
location:
{
"req": "card.location"
}
J *req = NoteNewRequest("card.location");
NoteRequest(req);
req = {"req": "card.location"}
rsp = card.Transaction(req)
While waiting for the Notecard to obtain a GPS fix, expect to see intermediate
status
messages in response to card.location
requests:
// When the module is still inactive
{
"status": "GPS inactive {gps-inactive}",
"mode": "periodic"
}
// When the module has started
{
"status": "GPS started {gps-active} {gps-active}",
"mode": "periodic"
}
// When the module is active, but searching for GPS
{
"status": "GPS search (19 sec, 41dB SNR, 5 sats) {gps-active}
{gps-signal} {gps-sats}",
"mode": "periodic"
}
You may see several variations of the second message before the module obtains
a fix. Once obtained, future card.location
requests include the current
Notecard latitude (lat
) and longitude (lon
) values, as well as the Unix
epoch time that location was captured.
{
"status": "GPS updated (58 sec, 41dB SNR, 9 sats) {gps-active}
{gps-signal} {gps-sats} {gps}",
"mode": "periodic",
"lat": 42.577600,
"lon": -70.871340,
"time": 1598554399
}
To preserve battery, when the Notecard's GPS module is in periodic mode, GPS is
only enabled if the built-in accelerometer detects movement since the last GPS
enable. If the Notecard has not moved, a card.location
request will indicate
that GPS is inactive and provide the last location reading.
{
"status": "GPS inactive {gps-inactive} {gps}",
"mode": "periodic",
"lat": 42.5776,
"lon": -70.87134,
"time": 1598557149
}
Tracking GPS Location Readings
When operating in periodic mode, use the card.location.track
request to
configure the Notecard to store GPS readings in a Notefile. Note that the
behavior in this section only applies to the capture of location events. The
rules for how and when those events sync are the same as general sync settings
defined with hub.set
.
{
"req": "card.location.track",
"start": true
}
J *req = NoteNewRequest("card.location.track");
JAddBoolToObject(req, "sync", true);
NoteRequest(req);
req = {"req": "card.location.track"}
req["sync"] = True
rsp = card.Transaction(req)
This will return an object confirming that tracking mode has started and
the minimum duration in seconds between Notes being placed in a Notefile. The
seconds
value is the value set in a request to card.location.mode
.
{
"seconds": 10,
"start": true
}
By default, tracking notes are placed into a Notefile named _track.qo
. To
define your own Notefile, use the file
argument.
{
"req": "card.location.track",
"start": true,
"file": "locations.qo"
}
J *req = NoteNewRequest("card.location.track");
JAddBoolToObject(req, "sync", true);
JAddStringToObject(req, "file", "locations.qo");
NoteRequest(req);
req = {"req": "card.location.track"}
req["sync"] = True
req["file"] = "locations.qo"
rsp = card.Transaction(req)
Tracking data is available to view in Notehub, once synced, and includes a number of helpful fields that can be Routed to your cloud applications.
{
"bearing": 194.8890307950282,
"distance": 5.591816976119877,
"seconds": 36,
"hdop": 1,
"temperature": 49.625,
"time": 1598560691,
"usb": true,
"velocity": 0.014337992246461224,
"voltage": 4.727260437757979
}
By default, tracking data will only be captured if the Notecard detects motion.
To add periodic tracking Notes when there is no movement, use the heartbeat
argument. You can also use the optional hours
argument to capture heartbeat
tracking notes at a rate that differs from the rate when there is motion.
{
"req": "card.location.track",
"start": true,
"heartbeat": true,
"hours": 1
}
J *req = NoteNewRequest("card.location.track");
JAddBoolToObject(req, "sync", true);
JAddBoolToObject(req, "heartbeat", true);
JAddNumberToObject(req, "hours", 1);
NoteRequest(req);
req = {"req": "card.location.track"}
req["sync"] = True
req["heartbeat"] = True
req["hours"] = 1
rsp = card.Transaction(req)
If you wish to initiate a sync to Notehub each time a tracking Note is added to
the Notecard, set the sync
field to true
:
{
"req": "card.location.track",
"sync": true
}
J *req = NoteNewRequest("card.location.track");
JAddBoolToObject(req, "sync", true);
NoteRequest(req);
req = {"req": "card.location.track"}
req["sync"] = True
rsp = card.Transaction(req)
To turn tracking mode off, set the stop
argument to true
.
{
"req": "card.location.track",
"stop": true
}
J *req = NoteNewRequest("card.location.track");
JAddBoolToObject(req, "stop", true);
NoteRequest(req);
req = {"req": "card.location.track"}
req["stop"] = True
rsp = card.Transaction(req)
Always-on GPS With Continuous Mode
To set your Notecard to GPS Continuous mode, use the card.location.mode
request:
{
"req": "card.location.mode",
"mode": "continuous"
}
J *req = NoteNewRequest("card.location.mode");
JAddStringToObject(req, "mode", "continuous");
NoteRequest(req);
req = {"req": "card.location.mode"}
req["mode"] = "continuous"
rsp = card.Transaction(req)
Which will return an object confirming that the Notecard is in continuous mode:
{"mode": "continuous"}
Once enabled, use the card.location
request to monitor connection status and
location:
{
"req": "card.location"
}
J *req = NoteNewRequest("card.location");
NoteRequest(req);
req = {"req": "card.location"}
rsp = card.Transaction(req)
While waiting for the Notecard to obtain a GPS fix, expect to see intermediate
status
messages in response to card.location
requests.
The Notecard will not turn on the GPS module until it has made a successful cellular connection upon startup to obtain the current time. Once the Notecard has the time, GPS is available for use, regardless of the state of a cellular connection.
// When the module is still inactive
{
"status": "GPS inactive {gps-inactive}",
"mode": "continuous"
}
// When the module is active, but searching for GPS
{
"status": "GPS search (19 sec, 41dB SNR, 5 sats) {gps-active}
{gps-signal} {gps-sats}",
"mode": "continuous"
}
You may see several variations of the status message before the module obtains
a fix. Once obtained, future card.location
requests include the current
Notecard latitude (lat
) and longitude (lon
) values, as well as the Unix
epoch time that location was captured.
{
"status": "GPS updated (58 sec, 41dB SNR, 9 sats) {gps-active}
{gps-signal} {gps-sats} {gps}",
"mode": "continuous",
"lat": 42.577600,
"lon": -70.871340,
"time": 1598554399
}
Continuous Cellular & Continuous GPS
The Notecard does not support running both a continuous
cellular connection ({"req":"hub.set", "mode":"continuous"}
) and continuous
GPS. If you attempt to set both cellular and GPS to continuous mode, the
Notecard will return an error. This applies both to card.location.mode
when the cellular connection is continuous, as well as hub.set
if GPS has
been set in continuous mode.
{"err": "cannot simultaneously use continuous card.location.mode and hub.set modes"}
If concurrent use of cellular and GPS is required in your solution, we recommend usage of an external GPS module.
Determining the Current GPS Mode
At any point, the GPS mode of the Notecard can be obtained by calling the
card.location.mode
command with no arguments.
{
"req": "card.location.mode"
}
J *req = NoteNewRequest("card.location.mode");
NoteRequest(req);
req = {"req": "card.location.mode"}
rsp = card.Transaction(req)
This will return the current GPS mode alongside additional meta data if geofencing and/or voltage-variable periods are enabled.
{
"mode": "continuous",
"max": 100,
"lat": 42.5776,
"lon": -70.87134,
"minutes": 2,
"threshold": 4
}
Geofencing With the Notecard
The Notecard can be configured to trigger an immediate sync to Notehub when the
device moves beyond a defined
geofence. Use the lat
and lon
arguments to set the center of the geofence, and the max
argument to specify
the number of meters from the center to set the geofence. You can also
optionally pass the minutes
argument to specify a number of minutes the
Notecard must be outside of the geofence before its location is tracked. The
default value for minutes
is 5.
{
"req": "card.location.mode",
"mode": "periodic",
"lat": 42.5776,
"lon": -70.87134,
"max": 100,
"minutes": 2
}
J *req = NoteNewRequest("card.location.mode");
JAddStringToObject(req, "mode", "periodic");
JAddNumberToObject(req, "lat", 42.577600);
JAddNumberToObject(req, "lon", -70.871340);
JAddNumberToObject(req, "max", 100);
JAddNumberToObject(req, "minutes", 2);
NoteRequest(req);
req = {"req": "card.location.mode"}
req["mode"] = "periodic"
req["lat"] = 42.577600
req["lon"] = -70.871340
req["max"] = 100
req["minutes"] = 2
rsp = card.Transaction(req)
This will return an object confirming that the geofence is enabled using the parameters provided.
{
"max": 100,
"mode": "periodic",
"lat": 42.5776,
"lon": -70.87134,
"minutes": 2
}
Disabling GPS
When you no longer need to capture GPS data from the Notecard, turn it off with
a card.location.mode
request and mode
field set to off
.
{
"req": "card.location.mode",
"mode": "off"
}
J *req = NoteNewRequest("card.location.mode");
JAddStringToObject(req, "mode", "off");
NoteRequest(req);
req = {"req": "card.location.mode"}
req["mode"] = "off"
rsp = card.Transaction(req)
Which will return an object confirming that GPS is off:
{"mode": "off"}
Even after GPS has been disabled, the Notecard keeps the last location obtained,
which can be retrieved at any time with a card.location
request.
{
"req": "card.location"
}
J *req = NoteNewRequest("card.location");
NoteRequest(req);
req = {"req": "card.location"}
rsp = card.Transaction(req)
{
"status": "GPS is off {gps-inactive} {gps}",
"mode": "off",
"lat": 42.5776,
"lon": -70.87134,
"time": 1598555070
}
If you wish to delete the last known location stored in the Notecard, use the
delete
argument in a card.location.mode
request.
{
"req": "card.location.mode",
"delete": true
}
J *req = NoteNewRequest("card.location.mode");
JAddBoolToObject(req, "delete", true);
NoteRequest(req);
req = {"req": "card.location.mode"}
req["delete"] = True
rsp = card.Transaction(req)
Subsequent requests to card.location
no longer provide location data, until
GPS is re-enabled and a new reading is captured.
{
"status": "GPS is off {gps-inactive} {gps}",
"mode": "off"
}