The one thing that I don't like about your solution, Daba, is that some months you populate WaitingTimes[31] and some months you don't. Feb is even worse. So when you're looking at "the last 30 days of data", you have to know whether or not to include certain registers.
The COP ([1],[0],len) technique simplifies looking at 30 days worth of data. Making an array of UDTs allows the capturing of more data points than just the "Idle" times. There is a difference if the machine is idle for a total of 1 hour, but was idle 300 times in the shift (meaning that it was typically waiting 12 seconds between parts), versus being idle for an hour only 1 time in the shift (indicating a major downtime event).
A UDT can also, if it's important, include shift, day stamp, and whatever else is desired.
I'm all in favor of "keep it simple". But there's also such thing as too simple when there are unrealized needs.
To modify what I posted to a 30-day cycle, I would not use the RTC.Day register, but would manage my own pointer into a 30-element array, just cycling around 0 to 29. This would certainly make the summation and averaging easier in the long run, but as I said just about anything is "do-able", and I'm not making the choice which way to go, just suggesting ideas.
The COP idea will certainly work, but there's no need to shift the data, just increment a pointer into the storage and MOD it with 29
And if you want to differentiate between "waiting once for a long time", and "waiting many times for short times", IMHO the PLC isn't the place to do that sort of statistical analysis, SQL anyone ?