Ejemplo n.º 1
0
        /// <summary>
        /// Эта функция служит для переупорядочивания записей в том случае, когда чёрный экран всплывает по бездействию,
        /// т.к. запись "continue" может быть уже после того, как программа убедится в бездействии пользователя и зачтёт часть времени бездействия в минус от текущего времени.
        /// </summary>
        private static void correctTimeRecordsFromAutoBlack(TimeRecordsList result)
        {
            lock (result)
                for (int i = 1; i < result.Count; i++) // 0 - самый недавний элемент
                {
                    if (result[i - 1].timeMark - result[i].timeMark < 0)
                    {
                        if (!result[i - 1].isOffAction)
                        {
                            throw new Exception("Фатальная ошибка в функции correctTimeRecordsFromAutoBlack. Сообщите разработчику [email protected]. " + result[i - 1].type + "/" + result[i].type + "//" + result[i - 1].timeMark + "/" + result[i].timeMark + "-" + i);
                        }

                        if (result[i].isOnAction)
                        {
                            result.RemoveAt(i);
                            i--;

                            currentStatus.modify(result[i]);
                        }
                        else
                        {
                            var o = result[i];
                            result.RemoveAt(i);
                            result.Insert(i - 1, o);
                        }
                    }
                }
        }
Ejemplo n.º 2
0
        private long calcLastRelaxTime(TimeRecordsList records, long minFullRelaxInterval, long maxRelaxTime)
        {
            long lastTime = DateTime.Now.Ticks;

            for (int i = 0; i < records.Count; i++)
            {
                if (records[i].isOffAction)
                {
                    /*int k = getTimeRecordWithAction(records, true, i + 1);
                     * if (k < 0)
                     *  return lastTime;
                     * if (lastTime - records[k - 1].timeMark > minRelaxInterval) */
                    if (lastTime - records[i].timeMark > minRelaxInterval)
                    {
                        return(lastTime);
                    }
                }
                else
                if (records[i].isOnAction)
                {
                    lastTime = records[i].timeMark;
                }
            }

            return(records[records.Count - 1].timeMark);
        }
Ejemplo n.º 3
0
        private static void TrimTimeRecords(TimeRecordsList result, long workInterval)
        {
            if (trimmedCount == result.Count)
            {
                return;
            }

            correctTimeRecordsFromAutoBlack(result);
            correctTimeRecordsFromBreakdown(result);

            trimmedCount = 0;
            if (result.Count <= 1)
            {
                return;
            }

            long lastMarkTime = 0;

            //if (result[0].isOffAction)
            lastMarkTime = DateTime.Now.Ticks;

            for (int i = 0; i < result.Count; i++)
            {
                long timeMark = result[i].timeMark;
                if (lastMarkTime - timeMark > workInterval)
                {
                    result.RemoveRange(i, result.Count - i);
                    break;
                }

                lastMarkTime = timeMark;
            }

            trimmedCount = result.Count;
        }
Ejemplo n.º 4
0
 private void ParseTimeRecords(string[] t, TimeRecordsList result)
 {
     for (int i = t.Length - 1; i >= 0; i--)
     {
         var rec = new TimeRecord(t[i]);
         result.Add(rec);
     }
 }
Ejemplo n.º 5
0
        double calcRelaxState(TimeRecordsList records, long relaxByHour, long maxRelaxTime)
        {
            double result   = 1.0;
            long   lastTime = 0;
            var    relax    = new TimeRecord.status();

            for (int i = records.Count - 1; i >= -1; i--)
            {
                if (relax.modify(records[i]) || (i < 0 && lastTime != 0))
                {
                    if (relax.workOldState == TimeRecord.status.st.No)
                    {
                        if (lastTime == 0)
                        {
                            throw new Exception("В расчёте времени отдыха зафиксирована невозможная ситуация типа TimeRecord.status.st.No==TimeRecord.status.st.Unknown");
                        }

                        long relaxTime = records[i].timeMark - lastTime;
                        if (relaxTime < minRelaxInterval)
                        {
                            relaxTime = 0;
                        }

                        result += (double)relaxTime / (double)relaxByHour / 2.0; // в 0 за два часа
                        if (result > 1.0)
                        {
                            result = 1.0;   // нельзя отдохнуть более, чем на 100%
                        }
                    }
                    else
                    if (relax.workOldState == TimeRecord.status.st.Yes)
                    {
                        if (lastTime == 0)
                        {
                            throw new Exception("В расчёте времени отдыха зафиксирована невозможная ситуация типа TimeRecord.status.st.Yes==TimeRecord.status.st.Unknown");
                        }

                        result -= (double)(records[i].timeMark - lastTime) / (double)(hour - relaxByHour) / 2.0;  // на 1 за два часа (работы и отдыха в заданном режиме)
                    }

                    if (relax.work != TimeRecord.status.st.Unknown)
                    {
                        lastTime = records[i].timeMark;
                    }
                    else
                    {
                        lastTime = 0;
                    }
                }
            }

            if (result > 1.0)
            {
                result = 1.0;   // нельзя отдохнуть более, чем на 100%
            }
            return(result);
        }
Ejemplo n.º 6
0
        private static void ShiftTimeRecords(TimeRecordsList result)
        {
            long timeShift = 0;

            for (int i = 0; i < result.Count; i++)
            {
                var rec = result[i];

                rec.timeMark = rec.timeMark1 + timeShift;
                rec.shifted  = timeShift;

                if (rec.type == TimeRecord.timeChanged)
                {
                    timeShift += rec.timeMark1 - rec.timeMark2;
                }
            }
        }
