I have Borons deployed in the field and I would like to keep track of their online status within about 5 minutes of accuracy. Right now I'm doing this by publishing vitals every 5 minutes and sending that data over a webhook to my server, where I update a 'last heard from' timestamp in a database for that device on each webhook received. However, publishing vitals uses way more cellular data than is strictly necessary.
Publishing an event with a one-character name like 'h' with no data would use far less data, but because publishes consume data operations while vitals do not, this would cause the Borons to exceed their monthly limit.
Is there some way to send out a ping or keep alive heartbeat from the Boron so that it will trigger a webhook like a regular event?
Does pinging a device through the Cloud API (Cloud API reference | Reference Documentation | Particle) use significantly less data than publishing vitals? I'm thinking of just setting up a cron job externally to ping every device in the database every five minutes if that would be more efficient, although generating the heartbeat on the device would lower the complexity of the system
pingDevice uses slightly less data than a publish, but it counts as a data operation so it probably won't be a better solution for your use case. Also as the number of devices increases, you could hit the API call limit of 10000 every 5 minutes per requesting IP address.
Wow, I wasn't aware that pings used data operations. So vitals publishes are the only way for a device to send any message to the cloud without consuming a data operation?
Another solution I'm considering is just implementing a completely separate heartbeat mechanism over UDP directly to my backend if that's the only path available; would that be recommended for this use case?
In general we do not recommend bypassing the cloud, however for your use case it's probably the only reasonable option. A few notes:
Of course your server will need a public IP address.
Do the DNS resolution once (if you are using DNS instead of a hardcoded IP address), as DNS will also use data and if you use a hostname with UDP it will look up the address every time with no caching.
This is only viable because you don't really need encryption or authentication for a device alive check.
You'll probably need to put the Device ID in the UDP payload to identify which devices you are receiving the ping from.
You might be able to use TCP, which would allow even lower data usage because you could send the Device ID on connection establishment, and then only end a single byte every 5 minutes, though that would expand to a TCP packet and a TCP ACK, but still low usage. The downside is that if you have a lot of devices, that's potentially a lot of connections to keep open on your server.
I will experiment and see what works best; it's a node server so handling many connections in parallel shouldn't be an issue. Thank you for the recommendation