Publish length vs battery life

I have a boron LTE and trying to maximize battery life. Currently, wake up every 15 minutes, take readings from 4 things, publish and fall back asleep. My current publish string is something like {aaaa:12.4, bbbb:999, cccc:99, dddd: 1234}.

First, Wondering what the impact on battery life would be if I shortened it to say {a:12.4,b:999,c:99,d:1234}

Or if I only need 2 variables every 15 minutes but could wait on publishing the other variables every 8 hours I could break my publish into two separate ones:
{a:12.4, b:99} sending every 15 minutes
{a:12.4,b:999,c:99,d:1234} Sending every 8 hours.

Does anyone have experience in understanding battery life vs the Length of the JSON object being sent? Is all the power being consumed to just establish the connection and the size of the data packet is minimal or how much of an impact could I expect?

I’m also looking at taking a reading but only turn on the cellular and publishing if the value changed from the previous reading.

Each approach and combination of approaches just adds some complexity and work to restructure some things. Wondering which is the biggest impact.

Any guidance is appreciated.

That's negligible. Once the connection is established (which can take up to minutes) the difference in time needed for a few extra bytes is in the realm of milliseconds (if that).

The only thing that would benefit from shorter messages would be your data allowance per month.

This will impact your battery life by orders of magnitude more than shorter messages - unless you will always have a change in value that requires a connection. But keeping the time your device stays connected as short as possible would be a good start.
So do all the stuff that does not require a connection first, then eventually connect, send, disconnect and go back to sleep.

However, you also need to consider how you will deal with OTA updates as they will need a minimal online time to kick in.

1 Like

Thanks Scruff, saved me some time in trying to test this. Or add unnecessary complexity in dealing with different events. Much appreciated.

Right now my code is probably sloppy as I don’t power on the sensor and take my sensor readings until Particle.connected. Might be able to do that while the modem is still off, then do the particle.connect and then fire off the publish event once I see particle.connected. Do you have any guidance on delays needed for OTA update check? 1-2 seconds or longer than that? I could do something like stay connected for 10 seconds every 24 hours or something like that to handle OTA checks right?

I also understand it as there is a keepAlive duration of 23 minutes. After a sleep for 23 minutes the device needs to re-register with the cloud which consumes a bunch of data and I suspect battery life. I like the idea of not publishing unless the value changed but depending on the rate of change in that value From my sensor I could be publishing every 30 minutes which I suspect the re-registering would kill any gains I’ve made. I thought I saw in a different post the sweet spot is about 1 hour. In other words, try and avoid sleeping between 23 minutes - 60 minutes because all gains in battery life are lost with needing to reregister. Am I understanding that right?

IIRC, that should be no less than 15 seconds after Particle.conneted() == true and once the device registers that a new firmware would be ready for consumption (only available for product device) you need to prevent the device from going to sleep till it selfresets.

Indeed you do :+1:

Thanks for the explanation. I am using a “product” and played once or twice with the OTA update. I’m very impressed in how that works.

Since your so helpful had another related question. What’s the cleanest (least power hungry) way to push a value/call a function down to a device that sleeps/wakes up/sleeps given my example above? I’d like a user to be able to hit a button on my web app that says “stay awake for 60 minutes”. The next time the device wakes up it somehow gets this message and then stays awake for 1 hour allowing the user to interact and take as many readings as they want before falling back asleep.

Here is what I currently have in place: I currently set up a “server sent events” client in Python that listens to the particle for new events from my fleet. When new events arrive it pushes that event data to SQL, queries SQL for that devices alert setting and then sends a text alert if needed by hitting the Twilio API.

Here is what I was thinking: from the web app, when a user hits the button, set a flag in SQL table for that device maybe called “stayAwakeRequest. When my python script receives new data for a device it immediately queries that specific device settings. It would see this flag and then make an API call back to particle to call a function maybe “stayAwake(60)” and then reset the flag in SQL so it only does it once.

