Exemplo n.º 1
0
        public void CheckQueues(MazakSchedulesAndLoadActions mazakData)
        {
            if (!OpenDatabaseKitDB.MazakTransactionLock.WaitOne(TimeSpan.FromMinutes(3), true))
            {
                log.Debug("Unable to obtain mazak db lock, trying again soon.");
                return;
            }
            try
            {
                var transSet = CalculateScheduleChanges(mazakData);

                if (transSet != null && transSet.Schedules.Count() > 0)
                {
                    _transDB.Save(transSet, "Setting material from queues");
                }
                CurrentQueueMismatch = false;
            }
            catch (Exception ex)
            {
                CurrentQueueMismatch = true;
                log.Error(ex, "Error checking for new material");
            }
            finally
            {
                OpenDatabaseKitDB.MazakTransactionLock.ReleaseMutex();
            }
        }
Exemplo n.º 2
0
 public LogTranslation(BlackMaple.MachineFramework.JobDB jDB,
                       BlackMaple.MachineFramework.JobLogDB logDB,
                       MazakSchedulesAndLoadActions mazakSch,
                       BlackMaple.MachineFramework.FMSSettings settings,
                       Action <LogEntry> onMazakLogMessage)
 {
     _jobDB          = jDB;
     _log            = logDB;
     _mazakSchedules = mazakSch;
     _settings       = settings;
     _onMazakLog     = onMazakLogMessage;
     _jobs           = new Dictionary <string, JobPlan>();
 }
Exemplo n.º 3
0
        public MazakWriteData CalculateScheduleChanges(MazakSchedulesAndLoadActions mazakData)
        {
            log.Debug("Starting check for new queued material to add to mazak");

            var schs = LoadSchedules(mazakData);

            if (!schs.Any())
            {
                return(null);
            }

            AttemptToUnallocateCastings(schs);
            CalculateTargetMatQty(mazakData, schs);
            AttemptToAllocateCastings(schs, mazakData);
            return(UpdateMazakMaterialCounts(schs));
        }
Exemplo n.º 4
0
        private void CalculateTargetMatQty(MazakSchedulesAndLoadActions mazakData, IEnumerable <ScheduleWithQueues> schs)
        {
            // go through each job and process, and distribute the queued material among the various paths
            // for the job and process.
            foreach (var job in schs.GroupBy(s => s.Unique))
            {
                var uniqueStr = job.Key;
                var numProc   = job.First().Job.NumProcesses;
                log.Debug("Checking job {uniq} with schedules {@pathGroup}", uniqueStr, job);

                // do processes 2+ so that correct material counts are present during check for
                // castings in proc1.
                for (int proc = 2; proc <= numProc; proc++)
                {
                    CheckInProcessMaterial(job.First().Job, job, proc);
                }
                CheckCastingsForProc1(job, mazakData);
            }
        }
Exemplo n.º 5
0
 public MazakSchedulesAndLoadActions LoadSchedulesAndLoadActions()
 {
     return(WithReadDBConnection(conn =>
     {
         var trans = conn.BeginTransaction();
         try
         {
             var ret = new MazakSchedulesAndLoadActions()
             {
                 Schedules = _openReadDB.LoadSchedules(conn, trans).Schedules,
                 LoadActions = CurrentLoadActions(),
                 Tools = LoadTools(conn, trans)
             };
             trans.Commit();
             return ret;
         }
         catch
         {
             trans.Rollback();
             throw;
         }
     }));
 }
Exemplo n.º 6
0
        private List <DecrSchedule> JobsToDecrement(MazakSchedulesAndLoadActions schedules)
        {
            var jobs = new List <DecrSchedule>();

            foreach (var sch in schedules.Schedules)
            {
                //parse schedule
                if (!MazakPart.IsSailPart(sch.PartName))
                {
                    continue;
                }
                if (string.IsNullOrEmpty(sch.Comment))
                {
                    continue;
                }
                MazakPart.ParseComment(sch.Comment, out string unique, out var procToPath, out bool manual);
                if (manual)
                {
                    continue;
                }

                //load the job
                if (string.IsNullOrEmpty(unique))
                {
                    continue;
                }
                var job = _jobDB.LoadJob(unique);
                if (job == null)
                {
                    continue;
                }

                // if already decremented, ignore
                if (_jobDB.LoadDecrementsForJob(unique).Any())
                {
                    continue;
                }


                // check load is in process
                var loadOpers  = schedules.LoadActions;
                var loadingQty = 0;
                if (loadOpers != null)
                {
                    foreach (var action in loadOpers)
                    {
                        if (action.Unique == job.UniqueStr && action.Process == 1 && action.LoadEvent && action.Path == procToPath.PathForProc(action.Process))
                        {
                            loadingQty += action.Qty;
                            Log.Debug("Found {uniq} is in the process of being loaded action {@action}", job.UniqueStr, action);
                        }
                    }
                }

                jobs.Add(new DecrSchedule()
                {
                    Schedule   = sch,
                    Job        = job,
                    Proc1Path  = procToPath.PathForProc(proc: 1),
                    NewPlanQty = CountCompletedOrMachiningStarted(sch) + loadingQty
                });
            }

            return(jobs);
        }
