When people think about asset trackers, typically they think about tracking things that should move: planes, trains, and automobiles.
What we don't think about as frequently is keeping track of things that shouldn't move: statues, environmental monitoring devices, RVs or boats stored in the off season, and other valuables that would be unfortunate to lose or have stolen.
At work recently (I work for IoT startup Blues Wireless), someone shared a story about beekeepers using tracking devices to protect their hives (that honey is literally liquid gold!) and suggested Blues' devices would be a great tool for a low-cost hive-tracking solution, and that got the wheels turning in my head.
Blues' mission is to make IoT connectivity easy. Whether your IoT device has a stable Wi-Fi connection - or it's in a beehive somewhere out in a meadow. Blues provides low-power Notecards that connect to a secure cloud (Notehub) via prepaid cellular data and pump the device's data (in JSON format) to the cloud for easy access.
The best part is, once the data is in the Notehub cloud, it can be routed out again to a third-party cloud platform, a web app, a low-code dashboard, or even a messaging platform like Twilio.
With Twilio, we can do things like send SMS alerts when a device that should be stationary starts moving, including details like last known location coordinates. Sounds like a pretty perfect solution to me.
Today, I'll show you how to build an anti-theft device for under $100, that will use a cellular module to send its location data to a cloud and trigger SMS alerts whenever motion is detected, for faster asset recovery.
Assemble the Anti-Theft DeviceSince my project is to keep track of objects that shouldn't be moving but are (reverse asset tracking, if you will), things like reliable Internet connectivity while the object is in motion and long-lasting battery life when it's not, are both important considerations.
Luckily, Blues Wireless has hardware that solves for both of these problems. The Blues Wireless Notecard provides prepaid global cellular access, which incudes 500MB of data and 10 years of service. The model I chose works well with both LTE-M and NB-IoT protocols, and it's extremely low-power at just ~8uA when idle.
In addition to my Notecard, I used a Blues Wireless Notecarrier AL which is a companion prototyping board for the Notecard with onboard cellular and GPS antennas.
I chose the Notecarrier AL version in particular because it has JST connectors for a LiPo battery, but there is also version a that uses AA batteries, and all of the Notecarrier boards also have micro-USB connectors that can power the device and provide a USB interface to a Notecard.
That last piece of this puzzle is the power source. As I mentioned, I went with the Notecarrier AL, which has JST connectors for a LiPo battery, so I bought an Adafruit Lithium Ion Polymer Batter - 3.7v 2500mAh to power the whole shebang.
Now put it all together: screw in the Notecard to the Notecarrier, attach the cellular and GPS antenna and connectors on the board to the Notecard, and plug the LiPo battery in to the JST connector port labelled "LiPo".
With the anti-theft device hardware assembly complete, it's time to set up our cloud and Twilio configurations.
NOTE: If you'd like more detailed instructions on assembling your tracker, check out our developer experience website's getting started section.Set Up a Notehub Project for the Tracker to Report To
Before setting up the Notecard itself with its marching orders, we need to create a new cloud project in Notehub.io to direct the Notecard's data to.
Since the Notecard is a device-to-cloud data pump, it doesn't live on the public Internet (making it an extremely secure device) and therefore needs a proxy with which to sync data: Notehub.
Notehub is a thin cloud service that securely accepts data from the cellular Notecard (off the public Internet, using private VPN tunnels) and then instantly routes the data to the cloud provider of your choice (be it AWS, Azure, Google Cloud, or any IoT-optimized service like Ubidots, Datacake, Losant, and others).
1. If you haven't already, create an account with Notehub now. It's free for up to the first 5, 000 routed events per month (routed event = data transmissions from Notehub to your cloud endpoint of choice). This should be way more than what's needed (hopefully) for this anti-theft device.
2. After signing up, click the "Create Project" button in the top right of the Notehub screen and fill in the project details.
Copy the project UID after the new project is created - we'll need it when configuring the Notecarrier itself.
Make a Free Twilio Starter AccountThe other thing you'll need to set up is a free starter account with Twilio because it's Twilio's API that we'll be leveraging for our SMS alerts.
When I set up my test account, I followed the Blues Twilio documentation, and I would recommend starting there.
NOTE: If you click the Twilio link the in the "Prerequisites" section of the documentation, you'll get some extra Twilio starter credits via a Blues Wireless referral link. π°
Once your account's set up, make sure to verify a caller ID (probably your own cell phone number for testing purposes) and assign a Twilio phone number to your account (this is the number that will send the SMS notifications later).
Here's how I can tell from the dashboard my account has a Twilio phone number associated with it.
Now let's set up our Notecard. We'll revisit connecting Notehub and Twilio after the Notecard is recording motion data.
Program the Notecard for Asset TrackingIf you've not configured a Notecard before, not to worry, Blues aims to make this experience easy as well with simple JSON commands.
While there is a full-scale Notecard CLI you can download to your local machine to interface with the Notecard, I tend to use the web-based Notecard CLI built in to our developer experience site. It's easier in my mind.
All you need is a micro-USB to USB-A converter cable to plug it in to your laptop and begin interacting with your Notecard.
Once you're connected to your Notecard issue the following set of commands to it.
1. Factory reset your Notecard.
Always good to start a new project from a clean slate.
{"req":"card.restore","delete":true}
2. Attach the tracker to the Notehub project, set its mode and sync times
{
"req":"hub.set",
"product":"com.blues.paige:anti_theft_tracker",
"mode":"periodic",
"outbound":1440,
"inbound":1440
}
The periodic
setting will only send any un-synced outbound
info to Notehub every 1440 minutes (once per day), and it will always sync on the inbound
interval every 1440 minutes as well, in order to process any new notes and environment variables from Notehub.
Since we don't anticipate much in the way of changing environment variables or regular Notecard activity long intervals between syncs are fine. This will also help to preserve battery life as the most power intensive activities this tracker will experience is getting a GPS location and transmitting that data to Notehub.
3. Set the Notecard's mode and frequency of location detection
{"req":"card.location.mode","mode":"periodic","seconds":60}
When in periodic
mode, the Notecard's GPS module will only activate to take readings if the Notecard detects motion through its onboard accelerometer. Telling the Notecard to take new GPS readings every 60 seconds is more battery intensive than time interval over 5 minutes, but if something's being stolen, I'd prefer more frequent alerts as to its current whereabouts.
4. Start tracking, set a check-in heartbeat once a day, and sync new notes to Notehub immediately
{
"req":"card.location.track",
"start":true,
"heartbeat":true,
"hours":24,
"sync": true
}
card.location.track
will store location-tagged tracking data like velocity, bearing, and distance in a Notefile that will be sent to Notehub as soon as it's created - that's what the "sync" true
command at the end of this line does. As soon as the new event is created on the Notecard it sends it straight off to Notehub, no waiting until the next regularly scheduled outbound
interval.
Again, this is more power intensive, but for this type of tracker, we want events as close to real-time as possible to increase the chances of asset recovery.
The default file is _track.qo
, but you can specify your own file name with the file
field.
The heartbeat
and hours
tells the Notecard to create an entry at a defined interval, regardless of motion. It's just a gut check that the Notecard is still working.
NOTE: If you'd like more info on configuring asset trackers, check out all the info around them on the Blues Developer Experience site.Generate Some Test Tracking Events in Notehub
Now take the Notecard on a walk or a drive to see the kind of data it's generating and sending to Notehub.
Inside of the Notehub project, click on the "Events" tab, and inside the filter input put in _track.qo
to see a list of the tracking events your Notecard should be generating.
As you can see if you look closely at the image, my Notecard is reporting a mixture of heartbeat (motion-less) data and motion detected data.
Put a pin in that, though, we'll figure out a way to sort through this data and prevent sending false positives to Twilio.
Send Motion Alerts with Location Data via TwilioOk! It's time to start sending some of these _track.qo
events to Twilio.
This is probably the portion of the project that took me the longest, and mostly because I was getting familiar with the JSONata syntax - but I'm getting ahead of myself.
Let's go through this part step by step.
NOTE: If you'd like to skip the JSONata explanation, just go right to step 2B - that's the final version of this JSONata function.
1. Create a new Twilio route in Notehub looking for _track.qo files
The Twilio starter guide on the Blues Wireless developer experience site does an awesome job showing exactly how to set up a new route from Notehub to Twilio, please follow it until the eighth step where selected note files are defined as being labeled twilio.qo
- ours will not be, instead our project will be looking for _track.qo
files like in my screenshot.
2. Paste in this JSONata code inside of your Twilio route's Transform Data section
If you read through the majority of the Twilio starter guide instructions you probably reached the part about transforming the original Notecard payload via JSONata before sending it on to Twilio.
JSONata, if you're not familiar with it (I wasn't before now), is a lightweight query and transformation language for JSON data. The syntax takes some getting used to, but once it's working, it's pretty cool.
And another neat thing I learned about Notehub, is that any notefile payload can be run though a JSONata transformation function to cut out most of the JSON we don't care about and only route out the important bits to wherever the info is bound next (Twilio, in our case).
So here's version 1 of the JSONata to paste into your Transform Data section in Notehub:
( $from := "+190354XXXX";
$to := "+1404641XXXX";
$body := function(){
(
$join([
"Alert! ",
best_id ? best_id : device,
" is on the move!",
" Last spotted at: ",
$string($round(best_lat, 6)),
",",
$string($round(best_lon, 6)),
" around ",
$fromMillis(when * 1000,
"[M01]/[D01]/[Y0001] [h#1]:[m01][P]",
"-0500"),
" EST."
])
)
};
"&Body=" & $body() & "&From=" & $from & "&To=" & $to & "&";
)
In this expression, we define three variables:
$from
- the Twilio phone number,$to
- the test phone number (probably your phone number),- and
$body
- a JSONata function to join strings together letting us know which Notecard is on the move (defined either by the Notecard'sbest_id
value - its serial number, falling back to itsdevice
ID if that value's not there), its last known latitude (best_lat
) and longitude (best_lon
) and the time it last reported (when
).
Each variable or function is separated from the next by a semicolon, and to string multiple variables and functions together like this example does, wrap them all inside of parentheses.
In addition to the basic info pulled from the original _track.qo
Notefile, we did a little JSONata manipulation using built-in functions like $string
, $round
, and $fromMillis
to make the values nicer to read to people.
Finally, in the last line where "&Body="
is defined, we call the newly made $body()
function to get the string we need to send to Twilio for its message, and add the $from
and $to
variables we also defined so Twilio knows who the text should come from and who should receive it.
2A. Filtering out heartbeat _track.qo
events with $doNotRoute()
This is a good start, but what about those heartbeat events that also come in to Notehub as _track.qo
events? Using the JSONata above, those will be sent to Twilio once a day and send a false positive SMS alert that the Notecard is on the move when it's not.
Enter $doNotRoute()
: a custom Blues JSONata command that will conditionally route events out of Notehub, which is exactly what we need.
If you examine the plain JSON of a _track.qo
event where motion is happening versus one where it's just a heartbeat check in, you'll notice the one with motion has two properties that the heartbeat doesn't have: motion
and seconds
.
Notecard _track.qo
event with motion data
{
// some event specific data up here
"device": "dev:86447XXXXXXXX",
"best_id": "Notey McNotecard",
"product": "product:com.blues.paige:anti_theft_tracker",
"received": 1646683287,
"req": "note.add",
"when": 1646683261,
"file": "_track.qo",
"body": {
"hdop": 1,
"motion": 4,
"seconds": 74,
"temperature": 29.125,
"time": 1646683260,
"voltage": 4.21875
},
"best_location_type": "gps",
// a bunch of extra location JSON data here
}
Inside of the body
there's motion
and seconds
- this means the Notecard is in motion.
Notecard _track.qo
event without motion data
{
// some event specific data up here
"device": "dev:86447XXXXXXXX",
"best_id": "Notey McNotecard",
"product": "product:com.blues.paige:anti_theft_tracker",
"received": 1646600372,
"req": "note.add",
"when": 1646600347,
"file": "_track.qo",
"updates": 1,
"body": {
"hdop": 1,
"status": "heartbeat",
"temperature": 25.5,
"time": 1646341009,
"voltage": 4.2734375
},
"best_location_type": "gps",
// a bunch of extra location JSON data here
}
No motion
and seconds
in this Notecard's body
, plus its status
is "heartbeat"
: no motion.
We can use one (or both of these properties) to conditionally route values to Twilio. Game changer.
Replace the original JSONata with this newly updated version 2 code:
( $from := "+190354XXXX";
$to := "+1404641XXXX";
$body := function(){
(
$join([
"Alert! ",
best_id ? best_id : device,
" is on the move!",
" Last spotted at: ",
$string($round(best_lat, 6)),
",",
$string($round(best_lon, 6)),
" around ",
$fromMillis(when * 1000,
"[M01]/[D01]/[Y0001] [h#1]:[m01][P]",
"-0500"),
" EST."
])
)
};
$result := ($exists(body.motion)) ? "&Body=" & $body() & "&From=" & $from & "&To=" & $to & "&" : $doNotRoute();
)
The change is in the last lines where the "&Body=...
is constructed.
Instead of sending the transformed Notefile no matter what, now a new variable named $result
is declared and using the JSONata $exists
method, we check if the original payload has the value of body.motion.
If it does, the $body()
function runs and the data's sent to Twilio, if it doesn't $doNotRoute()
is invoked instead and the Note is not sent.
Fantastic!
2B. Add a Google Maps link for convenience
Ok, this should prevent false positives from getting through, but there's one more enhancement I want to make to this message. I don't know about you, but if I had something being stolen, seeing the GPS coordinates printed out isn't particularly useful in the heat of the moment.
I'd like to be able to click a link in the SMS and see those coordinates displayed on a map.
Contrary to what you might think, there's currently no universally agreed upon way to construct GPS coordinates in a text message so that an iPhone or Android messaging service will recognize they are coordinates (like they do for phone numbers and addresses) and automatically hyperlink them to open a map app on a phone.
Instead we must do it ourselves. So my workaround is to provide a Google Maps hyperlink at the end of the message which users can choose to click on or not (I figure Google Maps is an almost universally used app regardless of phone OS, and if the user doesn't want to use it, they can copy the GPS string from the main message body and paste it into their map app of choice instead).
So one last time, replace your JSONata text with this version 3 code:
( $from := "+190354XXXX";
$to := "+1404641XXXX";
$body := function(){
(
$join([
"Alert! ",
best_id ? best_id : device,
" is on the move!",
" Last spotted at: ",
$string($round(best_lat, 6)),
",",
$string($round(best_lon, 6)),
" around ",
$fromMillis(when * 1000,
"[M01]/[D01]/[Y0001] [h#1]:[m01][P]",
"-0500"),
" EST.",
" Google maps link: http://maps.google.com/?q=",
$string(best_lat),
",",
$string(best_lon)
])
)
};
$result := ($exists(body.motion)) ? "&Body=" & $body() & "&From=" & $from & "&To=" & $to & "&" : $doNotRoute();
)
This version modifies the end of the $body
function, adding an extra line that feeds the latitude and longitude coordinates into a Google Maps URL so it can be clicked on from the SMS.
Here's what the final JSONata expression should look like inside of the Twilio Notehub route.
Now hit the "Apply Changes" button to save the route details.
Time to test this tracker out!
Alert! π¨ The Notecard is on the Move!Grab your Notecard tracker and take it on a walk.
If all goes according to plan, your phone should begin receiving text message like the ones below in no time at all.
If not, not to worry, I've got some troubleshooting tips down in the next section to help you out.
And if you click on the Google Maps link within the SMS, the Notecard's current location should open up in Google Maps.
Ta-da! We know right where that Notecard is, and as long as it keeps moving, every minute it will send a text message with its newly updated location.
After confirming it works, let's go on to some things that might trip you up as you put this anti-theft device in place.
Gotchas: Troubleshooting the Anti-Theft DeviceHopefully this tutorial has been easy to follow - I know there's a few moving pieces to keep track of (no pun intended), but I did hit some roadblocks getting to this working example, and I wanted to point them out in case you encounter similar as you build your own prototype.
Issue #1: The JSONata-transformed payload isn't making it to Twilio
This is the main issue I encountered as I was building this project was formatting the JSONata correctly so that it actually sent to Twilio. When it fails currently, nothing useful gets through to Twilio's logs to assist with debugging.
Solution #1: Copy / paste the JSONata into JSONata Exerciser
JSONata Exerciser is an online platform for constructing and testing JSONata queries.
On the left-hand side of the screen you can paste in the JSON payload you're trying to run the JSONata query against, and on the right hand side you build your JSONata query itself to see what the output in the bottom right looks like (or what error message is thrown).
So here's what to do:
- Copy the full JSON payload from one of your Notecard's
_track.qo
events via the Notehub UI (click into any of the events and select the "JSON" tab), - Paste it in to the JSON Exerciser on the left side,
- Copy the JSONata expression from the Twilio route,
- Paste it into the JSON Exerciser and debug from there.
See what your output is, and if the Exerciser finds syntax errors start debugging them here.
Solution #2: Set up a second Notehub route to Webhook.site
Webhook.site is a handy website where we can route our JSONata-transformed data to and see the output.
To use it:
- Navigate to https://webhook.site,
- Copy the session specific URL so you can route your events there,
- And add a new route URL in Notehub pointing to that unique Webhook.site URL.
Hopefully these two debugging options will help you refine your JSONata expression enough that the message will get through to Twilio which will allow you to figure out the most useful info to send via SMS.
Issue #2: Twilio's not forwarding the message
I learned through trial and error that unless a Twilio phone number is set up in Twilio, any received messages from Notehub won't be forwarded on to the verified phone number.
Solution: Assign a Twilio phone number by following this helpful post here
Twilio is actually a very cost effective platform for things like SMS messaging. Each SMS message costs $0.015 USD (that includes both receiving the message from Notehub and forwarding to the end cell phone number), and assigning a Twilio phone number is $1 USD per month.
If you ever don't need the Twilio phone number (like if this just a prototype project), simply unassign the number and whatever remaining Twilio balance you have will be preserved until you need it again.
Issue #3: All Notehub _track.qo
events are forwarding to Twilio
This is probably happening because the Blues-specific $doNotRoute()
function is not included in your JSONata expression.
Refer back to the final version of the "Sending Motion Alerts via Twilio" section (version 3) of this article to compare your JSONata expression with the code there.
Issue #4: The Notecard's not getting a GPS lock to report its location
Although the antennas on the Notecarrier ALs are good, they're not infallible.
Solution: For best results, try to ensure your Notecard / Notecarrier has a decent view of the sky.
Cellular coverage across the country or around the world can be spotty at times, so try to place the device so there's a better chance it can see the sky: it needs at least a couple of satellites to figure out where in the world it is.
I strongly recommend placing the Notecard wherever you intend it to be on or in your asset and test if it can get a GPS location.
Issue #5: The anti-theft tracker needs a weather proof enclosure
For my proof of concept, an enclosure wasn't necessary, but if you plan to deploy this out in the field somewhere your Notecard is going to need some protection from the elements for best results.
Some of my coworkers are very handy and willing to build their own enclosures, I am not one of them.
Solution: Buy almost any sized Notecard enclosure you need off of Amazon
Luckily, Amazon sells these waterproof, dust proof plastic boxes in a bevy of different sizes just right for something like an anti-theft Notecard device.
Just choose one that fits your needs and attach to the device to track.
NOTE: Although these boxes are sealed, if you need to drill a hole for a steady state power supply, I'm told a simple cordless drill can do the job.Conclusion
I'm really pleased with how this project turned out, (and I already have a few coworkers who'd like to test it out with some assets of their own).
All in all, using just a Notecard, Notehub, and Twilio, I was able to build an accurate, low power anti-theft device that will let you know when something's up and (hopefully) make recovery of it that much quicker.
And I'm impressed with how powerful JSONata expressions can be to transform JSON payloads into just the data needed. That was very cool to learn more about.
All that being said, if you're looking for some next steps...
- Get your own Blues Wireless Notecard and Notecarrier AL
- Browse other Hackster projects that use the Notecard in edge scenarios
- Share what you end up building with us on social!
Happy tracking! πΊοΈ
Comments