My question:

  1. is there an easier way than this? Would be awesome if Particle could Queue up API requests for devices that sleep vs having us try and do it in our own back ends.
  2. This would require using that users personal token for the API call correct since with a product the device is owned and controlled by the user. As the product owner, can I use my Client ID and Secret for this API call? Right now I’m structured as saving the clients token to their browser cookies and then when they want to call a function I read the cookie before making the API call. If I need to call a function on their behalf then I’d also need to save their token in my SQL table which I was hoping to avoid.

Your input is appreciated!

For that you could use Device Notes to store the data and have the device run a Particle.subscribe()/Particle.publish() combo to request and receive the stored data.
https://docs.particle.io/reference/device-cloud/api/#add-device-notes

This way you'd not need any extra infrastructure.

However, since you have that infrastructure you can just have the device query the data directly from your DB instead of going via pub/sub.

Doing it the way you discribe above would involve some minimum wake time for this asynchronous scheme to reliably work.

1 Like

That’s a very interesting and clever technique using device notes. I’ll have to keep that in mind. I found the GitHub repo example you have out there as well. Good stuff!

It seems the pub/sub and device notes would work well for my own device, or devices owned by me where I can just hardcore the token into the webhook but my understanding is if I have the device as a product and that product is claimed by a customer, then I need that customers token for the Webhook to work or can I use my Client ID & Secret or my token instead?

Do you have a good example or reference on how to do this? It would be greatly appreciated. I’ve learned a decent amount the last 6 months or so but not sure where I’d start in order to read my SQL directly from particle. I just assumed I needed some sort of backend Service/API as the go between between my device, the particle cloud API/webhook and my SQL table.

Finally, wouldn’t doing the extra query from my device each power on/sleep cycle take extra power since it has to do this every time? I’m thinking a user would enter this “stayOn(1hour) mode more than every few days, maybe even once a week. So rather that, I was thinking the device wouldn’t do anything different 98% if the time. I guess to your point though it may need to stay awake a few seconds after particle.publish to wait for me to call the function.

Why do your customers need to claim the device? Your model of a central web app doesn't really work in these circumstances.

Here is what I was thinking: from the web app, when a user hits the button, set a flag in SQL table for that device maybe called “stayAwakeRequest. When my python script receives new data for a device it immediately queries that specific device settings. It would see this flag and then make an API call back to particle to call a function maybe “stayAwake(60)” and then reset the flag in SQL so it only does it once.

This is what I do with a fleet of 500 odd devices, they are all on a sleep, wake cycle. When they wake they send a "just woken" message and if the web app has a queued request then it calls a particle function which can then put the device into a state where it doesn't go to sleep at least for long enough to flash them.

You could also use Rick’s publish library to store the sensor readings and then publish all those saved readings at pre timed intervals to keep from needing to reconnect to the cloud every 15 mins but instead every hour or 4 hours ect.

Not sure how often you need the data to update on the other end or if battery life is more important.

Right now if a user wants to call a function on their device then within the web app itself, I make an aJax call to the particle cloud API within that JavaScript using the token I stored as a cookie In their browser when they logged in. If i “claimed” all the devices and managed who owned what device in my backend then I’d be exposing my token to the front end. This token would have access to the entire fleet. A tech savvy person, at least in theory, could grab my token and then query/control other people’s devices outside of my web app. Granted, very very unlikely that would ever happen especially since I’m starting so small but that’s the reason I went with having users claim their devices also in the particle cloud API. This way, the token they could see in their web app is their personal token even if they tried querying Particle for other devices they would only see theirs. I guess I could have the front end app make a call to my back end and then my backend make a call to particle as an alternative. 6 months ago I had no idea what an API was, 12 months ago I didn’t know what JSON, Python JavaScript, or HTML was so I’m still very much a rookie at this. It’s been a fun learning journey for sure and these forums are great! If there is a better/simpler way it’d be great to hear,

