public List <KeyValuePair <long, int> > ReadDiscrete(List <long> gids) { List <KeyValuePair <long, int> > result = new List <KeyValuePair <long, int> >(gids.Count); foreach (long gid in gids) { Discrete d = model.GetDiscrete(gid); if (d == null || d.BaseAddress < 0 || d.BaseAddress > ushort.MaxValue / 2) { continue; } ushort address = (ushort)(d.BaseAddress * 2); ushort high, low; if (!inputRegisters.TryGetValue(address, out high) || !inputRegisters.TryGetValue((ushort)(address + 1), out low)) { continue; } int value; GetValues(high, low, out _, out value); result.Add(new KeyValuePair <long, int>(gid, value)); } return(result); }
public void UpdateModel() { SCADAModel model = SCADAModel.Instance; if (model == null) { return; } Dictionary <int, List <long> > byAddress = new Dictionary <int, List <long> >(); List <ushort> inputAddresses = new List <ushort>(); foreach (Analog a in model.GetAllAnalogs()) { if (a == null || !IsValidAddress(a.BaseAddress)) { continue; } List <long> gids; if (byAddress.TryGetValue(a.BaseAddress, out gids)) { gids.Add(a.GID); } else { byAddress[a.BaseAddress] = new List <long>(1) { a.GID }; } if (a.Direction == SignalDirection.Write) { continue; } ushort address = GetAddress(a.BaseAddress); inputAddresses.Add(address); } foreach (Discrete d in model.GetAllDiscretes()) { if (d == null || !IsValidAddress(d.BaseAddress)) { continue; } List <long> gids; if (byAddress.TryGetValue(d.BaseAddress, out gids)) { gids.Add(d.GID); } else { byAddress[d.BaseAddress] = new List <long>(1) { d.GID }; } if (d.Direction == SignalDirection.Write) { continue; } ushort address = GetAddress(d.BaseAddress); inputAddresses.Add(address); } List <IModbusFunction> acquisitionFunctions = new List <IModbusFunction>(); if (inputAddresses.Count <= 0) { return; } inputAddresses.Sort(); int runStart = inputAddresses[0]; int runCount = 0; for (int i = 0; i < inputAddresses.Count; ++i) { int address = inputAddresses[i]; if (runCount < 124 && address == runStart + runCount) { runCount += 2; } else if (runCount > 0) { acquisitionFunctions.Add(new ReadInputRegistersFunction(new ModbusReadCommandParameters(6, (byte)EModbusFunctionCode.READ_INPUT_REGISTERS, (ushort)runStart, (ushort)runCount, 0, 1))); runCount = 2; runStart = address; } } if (runCount > 0) { acquisitionFunctions.Add(new ReadInputRegistersFunction(new ModbusReadCommandParameters(6, (byte)EModbusFunctionCode.READ_INPUT_REGISTERS, (ushort)runStart, (ushort)runCount, 0, 1))); } modelLock.EnterWriteLock(); { this.model = model; this.acquisitionFunctions = acquisitionFunctions; this.byAddress = byAddress; } modelLock.ExitWriteLock(); List <KeyValuePair <long, float> > analogInputs = new List <KeyValuePair <long, float> >(); List <KeyValuePair <long, float> > analogOutputs = new List <KeyValuePair <long, float> >(); List <KeyValuePair <long, int> > discreteInputs = new List <KeyValuePair <long, int> >(); List <KeyValuePair <long, int> > discreteOutputs = new List <KeyValuePair <long, int> >(); foreach (KeyValuePair <int, List <long> > addressEntry in byAddress) { ushort address = GetAddress(addressEntry.Key); ushort high, low; float analogIn; int discreteIn; float analogOut; int discreteOut; inputRegisters.TryGetValue(address, out high); inputRegisters.TryGetValue((ushort)(address + 1), out low); GetValues(high, low, out analogIn, out discreteIn); holdingRegisters.TryGetValue(address, out high); holdingRegisters.TryGetValue((ushort)(address + 1), out low); GetValues(high, low, out analogOut, out discreteOut); for (int i = 0; i < addressEntry.Value.Count; ++i) { long gid = addressEntry.Value[i]; switch (ModelCodeHelper.GetTypeFromGID(gid)) { case DMSType.Analog: Analog a = model.GetAnalog(gid); if (a == null) { continue; } switch (a.Direction) { case SignalDirection.Read: analogInputs.Add(new KeyValuePair <long, float>(gid, analogIn)); break; case SignalDirection.Write: analogOutputs.Add(new KeyValuePair <long, float>(gid, analogOut)); break; case SignalDirection.ReadWrite: analogInputs.Add(new KeyValuePair <long, float>(gid, analogIn)); analogOutputs.Add(new KeyValuePair <long, float>(gid, analogOut)); break; default: continue; } break; case DMSType.Discrete: Discrete d = model.GetDiscrete(gid); if (d == null) { continue; } switch (d.Direction) { case SignalDirection.Read: discreteInputs.Add(new KeyValuePair <long, int>(gid, discreteIn)); break; case SignalDirection.Write: discreteOutputs.Add(new KeyValuePair <long, int>(gid, discreteOut)); break; case SignalDirection.ReadWrite: discreteInputs.Add(new KeyValuePair <long, int>(gid, discreteIn)); discreteOutputs.Add(new KeyValuePair <long, int>(gid, discreteOut)); break; default: continue; } break; default: continue; } } } PublishMeasurementValues(analogInputs, analogOutputs, discreteInputs, discreteOutputs); }