Esempio n. 1
0
        /// <summary>
        /// Opens the Select Device Window
        /// </summary>
        private void SelectDevice(Mapping mapping)
        {
            SelectSignal deviceSelection = new SelectSignal();
            SelectSignalMappingVM <AdaptDevice> deviceSelectionVM = new SelectSignalMappingVM <AdaptDevice>((d) => {
                mapping.SourceDeviceID   = d.ID;
                mapping.SourceDeviceName = d.Name;

                mapping.ChannelMappings = new Dictionary <int, string>();

                // Validate Signals on that device
                List <TemplateInputSignal> targetSignals;
                using (AdoDataConnection connection = new AdoDataConnection(ConnectionString, DataProviderString))
                    targetSignals = new TableOperations <TemplateInputSignal>(connection)
                                    .QueryRecordsWhere("DeviceID = {0}", mapping.TargetDeviceID).ToList();

                List <AdaptSignal> sourceSignals = AdaptSignal.Get(DataSource, DataSourceModel.ID, ConnectionString, DataProviderString)
                                                   .Where(s => s.Device == d.ID).ToList();

                mapping.IsValid = sourceSignals.Count() >= targetSignals.Count();

                for (int i = 0; i < targetSignals.Count(); i++)
                {
                    int index = sourceSignals.FindIndex(item => item.Phase == targetSignals[i].Phase && item.Type == targetSignals[i].MeasurmentType);
                    if (index == -1)
                    {
                        mapping.ChannelMappings.Add(targetSignals[i].ID, "");
                    }
                    else
                    {
                        mapping.ChannelMappings.Add(targetSignals[i].ID, sourceSignals[index].ID);
                    }
                }
                mapping.IsValid    = !mapping.ChannelMappings.Any(item => string.IsNullOrEmpty(item.Value));
                mapping.IsSelected = true;
                DeviceMappings     = new ObservableCollection <Mapping>(DeviceMappings);
                OnPropertyChanged(nameof(DeviceMappings));
                OnPropertyChanged(nameof(Valid));
            }, (d, s) => d.Name.ToLower().Contains(s.ToLower()), (d) => d.Name, AdaptDevice.Get(DataSource, DataSourceModel.ID, ConnectionString, DataProviderString));

            deviceSelection.DataContext = deviceSelectionVM;
            deviceSelection.Show();
        }
        //Start this by Only looking at Config Files and Lines that have =
        public bool Execute(MeterDataSet meterDataSet)
        {
            if (meterDataSet.Type != DataSetType.Config)
            {
                return(false);
            }

            if (!HasComplianceMeter(meterDataSet))
            {
                return(false);
            }

            using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
            {
                ComplianceMeter meter = new TableOperations <ComplianceMeter>(connection).QueryRecordWhere("MeterId = {0}", meterDataSet.Meter.ID);

                //This means we need to activate the meter
                if (!meter.Active)
                {
                    meter.Active = true;
                    new TableOperations <ComplianceMeter>(connection).UpdateRecord(meter);
                }

                // Get appropriate Base Configurations
                IEnumerable <BaseConfig> baseConfigsMeter = new TableOperations <BaseConfig>(connection).QueryRecordsWhere("MeterId = {0}", meter.ID);

                //Filter by Pattern
                baseConfigsMeter = baseConfigsMeter.Where(item => FilePath.IsFilePatternMatch(item.Pattern, meterDataSet.FilePath, true));


                if (baseConfigsMeter.Count() == 0)
                {
                    return(true);
                }

                // Pares File using Compliance Operations
                // Instantiates the given data reader and wraps it in a disposable wrapper object.
                Model.ComplianceOperation parser = new TableOperations <Model.ComplianceOperation>(connection).QueryRecords("LoadOrder")
                                                   .FirstOrDefault(reader => FilePath.IsFilePatternMatch(reader.FilePattern, meterDataSet.FilePath, true));

                ComplianceParserWrapper wrapper;
                try
                {
                    Assembly assembly = Assembly.LoadFrom(parser.AssemblyName);
                    Type     type     = assembly.GetType(parser.TypeName);
                    wrapper = new ComplianceParserWrapper(parser.ID, type);
                }
                catch (Exception ex)
                {
                    string message = $"Failed to create Compliance File parser of type {parser.TypeName}: {ex.Message}";
                    throw new TypeLoadException(message, ex);
                }


                // Parse ConfigFile into Dictionary of Fields

                Dictionary <string, string> activeConfig = new Dictionary <string, string>();
                try
                {
                    activeConfig = wrapper.DataObject.ParseFields(meterDataSet);
                }
                catch (Exception ex)
                {
                    string message = $"Failed to parse Config File for Compliance Fields {parser.TypeName}: {ex.Message}";
                    throw new TypeLoadException(message, ex);
                }

                // If Meter is not Reviewed just keep updating Base Config
                if (!meter.Reviewed)
                {
                    foreach (BaseConfig baseConfig in baseConfigsMeter)
                    {
                        UpdateBaseConfig(baseConfig, activeConfig);
                    }
                    return(true);
                }

                // Get a Bunch of AlarmStates
                TableOperations <ComplianceState> complianceStateTbl = new TableOperations <ComplianceState>(connection);
                ComplianceState resolved     = complianceStateTbl.QueryRecordWhere("Description = 'In Compliance'");
                ComplianceState noCompliance = complianceStateTbl.QueryRecordWhere("Description = 'Compliance Issue'");
                ComplianceState acknowledged = complianceStateTbl.QueryRecordWhere("Description = 'Acknowledged'");
                ComplianceState reviewed     = complianceStateTbl.QueryRecordWhere("Description = 'Reviewed'");

                TableOperations <ComplianceRecord>         complianceRecordTbl         = new TableOperations <ComplianceRecord>(connection);
                TableOperations <ComplianceRecordView>     complianceRecordViewTbl     = new TableOperations <ComplianceRecordView>(connection);
                TableOperations <ComplianceRecordField>    recordFieldTbl              = new TableOperations <ComplianceRecordField>(connection);
                TableOperations <ComplianceField>          complianceFieldTbl          = new TableOperations <ComplianceField>(connection);
                TableOperations <ComplianceAction>         complianceActionTbl         = new TableOperations <ComplianceAction>(connection);
                TableOperations <ComplianceFieldValue>     complianceFieldValueTbl     = new TableOperations <ComplianceFieldValue>(connection);
                TableOperations <ComplianceFieldValueView> complianceFieldValueViewTbl = new TableOperations <ComplianceFieldValueView>(connection);


                //Walk through each BaseConfig separately
                foreach (BaseConfig baseConfig in baseConfigsMeter)
                {
                    // Get relevant Compliance Fields
                    List <ComplianceField> baseConfigfields = complianceFieldTbl.QueryRecordsWhere("BaseConfigId = {0}", baseConfig.ID).ToList();

                    if (baseConfigfields.Count() == 0)
                    {
                        continue;
                    }

                    List <ComplianceField> changingFields = baseConfigfields.Where(fld => {
                        ComplianceFieldValueView value = complianceFieldValueViewTbl.QueryRecordWhere("FieldId = {0}", fld.ID);
                        if (value == null)
                        {
                            return(!fld.Evaluate(activeConfig[fld.Name]));
                        }
                        return(activeConfig[fld.Name] != value.Value);
                    }).ToList();

                    if (changingFields.Count == 0)
                    {
                        continue;
                    }


                    //Clear so that -1 if Record is resolved
                    IEnumerable <IGrouping <int, ComplianceField> > recordGroups = changingFields.GroupBy(fld =>
                    {
                        ComplianceRecordView record = complianceRecordViewTbl.QueryRecordWhere("BaseConfigId = {0} AND ID IN (SELECT RecordID FROM ComplianceRecordFields WHERE FieldId = {1}) AND Status IN ({2},{3}, {4})", baseConfig.ID, fld.ID, acknowledged.ID, noCompliance.ID, reviewed.ID);
                        if (record == null)
                        {
                            return(-1);
                        }
                        return(record.ID);
                    }, fld => fld);


                    //Count those that exist and change Status
                    meterDataSet.ComplianceIssues += recordGroups.Count();
                    if (recordGroups.Any(g => g.Key == -1))
                    {
                        meterDataSet.ComplianceIssues--;
                    }


                    // Some Records can not be updated with failing Fields they need to be separate
                    List <ComplianceField> newFields = new List <ComplianceField>();

                    // Work Backwards to get associated Record for a Field
                    foreach (IGrouping <int, ComplianceField> group in recordGroups)
                    {
                        //we skip those that don't have a record
                        if (group.Key > -1)
                        {
                            // grab status
                            ComplianceRecordView view = complianceRecordViewTbl.QueryRecordWhere("Id = {0}", group.Key);

                            //Check if we can resolve everything including some fields that are previously resolved.
                            bool canResolve = complianceFieldValueViewTbl.QueryRecordsWhere("RecordID = {0}", group.Key).All(fld => {
                                string value;
                                if (!activeConfig.TryGetValue(fld.FieldName, out value))
                                {
                                    value = fld.Value;
                                }
                                return(baseConfigfields.Find(field => field.ID == fld.FieldId).Evaluate(value));
                            });

                            if (canResolve)
                            {
                                //Create Action
                                complianceActionTbl.AddNewRecord(new ComplianceAction()
                                {
                                    Note        = "New File Downloaded",
                                    UserAccount = "MiMD",
                                    RecordId    = group.Key,
                                    StateId     = resolved.ID,
                                    Timestamp   = DateTime.UtcNow
                                });

                                int resolvedId = connection.ExecuteScalar <int>("SELECT @@identity");

                                group.ToList().ForEach(item => complianceFieldValueTbl.AddNewRecord(new ComplianceFieldValue()
                                {
                                    ActionId = resolvedId,
                                    FieldId  = item.ID,
                                    Value    = activeConfig[item.Name]
                                }));
                            }
                            else if (view.Status == noCompliance.ID)
                            {
                                //Create Action
                                complianceActionTbl.AddNewRecord(new ComplianceAction()
                                {
                                    Note        = "New File Downloaded",
                                    UserAccount = "MiMD",
                                    RecordId    = group.Key,
                                    StateId     = null,
                                    Timestamp   = DateTime.UtcNow
                                });

                                int resolvedId = connection.ExecuteScalar <int>("SELECT @@identity");

                                group.ToList().ForEach(item => complianceFieldValueTbl.AddNewRecord(new ComplianceFieldValue()
                                {
                                    ActionId = resolvedId,
                                    FieldId  = item.ID,
                                    Value    = activeConfig[item.Name]
                                }));
                            }
                            else
                            {
                                List <ComplianceField> nonresolving = group.ToList().Where(fld => {
                                    string old = complianceFieldValueViewTbl.QueryRecordWhere("FieldId = {0}", fld.ID).Value;
                                    return(!fld.Evaluate(activeConfig[fld.Name]) && fld.Evaluate(old));
                                }).ToList();

                                List <ComplianceField> resolving = group.ToList().Where(fld => {
                                    string old = complianceFieldValueViewTbl.QueryRecordWhere("FieldId = {0}", fld.ID).Value;
                                    return(!fld.Evaluate(old));
                                }).ToList();

                                if (resolving.Count > 0)
                                {
                                    complianceActionTbl.AddNewRecord(new ComplianceAction()
                                    {
                                        Note        = "New File Downloaded",
                                        UserAccount = "MiMD",
                                        RecordId    = group.Key,
                                        StateId     = null,
                                        Timestamp   = DateTime.UtcNow
                                    });

                                    int resolvedId = connection.ExecuteScalar <int>("SELECT @@identity");

                                    resolving.ForEach(item => complianceFieldValueTbl.AddNewRecord(new ComplianceFieldValue()
                                    {
                                        ActionId = resolvedId,
                                        FieldId  = item.ID,
                                        Value    = activeConfig[item.Name]
                                    }));
                                }
                                newFields = newFields.Concat(nonresolving).ToList();
                            }
                        }
                        else
                        {
                            newFields = newFields.Concat(group.ToList()).ToList();
                        }
                    }

                    if (newFields.Count == 0)
                    {
                        continue;
                    }

                    // Add the new Compliance Issue to count if it is opened
                    meterDataSet.ComplianceIssues++;

                    complianceRecordTbl.AddNewRecord(new ComplianceRecord()
                    {
                        BaseConfigId = baseConfig.ID,
                        MeterId      = meter.ID,
                        TimerOffset  = 0
                    });

                    int recordId = connection.ExecuteScalar <int>("SELECT @@identity");

                    //Create Action
                    complianceActionTbl.AddNewRecord(new ComplianceAction()
                    {
                        Note        = "New File Downloaded",
                        UserAccount = "MiMD",
                        RecordId    = recordId,
                        StateId     = noCompliance.ID,
                        Timestamp   = DateTime.UtcNow
                    });

                    int actionId = connection.ExecuteScalar <int>("SELECT @@identity");

                    newFields.ForEach(item => recordFieldTbl.AddNewRecord(new ComplianceRecordField()
                    {
                        FieldId  = item.ID,
                        RecordId = recordId
                    }));

                    newFields.ForEach(item => complianceFieldValueTbl.AddNewRecord(new ComplianceFieldValue()
                    {
                        ActionId = actionId,
                        FieldId  = item.ID,
                        Value    = activeConfig[item.Name]
                    }));
                }
                return(true);
            }
        }