Exemplo n.º 7
0
        private void AttemptToAllocateCastings(IEnumerable <ScheduleWithQueues> schs, MazakSchedulesAndLoadActions mazakData)
        {
            // go through each job and check for castings in an input queue that have not yet been assigned to a job
            foreach (var job in schs.Where(s => !s.LowerPriorityScheduleMatchingPartSkipped).OrderBy(s => s.Job.RouteStartingTimeUTC).GroupBy(s => s.Unique))
            {
                var uniqueStr = job.Key;
                var partName  = job.First().Job.PartName;
                var numProc   = job.First().Job.NumProcesses;
                log.Debug("Checking job {uniq} with for unallocated castings", uniqueStr);

                bool needRecheckProc1 = false;

                // check for any raw material to assign to the job
                var proc1Queues =
                    job
                    .Select(s => s.Procs[1].InputQueue)
                    .Where(q => !string.IsNullOrEmpty(q))
                    .Distinct();
                foreach (var queue in proc1Queues)
                {
                    var inQueue = _log.GetMaterialInQueue(queue);

                    var remain = job.Select(s =>
                                            s.SchRow.PlanQuantity - CountCompletedOrMachiningStarted(s)
                                            ).Sum();
                    var alreadyAssigned =
                        inQueue
                        .Where(m => m.Unique == uniqueStr && FindNextProcess(m.MaterialID) == 1)
                        .Count();
                    var partsToAllocate =
                        inQueue
                        .Where(m => string.IsNullOrEmpty(m.Unique) && m.PartName == partName)
                        .Any();
                    log.Debug("Checking unique {uniq} for unallocated castings in queue {queue}, " +
                              " found {remain} remaining parts, {assigned} already assigned parts, {toAllocate} parts to allocate",
                              uniqueStr, queue, remain, alreadyAssigned, partsToAllocate);

                    if (remain > alreadyAssigned && partsToAllocate)
                    {
                        var newMats = _log.AllocateCastingsInQueue(queue, partName, uniqueStr, numProc, remain - alreadyAssigned);
                        log.Debug("Alloacted new ids {@matIds} to {unique}, recalculating proc1 castings", newMats, uniqueStr);
                        needRecheckProc1 = true;
                    }
                }

                if (needRecheckProc1)
                {
                    CheckCastingsForProc1(job, mazakData);
                }
            }
        }
Exemplo n.º 8
0
        private void CheckCastingsForProc1(IGrouping <string, ScheduleWithQueues> job, MazakSchedulesAndLoadActions mazakData)
        {
            string uniqueStr = job.Key;

            // group the paths for this process by input queue
            var proc1PathsByQueue = job
                                    .Where(s => s.SchRow.PlanQuantity > CountCompletedOrMachiningStarted(s))
                                    .Select(s => s.Procs[1])
                                    .Where(p => !string.IsNullOrEmpty(p.InputQueue))
                                    .GroupBy(p => p.InputQueue);

            foreach (var queueGroup in proc1PathsByQueue)
            {
                var matInQueue =
                    _log.GetMaterialInQueue(queueGroup.Key)
                    .Where(m => m.Unique == uniqueStr && FindNextProcess(m.MaterialID) == 1)
                    .Count()
                ;
                var curMazakSchMat = queueGroup.Select(s => s.SchProcRow.ProcessMaterialQuantity).Sum();

                log.Debug("Calculated {matInQueue} parts in queue and {mazakCnt} parts in mazak for job {uniq} proccess 1",
                          matInQueue, curMazakSchMat, uniqueStr);

                if (queueGroup.Count() == 1)
                {
                    // put all material on the single path
                    if (matInQueue != curMazakSchMat)
                    {
                        queueGroup.First().TargetMaterialCount = matInQueue;
                    }
                }
                else
                {
                    // keep each path at least fixQty piece of material
                    if (matInQueue > curMazakSchMat)
                    {
                        int remain         = matInQueue - curMazakSchMat;
                        var potentialPaths =
                            queueGroup
                            .Where(p => p.SchProcRow.ProcessMaterialQuantity == 0)
                            .OrderBy(p => p.SchProcRow.ProcessExecuteQuantity);
                        foreach (var p in potentialPaths)
                        {
                            int fixQty = p.SchProcRow.FixQuantity;
                            if (fixQty <= remain)
                            {
                                remain -= fixQty;
                                p.TargetMaterialCount = fixQty;
                            }
                            if (remain <= 0)
                            {
                                break;
                            }
                        }
                    }
                    else if (matInQueue < curMazakSchMat)
                    {
                        int toRemove       = curMazakSchMat - matInQueue;
                        var potentialPaths =
                            queueGroup
                            .Where(p => p.SchProcRow.ProcessMaterialQuantity > 0)
                            .OrderByDescending(p => p.SchProcRow.ProcessMaterialQuantity)
                            .ThenBy(p => p.SchProcRow.ProcessExecuteQuantity);
                        foreach (var p in potentialPaths)
                        {
                            if (toRemove >= p.SchProcRow.ProcessMaterialQuantity)
                            {
                                p.TargetMaterialCount = 0;
                                toRemove -= p.SchProcRow.ProcessMaterialQuantity;
                            }
                            else
                            {
                                p.TargetMaterialCount = p.SchProcRow.ProcessMaterialQuantity - toRemove;
                                toRemove = 0;
                            }
                            if (toRemove <= 0)
                            {
                                break;
                            }
                        }
                    }
                }
            }

            // now deal with the non-input-queue parts. They could have larger material than planned quantity
            // if the schedule has been decremented
            foreach (var sch in job)
            {
                if (string.IsNullOrEmpty(sch.Procs[1].InputQueue) &&
                    sch.SchRow.PlanQuantity <= CountCompletedOrMachiningStarted(sch) &&
                    sch.Procs[1].SchProcRow.ProcessMaterialQuantity > 0
                    )
                {
                    sch.Procs[1].TargetMaterialCount = 0;
                }
            }
        }
