private void OnAnalogAddedEvent(object sender, EventArgs e) { Console.WriteLine("OnAnalogEventAdded started"); Analog analog = (Analog)e; IORequestBlock iorb = new IORequestBlock() { RequestType = RequestType.SEND, ProcessControllerName = analog.ProcContrName }; DBContext dbContext = new DBContext(); RTU rtu; if ((rtu = dbContext.GetRTUByName(analog.ProcContrName)) != null) { iorb.ReqAddress = (ushort)rtu.GetCommandAddress(analog); bool shouldCommand = false; switch (rtu.Protocol) { case IndustryProtocols.ModbusTCP: ModbusHandler mdbHandler = new ModbusHandler(); mdbHandler.Header = new ModbusApplicationHeader() { TransactionId = 0, Length = 5, ProtocolId = (ushort)IndustryProtocols.ModbusTCP, DeviceAddress = rtu.Address }; mdbHandler.Request = new WriteRequest() { StartAddr = (ushort)rtu.GetCommandAddress(analog) }; if (shouldCommand = AnalogProcessor.InitialWorkPointAnalog(analog)) { mdbHandler.Request.FunCode = FunctionCodes.WriteSingleRegister; AnalogProcessor.EGUToRawValue(analog); ((WriteRequest)mdbHandler.Request).Value = analog.RawCommValue; iorb.SendBuff = mdbHandler.PackData(); iorb.SendMsgLength = iorb.SendBuff.Length; Console.WriteLine(BitConverter.ToString(iorb.SendBuff, 0, 12)); IORequests.EnqueueRequest(iorb); analog.IsInit = true; } break; } } Console.WriteLine("OnAnalogEventAdded finished"); }
public OMSSCADACommon.Responses.Response WriteSingleDigital(string id, CommandTypes command) { Console.WriteLine("WriteSingleDigital!"); Digital digital = null; OMSSCADACommon.Responses.Response response = new OMSSCADACommon.Responses.Response(); // sporno //while (!Database.IsConfigurationRunning) // getting PV from db ProcessVariable pv; if (dbContext.GetProcessVariableByName(id, out pv)) { digital = (Digital)pv; } // does this ID exist in the database if (digital == null) { response.ResultMessage = ResultMessage.INVALID_ID; return(response); } // is this a valid command for this digital device if (!CommandValidator.ValidateDigitalCommand(digital, command)) { response.ResultMessage = ResultMessage.INVALID_DIG_COMM; return(response); } RTU rtu; if ((rtu = dbContext.GetRTUByName(digital.ProcContrName)) != null) { IORequestBlock iorb = new IORequestBlock() { RequestType = RequestType.SEND, ProcessControllerName = digital.ProcContrName }; iorb.ReqAddress = (ushort)rtu.GetCommandAddress(digital); switch (rtu.Protocol) { case IndustryProtocols.ModbusTCP: ModbusHandler mdbHandler = new ModbusHandler { Header = new ModbusApplicationHeader() { TransactionId = 0, Length = 5, ProtocolId = (ushort)IndustryProtocols.ModbusTCP, DeviceAddress = rtu.Address }, Request = new WriteRequest() { FunCode = FunctionCodes.WriteSingleCoil, StartAddr = (ushort)rtu.GetCommandAddress(digital), Value = (ushort)command } }; iorb.SendBuff = mdbHandler.PackData(); iorb.SendMsgLength = iorb.SendBuff.Length; break; } IORequests.EnqueueRequest(iorb); Console.WriteLine("enqued {0}", BitConverter.ToString(iorb.SendBuff, 0, 12)); digital.Command = command; response.ResultMessage = ResultMessage.OK; } else { // rtu does not exist } return(response); }
// napravila, ali nisam testirala do kraja, to je nekad za buducnost, svakako ne treba sad :) public OMSSCADACommon.Responses.Response WriteSingleAnalog(string id, float value) { Console.WriteLine("WriteSingleAnalog!"); Analog analog = null; OMSSCADACommon.Responses.Response response = new OMSSCADACommon.Responses.Response(); // to do: //while (!Database.IsConfigurationRunning) // getting PV from db ProcessVariable pv; if (dbContext.GetProcessVariableByName(id, out pv)) { analog = (Analog)pv; } // does this ID exist in the database if (analog == null) { response.ResultMessage = ResultMessage.INVALID_ID; return(response); } // to do: // ovde analogProcessor provera opsega, alarma...bla, bla RTU rtu; if ((rtu = dbContext.GetRTUByName(analog.ProcContrName)) != null) { IORequestBlock iorb = new IORequestBlock() { RequestType = RequestType.SEND, ProcessControllerName = analog.ProcContrName }; iorb.ReqAddress = (ushort)rtu.GetCommandAddress(analog); bool shouldCommand = false; switch (rtu.Protocol) { case IndustryProtocols.ModbusTCP: ModbusHandler mdbHandler = new ModbusHandler { Header = new ModbusApplicationHeader() { TransactionId = 0, Length = 5, ProtocolId = (ushort)IndustryProtocols.ModbusTCP, DeviceAddress = rtu.Address }, Request = new WriteRequest() { FunCode = FunctionCodes.WriteSingleCoil, StartAddr = (ushort)rtu.GetCommandAddress(analog) } }; if (shouldCommand = AnalogProcessor.SetNewWorkPoint(analog, value)) { mdbHandler.Request.FunCode = FunctionCodes.WriteSingleRegister; ((WriteRequest)mdbHandler.Request).Value = (ushort)analog.RawCommValue; } iorb.SendBuff = mdbHandler.PackData(); iorb.SendMsgLength = iorb.SendBuff.Length; break; } IORequests.EnqueueRequest(iorb); Console.WriteLine("enqued {0}", BitConverter.ToString(iorb.SendBuff, 0, 12)); response.ResultMessage = ResultMessage.OK; } else { // rtu does not exist } return(response); }
/// <summary> /// Send Commands to simulator, to make its state consistent with RTDB /// </summary> public void InitializeSimulator() { // ovo probati sa taskovima, za svaki od rtu-ova. ipak ne, jer nekim promenljivim komandujes, nekim ne // var rtus = dbContext.GettAllRTUs(); //Parallel.ForEach(rtus, (currentRtu, state) => //{ // Console.WriteLine("InitSim Parallel.foreach RTU name = {0}, Therad id = {1} started", currentRtu.Key, Thread.CurrentThread.ManagedThreadId); // IIndustryProtocolHandler IProtHandler = null; // RTU rtu = dbContext.GetRTUByName(currentRtu.Key); // if (currentRtu.Value != null) // { // IORequestBlock iorb = new IORequestBlock() // { // RequestType = RequestType.SEND, // ProcessControllerName = currentRtu.Key // }; // switch (rtu.Protocol) // { // case IndustryProtocols.ModbusTCP: // IProtHandler = new ModbusHandler() // { // Header = new ModbusApplicationHeader // { // TransactionId = 0, // ProtocolId = (ushort)IndustryProtocols.ModbusTCP, // DeviceAddress = rtu.Address, // Length = 5 // }, // Request = new WriteRequest() // }; // break; // } // //to do. praviti nove iorbove // // za svaku varijablu trebas imati should command ili ne i u zavisnosti od toga puniti data, racunati length zahtvea i ostalo // //-------------analogs--------------- // var analogs = dbContext.GetProcessVariable().Where(pv => pv.Type == VariableTypes.ANALOG && pv.IsInit == false && // pv.ProcContrName.Equals(currentRtu.Key)).OrderBy(pv => pv.RelativeAddress); // int requestCount = analogs.ToList().Count(); // if (requestCount != 0) // { // ProcessVariable firstPV = analogs.FirstOrDefault(); // iorb.ReqAddress = (ushort)rtu.GetAcqAddress(firstPV); // if (IProtHandler != null) // { // switch (rtu.Protocol) // { // case IndustryProtocols.ModbusTCP: // for(int i = 0; i < requestCount; i++) // { // } // ((ReadRequest)((ModbusHandler)IProtHandler).Request).FunCode = FunctionCodes.ReadInputRegisters; // ((ReadRequest)((ModbusHandler)IProtHandler).Request).Quantity = (ushort)requestCount; // ((ReadRequest)((ModbusHandler)IProtHandler).Request).StartAddr = iorb.ReqAddress; // break; // } // iorb.Flags = requestCount; // iorb.SendBuff = IProtHandler.PackData(); // iorb.SendMsgLength = iorb.SendBuff.Length; // IORequests.EnqueueRequest(iorb); // } // } // //-------------digitals---------------(to do: add init flag...) // var digitals = dbContext.GetProcessVariable().Where(pv => pv.Type == VariableTypes.DIGITAL && // pv.ProcContrName.Equals(currentRtu.Key)).OrderBy(pv => pv.RelativeAddress); // requestCount = digitals.ToList().Count(); // if (requestCount != 0) // { // ProcessVariable firstPV = digitals.FirstOrDefault(); // iorb.ReqAddress = (ushort)rtu.GetAcqAddress(firstPV); // if (IProtHandler != null) // { // switch (rtu.Protocol) // { // case IndustryProtocols.ModbusTCP: // ((ReadRequest)((ModbusHandler)IProtHandler).Request).FunCode = FunctionCodes.ReadDiscreteInput; // ((ReadRequest)((ModbusHandler)IProtHandler).Request).Quantity = (ushort)requestCount; // ((ReadRequest)((ModbusHandler)IProtHandler).Request).StartAddr = iorb.ReqAddress; // break; // } // iorb.Flags = requestCount; // iorb.SendBuff = IProtHandler.PackData(); // iorb.SendMsgLength = iorb.SendBuff.Length; // IORequests.EnqueueRequest(iorb); // } // } // } //}); List <ProcessVariable> pvs = dbContext.GetProcessVariable().ToList(); if (pvs.Count != 0) { foreach (ProcessVariable pv in pvs) { IORequestBlock iorb = new IORequestBlock() { RequestType = RequestType.SEND, ProcessControllerName = pv.ProcContrName }; RTU rtu; if ((rtu = dbContext.GetRTUByName(pv.ProcContrName)) != null) { iorb.ReqAddress = (ushort)rtu.GetCommandAddress(pv); bool shouldCommand = false; switch (rtu.Protocol) { case IndustryProtocols.ModbusTCP: ModbusHandler mdbHandler = new ModbusHandler(); mdbHandler.Header = new ModbusApplicationHeader() { TransactionId = 0, Length = 5, ProtocolId = (ushort)IndustryProtocols.ModbusTCP, DeviceAddress = rtu.Address }; mdbHandler.Request = new WriteRequest() { StartAddr = (ushort)rtu.GetCommandAddress(pv) }; switch (pv.Type) { // initialy, on simulator all digitals are set to 0 -> closed state case VariableTypes.DIGITAL: Digital digital = (Digital)pv; CommandTypes comm; if (shouldCommand = CommandValidator.InitialCommandingForDigital(digital, out comm)) { mdbHandler.Request.FunCode = FunctionCodes.WriteSingleCoil; ((WriteRequest)mdbHandler.Request).Value = (ushort)comm; } break; case VariableTypes.ANALOG: Analog analog = (Analog)pv; if (shouldCommand = AnalogProcessor.InitialWorkPointAnalog(analog)) { mdbHandler.Request.FunCode = FunctionCodes.WriteSingleRegister; ((WriteRequest)mdbHandler.Request).Value = (ushort)analog.RawCommValue; } analog.IsInit = true; break; case VariableTypes.COUNTER: Counter counter = (Counter)pv; break; } if (shouldCommand) { iorb.SendBuff = mdbHandler.PackData(); iorb.SendMsgLength = iorb.SendBuff.Length; //if (pv.Name == "MEAS_AN_1") // Console.WriteLine(BitConverter.ToString(iorb.SendBuff, 0, 12)); } break; } if (shouldCommand) { IORequests.EnqueueRequest(iorb); } } else { // izbrisati omdah te procesne varijable sa rtu-om tog imena? Console.WriteLine("Invalid config: ProcContrName = {0} does not exists.", pv.ProcContrName); continue; } } } }
/// <summary> /// Processing answers from Simulator - Process Controller /// </summary> public void ProcessPCAnwers(TimeSpan timeout, CancellationToken token) { while (!token.IsCancellationRequested) { bool isSuccessful; IORequestBlock answer = IORequests.DequeueAnswer(out isSuccessful, timeout); if (isSuccessful) { bool isChange = false; RTU rtu; // sporno //while (!Database.IsConfigurationRunning) if ((rtu = dbContext.GetRTUByName(answer.ProcessControllerName)) != null) { switch (rtu.Protocol) { case IndustryProtocols.ModbusTCP: ModbusHandler mdbHandler = new ModbusHandler(); try { mdbHandler.UnpackData(answer.RcvBuff, answer.RcvMsgLength); switch (mdbHandler.Response.FunCode) { case FunctionCodes.ReadDiscreteInput: { BitReadResponse response = (BitReadResponse)mdbHandler.Response; var responsePVCount = answer.Flags; ushort varAddr = answer.ReqAddress; for (int i = 0; i < responsePVCount; i++, varAddr++) { ProcessVariable pv; if (rtu.GetProcessVariableByAddress(varAddr, out pv)) { Digital target = (Digital)pv; try { bool isOpened = response.BitValues[i]; if (target.State != target.ValidStates[isOpened ? 1 : 0]) { isChange = true; target.State = target.ValidStates[isOpened ? 1 : 0]; Console.WriteLine(" CHANGE! Digital variable {0}, state: {1}", target.Name, target.State); DMSClient dMSClient = new DMSClient(); dMSClient.ChangeOnSCADADigital(target.Name, target.State); } } catch { Console.WriteLine("Digital variable {0}, state: INVALID", target.Name); } } } if (isChange) { ScadaModelParser parser = new ScadaModelParser(); parser.SerializeScadaModel(); } } break; // analog input case FunctionCodes.ReadInputRegisters: { RegisterReadResponse response = (RegisterReadResponse)mdbHandler.Response; var responsePVCount = answer.Flags; ushort varAddr = answer.ReqAddress; for (int i = 0; i < responsePVCount; i++, varAddr++) { ProcessVariable pv; if (rtu.GetProcessVariableByAddress(varAddr, out pv)) { Analog target = (Analog)pv; try { ushort newRawAcqValue = response.RegValues[target.RelativeAddress]; float newAcqValue; AnalogProcessor.RawValueToEGU(target, newRawAcqValue, out newAcqValue); if (target.AcqValue != newAcqValue) { isChange = true; target.RawAcqValue = newRawAcqValue; target.AcqValue = newAcqValue; Console.WriteLine(" CHANGE! Analog variable {0}, AcqValue: {1}", target.Name, target.AcqValue); //to do: propagacija analogih promena(ako se secate Pavlica je prvo rekao da nam to ne treba da samo jednom zakucamo vrednost na pocetku) xD DMSClient dMSClient = new DMSClient(); dMSClient.ChangeOnSCADAAnalog(target.Name, target.AcqValue); } } catch { // Console.WriteLine("Digital variable {0}, state: INVALID", target.Name); } } } if (isChange) { ScadaModelParser parser = new ScadaModelParser(); parser.SerializeScadaModel(); } } break; } } catch (Exception e) { Console.WriteLine(e.Message); } break; } } } } Console.WriteLine("ProcessPCAnswers.shutdown=true"); return; }
/// <summary> /// Processing answers from Simulator - Process Controller /// </summary> public void ProcessPCAnwers(TimeSpan timeout, CancellationToken token) { DataLinkHandler dataLinkHandler = new DataLinkHandler(); while (!token.IsCancellationRequested) { bool isSuccessful; IORequestBlock answer = IORequests.DequeueAnswer(out isSuccessful, timeout); if (isSuccessful) { bool isChange = false; RTU rtu; if ((rtu = dbContext.GetRTUByName(answer.ProcessControllerName)) != null) { switch (rtu.Protocol) { case IndustryProtocols.ModbusTCP: ModbusHandler mdbHandler = new ModbusHandler(); try { mdbHandler.UnpackData(answer.RcvBuff, answer.RcvMsgLength); switch (mdbHandler.Response.FunCode) { case FunctionCodes.ReadDiscreteInput: { BitReadResponse response = (BitReadResponse)mdbHandler.Response; var responsePVCount = answer.Flags; ushort varAddr = answer.ReqAddress; for (int i = 0; i < responsePVCount; i++, varAddr++) { ProcessVariable pv; if (rtu.GetProcessVariableByAddress(varAddr, out pv)) { Digital target = (Digital)pv; try { bool isOpened = response.BitValues[i]; if (target.State != target.ValidStates[isOpened ? 1 : 0]) { isChange = true; target.State = target.ValidStates[isOpened ? 1 : 0]; Console.WriteLine(" CHANGE! Digital variable {0}, state: {1}", target.Name, target.State); dMSProxy.ChangeOnSCADADigital(target.Name, target.State); } } catch { Console.WriteLine("Digital variable {0}, state: INVALID", target.Name); } } } if (isChange) { ScadaModelParser parser = new ScadaModelParser(); parser.SerializeScadaModel(); } } break; // analog input case FunctionCodes.ReadInputRegisters: { RegisterReadResponse response = (RegisterReadResponse)mdbHandler.Response; var responsePVCount = answer.Flags; ushort varAddr = answer.ReqAddress; for (int i = 0; i < responsePVCount; i++, varAddr++) { ProcessVariable pv; if (rtu.GetProcessVariableByAddress(varAddr, out pv)) { Analog target = (Analog)pv; try { ushort newRawAcqValue = response.RegValues[target.RelativeAddress]; float newAcqValue; AnalogProcessor.RawValueToEGU(target, newRawAcqValue, out newAcqValue); if (target.AcqValue != newAcqValue) { isChange = true; target.RawAcqValue = newRawAcqValue; target.AcqValue = newAcqValue; Console.WriteLine(" CHANGE! Analog variable {0}, AcqValue: {1}", target.Name, target.AcqValue); //to do: propagacija analogih promena(ako se secate Pavlica je prvo rekao da nam to ne treba da samo jednom zakucamo vrednost na pocetku) xD dMSProxy.ChangeOnSCADAAnalog(target.Name, target.AcqValue); } } catch { // Console.WriteLine("Digital variable {0}, state: INVALID", target.Name); } } } if (isChange) { ScadaModelParser parser = new ScadaModelParser(); parser.SerializeScadaModel(); } } break; } } catch (Exception e) { Console.WriteLine(e.Message); } break; case IndustryProtocols.DNP3TCP: byte len = answer.RcvBuff[2]; byte actualLen = (byte)(2 + 1 + 5 + 2); // start + len + ctrl + dest + source + crc len -= 5; // minus header while (len > 0) { if (len < 16) { // last chunk actualLen += (byte)(len + 2); break; } actualLen += (byte)(16 + 2); len -= 16; } byte[] message = new byte[actualLen]; for (int i = 0; i < actualLen; i++) { message[i] = answer.RcvBuff[i]; } List <UserLevelObject> userLevelObjects = dataLinkHandler.PackUp(message); if (userLevelObjects == null) { continue; } DNP3UserLayerHandler dNP3UserLayerHandler = new DNP3UserLayerHandler(new DNP3Handler(), dbContext); List <Tuple <string, float> > tuples = dNP3UserLayerHandler.ReadAllAnalogInputPointsReadResponse(userLevelObjects, rtu.Name); foreach (Tuple <string, float> tuple in tuples) { try { dMSProxy.ChangeOnSCADAAnalog(tuple.Item1, tuple.Item2); } catch { dMSProxy = new DMSSCADAProxy(); } } break; } } } } Console.WriteLine("ProcessPCAnswers.shutdown=true"); return; }
/// <summary> /// Send Commands to simulator, to make its state consistent with RTDB /// </summary> public void InitializeSimulator() { List <ProcessVariable> pvs = dbContext.GetAllProcessVariables(); if (pvs.Count != 0) { foreach (ProcessVariable pv in pvs) { IORequestBlock iorb = new IORequestBlock() { RequestType = RequestType.SEND, ProcessControllerName = pv.ProcContrName }; RTU rtu; if ((rtu = dbContext.GetRTUByName(pv.ProcContrName)) != null) { iorb.ReqAddress = (ushort)rtu.GetCommandAddress(pv); bool shouldCommand = false; switch (rtu.Protocol) { case IndustryProtocols.ModbusTCP: ModbusHandler mdbHandler = new ModbusHandler(); mdbHandler.Header = new ModbusApplicationHeader() { TransactionId = 0, Length = 5, ProtocolId = (ushort)IndustryProtocols.ModbusTCP, DeviceAddress = rtu.Address }; mdbHandler.Request = new WriteRequest() { StartAddr = (ushort)rtu.GetCommandAddress(pv) }; switch (pv.Type) { // initialy, on simulator all digitals are set to 0 -> closed state case VariableTypes.DIGITAL: Digital digital = (Digital)pv; CommandTypes comm; if (shouldCommand = CommandValidator.InitialCommandingForDigital(digital, out comm)) { mdbHandler.Request.FunCode = FunctionCodes.WriteSingleCoil; ((WriteRequest)mdbHandler.Request).Value = (ushort)comm; } break; case VariableTypes.ANALOG: Analog analog = (Analog)pv; if (shouldCommand = AnalogProcessor.InitialWorkPointAnalog(analog)) { mdbHandler.Request.FunCode = FunctionCodes.WriteSingleRegister; ((WriteRequest)mdbHandler.Request).Value = (ushort)analog.RawCommValue; } analog.IsInit = true; break; case VariableTypes.COUNTER: Counter counter = (Counter)pv; break; } if (shouldCommand) { iorb.SendBuff = mdbHandler.PackData(); iorb.SendMsgLength = iorb.SendBuff.Length; if (pv.Name == "MEAS_AN_1") { Console.WriteLine(BitConverter.ToString(iorb.SendBuff, 0, 12)); } } break; } if (shouldCommand) { IORequests.EnqueueRequest(iorb); } } else { // izbrisati omdah te procesne varijable sa rtu-om tog imena? Console.WriteLine("Invalid config: ProcContrName = {0} does not exists.", pv.ProcContrName); continue; } } } }
/// <summary> /// Processing answers from Simulator - Process Controller /// </summary> public void ProcessPCAnwers() { while (!isShutdown) { bool isSuccessful; IORequestBlock answer = IORequests.DequeueAnswer(out isSuccessful); if (isSuccessful) { RTU rtu; // sporno //while (!Database.IsConfigurationRunning) // Thread.Sleep(100); if ((rtu = dbContext.GetRTUByName(answer.ProcessControllerName)) != null) { switch (rtu.Protocol) { case IndustryProtocols.ModbusTCP: ModbusHandler mdbHandler = new ModbusHandler(); mdbHandler.UnpackData(answer.RcvBuff, answer.RcvMsgLength); switch (mdbHandler.Response.FunCode) { case FunctionCodes.ReadDiscreteInput: { BitReadResponse response = (BitReadResponse)mdbHandler.Response; ProcessVariable pv; Digital target = null; if (rtu.GetProcessVariableByAddress(answer.ReqAddress, out pv)) { target = (Digital)pv; } if (target != null) { int[] array = new int[1]; response.BitValues.CopyTo(array, 0); try { if (target.State != target.ValidStates[array[0]]) { Console.WriteLine("CHANGE!"); target.State = target.ValidStates[array[0]]; ScadaModelParser parser = new ScadaModelParser(); parser.SerializeScadaModel(); DMSClient dMSClient = new DMSClient(); dMSClient.ChangeOnSCADA(target.Name, target.State); } } catch { // Console.WriteLine("Digital variable {0}, state: INVALID", target.Name); } } } break; case FunctionCodes.ReadInputRegisters: { RegisterReadResponse response = (RegisterReadResponse)mdbHandler.Response; ProcessVariable pv; Analog target = null; // i ovde se zapravo cita iz baze! preko RTUa. znaci pristupamo rtuu, a moguce je da se desava rekonfiguracija. if (rtu.GetProcessVariableByAddress(answer.ReqAddress, out pv)) { target = (Analog)pv; } if (target != null) { ushort newRawAcqValue = response.RegValues[0]; try { float newAcqValue; AnalogProcessor.RawValueToEGU(target, newRawAcqValue, out newAcqValue); // videti kad menjas kommande if (target.AcqValue != newAcqValue) { Console.WriteLine("CHANGE analog!"); target.RawAcqValue = newRawAcqValue; target.AcqValue = newAcqValue; ScadaModelParser parser = new ScadaModelParser(); parser.SerializeScadaModel(); DMSClient dMSClient = new DMSClient(); // to do // dMSClient.ChangeOnSCADA(target.Name, target.State); } } catch { // Console.WriteLine("Digital variable {0}, state: INVALID", target.Name); } } } break; } break; } } else { Console.WriteLine("Answer disposed. Process Controller with name ={0} does not exit.", answer.ProcessControllerName); } } Thread.Sleep(100); } Console.WriteLine("ProcessPCAnswers.shutdown=true"); return; }
/// <summary> /// Producing IORB requests for automatic data acquistion /// </summary> public void StartAcquisition() { DBContext.OnAnalogAdded += OnAnalogAddedEvent; List <ProcessVariable> pvs; while (!isShutdown) { // sporno to do: //while (!Database.IsConfigurationRunning) // Thread.Sleep(100); pvs = dbContext.GetAllProcessVariables(); foreach (ProcessVariable pv in pvs) { IORequestBlock iorb = new IORequestBlock() { RequestType = RequestType.SEND_RECV, ProcessControllerName = pv.ProcContrName }; RTU rtu; if ((rtu = dbContext.GetRTUByName(pv.ProcContrName)) != null) { iorb.ReqAddress = (ushort)rtu.GetAcqAddress(pv); switch (rtu.Protocol) { case IndustryProtocols.ModbusTCP: ModbusHandler mdbHandler = new ModbusHandler(); // header is same for all read - acquistion requests mdbHandler.Header = new ModbusApplicationHeader() { TransactionId = 0, Length = 5, ProtocolId = (ushort)IndustryProtocols.ModbusTCP, DeviceAddress = rtu.Address }; mdbHandler.Request = new ReadRequest() { StartAddr = iorb.ReqAddress }; switch (pv.Type) { case VariableTypes.DIGITAL: Digital digital = (Digital)pv; mdbHandler.Request.FunCode = FunctionCodes.ReadDiscreteInput; ((ReadRequest)mdbHandler.Request).Quantity = (ushort)(Math.Floor((Math.Log(digital.ValidStates.Count, 2)))); break; case VariableTypes.ANALOG: Analog analog = (Analog)pv; if (!analog.IsInit) { continue; // dok se ne setuje inicijalna vrednost } mdbHandler.Request.FunCode = FunctionCodes.ReadInputRegisters; ((ReadRequest)mdbHandler.Request).Quantity = analog.NumOfRegisters; break; case VariableTypes.COUNTER: Counter counter = (Counter)pv; break; } iorb.SendBuff = mdbHandler.PackData(); break; } iorb.SendMsgLength = iorb.SendBuff.Length; //if (pv.Name == "MEAS_AN_1") // Console.WriteLine(BitConverter.ToString(iorb.SendBuff, 0, 12)); IORequests.EnqueueRequest(iorb); } else { // ne postoji taj rtu sa tim imenom. izbrisati te procesne varijable sa rtu-om tog imena Console.WriteLine("Invalid config: ProcContrName = {0} does not exists.", pv.ProcContrName); continue; } } Thread.Sleep(millisecondsTimeout: timerMsc); } Console.WriteLine("StartAcq.shutdown=true"); return; }