Beispiel #1
0
        public static IList <TimeSplit <T> > CalcEventsTimeSplitAggregate <T> (IReadOnlyDictionary <uint, IList <TimeSplit <T> > > dict)
        {
            // Calculate aggregate percentages

            return(dict.Values
                   .SelectMany(_ => _)
                   .GroupBy(ctrldict => ctrldict.StartTime)
                   .OrderBy(g => g.Key)
                   .AsParallel()
                   .Select(g => {
                var starttime = g.Key;
                var endtime = g.FirstOrDefault()?.EndTime ?? default(DateTimeOffset);
                var num = g.Count();

                var r = new TimeSplit <T>(
                    g.SelectMany(t => t.Data)
                    .GroupBy(kv => kv.Key, kv => kv.Value)
                    .ToDictionary(x => x.Key, x => x.Sum(p => p) / num)
                    );

                r.StartTime = starttime;
                r.EndTime = endtime;

                return r;
            }).OrderBy(x => x.StartTime)
                   .ToList());
        }
        public void CheckTimeSplit()
        {
            var checkTimeList = new List <string> {
                "10:11:01", "12:03:34", "14:05:04", "18:07:21"
            };
            var splitTime = new TimeSplit(checkTimeList);

            Assert.True(splitTime.IsTimeSplit);
        }
