// Event tag timer event
        public void OnEventTimer(object sender, ElapsedEventArgs args)
        {
            eventTimer.Stop();
            Log.Debug("FactoryData Plc Service Event Timer Event");

            var recordList   = new List <RecordTag>();
            var resultsAvail = false;

            try
            {
                foreach (ListTag elem in eventList)
                {
                    string trigger   = string.Concat(elem.Name, ".Trigger");
                    string ack       = string.Concat(elem.Name, ".Ack");
                    string data      = string.Concat(elem.Name, ".Data");
                    string timestamp = string.Concat(elem.Name, ".TS");

                    var triggerCheck = bool.Parse(logixEventDrv.Read(trigger));

                    if (triggerCheck == true)
                    {
                        resultsAvail = true;

                        var record = new RecordTag
                        {
                            TagId = elem.Id,
                            Data  = long.Parse(logixEventDrv.Read(data)),
                            PlcTS = DateTime.Parse(logixEventDrv.Read(timestamp)),
                        };

                        logixEventDrv.Write(ack, 1);

                        Log.Debug("Subscription Tag Read:" + elem.Name + " Value:" + record.Data + " Timestamp: " + record.PlcTS);
                        recordList.Add(record);

                        logixEventDrv.Write(ack, 0);
                    }
                }
                ;
            }
            catch (Exception ex)
            {
                Log.Error("Read Event Tag List exception: " + ex.Message);
            }

            if (resultsAvail == true)
            {
                var msgObject = new TagReadResultsMsg
                {
                    List = recordList
                };

                var type = new Type[] { typeof(TagReadResultsMsg) };

                using (var msg = new SendMessage())
                {
                    msg.Send(msgObject, "EventTag_Results", type);
                }

                resultsAvail = false;
            }

            eventTimer.Start();
        }
        // Transaction udt timer event
        private void OnTransactionTimer(object sender, ElapsedEventArgs e)
        {
            transactionTimer.Stop();

            Log.Debug("FactoryData Plc Service Transaction Timer Event");
            var resultList   = new List <TransactionRecord>();
            var resultsAvail = false;

            foreach (ListTag elem in transactionList)
            {
                Type   udtType = typeof(TransactionUDT);
                var    udt     = new TransactionUDT();
                string trigger = string.Concat(elem.Name, ".Trigger");
                string ack     = string.Concat(elem.Name, ".Ack");



                // Trigger bit check
                var triggerCheck = bool.Parse(logixTransactionDrv.Read(trigger));

                if (triggerCheck == true)
                {
                    resultsAvail = true;

                    try
                    {
                        udt = (TransactionUDT)logixTransactionDrv.ReadUDT(elem.Name, udtType);
                    }
                    catch (Exception ex)
                    {
                        Log.Error("Read transaction udt Exception: " + ex.Message);
                    }

                    // Transaction record
                    var result = new TransactionRecord
                    {
                        TagName = elem.Name,
                        Udt     = udt
                    };

                    // Populate result list
                    resultList.Add(result);

                    // Set acknowledge bit
                    logixTransactionDrv.Write(ack, 1);
                    logixTransactionDrv.Write(ack, 0);
                }
            }

            if (resultsAvail == true)
            {
                var msgObject = new TransactionResultsMsg
                {
                    Records = resultList
                };

                var type = new Type[] { typeof(TransactionResultsMsg) };

                using (var msg = new SendMessage())
                {
                    msg.Send(msgObject, "TransactionTag_Results", type);
                }

                resultsAvail = false;
            }

            transactionTimer.Start();
        }
        // Recieve message event
        private void ReadMQ_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
        {
            Log.Debug("Read Message Queue Event Triggered");
            //Read recieved message
            var msgRead = new Message();

            msgRead = readMQ.EndReceive(e.AsyncResult);
            Log.Debug(msgRead.Label + " Recieved MsgID: " + msgRead.Id);

            if (msgRead.Label == "Plc_Config")
            {
                msgRead.Formatter = new XmlMessageFormatter(new Type[] { typeof(PlcConfigMsg) });
                var msgData = ((PlcConfigMsg)msgRead.Body);

                // Instantiate Logix drivers
                logixEventDrv = new EthernetIPforCLXCom()
                {
                    IPAddress            = msgData.IPAddress,
                    DisableSubscriptions = msgData.DisableSubscriptions,
                    PollRateOverride     = msgData.PollRateOverride,
                    ProcessorSlot        = msgData.ProcessorSlot,
                    Port = msgData.Port
                };
                Log.Information("Logix Event driver created");

                logixSubscriptionDrv = new EthernetIPforCLXCom()
                {
                    IPAddress            = msgData.IPAddress,
                    DisableSubscriptions = msgData.DisableSubscriptions,
                    PollRateOverride     = msgData.PollRateOverride,
                    ProcessorSlot        = msgData.ProcessorSlot,
                    Port = msgData.Port
                };
                Log.Information("Logix Subscription driver created");

                logixTransactionDrv = new EthernetIPforCLXCom()
                {
                    IPAddress            = msgData.IPAddress,
                    DisableSubscriptions = msgData.DisableSubscriptions,
                    PollRateOverride     = msgData.PollRateOverride,
                    ProcessorSlot        = msgData.ProcessorSlot,
                    Port = msgData.Port
                };
                Log.Information("Logix Transaction driver created");

                // Set up read timers
                eventTimer = new Timer
                {
                    Interval = msgData.EventPollRate
                };
                eventTimer.Elapsed += new ElapsedEventHandler(OnEventTimer);

                subscriptionTimer = new Timer
                {
                    Interval = msgData.SubscriptionPollRate
                };
                subscriptionTimer.Elapsed += new ElapsedEventHandler(OnSubscriptionTimer);

                transactionTimer = new Timer
                {
                    Interval = msgData.TransactionPollRate
                };
                transactionTimer.Elapsed += new ElapsedEventHandler(OnTransactionTimer);

                // Get tag list from database
                var msgObject = new TagListReqMsg
                {
                    getTagList = true
                };

                var type = new Type[] { typeof(TagListReqMsg) };

                using (var msg = new SendMessage())
                {
                    msg.Send(msgObject, "TagList_Request", type);
                }

                Log.Debug("Plc Config Message Processed" + " MsgID: " + msgRead.Id);
            }

            if (msgRead.Label == "TagList_Config")
            {
                msgRead.Formatter = new XmlMessageFormatter(new Type[] { typeof(TagListMsg) });
                var msgData = ((TagListMsg)msgRead.Body);

                eventList        = new List <ListTag>();
                transactionList  = new List <ListTag>();
                subscriptionList = new List <ListTag>();


                foreach (ListTag elem in msgData.List)
                {
                    if (elem.TagTypeId == TagTypeConstants.eventType)
                    {
                        var tag = elem;
                        eventList.Add(tag);
                        Log.Debug("Tag added to event tag list: " + tag.Name);
                    }

                    if (elem.TagTypeId == TagTypeConstants.subscriptionType)
                    {
                        var tag = elem;
                        subscriptionList.Add(tag);
                        Log.Debug("Tag added to subscription tag list: " + tag.Name);
                    }

                    if (elem.TagTypeId == TagTypeConstants.transactionType)
                    {
                        var tag = elem;
                        transactionList.Add(tag);
                        Log.Debug("Tag added to transaction tag list: " + tag.Name);
                    }
                }
                ;

                // Start read timers
                eventTimer.Start();
                transactionTimer.Start();
                subscriptionTimer.Start();
                Log.Debug("Read timers started ");
            }

            // Resume listening for messages
            try
            {
                readMQ.BeginReceive();
                Log.Information("ReadMQ Listening For Messages");
            }
            catch (Exception ex)
            {
                Log.Error("ReadMQ Begin Recieve Exception: " + ex.Message);
            }
        }