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 only available with the Notecard Cellular or Notecard Cell+WiFi and 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.
Wi-Fi triangulation is available with any Notecard that has access to a Wi-Fi module (either on the Notecard or on a connected host). Unlike cell tower triangulation, it adds only 1-2 seconds of processing time, uses minimal power, can be nearly as accurate as a GPS-derived location, but does require additional configuration (see below).
See examples of Wi-Fi triangulation in action in these accelerator projects.
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:
A card.triangulate
request does not itself perform triangulate with the
Notecard. Rather, it gathers cell tower and/or Wi-Fi access point data that
Notehub uses to perform device triangulation.
In addition, this feature does not affect the location data returned by a
card.location
request, but is intended to increase the accuracy of location
data sent from Notehub to any
Routes defined in a
project. See
Viewing Triangulation Location Data in Notehub
below to understand where triangulation-based location data appears in Notehub
events.
Providing Wi-Fi Information to the Notecard
If your host has an onboard Wi-Fi module, you can perform a manual
access point scan and send this information to a Notecard without Wi-Fi using
the text
argument. Sending this data to a Notecard Cellular is required to
enable Wi-Fi triangulation, while the Notecard Cell+WiFi and Notecard WiFi have
triangulation
enabled by default.
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
}
Use the Notecard Auxiliary Wi-Fi Arduino library for an easier way of programmatically pulling a list of Wi-Fi access points with your Wi-Fi enabled host MCU and sending them to the Notecard.
Using Triangulation with the Notecard WiFi and Notecard Cell+WiFi
The Notecard WiFi and Notecard Cell+WiFi support Wi-Fi triangulation and it is enabled by default, with no end-user configuration required. Every event in Notehub sent by a Notecard with a Wi-Fi module will have triangulation location data appended.
Viewing Triangulation Location Data in Notehub
Enabling cell tower or Wi-Fi triangulation does not affect the location data
returned by a card.location
request (which is reserved solely for GPS location
data). However, when triangulation is enabled, additional triangulation-derived
fields with lat/lon coordinates will appear in Notehub events, 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,
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
}
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.
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"
}