CommandStatus ICommandHandler.Operate(ControlRelayOutputBlock command, ushort index, OperateType opType) { lock (mutex) { return(GetOrElseAndLogBinary(command, index, binaryMap, () => proxy.Operate(command, index, opType))); } }
CommandStatus ICommandHandler.Select(ControlRelayOutputBlock command, ushort index) { lock (mutex) { return(GetOrElse(index, binaryMap, () => proxy.Select(command, index))); } }
CommandStatus OnControl(ControlRelayOutputBlock command, ushort index, bool execute) { if (index == 0) { switch (command.code) { case (ControlCode.LATCH_ON): if (execute) { this.QueueOperation(true); } return(CommandStatus.SUCCESS); case (ControlCode.LATCH_OFF): if (execute) { this.QueueOperation(false); } return(CommandStatus.SUCCESS); default: return(CommandStatus.NOT_SUPPORTED); } } else { return(CommandStatus.NOT_SUPPORTED); } }
void handler_BinaryCommandAccepted(ControlRelayOutputBlock crob, ushort index) { if (this.InvokeRequired) { this.BeginInvoke(new Action(() => handler_BinaryCommandAccepted(crob, index))); } else { var output = String.Format("Accepted CROB: {0} - {1}", crob.code, index); this.listBoxLog.Items.Add(output); if (checkBoxMapBinary.Checked) { switch (crob.code) { case (ControlCode.LATCH_ON): this.LoadSingleBinaryOutputStatus(true, index); break; case (ControlCode.LATCH_OFF): this.LoadSingleBinaryOutputStatus(false, index); break; } } } }
void handler_BinaryCommandAccepted(ControlRelayOutputBlock crob, ushort index) { if (this.InvokeRequired) { this.BeginInvoke(new Action(() => handler_BinaryCommandAccepted(crob, index))); } else { var output = String.Format("Accepted CROB: {0} - {1}", crob.code, index); this.listBoxLog.Items.Add(output); if (checkBoxMapBinary.Checked) { var timestamp = DateTime.Now; switch (crob.code) { case (ControlCode.LATCH_ON): this.LoadSingleBinaryOutputStatus(true, index, timestamp); break; case (ControlCode.LATCH_OFF): this.LoadSingleBinaryOutputStatus(false, index, timestamp); break; case (ControlCode.CLOSE_PULSE_ON): this.LoadSingleBinaryOutputStatus(true, index, timestamp); if (crob.onTime > 0) { this.LoadSingleBinaryOutputStatus(false, index, timestamp.AddMilliseconds(crob.onTime)); } break; case (ControlCode.TRIP_PULSE_ON): this.LoadSingleBinaryOutputStatus(false, index, timestamp); if (crob.onTime > 0) { this.LoadSingleBinaryOutputStatus(true, index, timestamp.AddMilliseconds(crob.onTime)); } break; case (ControlCode.PULSE_ON): if (crob.onTime > 0) { this.LoadSingleBinaryOutputStatus(true, index, timestamp); this.LoadSingleBinaryOutputStatus(false, index, timestamp.AddMilliseconds(crob.onTime)); } break; case (ControlCode.PULSE_OFF): if (crob.offTime > 0) { this.LoadSingleBinaryOutputStatus(false, index, timestamp); this.LoadSingleBinaryOutputStatus(true, index, timestamp.AddMilliseconds(crob.offTime)); } break; } } } }
CommandStatus GetOrElseAndLogBinary(ControlRelayOutputBlock command, ushort index, IDictionary <UInt16, CommandStatus> dictionary, Func <CommandStatus> action) { var result = GetOrElse(index, dictionary, action); if (result == CommandStatus.SUCCESS && BinaryCommandAccepted != null) { BinaryCommandAccepted(command, index); } return(result); }
// demonstrates how to build a set of command headers for a complex command request static ICommandHeaders GetCommandHeaders() { var crob = new ControlRelayOutputBlock(ControlCode.PULSE_ON, 1, 100, 100); var ao = new AnalogOutputDouble64(1.37); return(CommandSet.From( CommandHeader.From(IndexedValue.From(crob, 0)), CommandHeader.From(IndexedValue.From(ao, 1)) )); }
public static ControlRelayOutputBlock GetCROB(this Command unatt_command) { if (unatt_command.DigitalControl.HasValue) { ControlRelayOutputBlock crob = new ControlRelayOutputBlock(unatt_command.DigitalControl.Value, Convert.ToByte(unatt_command.DigitalCount), Convert.ToUInt16(unatt_command.DigitalOnTime), Convert.ToUInt16(unatt_command.DigitalOffTime)); return crob; } else { throw new ArgumentException("Invalid argument: Point.Type must be DIGITAL_CONTROL and DigitalValue must be != null"); } }
public static void OperateDevice(string mrid, string operation, ushort point_index) { CIMData.SCADAInfo dv = findDevice(mrid); if (dv == null) { Console.WriteLine("Error - device: " + mrid + " is not in the list of devices. Be sure to start polling before controls are issued!"); } else if (dv.Connected != true) { Console.WriteLine("Error - cannot operate device until while it is not connected"); } else { var crob = new ControlRelayOutputBlock(DetermineOperationCode(operation), 1, 100, 100); var single = dv.Master.SelectAndOperate(crob, point_index, TaskConfig.Default); single.ContinueWith((result) => Console.WriteLine("Result: " + result.Result)); } }
CommandStatus ICommandHandler.Operate(ControlRelayOutputBlock command, uint index) { return status(); }
CommandStatus ICommandHandler.Select(ControlRelayOutputBlock command, ushort index) { return OnControl(command, index, false); }
// This process watches (via change stream) for commands inserted to a commands collection // When the command is considered valid it is forwarded to the RTU static async void ProcessMongoCmd(JSONSCADAConfig jsConfig) { do { try { var Client = ConnectMongoClient(jsConfig); var DB = Client.GetDatabase(jsConfig.mongoDatabaseName); var collection = DB .GetCollection <rtCommand>(CommandsQueueCollectionName); bool isMongoLive = DB .RunCommandAsync((Command <BsonDocument>) "{ping:1}") .Wait(1000); if (!isMongoLive) { throw new Exception("Error on connection " + jsConfig.mongoConnectionString); } Log("MongoDB CMD CS - Start listening for commands via changestream..."); var filter = "{ operationType: 'insert' }"; var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <rtCommand > >().Match(filter); using (var cursor = await collection.WatchAsync(pipeline)) { await cursor .ForEachAsync(async change => { if (!Active) { return; } // process change event, only process inserts if ( change.OperationType == ChangeStreamOperationType.Insert ) { // consider only commands for this driver { Log("MongoDB CMD CS - Looking for connection " + change .FullDocument .protocolSourceConnectionNumber + "..."); var found = false; foreach (DNP3_connection srv in DNP3conns ) { if ( srv.protocolConnectionNumber == change .FullDocument .protocolSourceConnectionNumber ) { found = true; var cs = srv.channel.GetChannelStatistics(); if ( srv.isConnected && srv.commandsEnabled ) { var group = change.FullDocument.protocolSourceCommonAddress; var variation = change.FullDocument.protocolSourceASDU; if (group == 41 || group == 12) { if ( // check for command expired DateTime .Now .ToLocalTime() .Subtract(change .FullDocument .timeTag .ToLocalTime( )) .Seconds < 10 ) { // can execute System.Threading.Tasks.Task <CommandTaskResult> cmdTask = null; if (group == 12) { OperationType ot = OperationType.NUL; TripCloseCode tc = TripCloseCode.NUL; switch (System.Convert.ToUInt16(change.FullDocument.protocolSourceCommandDuration)) { default: case 0: ot = OperationType.NUL; break; case 1: if (change.FullDocument.value != 0) { ot = OperationType.PULSE_ON; } else { ot = OperationType.PULSE_OFF; } break; case 2: if (change.FullDocument.value != 0) { ot = OperationType.PULSE_OFF; } else { ot = OperationType.PULSE_ON; } break; case 3: if (change.FullDocument.value != 0) { ot = OperationType.LATCH_ON; } else { ot = OperationType.LATCH_OFF; } break; case 4: if (change.FullDocument.value != 0) { ot = OperationType.LATCH_OFF; } else { ot = OperationType.LATCH_ON; } break; case 11: if (change.FullDocument.value != 0) { ot = OperationType.PULSE_ON; tc = TripCloseCode.CLOSE; } else { ot = OperationType.PULSE_OFF; tc = TripCloseCode.TRIP; } break; case 13: if (change.FullDocument.value != 0) { ot = OperationType.LATCH_ON; tc = TripCloseCode.CLOSE; } else { ot = OperationType.LATCH_OFF; tc = TripCloseCode.TRIP; } break; case 21: if (change.FullDocument.value != 0) { ot = OperationType.PULSE_ON; tc = TripCloseCode.TRIP; } else { ot = OperationType.PULSE_OFF; tc = TripCloseCode.CLOSE; } break; case 23: if (change.FullDocument.value != 0) { ot = OperationType.LATCH_ON; tc = TripCloseCode.TRIP; } else { ot = OperationType.LATCH_OFF; tc = TripCloseCode.CLOSE; } break; } ControlRelayOutputBlock crob = new ControlRelayOutputBlock(ot, tc, false, 1, 0, 0); if (System.Convert.ToBoolean(change.FullDocument.protocolSourceCommandUseSBO)) { cmdTask = srv.master.SelectAndOperate( crob, System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } else { cmdTask = srv.master.DirectOperate( crob, System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } } else if (group == 41 && variation == 1) { if (System.Convert.ToBoolean(change.FullDocument.protocolSourceCommandUseSBO)) { cmdTask = srv.master.SelectAndOperate( new AnalogOutputInt32(System.Convert.ToInt32(change.FullDocument.value)), System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } else { cmdTask = srv.master.DirectOperate( new AnalogOutputInt32(System.Convert.ToInt32(change.FullDocument.value)), System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } } else if (group == 41 && variation == 2) { if (System.Convert.ToBoolean(change.FullDocument.protocolSourceCommandUseSBO)) { cmdTask = srv.master.SelectAndOperate( new AnalogOutputInt16(System.Convert.ToInt16(change.FullDocument.value)), System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } else { cmdTask = srv.master.DirectOperate( new AnalogOutputInt16(System.Convert.ToInt16(change.FullDocument.value)), System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } } else if (group == 41 && variation == 3) { if (System.Convert.ToBoolean(change.FullDocument.protocolSourceCommandUseSBO)) { cmdTask = srv.master.SelectAndOperate( new AnalogOutputFloat32(System.Convert.ToSingle(change.FullDocument.value)), System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } else { cmdTask = srv.master.DirectOperate( new AnalogOutputFloat32(System.Convert.ToSingle(change.FullDocument.value)), System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } } else if (group == 41 && variation == 4) { if (System.Convert.ToBoolean(change.FullDocument.protocolSourceCommandUseSBO)) { cmdTask = srv.master.SelectAndOperate( new AnalogOutputDouble64(System.Convert.ToDouble(change.FullDocument.value)), System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } else { cmdTask = srv.master.DirectOperate( new AnalogOutputDouble64(System.Convert.ToDouble(change.FullDocument.value)), System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } } else if (group == 41) // group 41, other variations defaults to float32 { if (System.Convert.ToBoolean(change.FullDocument.protocolSourceCommandUseSBO)) { cmdTask = srv.master.SelectAndOperate( new AnalogOutputFloat32(System.Convert.ToSingle(change.FullDocument.value)), System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } else { cmdTask = srv.master.DirectOperate( new AnalogOutputFloat32(System.Convert.ToSingle(change.FullDocument.value)), System.Convert.ToUInt16(change.FullDocument.protocolSourceObjectAddress), TaskConfig.Default); } } if (cmdTask != null) { _ = cmdTask.ContinueWith((result) => { Console.WriteLine("Result: " + result.Result); Log("MongoDB CMD CS - " + srv.name + " - Command " + " TAG:" + change.FullDocument.tag + " GRP:" + change.FullDocument.protocolSourceCommonAddress + " VAR:" + change.FullDocument.protocolSourceASDU + " OBJ:" + change.FullDocument.protocolSourceObjectAddress + " Value:" + change.FullDocument.value + " Delivered"); // update as delivered var filter = new BsonDocument(new BsonDocument("_id", change.FullDocument.id)); var update = new BsonDocument("$set", new BsonDocument { { "delivered", true }, { "ack", result.Result.Results.FirstOrDefault().PointState == CommandPointState.SUCCESS && result.Result.Results.FirstOrDefault().Status == CommandStatus.SUCCESS }, { "ackTimeTag", BsonValue.Create(DateTime.Now) }, { "resultDescription", result.Result.ToString() } }); var res = collection .UpdateOneAsync(filter, update); }); } else { Console.WriteLine("Command Error"); } } else { // update as expired Log("MongoDB CMD CS - " + srv.name + " - Command " + " TAG:" + change.FullDocument.tag + " GRP:" + change.FullDocument.protocolSourceCommonAddress + " VAR:" + change.FullDocument.protocolSourceASDU + " OBJ:" + change.FullDocument.protocolSourceObjectAddress + " Value:" + change.FullDocument.value + " Expired"); var filter = new BsonDocument(new BsonDocument("_id", change .FullDocument .id)); var update = new BsonDocument("$set", new BsonDocument("cancelReason", "expired")); var result = await collection .UpdateOneAsync(filter, update); } } else { // update as canceled (asdu not implemented) Log("MongoDB CMD CS - " + srv.name + " - Command " + " TAG:" + change.FullDocument.tag + " GRP:" + change.FullDocument.protocolSourceCommonAddress + " VAR:" + change.FullDocument.protocolSourceASDU + " OBJ:" + change.FullDocument.protocolSourceObjectAddress + " Value:" + change.FullDocument.value + " ASDU Not Implemented"); var filter = new BsonDocument(new BsonDocument("_id", change .FullDocument .id)); var update = new BsonDocument("$set", new BsonDocument("cancelReason", "asdu not implemented")); var result = await collection .UpdateOneAsync(filter, update); } } else { // update as canceled (not connected) Log("MongoDB CMD CS - " + srv.name + " - Command " + " TAG:" + change.FullDocument.tag + " GRP:" + change.FullDocument.protocolSourceCommonAddress + " VAR:" + change.FullDocument.protocolSourceASDU + " OBJ:" + change.FullDocument.protocolSourceObjectAddress + " Value:" + change.FullDocument.value + change.FullDocument.value + ( srv.commandsEnabled ? " Not Connected" : " Commands Disabled" )); var filter = new BsonDocument(new BsonDocument("_id", change .FullDocument .id)); var update = new BsonDocument("$set", new BsonDocument("cancelReason", ( srv .commandsEnabled ? "not connected" : "commands disabled" ))); var result = await collection .UpdateOneAsync(filter, update); } break; } } if (!found) { // update as canceled command (not found) Log("MongoDB CMD CS - " + change .FullDocument .protocolSourceConnectionNumber .ToString() + " - Command " + " TAG:" + change.FullDocument.tag + " GRP:" + change.FullDocument.protocolSourceCommonAddress + " VAR:" + change.FullDocument.protocolSourceASDU + " OBJ:" + change.FullDocument.protocolSourceObjectAddress + " Value:" + change.FullDocument.value + " Not Found"); var filter = new BsonDocument(new BsonDocument("_id", change .FullDocument .id)); var update = new BsonDocument("$set", new BsonDocument("cancelReason", "connection not found")); var result = await collection .UpdateOneAsync(filter, update); } } } }); } } catch (Exception e) { Log("Exception MongoCmd"); Log(e); Log(e .ToString() .Substring(0, e.ToString().IndexOf(Environment.NewLine))); System.Threading.Thread.Sleep(3000); } }while (true); }
void handler_BinaryCommandAccepted(ControlRelayOutputBlock crob, ushort index) { if (this.InvokeRequired) { this.BeginInvoke(new Action(() => handler_BinaryCommandAccepted(crob, index))); } else { var output = String.Format("Accepted CROB: {0} - {1}", crob.code, index); this.listBoxLog.Items.Add(output); if (checkBoxMapBinary.Checked) { var timestamp = DateTime.Now; switch (crob.code) { case (ControlCode.LATCH_ON): this.LoadSingleBinaryOutputStatus(true, index, timestamp); break; case (ControlCode.LATCH_OFF): this.LoadSingleBinaryOutputStatus(false, index, timestamp); break; case (ControlCode.CLOSE_PULSE_ON): this.LoadSingleBinaryOutputStatus(true, index, timestamp); if (crob.onTime > 0) this.LoadSingleBinaryOutputStatus(false, index, timestamp.AddMilliseconds(crob.onTime)); break; case (ControlCode.TRIP_PULSE_ON): this.LoadSingleBinaryOutputStatus(false, index, timestamp); if (crob.onTime > 0) this.LoadSingleBinaryOutputStatus(true, index, timestamp.AddMilliseconds(crob.onTime)); break; case (ControlCode.PULSE_ON): if (crob.onTime > 0) { this.LoadSingleBinaryOutputStatus(true, index, timestamp); this.LoadSingleBinaryOutputStatus(false, index, timestamp.AddMilliseconds(crob.onTime)); } break; case (ControlCode.PULSE_OFF): if (crob.offTime > 0) { this.LoadSingleBinaryOutputStatus(false, index, timestamp); this.LoadSingleBinaryOutputStatus(true, index, timestamp.AddMilliseconds(crob.offTime)); } break; } } } }
CommandStatus ICommandHandler.Select(ControlRelayOutputBlock command, ushort index) { return(OnControl(command, index, false)); }
CommandStatus ICommandHandler.Operate(ControlRelayOutputBlock command, ushort index) { return(OnControl(command, index, true)); }
CommandStatus ICommandHandler.Operate(ControlRelayOutputBlock command, ushort index, OperateType opType) { lock (mutex) { return GetOrElseAndLogBinary(command, index, binaryMap, () => proxy.Operate(command, index, opType)); } }
static int Main(string[] args) { IDNP3Manager mgr = DNP3ManagerFactory.CreateManager(); mgr.AddLogHandler(PrintingLogAdapter.Instance); //this is optional var channel = mgr.AddTCPClient("client", LogLevels.NORMAL, TimeSpan.FromSeconds(5), TimeSpan.FromMinutes(2), "127.0.0.1", 20000); //optionally, add a listener for the channel state channel.AddStateListener(state => Console.WriteLine("channel state: " + state)); var config = new MasterStackConfig(); //setup your stack configuration here. config.link.localAddr = 1; config.link.remoteAddr = 10; var master = channel.AddMaster("master", PrintingSOEHandler.Instance, DefaultMasterApplication.Instance, config); // you a can optionally add various kinds of polls var integrityPoll = master.AddClassScan(ClassField.AllClasses, TimeSpan.FromMinutes(1)); var rangePoll = master.AddRangeScan(30, 2, 5, 7, TimeSpan.FromSeconds(20)); var classPoll = master.AddClassScan(ClassField.AllEventClasses, TimeSpan.FromSeconds(5)); // you a can optionally add state callbacks for monitoring these polls integrityPoll.AddScanCallback((PollState state) => Console.WriteLine("integrity poll state change: " + state)); classPoll.AddScanCallback((PollState state) => Console.WriteLine("class poll state change: " + state)); rangePoll.AddScanCallback((PollState state) => Console.WriteLine("range poll state change: " + state)); master.Enable(); // enable communications Console.WriteLine("Enter an index to send a command"); while (true) { switch (Console.ReadLine()) { case "c": var crob = new ControlRelayOutputBlock(ControlCode.PULSE, 1, 100, 100); var future = master.GetCommandProcessor().SelectAndOperate(crob, 0); future.Listen((result) => Console.WriteLine("Result: " + result)); break; case "l": // add interpretation to the current logging level var filters = channel.GetLogFilters(); channel.SetLogFilters(filters.Add(LogFilters.TRANSPORT_TX | LogFilters.TRANSPORT_RX)); break; case "i": integrityPoll.Demand(); break; case "r": rangePoll.Demand(); break; case "e": classPoll.Demand(); break; case "x": return(0); default: break; } } }
CommandStatus ICommandHandler.Operate(ControlRelayOutputBlock command, ushort index, OperateType opType) { return OnControl(command, index, true); }
static int Main(string[] args) { IDNP3Manager mgr = DNP3ManagerFactory.CreateManager(1, PrintingLogAdapter.Instance); var channel = mgr.AddTCPClient("client", LogLevels.ALL, ChannelRetry.Default, "127.0.0.1", 20000); //optionally, add a listener for the channel state channel.AddStateListener(state => Console.WriteLine("channel state: " + state)); var config = new MasterStackConfig(); //setup your stack configuration here. config.link.localAddr = 1; config.link.remoteAddr = 10; var key = new byte[16]; for (int i = 0; i < key.Length; ++i) { key[i] = 0xFF; } var master = channel.AddMaster("master", PrintingSOEHandler.Instance, DefaultMasterApplication.Instance, config); // you a can optionally add various kinds of polls var integrityPoll = master.AddClassScan(ClassField.AllClasses, TimeSpan.FromMinutes(1), TaskConfig.Default); var rangePoll = master.AddRangeScan(30, 2, 5, 7, TimeSpan.FromSeconds(20), TaskConfig.Default); var classPoll = master.AddClassScan(ClassField.AllEventClasses, TimeSpan.FromSeconds(5), TaskConfig.Default); /* you can also do very custom scans * var headers = new Header[] { Header.Range8(1, 2, 7, 8), Header.Count8(2, 3, 7) }; * var weirdPoll = master.AddScan(headers, TimeSpan.FromSeconds(20)); */ master.Enable(); // enable communications Console.WriteLine("Enter a command"); while (true) { switch (Console.ReadLine()) { case "a": // perform an ad-hoc scan of all analogs master.ScanAllObjects(30, 0, TaskConfig.Default); break; case "c": var task = master.SelectAndOperate(GetCommandHeaders(), TaskConfig.Default); task.ContinueWith((result) => Console.WriteLine("Result: " + result.Result)); break; case "o": var crob = new ControlRelayOutputBlock(ControlCode.PULSE_ON, 1, 100, 100); var single = master.SelectAndOperate(crob, 1, TaskConfig.Default); single.ContinueWith((result) => Console.WriteLine("Result: " + result.Result)); break; case "l": // add interpretation to the current logging level var filters = channel.GetLogFilters(); channel.SetLogFilters(filters.Add(LogFilters.TRANSPORT_TX | LogFilters.TRANSPORT_RX)); break; case "i": integrityPoll.Demand(); break; case "r": rangePoll.Demand(); break; case "e": classPoll.Demand(); break; case "x": return(0); default: break; } } }
CommandStatus ICommandHandler.Select(ControlRelayOutputBlock command, ushort index) { lock (mutex) { return GetOrElse(index, binaryMap, () => proxy.Select(command, index)); } }
CommandStatus GetOrElseAndLogBinary(ControlRelayOutputBlock command, ushort index, IDictionary<UInt16, CommandStatus> dictionary, Func<CommandStatus> action) { var result = GetOrElse(index, dictionary, action); if (result == CommandStatus.SUCCESS && BinaryCommandAccepted != null) { BinaryCommandAccepted(command, index); } return result; }
static int Main(string[] args) { var application = new MasterApplicatonSA(); IDNP3Manager mgr = DNP3ManagerFactory.CreateManager(); Console.WriteLine(String.Format("Crypto: {0}", mgr.SSLVersion())); mgr.AddLogHandler(PrintingLogAdapter.Instance); //this is optional var channel = mgr.AddTCPClient("client", LogLevels.NORMAL, ChannelRetry.Default, "127.0.0.1", 20000); //optionally, add a listener for the channel state channel.AddStateListener(state => Console.WriteLine("channel state: " + state)); var config = new MasterStackConfig(); //setup your stack configuration here. config.link.localAddr = 1; config.link.remoteAddr = 10; var master = channel.AddMasterSA("master", PrintingSOEHandler.Instance, application, config); // define users on the master master.AddUser(User.Default, UpdateKey.Demo(0xFF, KeyWrapAlgorithm.AES_128)); // you a can optionally add various kinds of polls var integrityPoll = master.AddClassScan(ClassField.AllClasses, TimeSpan.FromMinutes(1), TaskConfig.Default); var rangePoll = master.AddRangeScan(30, 2, 5, 7, TimeSpan.FromSeconds(20), TaskConfig.Default); var classPoll = master.AddClassScan(ClassField.AllEventClasses, TimeSpan.FromSeconds(5), TaskConfig.Default); /* you can also do very custom scans * var headers = new Header[] { Header.Range8(1, 2, 7, 8), Header.Count8(2, 3, 7) }; * var weirdPoll = master.AddScan(headers, TimeSpan.FromSeconds(20)); */ master.Enable(); // enable communications Console.WriteLine("Enter a command"); while (true) { switch (Console.ReadLine()) { case "a": // perform an ad-hoc scan of all analogs master.ScanAllObjects(30, 0, TaskConfig.Default); break; case "c": var crob = new ControlRelayOutputBlock(ControlCode.PULSE_ON, 1, 100, 100); var commands = CommandHeader.From(IndexedValue.From(crob, 0)); var task = master.SelectAndOperate(commands, TaskConfig.With(User.Default)); task.ContinueWith((result) => Console.WriteLine("Result: " + result.Result)); break; case "l": // add interpretation to the current logging level var filters = channel.GetLogFilters(); channel.SetLogFilters(filters.Add(LogFilters.TRANSPORT_TX | LogFilters.TRANSPORT_RX)); break; case "i": integrityPoll.Demand(); break; case "r": rangePoll.Demand(); break; case "e": classPoll.Demand(); break; case "x": return(0); default: break; } } }
public static void OperateDevice(string mrid, string operation, ushort point_index) { CIMData.SCADAInfo dv = findDevice(mrid); string tmps = "UNKNOWN"; if (dv == null) { tmps = "Error - device: " + mrid + " is not in the list of devices. Be sure to start polling before controls are issued!"; Console.WriteLine(tmps); return; } else if (dv.Connected != true) { tmps = "Error - cannot operate device until while it is not connected"; Console.WriteLine(tmps); return; } else { var crob = new ControlRelayOutputBlock(DetermineOperationCode(operation), 1, 100, 100); var res = dv.Master.SelectAndOperate(crob, point_index, TaskConfig.Default); res.ContinueWith((result) => { Console.WriteLine("Result: " + result.Result); }); } }
CommandStatus OnControl(ControlRelayOutputBlock command, ushort index, bool execute) { if (index == 0) { switch (command.code) { case (ControlCode.LATCH_ON): if(execute) this.QueueOperation(true); return CommandStatus.SUCCESS; case (ControlCode.LATCH_OFF): if (execute) this.QueueOperation(false); return CommandStatus.SUCCESS; default: return CommandStatus.NOT_SUPPORTED; } } else { return CommandStatus.NOT_SUPPORTED; } }