Beispiel #3
0
        public async Task <IReadOnlyDictionary <uint, IList <TimeSplit <T> > > > GetEventsTimeSplit <T> (DateTimeOffset from, DateTimeOffset to, Func <EventX, T> grouping, string field, T nullValue, bool skipNulls, TimeSpan step, TimeSpan timezone, string orgId, ICollection <uint> controllers)
        {
            if (from > to)
            {
                throw new ArgumentOutOfRangeException(nameof(from), "Start date must not be later than the end date.");
            }
            if (grouping == null)
            {
                throw new ArgumentNullException(nameof(grouping));
            }

            var clist = await Utils.GetValidControllersAsync(m_DB, orgId).ConfigureAwait(false);

            if (clist == null)
            {
                return(null);
            }

            if (controllers == null || controllers.Contains(0))
            {
                controllers = clist.Select(c => (uint)c.ID).ToList();
            }
            else
            {
                var newlist = clist.Select(c => (uint)c.ID).Intersect(controllers).ToList();

                // No controllers selected
                if (newlist.Count <= 0 || newlist.Count < controllers.Count)
                {
                    return(null);
                }

                controllers = newlist;
            }

            var incrementdate = Utils.GetIncrementDateFunc(step, timezone);

            var result = new ConcurrentDictionary <uint, ConcurrentBag <EventX> >(controllers.Select(id => new KeyValuePair <uint, ConcurrentBag <EventX> >(id, new ConcurrentBag <EventX>())));

            foreach (var controllerId in controllers)
            {
                // Start selecting one day before the lower bound
                var r = await GetDataAsync <EventX>(Storage.EventsTable, from.AddDays(-1), to, null, Sorting.None, orgId, controllerId, field, skipNulls).ConfigureAwait(false);

                if (r == null)
                {
                    return(null);
                }

                foreach (var ev in r)
                {
                    result.AddOrUpdate(ev.Controller, new ConcurrentBag <EventX>()
                    {
                        ev
                    }, (k, v) => { v.Add(ev); return(v); });
                }
            }

            // Process all the controllers in parallel
            var dict = new ConcurrentDictionary <uint, List <Dictionary <T, double> > >();

            var slots = 1;

            result.AsParallel().ForAll(ctrl => {
                var xlist        = ctrl.Value.OrderBy(ev => ev.Time).ThenBy(ev => ev.RowKey).ToList();
                var ctrldictlist = dict.GetOrAdd(ctrl.Key, x => new List <Dictionary <T, double> >());

                if (step == default(TimeSpan))
                {
                    step = to - from;
                }
                var lastdate  = from;
                var laststate = default(T);
                var hasvalue  = false;
                var slot      = 0;

                for (var lower = from; lower < to; lower = incrementdate(lower, step), slot++)
                {
                    var upper = incrementdate(lower, step);
                    if (upper > to)
                    {
                        upper = to;
                    }

                    if (slots <= slot)
                    {
                        slots = slot + 1;
                    }

                    var ctrldict = new Dictionary <T, double>();
                    ctrldictlist.Add(ctrldict);

                    // Add a dummy record at the end to make sure we get the very last segment
                    foreach (var entry in xlist.Concat(new[] { new EventX() }))
                    {
                        var newstate = grouping(entry);

                        if (newstate == null)
                        {
                            newstate = nullValue;
                        }

                        if (entry.Time < lastdate)
                        {
                            // Value below the lower bound
                            laststate = newstate;
                            hasvalue  = true;
                            continue;
                        }
                        else if (!hasvalue)
                        {
                            // Value within range but there is still no state - try to estimate
                            if (typeof(T) == typeof(bool) || newstate is bool)
                            {
                                laststate = (T)Convert.ChangeType(!((bool)Convert.ChangeType(newstate, typeof(bool))), typeof(T));
                            }
                            else
                            {
                                laststate = nullValue;
                            }

                            hasvalue = true;
                        }

                        // Value in range
                        var interval = entry.Time - lastdate;

                        if (entry.Time >= upper)
                        {
                            interval = upper - lastdate;
                            lastdate = upper;
                        }
                        else
                        {
                            lastdate = entry.Time;
                        }

                        if (ctrldict.ContainsKey(laststate))
                        {
                            ctrldict[laststate] += interval.TotalMilliseconds;
                        }
                        else
                        {
                            ctrldict[laststate] = interval.TotalMilliseconds;
                        }

                        if (entry.Time >= upper)
                        {
                            break;
                        }
                        else
                        {
                            laststate = newstate;
                        }
                    }
                }
            });

            return(dict.ToDictionary(kv => kv.Key, kv => {
                var startdate = from;

                return kv.Value.Select((entry, x) => {
                    var enddate = (step == TimeSpan.Zero || x >= slots - 1) ? to : incrementdate(startdate, step);
                    var timerange = (enddate - startdate).TotalMilliseconds;

                    var r = new TimeSplit <T>(entry.ToDictionary(t => t.Key, t => t.Value / timerange));

                    r.StartTime = startdate;
                    r.EndTime = enddate;

                    startdate = incrementdate(startdate, step);

                    return r;
                }).ToList() as IList <TimeSplit <T> >;
            }));
        }
        void addWkTimeSegment(DateTime timeA, DateTime timeB, EvOfIntFlag eoiA, EvOfIntFlag eoiB, Brush brh, ref TimeSplit ts)
        {
            if (eoiA == EvOfIntFlag.ScreenSaverrUp && eoiB == EvOfIntFlag.BootAndWakeUps)
            {
                eoiB = EvOfIntFlag.ScreenSaverrUp;                                                                     // ignore odd pwr-on during scrsvr runs.
            }
            if (eoiA == EvOfIntFlag.BootAndWakeUps && eoiB == EvOfIntFlag.ScreenSaverrDn)
            {
                eoiA = EvOfIntFlag.ScreenSaverrUp;                                                                     // ignore odd pwr-on during scrsvr runs.
            }
            add_________Time(timeA, timeB, eoiA, eoiB, ref ts);

            var angleA = _aw * (eoiA == EvOfIntFlag.ScreenSaverrUp ? timeA.AddSeconds(-Ssto_GpSec).TimeOfDay.TotalDays : timeA.TimeOfDay.TotalDays); // for ss up - start idle line 2 min prior
            var angleB = _aw * (eoiB == EvOfIntFlag.ScreenSaverrUp ? timeB.AddSeconds(-Ssto_GpSec).TimeOfDay.TotalDays : timeB.TimeOfDay.TotalDays); // for ss dn - end   work line 2 min prior

            var hgt =
                eoiA == EvOfIntFlag.Day1stAmbiguos ? (_ah / 9) :
                eoiA == EvOfIntFlag.ScreenSaverrUp ? (_ah / 7) :
                eoiA == EvOfIntFlag.ScreenSaverrDn ? (_ah / 1) :
                eoiA == EvOfIntFlag.BootAndWakeUps ? (_ah / 1) :
                eoiA == EvOfIntFlag.Who_Knows_What ? (_ah / 8) :
                0;

            var isUp = eoiA == EvOfIntFlag.ScreenSaverrDn || eoiA == EvOfIntFlag.BootAndWakeUps;
            var top  = _ah - hgt;
            var wid  = Math.Abs(angleB - angleA);

            var time = TimeSpan.FromDays(wid / _aw);

            addRectangle(top, hgt, angleA, wid, brh, $"Span: {time:h\\:mm\\:ss}  => {wid:N0} pxl.");
            if (wid > .005 * _aw)
            {
                var isBig = time > TimeSpan.FromHours(1);
                addUiElnt(
                    isUp ? 2 : -1,
                    angleB - (isBig ? 28 : 20),
                    new TextBlock
                {
                    Text       = isBig ? $"{time:h\\:mm}" : $"{time,3:\\:m}",
                    FontSize   = isUp ? 14 : 12,
                    Foreground = isUp ? Brushes.LimeGreen : Brushes.DodgerBlue,
                    ToolTip    = $"Span: {time:h\\:mm\\:ss}  => {wid:N0} pxl."
                });
 void add_________Time(DateTime timeA, DateTime timeB, EvOfIntFlag eoiA, EvOfIntFlag eoiB, ref TimeSplit ts)
 {
     if (eoiA == EvOfIntFlag.ScreenSaverrDn || eoiA == EvOfIntFlag.BootAndWakeUps)
     {
         ts.WorkedFor += (timeB - timeA);
     }
     else
     {
         ts.IdleOrOff += (timeB - timeA);
     }
 }
        });                                                                                                                                                                                                                                                                                //addArcDtl(hgt, left, width);

        void drawUpDnLine(DateTime trgDate, string pc, string rgb)
        {
            var pcClr = new SolidColorBrush((Color)ColorConverter.ConvertFromString(rgb));
            var ts    = new TimeSplit();

            //..Trace.Write($">>>-\tdrawUpDnLine():  {trgDate:d} ->> {pc,-16} \t");
            tbSummary.Text = "$@#";
            try
            {
                _ah = canvasBar.ActualHeight;
                _aw = canvasBar.ActualWidth;
                var timeA  = trgDate;
                var timeB  = trgDate.AddDays(.9999999);
                var isHere = Environment.MachineName.Equals(pc, StringComparison.OrdinalIgnoreCase);

                SortedList <DateTime, int> eois;
                if (isHere)
                {
                    var localEvLog = EvLogHelper.GetAllUpDnEvents(timeA, timeB);
                    var dbaseEvLog = DbLogHelper.GetAllUpDnEvents(timeA, timeB, pc);
                    eois = localEvLog.Count > dbaseEvLog.Count ? localEvLog : dbaseEvLog; // Jan 2020: whoever has more events wins!
                }
                else
                {
                    eois = DbLogHelper.GetAllUpDnEvents(timeA, timeB, pc);
                }

                if (trgDate == DateTime.Today && isHere)
                {
                    eois.Add(DateTime.Now, 2); // == ((int)EvOfIntFlag.ScreenSaverrUp)
                }
                if (eois.Count < 1)
                {
                    tbSummary.Text = $"{trgDate,16:ddd, MMM dd yyyy}  no activities logged on this date.";
                }
                else
                {
                    var eoi0     = eois.FirstOrDefault();
                    var prevEoiF = eoi0.Value == (int)EvOfIntFlag.ScreenSaverrDn ? EvOfIntFlag.ScreenSaverrUp :
                                   eoi0.Value == (int)EvOfIntFlag.BootAndWakeUps ? EvOfIntFlag.ShutAndSleepDn : EvOfIntFlag.Day1stAmbiguos;

                    foreach (var eoi in eois)
                    {
                        addWkTimeSegment(timeA, eoi.Key, prevEoiF, (EvOfIntFlag)eoi.Value, pcClr, ref ts);

                        timeA    = eoi.Key;
                        prevEoiF = (EvOfIntFlag)eoi.Value;
                    }

                    var lastScvrUp = (eois.Any(r => r.Value == (int)EvOfIntFlag.ScreenSaverrUp || r.Value == (int)EvOfIntFlag.ShutAndSleepDn) ?
                                      eois.Where(r => r.Value == (int)EvOfIntFlag.ScreenSaverrUp || r.Value == (int)EvOfIntFlag.ShutAndSleepDn).Last() : eois.Last()).Key;

                    var finalEvent = eois.Last().Key;

                    ts.TotalDaysUp = (lastScvrUp < finalEvent ? lastScvrUp : finalEvent) - eois.First().Key;

                    tbSummary.Text = $"{trgDate,16:ddd, MMM dd yyyy}    {ts.TotalDaysUp,5:h\\:mm}  ({ts.WorkedFor:h\\:mm})    ";
                }

                tbSummary.Foreground = (trgDate.DayOfWeek == DayOfWeek.Saturday || trgDate.DayOfWeek == DayOfWeek.Sunday) ? cWEd : cWDd;
                gridvroot.Background = (trgDate.DayOfWeek == DayOfWeek.Saturday || trgDate.DayOfWeek == DayOfWeek.Sunday) ? cPnk : cBlk;
            }
            catch (Exception ex) { ex.Pop(); }
            finally { Trace.WriteLine($" ==> { tbSummary.Text} "); }
        }