Ubidots Community

[SOLVED] How to build a rolling 10 day median synthetic variable?

I am trying to do something that I think is possible with a combination of a synthetic variable expression and an event.

I have counters in parks across the state and, occasionally, something happens that impacts the counts. For example, when a road tube wears out, it fails to count the cars and it will drop off to zero over time. I would like to see if there is a way to trigger an event that would alert park staff to this condition.

Here is what I planned:

  1. I would take a 10 day rolling median of the maximum daily count. The maximum daily count is a synthetic variable based on the daily count which grows over the day and is defined as:
Daily Max = max( Daily ,"1D")

Then I could take the median of the Daily Max synthetic variable over a rolling 10-day windows which I thought would be:

10-day Rolling Median Daily Max = median(Daily Max ,"10D")

Then, I would take a look at each day’s daily max, and if it was less than 20% of the 10-day median, I would send an alert to the park staff. Something like this:

low count alert = where ( Daily Max < 0.2 * median( Daily Max ,"10D") ,1,0)

I could then trigger an event on the low count alert synthetic variable.

Of course, this does not work as it seems that the “10D” argument means the median value is only calculated once every 10 days. This is not what I was going for.

Any suggestions on how to make this work?

Thanks, Chip

Hi @chipmc,

The data range functions available in the synthetic variables engine aren’t of the rolling type. They instead compute fix cycles based on the range you entered. For example, median(var, "10D") computes the median every 10 days, that is, one value every 10 days. This is something you already experienced but I thought it worth of clarifying.
Also in that same front, allowed data ranges are only those that can evenly divide the next range. For example, if using days (“D”), whatever the number is, it has to evenly divide one month (“M”). Under such example, the only available value for days is “1D” because for 31-days months, you can’t evenly divide a month. For you reference, this is explained here. Note that while the engine does compute values when using “10D”, there could be instances where the calculation isn’t correct and hard to explain.

Now, here’s what I think you can do instead to get the 10-days rolling median: build an UbiFunction to compute it. The task that would need to take place in the Function code are:

  • Retrieve the last 10 days worth of data from the Daily max synthetic variable.
  • Compute the median.
  • Compare the median with the last Daily max value that you already retrieved. Comparison is to check if last value is lesser than 20% of the median.
  • Lasty, post 1 or 0 to the low count alert variable to trigger the event. This won’t be a synthetic variable anymore but a raw one feed from this function

Some consideration and points to notice:

  1. You won’t need multiple synthetic variables, just the Daily max.
  2. I’m not sure about this but I’m guessing you won’t need a real time update so you can trigger the UbiFunction once or twice per day only, although this is up to you.
  3. To trigger the function, you can use Scheduled Events at certain times of the day.

Does this make sense?


1 Like


Yes, this makes sense. I guess I need to get smarter on UbiFunctions but this is a great reason to do so.