Exemplo n.º 9
0
        private IEnumerable <ScheduleWithQueues> LoadSchedules(MazakSchedulesAndLoadActions mazakData)
        {
            var loadOpers    = mazakData.LoadActions;
            var schs         = new List <ScheduleWithQueues>();
            var pending      = _log.AllPendingLoads();
            var skippedParts = new HashSet <string>();

            foreach (var schRow in mazakData.Schedules.OrderBy(s => s.DueDate).ThenBy(s => s.Priority))
            {
                if (!MazakPart.IsSailPart(schRow.PartName))
                {
                    continue;
                }

                MazakPart.ParseComment(schRow.Comment, out string unique, out var procToPath, out bool manual);

                var job = _jobDB.LoadJob(unique);
                if (job == null)
                {
                    continue;
                }

                // only if no load or unload action is in process
                bool foundJobAtLoad = false;
                foreach (var action in loadOpers)
                {
                    if (action.Unique == job.UniqueStr && action.Path == procToPath.PathForProc(action.Process))
                    {
                        foundJobAtLoad = true;
                        skippedParts.Add(job.PartName);
                        log.Debug("Not editing queued material because {uniq} is in the process of being loaded or unload with action {@action}", job.UniqueStr, action);
                        break;
                    }
                }
                foreach (var pendingLoad in pending)
                {
                    var s = pendingLoad.Key.Split(',');
                    if (schRow.PartName == s[0])
                    {
                        skippedParts.Add(job.PartName);
                        foundJobAtLoad = true;
                        log.Debug("Not editing queued material because found a pending load {@pendingLoad}", pendingLoad);
                        break;
                    }
                }
                if (foundJobAtLoad)
                {
                    continue;
                }

                // start building the schedule
                var sch = new ScheduleWithQueues()
                {
                    SchRow = schRow,
                    Unique = unique,
                    Job    = job,
                    LowerPriorityScheduleMatchingPartSkipped = skippedParts.Contains(job.PartName),
                    Procs = new Dictionary <int, ScheduleWithQueuesProcess>(),
                };
                bool missingProc = false;
                for (int proc = 1; proc <= job.NumProcesses; proc++)
                {
                    MazakScheduleProcessRow schProcRow = null;
                    foreach (var row in schRow.Processes)
                    {
                        if (row.ProcessNumber == proc)
                        {
                            schProcRow = row;
                            break;
                        }
                    }
                    if (schProcRow == null)
                    {
                        log.Error("Unable to find process {proc} for job {uniq} and schedule {schid}", proc, job.UniqueStr, schRow.Id);
                        missingProc = true;
                        break;
                    }
                    var path = procToPath.PathForProc(proc);
                    sch.Procs.Add(proc, new ScheduleWithQueuesProcess()
                    {
                        SchProcRow = schProcRow,
                        PathGroup  = job.GetPathGroup(process: proc, path: path),
                        InputQueue = job.GetInputQueue(process: proc, path: path)
                    });
                }
                if (!missingProc)
                {
                    schs.Add(sch);
                }
            }
            return(schs);
        }