Пример #1
0
        protected override IEnumerable <Prompt> Execute_Subclass()
        {
            ResetSubscriptionCache();
            var signals = SignalFileParser.Parse(SignalFileLocation);

            try
            {
                if (!EvaluatePerformanceImpact(signals))
                {
                    Prompts.Add(new Prompt
                    {
                        Message  = "Could not successfully evaluate performance, cannot continue.",
                        Severity = PromptSeverity.MayNotContinue
                    });
                    return(Prompts);
                }

                GetAndUpdateInitialPropertiesForSignals(_signalsToUse);
            }
            catch (Exception ex)
            {
                Prompts.Add(ex.ToPrompt());
                return(Prompts);
            }

            return(Prompts);
        }
Пример #2
0
        /// <summary>
        /// Due to some performance issues with version of EBO prior to 2.0, we will limit the amount of points that can be consumed out of EBO versions
        /// prior to 2.0 to 100. No limit for point count in version 2.0 and above.
        /// </summary>
        private bool EvaluatePerformanceImpact(List <Signal> signals)
        {
            try
            {
                // We save this right away so we can execute this setup processor from the value push processor if it is not running
                Cache.AddOrUpdateItem(this.ConfigurationId, "SetupProcessorConfigurationId", this.CacheTenantId, 0);
                var response   = ManagedEwsClient.GetWebServiceInformation(EboEwsSettings);
                var eboVersion = new Version(response.GetWebServiceInformationSystem.Version);
                if (eboVersion.Major > 1)
                {
                    _signalsToUse = signals;
                }
                else
                {
                    if (signals.Count > 100)
                    {
                        Prompts.Add(new Prompt
                        {
                            Severity = PromptSeverity.MayContinue,
                            Message  = $"Due to performance concerns, only 100 points out of {signals.Count} can be consumed when using EBO versions prior to 2.0. Please update your EBO to version 2.0 or greater to get the full functionality of the EBO IoT Edge Smart Connector Extension."
                        });
                    }

                    _signalsToUse = signals.Take(100).ToList();
                }
                return(true);
            }
            catch (Exception ex)
            {
                Logger.LogError(LogCategory.Processor, this.Name, ex.ToString());
                return(false);
            }
        }
Пример #3
0
        protected override IEnumerable <Prompt> Execute_Subclass()
        {
            if (Signals == null || !Signals.Any())
            {
                GetSignalNullReason();
                return(Prompts);
            }

            try
            {
                StartMqttClient().Wait();
            }
            catch (Exception ex)
            {
                Logger.LogError(LogCategory.Processor, this.Name, $"Starting MQTT Client failed");
                Prompts.Add(ex.ToPrompt());
                return(Prompts);
            }

            _tempSignals = Signals.ToList();
            // Read existing subscriptions
            if (!ReadExistingSubscriptions(_tempSignals).Result)
            {
                Prompts.Add(new Prompt {
                    Message = $"Did not successfully read all existing subscriptions."
                });
            }

            // Subscribe and read new subscriptions
            if (!SubscribeAndReadNew(_tempSignals).Result)
            {
                Prompts.Add(new Prompt {
                    Message = $"Did not successfully read all new subscriptions."
                });
            }

            Logger.LogTrace(LogCategory.Processor, this.Name, "Waiting for all messages be be published...");
            while (ManagedMqttClient.PendingApplicationMessagesCount > 0)
            {
                Logger.LogTrace(LogCategory.Processor, this.Name, $"{ManagedMqttClient.PendingApplicationMessagesCount} messages left waiting to be published..");
                if (this.IsCancellationRequested)
                {
                    return(new List <Prompt>());
                }
                Task.Delay(1000).Wait();
            }

            Logger.LogTrace(LogCategory.Processor, this.Name, "Stopping Managed MQTT Client..");
            ManagedMqttClient.StopAsync().Wait();
            while (ManagedMqttClient.IsStarted)
            {
                Logger.LogTrace(LogCategory.Processor, this.Name, "Still waiting for MQTT Client to Stop...");
                Task.Delay(1000).Wait();
            }

            // Update the cache with new values..
            Signals = _tempSignals;
            return(Prompts);
        }