I like it... so how long is your device “connected” before falling back asleep automatically? I’d assume just a few seconds right? Have you tested how minimal time is needed for the round the circle trip takes (device to cloud to back end to cloud to device)?

so how long is your device “connected” before falling back asleep automatically

10-15 seconds, this is on WiFi not cellular, cellular would need more time I believe. This timing is to allow for delays in the web app to process a queue wake request and probably could be shorter but we would rather have the device wake for sure.

Right now if a user wants to call a function on their device then within the web app itself, I make an aJax call to the particle cloud API within that JavaScript using the token I stored as a cookie In their browser when they logged in. If i “claimed” all the devices and managed who owned what device in my backend then I’d be exposing my token to the front end. This token would have access to the entire fleet.

Understood now - that wouldn't be very secure. There needs to be a separation between the frontend of your web app which is serving the web page the user is interacting with on their browser and the backend that actually checks the identity of the web app user and confirms it is authorised to use the backend service to call an API with the correct product token for the device ID. There are also other techniques required to ensure that a browser user cannot interact improperly with these backend services. This all falls outside of this forum.

Oddly enough it’ll cycle between needing to report status every 10-20 minutes to update the mothership with readings from sensors or send text alert to the user based on settings and then being able to sleep 16 hours or even multiple days until the next period. Even when in the period of being able to sleep 16 hours I’d still likely have it wake up every 2-4 hours to update values.

This is what I’d like to do when sleeping but haven’t looked into it yet. Is this a public library I would find through “particle: find libraries” on github, somewhere in this forums, or where would I find it? This is what I’d like to do when in the period of low demand.

Due to the cycling back and forth between high demand and low demand, I really like the concept of doing this in my back end. I can very easily change the settings or logic that determines how long it should sleep for. My application, like many is temperature dependent. Was thinking if I knew the zip code where the device is used I could have my backend hit some kind of weather API for the hourly temperature for that zip code 8 hours in the future. Depending on the future predicted temperature I could tell how long the device should sleep for with better accuracy.

All interesting stuff. I sure do appreciate the great info and advice on these forums!

That could be performed by each Boron quickly using a weather service's API.
You have several choices for the Boron to determine it's general location.

1 Like

Interesting... you know if any good examples or reference info on how to make this happen. I need to minimize power so whatever method I deploy can’t be power hungry.

There are several Threads on the Forum.
I ended up using DarkSky.net for my weather service.

I use NodeRED to request weather predictions, and to track the forecasted Dew-points with the actual measured Dew-points for a bank of Evaporative Cooling towers. It doesn’t involve Particle’s Cloud.

You could also use a webhook. I don’t know which would work the best for you.
Either direction requires (1) of (2) things from you, in my mind:

  1. Each individual Boron needs to know the city or general location to request the weather forecast
    or
  2. A list of all Boron’s (and their Locations) needs to be maintained by You

In my mind, I’d lean towards the simplest solution (no weather predictions)… which seems like just a progressive Sleep Schedule based on the change in measured temperature. Your Power Budget wont take a big hit by waking in manual mode every 15 minutes to measure the temperature without starting the Modem or Particle Cloud Connection.
The Boron would operate in a Stand-Alone mode. Then you’d only need some provision to check an external database for a Firmware Update Flag every day (say lunchtime). No Tokens involved ?
This suggestion is based on the Power Budget being your major design goal, per your comments.

Just wanted to say how great this community is! I’ve learned quite a bit both in this post as well as other posts and really appreciate you guys taking the time to share your knowledge! Thank you everyone for the help and guidance! It is very much appreciated!

2 Likes

@Rftop Yeah, I’ll likely keep it simple. Like you said, waking for a few seconds every 20 minutes just to take readings and then fall back asleep without turning on the cellular should have minimal impact on battery life. It sure does keep it clean/simple.