aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Tango.PPC.Common/Statistics/DefaultStatisticsService.cs
blob: d05b4c6bf769ebbf5038c96b4d8617b0ac8f3542 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
/* Generated from: FileAttribute.proto */

/* Do not generate deprecated warnings for self */
#ifndef PROTOBUF_C__NO_DEPRECATED
#define PROTOBUF_C__NO_DEPRECATED
#endif

#include "FileAttribute.pb-c.h"
static const ProtobufCEnumValue file_attribute__enum_values_by_number[7] =
{
  { "", "", 0 },
  { "", "", 1 },
  { "", "", 2 },
  { "", "", 4 },
  { "", "", 8 },
  { "", "", 16 },
  { "", "", 32 },
};
static const ProtobufCIntRange file_attribute__value_ranges[] = {
{0, 0},{4, 3},{8, 4},{16, 5},{32, 6},{0, 
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL;
using Tango.BL.DTO;
using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.Core;
using Tango.Core.DI;
using Tango.Integration.ExternalBridge;
using Tango.Integration.JobRuns;
using Tango.PPC.Common.Connection;
using Tango.PPC.Common.ExternalBridge;
using Tango.PPC.Shared.Statistics;

namespace Tango.PPC.Common.Statistics
{
    [TangoCreateWhenRegistered]
    public class DefaultStatisticsService : ExtendedObject, IStatisticsService, IExternalBridgeRequestHandler
    {
        private IMachineProvider _machineProvider;
        private Dictionary<ExternalBridgeReceiver, String> _streamingReceivers;
        private List<ColorCatalog> _catalogs;
        private List<ColorCatalogsItem> _color_catalog_Items;
        private List<ColorSpace> _colorSpaces;
        private Dictionary<String, LiquidType> _liquidTypes;

        public bool Enabled { get; set; } = true;

        public DefaultStatisticsService(IPPCExternalBridgeService externalBridge, IMachineProvider machineProvider)
        {
            _streamingReceivers = new Dictionary<ExternalBridgeReceiver, string>();

            try
            {
                _machineProvider = machineProvider;
                externalBridge.RegisterRequestHandler(this);
            }
            catch (Exception ex)
            {
                LogManager.Log(ex, "Error initializing the statistics service.");
                Enabled = false;
            }

            _machineProvider.MachineOperator.JobRunsLogger.JobRunAvailable += JobRunsLogger_JobRunAvailable;
        }

        private void JobRunsLogger_JobRunAvailable(object sender, JobRunAvailableEventArgs e)
        {
            Task.Factory.StartNew(async () =>
            {
                var jobRunComposition = await CreateJobRunComposition(e.JobRun);

                foreach (var receiver in _streamingReceivers.ToList())
                {
                    try
                    {
                        var response = new StartJobRunsStreamingResponse();
                        response.JobRunComposition = jobRunComposition;
                        await receiver.Key.SendGenericResponse(response, receiver.Value);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex);
                    }
                }
            });
        }

        [ExternalBridgeRequestHandlerMethod(typeof(GetStatisticsRequiredFiltersRequest), RequestHandlerLoggingMode.LogRequestName)]
        public async Task OnGetStatisticsRequiredFiltersRequest(GetStatisticsRequiredFiltersRequest request, String token, ExternalBridgeReceiver receiver)
        {
            this.ThrowIfDisabled();

            var response = new GetStatisticsRequiredFiltersResponse();

            using (ObservablesContext db = ObservablesContext.CreateDefault())
            {
                var jobNames = (await db.JobRuns.Select(x => x.JobName).ToListAsync()).Distinct().ToList();

                var threadNames = await db.Rmls.Select(x => new { x.Guid, x.Name, x.DisplayName }).ToListAsync();

                if (_machineProvider.Machine.SiteGuid != null)
                {
                    var siteRmlsGuids = (await db.SitesRmls.Where(x => x.SiteGuid == _machineProvider.Machine.SiteGuid).ToListAsync()).Select(x => x.RmlGuid).Where(x => x != null).Distinct().ToList();
                    threadNames.RemoveAll(x => !siteRmlsGuids.Contains(x.Guid));
                }

                response.FiltersData.Jobs = jobNames;
                response.FiltersData.Rmls = threadNames.Select(x => new ThreadFilterData() { Guid = x.Guid, Name = x.DisplayName.IsNotNullOrEmpty() ? x.DisplayName : x.Name }).ToList();
            }

            await receiver.SendGenericResponse(response, token);
        }

        [ExternalBridgeRequestHandlerMethod(typeof(GetStatisticsRequest), RequestHandlerLoggingMode.LogRequestName)]
        public async Task OnGetStatisticsRequest(GetStatisticsRequest request, String token, ExternalBridgeReceiver receiver)
        {
            this.ThrowIfDisabled();

            var response = new GetStatisticsResponse();

            using (ObservablesContext db = ObservablesContext.CreateDefault())
            {
                response.Result.LiquidTypes = db.LiquidTypes.ToList().Select(x => LiquidTypeDTO.FromObservable(x)).ToList();

                var filters = request.Filters;

                var db_JobRuns = db.JobRuns.Where(x => (x.StartDate <= filters.EndDateUTC && x.StartDate >= filters.StartDateUTC));

                int[] jobRunStatusArr = filters.EndStatuses.Distinct().ToArray();
                if (jobRunStatusArr.Length > 0)
                {
                    db_JobRuns = db_JobRuns.Where(x => jobRunStatusArr.Contains(x.Status));
                }

                int[] jobDesignationArr = filters.JobDesignation.Distinct().ToArray();
                if (jobDesignationArr.Length > 0)
                {
                    db_JobRuns = db_JobRuns.Where(x => jobDesignationArr.Contains(x.JobDesignation));
                }

                if (!filters.IncludeHeadCleaning)
                {
                    db_JobRuns = db_JobRuns.Where(x => !x.IsHeadCleaning);
                }

                List<String> rmlGuids = filters.RmlGuids;

                if (filters.RmlGuids.Count > 0)
                {
                    db_JobRuns = db_JobRuns.Where(x => rmlGuids.Contains(x.RmlGuid));
                }

                if (filters.JobName.IsNotNullOrEmpty())
                {
                    if (!filters.ExactJobName)
                    {
                        db_JobRuns = db_JobRuns.Where(x => x.JobName.ToLower().StartsWith(filters.JobName.ToLower()));
                    }
                    else
                    {
                        db_JobRuns = db_JobRuns.Where(x => x.JobName.ToLower() == filters.JobName.ToLower());
                    }
                }

                db_JobRuns = db_JobRuns.Where(x => x.JobLength >= filters.MinLength && x.JobLength <= filters.MaxLength);

                var jobRuns = await db_JobRuns.ToListAsync();

                foreach (var jobRun in jobRuns)
                {
                    JobRunComposition jobRunComposition = await CreateJobRunComposition(jobRun);
                    response.Result.JobRuns.Add(jobRunComposition);
                }
            }

            await receiver.SendGenericResponse(response, token);
        }

        private async Task<JobRunComposition> CreateJobRunComposition(JobRun jobRun)
        {
            if (_colorSpaces == null)
            {
                using (ObservablesContext db = ObservablesContext.CreateDefault())
                {
                    _colorSpaces = await db.ColorSpaces.ToListAsync();
                    _catalogs = await db.ColorCatalogs.ToListAsync();
                    _color_catalog_Items = await db.ColorCatalogsItems.ToListAsync();
                }
            }

            if (_liquidTypes == null)
            {
                using (ObservablesContext db = ObservablesContext.CreateDefault())
                {
                    var types = await db.LiquidTypes.ToListAsync();
                    _liquidTypes = new Dictionary<string, LiquidType>();
                    foreach (var t in types)
                    {
                        _liquidTypes.Add(t.Name, t);
                    }
                }
            }

            JobRunComposition jobRunComposition = new JobRunComposition();
            jobRunComposition.JobRun = JobRunDTO.FromObservable(jobRun);

            PresentationJob pj = new PresentationJob();
            pj.ID = jobRun.ID;
            jobRunComposition.Job = pj;

            if (jobRun.JobFile != null)
            {
                foreach (var segment in jobRun.JobFile.Segments)
                {
                    PresentationSegment ps = new PresentationSegment();
                    ps.Length = (int)segment.Length;
                    pj.Segments.Add(ps);

                    foreach (var stop in segment.BrushStops.OrderBy(x => x.StopIndex).DistinctBy(x => x.OffsetPercent).ToList())
                    {
                        PresentationBrushStop pbs = new PresentationBrushStop();
                        pbs.ColorSpace = _colorSpaces.First(x => x.Guid == stop.ColorSpaceGuid).Space;
                        pbs.StartMeters = segment.Length * (stop.OffsetPercent / 100d); ;

                        foreach (var liquidType in stop.LiquidVolumes)
                        {
                            PresentationLiquidVolume plt = new PresentationLiquidVolume();

                            if (_liquidTypes.ContainsKey(liquidType.LiquidTypeName))
                            {
                                plt.LiquidType = _liquidTypes[liquidType.LiquidTypeName];
                                plt.Volume = liquidType.Volume;
                                pbs.LiquidVolumes.Add(plt);
                            }
                        }

                        pbs.LiquidVolumes = pbs.LiquidVolumes.OrderBy(x => x.LiquidType.PreferredIndex).ToList();

                        switch (pbs.ColorSpace)
                        {
                            case ColorSpaces.RGB:
                                pbs.Red = stop.Red;
                                pbs.Green = stop.Green;
                                pbs.Blue = stop.Blue;
                                break;
                            case ColorSpaces.LAB:
                                pbs.L = stop.L;
                                pbs.A = stop.A;
                                pbs.B = stop.B;
                                break;
                            case ColorSpaces.Volume:

                                //foreach (var lightInk in pbs.LiquidVolumes.Where(x => x.LiquidType.IsLightInk && x.Volume > 0))
                                //{
                                //    var darkInk = pbs.LiquidVolumes.FirstOrDefault(x => x.LiquidType.Code == lightInk.LiquidType.DarkInkCode);
                                //    if (darkInk != null)
                                //    {
                                //        darkInk.Volume = (double)((decimal)lightInk.Volume / 10m);
                                //        lightInk.Volume = 0;
                                //    }
                                //}

                                break;
                            case ColorSpaces.Catalog:
                                pbs.Catalog = _catalogs.FirstOrDefault(x => x.Guid == stop.ColorCatalogGuid)?.Name;
                                pbs.CatalogItem = _color_catalog_Items.FirstOrDefault(x => x.Guid == stop.ColorCatalogItemGuid)?.Name;
                                break;
                        }

                        pbs.BestMatchR = stop.BestMatchR;
                        pbs.BestMatchG = stop.BestMatchG;
                        pbs.BestMatchB = stop.BestMatchB;

                        ps.Stops.Add(pbs);
                    }
                }
            }

            jobRunComposition.JobRun.JobString = null;
            jobRunComposition.JobRun.LiquidQuantityString = null;

            return jobRunComposition;
        }

        [ExternalBridgeRequestHandlerMethod(typeof(GetJobRunExtendedInfoRequest), RequestHandlerLoggingMode.LogRequestName)]
        public async Task OnGetJobRunExtendedInfoRequest(GetJobRunExtendedInfoRequest request, String token, ExternalBridgeReceiver receiver)
        {
            this.ThrowIfDisabled();

            var response = new GetJobRunExtendedInfoResponse();

            String filePath = Path.Combine((_machineProvider.MachineOperator.JobRunsLogger as BasicJobRunsLogger).JobRunsFolder, $"{request.JobRunID}.run");
            String json = File.ReadAllText(filePath);

            JobRunInfo info = JsonConvert.DeserializeObject<JobRunInfo>(json);

            response.ExtendedInfo.JobRunID = info.JobRunID;
            response.ExtendedInfo.JobTicket = info.JobTicket;
            response.ExtendedInfo.Events = info.Events;
            response.ExtendedInfo.StartMachineStatus = info.StartMachineStatus;
            response.ExtendedInfo.EndMachineStatus = info.EndMachineStatus;

            await receiver.SendGenericResponse(response, token);
        }

        [ExternalBridgeRequestHandlerMethod(typeof(StartJobRunsStreamingRequest), RequestHandlerLoggingMode.LogRequestName)]
        public async Task OnStartJobRunsStreamingRequest(StartJobRunsStreamingRequest request, String token, ExternalBridgeReceiver receiver)
        {
            this.ThrowIfDisabled();

            if (!_streamingReceivers.ContainsKey(receiver))
            {
                _streamingReceivers.Add(receiver, token);
            }

            var response = new StartJobRunsStreamingResponse();

            await receiver.SendGenericResponse(response, token);
        }

        [ExternalBridgeRequestHandlerMethod(typeof(StopJobRunsStreamingRequest), RequestHandlerLoggingMode.LogRequestName)]
        public async Task OnStopJobRunsStreamingRequest(StopJobRunsStreamingRequest request, String token, ExternalBridgeReceiver receiver)
        {
            this.ThrowIfDisabled();

            if (_streamingReceivers.ContainsKey(receiver))
            {
                _streamingReceivers.Remove(receiver);
            }

            var response = new StopJobRunsStreamingResponse();

            await receiver.SendGenericResponse(response, token);
        }

        public void OnReceiverDisconnected(ExternalBridgeReceiver receiver)
        {
            if (_streamingReceivers.ContainsKey(receiver))
            {
                _streamingReceivers.Remove(receiver);
            }
        }
    }
}