Пример #4
0
        private void GetAndUpdateInitialPropertiesForSignals(List <Signal> signals)
        {
            var newSignals = new List <Signal>();

            Logger.LogTrace(LogCategory.Processor, this.Name, $"Getting units for all signals.. {signals.Count} total.");
            // Get list of signals that have not been previously discovered
            var newSignalsLeftToAdd = signals.Where(a => !Signals.Select(b => b.EwsId).Contains(a.EwsId)).ToList();

            Logger.LogTrace(LogCategory.Processor, this.Name, $"Found, {newSignalsLeftToAdd.Count} total to add.");
            while (newSignalsLeftToAdd.Any())
            {
                Logger.LogTrace(LogCategory.Processor, this.Name, $"Found, {newSignalsLeftToAdd.Count} left to add.");
                if (IsCancellationRequested)
                {
                    return;
                }
                try
                {
                    var response         = ManagedEwsClient.GetItems(EboEwsSettings, newSignalsLeftToAdd.Take(100).Select(a => a.EwsId).ToArray());
                    var successfulValues = response.GetItemsItems.ValueItems?.ToList();
                    AddSuccessfulSignalsToCache(signals, successfulValues, newSignals);

                    // The below code is a workaround for EBO timing out on GetItems for many values, and returning either an INVALID_ID or TIMEOUT error when the values are in fact valid. We need to make sure we discover as many as possible, so let's loop until we do.
                    // We will do this as long as at least 1 value from the request was successful.
                    while (successfulValues != null && successfulValues.Any() && response.GetItemsErrorResults != null && response.GetItemsErrorResults.Any(a => a.Message == "INVALID_ID" || a.Message == "TIMEOUT"))
                    {
                        response         = ManagedEwsClient.GetItems(EboEwsSettings, response.GetItemsErrorResults.Where(a => a.Message == "INVALID_ID" || a.Message == "TIMEOUT").Select(a => a.Id).ToArray());
                        successfulValues = response.GetItemsItems.ValueItems?.ToList();
                        AddSuccessfulSignalsToCache(signals, successfulValues, newSignals);
                    }

                    var valuesToRetry = UpdateInvalidEwsIdsForRetry(signals, response);

                    response         = ManagedEwsClient.GetItems(EboEwsSettings, valuesToRetry.Select(a => a.EwsId).ToArray());
                    successfulValues = response.GetItemsItems.ValueItems?.ToList();
                    AddSuccessfulSignalsToCache(signals, successfulValues, newSignals);

                    foreach (var value in response.GetItemsErrorResults.ToList())
                    {
                        Prompts.Add(new Prompt {
                            Message = $"Error getting value, this value will not be pushed: {value.Id} - {value.Message}", Severity = PromptSeverity.MayNotContinue
                        });
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogError(LogCategory.Processor, this.Name, ex.ToString());
                    Prompts.Add(ex.ToPrompt());
                    // We will let it continue and see if everything else fails... Maybe some will work..
                }

                newSignalsLeftToAdd = newSignalsLeftToAdd.Skip(100).ToList();
            }

            signals.AddRange(newSignals);
            Signals = signals;

            SeedProcessorValues(signals);
        }
        private void GetAndUpdateInitialPropertiesForSignals(List <Signal> signals)
        {
            var newSignals = new List <Signal>();

            Logger.LogTrace(LogCategory.Processor, this.Name, "Getting units for all signals..");
            while (signals.Any())
            {
                if (IsCancellationRequested)
                {
                    return;
                }
                try
                {
                    var response         = ManagedEwsClient.GetItems(EboEwsSettings, signals.Take(500).Select(a => a.EwsId).ToArray());
                    var successfulValues = response.GetItemsItems.ValueItems.ToList();

                    foreach (var value in successfulValues)
                    {
                        var deviceSignal = signals.FirstOrDefault(a => a.EwsId == value.Id);
                        if (deviceSignal == null)
                        {
                            Logger.LogInfo(LogCategory.Processor, this.Name, $"Returned value does not exist in the list known signals..");
                        }
                        else
                        {
                            Enum.TryParse(value.Type, true, out EwsValueTypeEnum type);
                            Enum.TryParse(value.Writeable, true, out EwsValueWriteableEnum writeable);
                            Enum.TryParse(value.Forceable, true, out EwsValueForceableEnum forceable);
                            deviceSignal.Type      = type;
                            deviceSignal.Unit      = value.Unit;
                            deviceSignal.Writeable = writeable;
                            deviceSignal.Forceable = forceable;
                            newSignals.Add(deviceSignal);
                        }
                    }

                    foreach (var value in response.GetItemsErrorResults.ToList())
                    {
                        Prompts.Add(new Prompt {
                            Message = $"Error getting value, this value will not be pushed: {value.Id} - {value.Message}", Severity = PromptSeverity.MayNotContinue
                        });
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogError(LogCategory.Processor, this.Name, ex.ToString());
                    Prompts.Add(ex.ToPrompt());
                    // We will let it continue and see if everything else fails... Maybe some will work..
                }

                signals = signals.Skip(500).ToList();
            }

            Signals = newSignals;
        }
Пример #6
0
        protected override IEnumerable <Prompt> Execute_Subclass()
        {
            try
            {
                StartMqttClient().Wait();
            }
            catch (Exception ex)
            {
                Logger.LogError(LogCategory.Processor, this.Name, $"Starting MQTT Client failed");
                Prompts.Add(ex.ToPrompt());
                return(Prompts);
            }

            if (Signals == null)
            {
                Prompts.Add(new Prompt
                {
                    Message  = "There are no signals in the cache, please run the SetupProcessor or verify that it has run successfully.",
                    Severity = PromptSeverity.MayNotContinue
                });
                return(Prompts);
            }

            // Read existing subscriptions
            if (!ReadExistingSubscriptions(Signals).Result)
            {
                Prompts.Add(new Prompt {
                    Message = $"Did not successfully read all existing subscriptions."
                });
            }

            // Subscribe and read new subscriptions
            if (!SubscribeAndReadNew(Signals).Result)
            {
                Prompts.Add(new Prompt {
                    Message = $"Did not successfully read all new subscriptions."
                });
            }

            ManagedMqttClient.StopAsync().Wait();
            ManagedMqttClient.Dispose();

            // Update the cache with new values..
            Signals = Signals;
            return(Prompts);
        }
Пример #7
0
 /// <summary>
 /// Tries to determine why the Signal cache is empty, and attempts to resolve it if possible
 /// </summary>
 private void GetSignalNullReason()
 {
     try
     {
         var setupProcessorId = Cache.RetrieveItem("SetupProcessorConfigurationId", tenantId: CacheTenantId);
         if (setupProcessorId == null)
         {
             Prompts.Add(new Prompt
             {
                 Message  = "The Setup Processor has not been run. Make sure the Setup Processor has been configured correctly and run it again.",
                 Severity = PromptSeverity.MayNotContinue
             });
         }
         else
         {
             if (ActionBroker.IsConfigurationRunning((int)setupProcessorId))
             {
                 Prompts.Add(new Prompt
                 {
                     Message  = "The Setup Processor is currently running, once it has completed this will run successfully.",
                     Severity = PromptSeverity.MayNotContinue
                 });
             }
             else
             {
                 // For some reason the Setup Processor failed to run.. let's force it to run again, and hope it completes!
                 Logger.LogInfo(LogCategory.Processor, this.Name, "Force starting the Setup Processor, as it has failed to run for some reason, please check the logs for additional information.");
                 ActionBroker.StartConfiguration((int)setupProcessorId, DerivedFromConfigurationType.Processor);
                 Prompts.Add(new Prompt
                 {
                     Message  = "The Setup Processor processor has been forced to start, the Value Push Processor cannot run to completion until it has run successfully.",
                     Severity = PromptSeverity.MayNotContinue
                 });
             }
         }
     }
     catch (Exception ex)
     {
         Prompts.Add(new Prompt
         {
             Message  = ex.ToString(),
             Severity = PromptSeverity.MayNotContinue
         });
     }
 }
Пример #8
0
        protected override IEnumerable <Prompt> Execute_Subclass()
        {
            var signals = SignalFileParser.Parse(SignalFileLocation);

            try
            {
                EvaluatePerformanceImpact(signals);
            }
            catch (Exception ex)
            {
                Prompts.Add(ex.ToPrompt());
                return(Prompts);
            }

            GetAndUpdateInitialPropertiesForSignals(Signals);

            return(Prompts);
        }
Пример #9
0
        /// <summary>
        /// Due to some performance issues with version of EBO prior to 2.0, we will limit the amount of points that can be consumed out of EBO versions
        /// prior to 2.0 to 100. No limit for point count in version 2.0 and above.
        /// </summary>
        private void EvaluatePerformanceImpact(List <Signal> signals)
        {
            var eboVersion = new Version(ManagedEwsClient.GetWebServiceInformation(EboEwsSettings).GetWebServiceInformationSystem.Version);

            if (eboVersion.Major > 1)
            {
                Signals = signals;
            }
            else
            {
                if (signals.Count > 100)
                {
                    Prompts.Add(new Prompt
                    {
                        Severity = PromptSeverity.MayContinue,
                        Message  = $"Due to performance concerns, only 100 points out of {signals.Count} can be consumed when using EBO versions prior to 2.0. Please update your EBO to version 2.0 or greater to get the full functionality of the EBO IoT Edge Smart Connector Extension."
                    });
                }

                Signals = signals.Take(100).ToList();
            }
        }
Пример #10
0
        private void loadCellPrompts()
        {
            //读取Tabs
            for (int i = 0; i < PromptCells.Rows.RowCount; i++)
            {
                string TabName = PromptCells[i, 13].Text;
                if (!string.IsNullOrEmpty(TabName))
                {
                    //logger.Debug("增加Tab:" + TabName);
                    this.PromptTabs.Add(TabName);
                }
                else
                {
                    break;
                }
            }

            //读取计算器
            for (int i = 0; i < PromptCells.Rows.RowCount; i++)
            {
                string CalName = PromptCells[i, 17].Text;
                if (!string.IsNullOrEmpty(CalName))
                {
                    //logger.Debug("增加计算器:" + CalName);

                    var strs = CalName.Split('|');
                    if (strs.Length < 3)
                    {
                        continue;
                    }

                    string name = strs[0];

                    double upperBound;
                    if (!double.TryParse(strs[1], out upperBound))
                    {
                        continue;
                    }

                    double gap;
                    if (!double.TryParse(strs[2], out gap))
                    {
                        continue;
                    }

                    Calcuators.Add(new CalculatorItem()
                    {
                        Name       = name,
                        UpperBound = upperBound,
                        Gap        = gap,
                        Index      = i
                    });
                }
                else
                {
                    break;
                }
            }

            for (int i = 0; i < PromptCells.Rows.RowCount; i++)
            {
                var name = PromptCells[i, 0].Text;

                if (string.IsNullOrEmpty(name))
                {
                    //logger.Info("空行中断读取,行号:" + i.ToString());
                    break;
                }

                //忽略宽度、高度、深度三个变量
                if (i == 0 || i == 1 || i == 2)
                {
                    continue;
                }

                string value           = PromptCells[i, 1].Text;
                string controlType     = PromptCells[i, 2].Text;
                string helpMessage     = PromptCells[i, 3].Text;
                string verifyCode      = PromptCells[i, 4].Text;
                string comboString     = PromptCells[i, 5].Text;
                string color           = PromptCells[i, 7].Text;
                string picture         = PromptCells[i, 9].Text;
                string visible         = PromptCells[i, 10].Text;
                string hideInReport    = PromptCells[i, 11].Text;
                string tabIndex        = PromptCells[i, 12].Text;
                string calculatorIndex = PromptCells[i, 16].Text;


                //logger.Debug(string.Format("Prompt变量数据:{0}/{1}/{2}/{3}/{4}/{5}/{6}/{7}/{8}/{9}/{10}/{11}",
                //                           name,
                //                           value,
                //                           controlType,
                //                           helpMessage,
                //                           verifyCode,
                //                           comboString,
                //                           color,
                //                           picture,
                //                           visible,
                //                           hideInReport,
                //                           tabIndex,
                //                           calculatorIndex));

                PromptItem prompt = new PromptItem(name, value, controlType, helpMessage, verifyCode, comboString, color, picture, visible, hideInReport, tabIndex, calculatorIndex, i, this);
                Prompts.Add(prompt);
            }
        }
Пример #11
0
 public PromptVM AddPrompt(DialogPrompt dialogPrompt)
 {
     Prompts = Prompts ?? new List <DialogPrompt>();
     Prompts.Add(dialogPrompt);
     return(this);
 }
Пример #12
0
        private async Task <bool> SubscribeAndReadNew(List <Signal> signals)
        {
            Logger.LogTrace(LogCategory.Processor, this.Name, $"Creating and reading new subscriptions..");
            var activeSubscriptions = Cache.RetrieveItem($"ActiveSubscriptions", () => new List <string>(), CacheTenantId, 0) as List <string>;

            var subscribedIds = new List <string>();

            foreach (var subscription in activeSubscriptions)
            {
                var itemsToAdd = Cache.RetrieveItem <List <string> >($"ActiveSubscriptions#{subscription}", null, CacheTenantId);
                if (itemsToAdd != null)
                {
                    subscribedIds.AddRange(itemsToAdd);
                }
            }

            var unsubscribedIds = signals.Select(a => a.EwsId).Where(a => !subscribedIds.Contains(a)).ToList();

            Logger.LogDebug(LogCategory.Processor, this.Name, $"Found {unsubscribedIds.Count} points that are not currently subscribed to.");
            Logger.LogTrace(LogCategory.Processor, this.Name, $"Unsubscribed Point Ids: {unsubscribedIds.ToJSON()}");

            while (unsubscribedIds.Any())
            {
                if (IsCancellationRequested)
                {
                    return(false);
                }
                try
                {
                    var idsToSubscribeTo = unsubscribedIds.Take(MaxItemsPerSubscription).ToList();
                    CheckCancellationToken();
                    var si = new SubscriptionReader
                    {
                        Address  = EboEwsSettings.Address,
                        UserName = EboEwsSettings.UserName,
                        Password = EboEwsSettings.Password,
                        SubscriptionEventType = EwsSubscriptionEventTypeEnum.ValueItemChanged,
                        Ids = idsToSubscribeTo
                    };

                    // Attempt to update the values by reading the subscription, if this fails return all false as this could go on forever.
                    var results = si.ReadData();
                    // If all the ids we subscribed to failed, just continue on.. nothing to see here..
                    if (si.FailedSubscribedItems.Count == idsToSubscribeTo.Count)
                    {
                        return(true);
                    }
                    if (!await UpdateValues(si, results, true))
                    {
                        return(false);
                    }

                    Cache.AddOrUpdateItem(si.SubscribedItems, $"ActiveSubscriptions#{si.SubscriptionId}", CacheTenantId, 0);
                    unsubscribedIds = unsubscribedIds.Skip(MaxItemsPerSubscription).ToList();

                    activeSubscriptions.Add(si.SubscriptionId);
                    Cache.AddOrUpdateItem(activeSubscriptions, $"ActiveSubscriptions", CacheTenantId, 0);

                    // Add any prompts generated from reader to the list of prompts
                    Prompts.AddRange(si.ReadData().Prompts);

                    if (si.FailedSubscribedItems.Any())
                    {
                        Logger.LogInfo(LogCategory.Processor, this.Name, $"Some items failed to be subscribed to: {si.FailedSubscribedItems.ToJSON()}");
                    }
                }

                catch (Exception ex)
                {
                    Prompts.Add(ex.ToPrompt());
                    break;
                }
            }

            return(true);

            // TODO: How to handle subscriptions to value items that keep failing?
        }
Пример #13
0
 public void AddPrompt(TypePromptDocument typePrompt)
 {
     Prompts.Add(typePrompt);
     IsModified = true;
 }