Ejemplo n.º 7
0
        private TimeRecordsList readAndParse()
        {
            string[] t = new String[0];
            if (File.Exists(logFileName))
            {
                t = File.ReadAllLines(logFileName);
            }

            var result = new TimeRecordsList(Math.Min(t.Length, 1024));

            // Берём из настроек workInterval, т.к. этот метод запускается ещё до анализа и workInterval ещё не инициализирован
            long maxRelaxTime, relaxByHour, relaxEventInterval, RelaxTime, minShortWorkInterval;

            getTimes(out maxRelaxTime, out workInterval, out relaxByHour, out relaxEventInterval, out RelaxTime, out minShortWorkInterval);

            ParseTimeRecords(t, result);
            ShiftAndTrim(result);

            return(result);
        }
Ejemplo n.º 8
0
        int getTimeRecordWithAction(TimeRecordsList records, bool onAction, int startI)
        {
            for (int i = startI; i < records.Count; i++)
            {
                if (onAction)
                {
                    if (records[i].isOnAction)
                    {
                        return(i);
                    }
                }
                else
                if (records[i].isOffAction)
                {
                    return(i);
                }
            }

            return(-1);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// В случае, если продолжительное время не было сообщений от программы, вставить сообщение, что программа была завершена
        /// </summary>
        private static void correctTimeRecordsFromBreakdown(TimeRecordsList result)
        {
            var lastTime = DateTime.Now.Ticks;

            for (int i = 0; i < result.Count; i++)  // 0 - самый недавний элемент
            {
                if (!result[i].isOffAction && lastTime - result[i].timeMark > continueInterval + 6 * second)
                {
                    var time = result[i].timeMark + (continueInterval >> 1);
                    if (time > lastTime)
                    {
                        throw new Exception("Фатальная ошибка в функции correctTimeRecordsFromBreakdown. Сообщите разработчику [email protected]");
                    }

                    var tr = new TimeRecord(time, result[i].shifted);
                    result.Insert(i, tr);
                }

                lastTime = result[i].timeMark;
            }
        }
Ejemplo n.º 10
0
        private void ParseAndTrimLog()
        {
            if (timeRecords == null || trimmedCount < 0)
            {
                timeRecords = readAndParse();
                for (int i = timeRecords.Count - 1; i >= 0; i--)
                {
                    currentStatus.modify(timeRecords[i]);
                }

                if (timeRecords.Count == 0)
                {
                    File.WriteAllText(logFileName, "");
                }
                else
                if (timeRecords.Count == 1 && timeRecords[0].type == TimeRecord.started)
                {
                    File.WriteAllText(logFileName, "");
                    logServiceTime(timeRecords[0].type, timeRecords[0].timeMark);
                }
            }
        }
Ejemplo n.º 11
0
 private static void ShiftAndTrim(TimeRecordsList result)
 {
     ShiftTimeRecords(result);
     TrimTimeRecords(result, workInterval);
 }
Ejemplo n.º 12
0
        private long checkToRelax(TimeRecordsList records, out long relax, out long work, out long toRelax, out int relaxSimpleStatus, out double relaxState)
        {
            long maxRelaxTime, relaxByHour, relaxEventInterval, RelaxTime, minShortWorkInterval;

            getTimes(out maxRelaxTime, out workInterval, out relaxByHour, out relaxEventInterval, out RelaxTime, out minShortWorkInterval);

            relax = calcRelaxTime(timeRecords, workInterval, maxRelaxTime);
            work  = calcWorkTime(timeRecords, workInterval, maxRelaxTime);

            relaxState = calcRelaxState(timeRecords, relaxByHour, maxRelaxTime);
            long lastr = calcLastRelaxTime(timeRecords, workInterval, maxRelaxTime);

            var oneRelax  = (double)relaxEventInterval / (double)hour / 2.0;    // что даёт одна релаксация (считая полный цикл за два часа)
            var WallRelax = 1.0 - oneRelax;

            toRelax = (long)(2 * relaxByHour * (1.0 - relaxState));      // отдых от relaxState=0 занимает два часа общего времени (включая рабочее)

            relaxSimpleStatus = 0;

            long now = DateTime.Now.Ticks;

            DbgLog.dbg.dataToLog("checkToRelax", "relax data", new { toRelax     = toRelax, RelaxTime = RelaxTime, relaxEventInterval = relaxEventInterval,
                                                                     work        = work, relax = relax, oneRelax = oneRelax, WallRelax = WallRelax,
                                                                     relaxState  = relaxState, lastr = lastr, minShortWorkInterval = minShortWorkInterval,
                                                                     now         = now, maxRelaxTime = maxRelaxTime, minFullRelaxInterval = workInterval,
                                                                     relaxByHour = relaxByHour });

            if (toRelax < 0 || RelaxTime < 0)
            {
                Program.ToLogFile("toRelax < 0 || RelaxTime < 0");
                throw new Exception("Программа произвела неверный расчёт времени отдыха. Сообщите об этом разработчику!");
            }

            if (toRelax > relaxByHour * 2)
            {
                relaxSimpleStatus = 1;
            }
            if (toRelax > relaxByHour * 3)
            {
                relaxSimpleStatus = 2;
            }

            var trlt = Math.Max(RelaxTime, toRelax) / 10000 + 1.0;
            var s    = ((double)(RelaxTime / 10000) / trlt);

            if (
                work < (relaxEventInterval - RelaxTime) // || lastr + (relaxEventInterval - RelaxTime) * s > now
                )
            {
                return(0);
            }

            if (lastr + minShortWorkInterval * s > now)
            {
                return(0);
            }

            // rc/wc = (r + x)/w => w*rc/wc - r = x
            if (toRelax >= RelaxTime)
            {
                return(toRelax);
            }

            return(0);
        }