/// <summary>
        /// Start of processing of input queue
        /// </summary>
        public void StartJob()
        {
            SenderMonitorEvent.sendMonitorEvent(vpEventLog, "Starting send command service...", EventLogEntryType.Information);

            m_SenderTimer.Start();

            SenderMonitorEvent.sendMonitorEvent(vpEventLog, "Send command service has been started", EventLogEntryType.Information);
            fJobStarted = true;
        }
        /// <summary>
        /// Stop of processing of input queue
        /// </summary>
        public void StopJob()
        {
            SenderMonitorEvent.sendMonitorEvent(vpEventLog, "Stopping send command service...", EventLogEntryType.Information);

            //stop timers if working
            if (m_SenderTimer.Enabled)
            {
                m_SenderTimer.Stop();
            }

            SenderMonitorEvent.sendMonitorEvent(vpEventLog, "Send command service has been stopped", EventLogEntryType.Information);
            fJobStarted = false;
        }
        /// <summary>	Default constructor. </summary>
        public SenderJobs()
        {
            // Set up a timer to trigger every send command frequency.
            int sendCommandFrequencyInSeconds = int.Parse(System.Configuration.ConfigurationManager.AppSettings[cSendCommandFrequencyName]);

            OdataServiceUrl = System.Configuration.ConfigurationManager.AppSettings[cOdataService];
            OPCServerUrl    = System.Configuration.ConfigurationManager.AppSettings[cOPCServerUrl];

            wmiProductInfo = new KEPSenderServiceProductInfo(cServiceTitle,
                                                             Environment.MachineName,
                                                             Assembly.GetExecutingAssembly().GetName().Version.ToString(),
                                                             DateTime.Now,
                                                             sendCommandFrequencyInSeconds,
                                                             OdataServiceUrl);

            m_SenderTimer          = new System.Timers.Timer();
            m_SenderTimer.Interval = sendCommandFrequencyInSeconds * 1000; // seconds to milliseconds
            m_SenderTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnSenderTimer);

            SenderMonitorEvent.sendMonitorEvent(vpEventLog, string.Format("Send Command Frequncy = {0}", sendCommandFrequencyInSeconds), EventLogEntryType.Information);
        }
        private bool WriteToKEPServer(Session AMSession, SenderJobProps job)
        {
            // Step 2 -- Read the value of a node representing a PI Point data under the hood
            NodeId nodeToRead = new NodeId(job.Command /*Element*/, 2);
            Node   node       = AMSession.NodeCache.Find(nodeToRead) as Node;


            if (node != null)
            {
                DataValue  value  = AMSession.ReadValue(nodeToRead);
                WriteValue Wvalue = new WriteValue();
                Wvalue.NodeId      = nodeToRead;
                Wvalue.AttributeId = Attributes.Value;

                if ((node.NodeClass & (NodeClass.Variable | NodeClass.VariableType)) == 0)
                {
                    Wvalue.AttributeId = Attributes.DisplayName;
                }

                Wvalue.IndexRange  = null;
                Wvalue.Value       = value;
                Wvalue.Value.Value = ConvertToObject(job.CommandRule);

                if (Wvalue.Value.Value != null)
                {
                    WriteValueCollection nodesToWrite = new WriteValueCollection();
                    nodesToWrite.Add(Wvalue);

                    StatusCodeCollection     results         = null;
                    DiagnosticInfoCollection diagnosticInfos = null;

                    ResponseHeader responseHeader = AMSession.Write(
                        null,
                        nodesToWrite,
                        out results,
                        out diagnosticInfos);

                    Session.ValidateResponse(results, nodesToWrite);
                    //Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite);

                    if (results[0].Code == 0)
                    {
                        return(true);
                    }
                    else
                    {
                        SenderMonitorEvent.sendMonitorEvent(vpEventLog, String.Format("Can not send command to KEP Server. ErrorCode: {0}. ErrorText: {1}. Job order ID: {2}", results[0].Code, results[0].ToString(), job.JobOrderID), EventLogEntryType.Error);
                        return(false);
                    }
                }
                else
                {
                    SenderMonitorEvent.sendMonitorEvent(vpEventLog, String.Format("Can not convert command value: {0}. Job order ID: {1}", job.CommandRule, job.JobOrderID), EventLogEntryType.Error);
                    return(false);
                }
            }
            else
            {
                SenderMonitorEvent.sendMonitorEvent(vpEventLog, String.Format("Item not found: {0}. Job order ID: ", job.Command, job.JobOrderID), EventLogEntryType.Error);
                return(false);
            }
        }
        /// <summary>
        /// Processing of input queue
        /// </summary>
        public void OnSenderTimer(object sender, System.Timers.ElapsedEventArgs args)
        {
            SenderMonitorEvent.sendMonitorEvent(vpEventLog, "Monitoring the send command activity", EventLogEntryType.Information);
            m_SenderTimer.Stop();

            string lLastError         = string.Empty;
            int    CountJobsToProcess = 0;

            try
            {
                KEPSSenderdbData senderDbData  = new KEPSSenderdbData(OdataServiceUrl);
                JobOrders        jobsToProcess = senderDbData.getJobsToProcess();
                CountJobsToProcess = jobsToProcess.JobOrdersObj.Count;
                SenderMonitorEvent.sendMonitorEvent(vpEventLog, "Jobs to process: " + CountJobsToProcess, EventLogEntryType.Information);

                string sendState = string.Empty;
                if (CountJobsToProcess > 0)
                {
                    // Step 1 -- Connect to UA server
                    //string discoveryUrl = "opc.tcp://127.0.0.1:49320";
                    using (Session AMSession = ClientUtils.CreateSession(OPCServerUrl, "ArcelorMittal.UA.SenderCommand"))
                    {
                        foreach (JobOrders.JobOrdersValue jobVal in jobsToProcess.JobOrdersObj)
                        {
                            try
                            {
                                SenderJobProps job = new SenderJobProps(jobVal.ID,
                                                                        jobVal.Command,
                                                                        (string)(jobVal.CommandRule));

                                if (WriteToKEPServer(AMSession, job))
                                {
                                    sendState = "Done";
                                    wmiProductInfo.LastActivityTime = DateTime.Now;
                                }
                                else
                                {
                                    sendState = "Failed";
                                }
                                lLastError = String.Format("JobOrderID: {0}. Send to KEP Server element {1} = {2}. Status: {3}", job.JobOrderID, job.Command, job.CommandRule, sendState);

                                if (sendState == "Done")
                                {
                                    Requests.updateJobStatus(OdataServiceUrl, job.JobOrderID, sendState);
                                }
                                else if (sendState == "Failed")
                                {
                                    wmiProductInfo.LastServiceError = string.Format("{0}. On {1}", lLastError, DateTime.Now);
                                }
                            }
                            catch (Exception ex)
                            {
                                lLastError = "Error sending command: " + ex.ToString();
                                SenderMonitorEvent.sendMonitorEvent(vpEventLog, lLastError, EventLogEntryType.Error);
                                lLastError = "Reconecting...";
                                SenderMonitorEvent.sendMonitorEvent(vpEventLog, lLastError, EventLogEntryType.Information);
                                AMSession.Reconnect();
                            }
                        }
                        // Step 3 -- Clean up
                        AMSession.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                lLastError = "Error getting jobs: " + ex.ToString();
                SenderMonitorEvent.sendMonitorEvent(vpEventLog, lLastError, EventLogEntryType.Error);
                wmiProductInfo.LastServiceError = string.Format("{0}. On {1}", lLastError, DateTime.Now);
            }
            wmiProductInfo.SendCommandsCount += CountJobsToProcess;
            wmiProductInfo.PublishInfo();
            SenderMonitorEvent.sendMonitorEvent(vpEventLog, string.Format("Send command is done. {0} tasks", CountJobsToProcess), EventLogEntryType.Information);

            m_SenderTimer.Start();
        }