static void Main(string[] args) { /* * See the configuration example for how a typical application * might obtain a configuration. */ var configuration = ExampleConfiguration.Obtain(args); /* * Create the TagManager for communicating with the server and the * tag writer for sending tag values to the server. */ using (var manager = new TagManager(configuration)) using (var writer = manager.CreateWriter(bufferSize: 10)) { /* * Initially create two tags and write values to them. Using * Update enables creating both tags in a single API call. */ var doubleTag = new TagData("example.selection.double", DataType.Double); var intTag = new TagData("example.selection.int", DataType.Int32); // Currently, SystemLink Server does not return tag values in // selections for tags that do not collect aggregates. doubleTag.CollectAggregates = intTag.CollectAggregates = true; Console.WriteLine("Creating example tags..."); manager.Update(new[] { doubleTag, intTag }); var doubleWriter = new DoubleTagValueWriter(writer, doubleTag); var intWriter = new Int32TagValueWriter(writer, intTag); doubleWriter.Write(Math.PI); intWriter.Write((int)Math.PI); writer.SendBufferedWrites(); /* * Create a selection containing all tags whose paths begin * with our example prefix. */ Console.WriteLine("Creating selection..."); using (var selection = manager.Open(new[] { "example.selection.*" })) { /* * Read each tag value. Since we're using a selection, this * only results in a single request to the server. */ var doubleReader = selection.Values[doubleTag.Path] as DoubleTagValueReader; var intReader = selection.Values[intTag.Path] as Int32TagValueReader; Console.WriteLine("Double tag value: {0}", doubleReader?.Read()); Console.WriteLine("Int tag value: {0}", intReader?.Read()); /* * Create two more example tags and edit the metadata for * the original example tags in a single API call. */ var boolTag = new TagData("example.selection.bool", DataType.Bool, keywords: new[] { "new" }, properties: null); var stringTag = new TagData("example.selection.string", DataType.String, keywords: new[] { "new" }, properties: null); // Currently, SystemLink Server does not return tag values in // selections for tags that do not collect aggregates. boolTag.CollectAggregates = stringTag.CollectAggregates = true; Console.WriteLine("Creating additional tags..."); manager.Update(new[] { new TagDataUpdate(boolTag, TagUpdateFields.All), new TagDataUpdate(stringTag, TagUpdateFields.All), new TagDataUpdate(doubleTag.Path, DataType.Double, keywords: new[] { "edited" }, properties: null), new TagDataUpdate(intTag.Path, DataType.Int32, keywords: new[] { "edited" }, properties: null) }); var boolWriter = new BoolTagValueWriter(writer, boolTag); var stringWriter = new StringTagValueWriter(writer, stringTag); doubleWriter.Write(Math.E); intWriter.Write((int)Math.E); boolWriter.Write(true); stringWriter.Write("example"); writer.SendBufferedWrites(); /* * Selections don't automatically update with changes made * on the server. Iterating over all tags in the selection * will only see the first two tags in their original state. */ OutputSelection(selection); /* * Refreshing the selection will update with changes made * on the server. We have the option to refresh only the * metadata, only the values, or both metadata and values. * Refreshing the values will detect new tags on the server * but will not retrieve keywords and properties. */ Console.WriteLine("Refreshing selection values..."); selection.RefreshValues(); OutputSelection(selection); /* * A metadata refresh will get keywords and properties. */ Console.WriteLine("Refreshing selection metadata..."); selection.RefreshMetadata(); OutputSelection(selection); /* * Selections also enable deleting multiple tags from the * server in a single request. */ Console.WriteLine("Deleting example tags..."); selection.DeleteTagsFromServer(); } } }
static void Main(string[] args) { /* * See the configuration example for how a typical application * might obtain a configuration. */ var configuration = ExampleConfiguration.Obtain(args); /* * Create the TagManager for communicating with the server and the * tag writer for sending tag values to the server. */ using (var manager = new TagManager(configuration)) using (var writer = manager.CreateWriter(NumTags * 2)) { /* * Create two tags. Make one a double and the other an int. * Using Update enables creating both tags in a single API call. */ var doubleTag = new TagData("example.subscription.double", DataType.Double); var intTag = new TagData("example.subscription.int", DataType.Int32); Console.WriteLine("Creating example tags..."); manager.Update(new[] { doubleTag, intTag }); var doubleWriter = new DoubleTagValueWriter(writer, doubleTag); var intWriter = new Int32TagValueWriter(writer, intTag); using (var selection = manager.CreateSelection(doubleTag, intTag)) { try { /* * Subscribe to receive events when the current values * of the tags change. */ Console.WriteLine("Subscribing to tag value changes..."); using (var subscription = selection.CreateSubscription()) using (var handler = new TagChangedHandler(subscription)) { /* * Write to each tag and send them to the server. */ Console.WriteLine("Writing tag values (1/2)..."); doubleWriter.Write(Math.PI); intWriter.Write((int)Math.PI); writer.SendBufferedWrites(); /* * Wait for our subscription to receive each value. * There may be a delay between the value changing * on the server and the event firing. */ if (!handler.WaitForNotifications(NumTags, TimeSpan.FromSeconds(10))) { Console.WriteLine("Did not receive all tag writes"); return; } /* * Subscriptions only receive the latest value when * multiple writes to the same tag occur in a short * period of time. */ Console.WriteLine("Writing tag values (2/2)..."); doubleWriter.Write(Math.E); doubleWriter.Write(12.123); intWriter.Write((int)Math.E); intWriter.Write(12); // Writes are sent automatically due to buffer size. if (!handler.WaitForNotifications(NumTags * 2, TimeSpan.FromSeconds(10))) { Console.WriteLine("Did not receive all tag writes"); return; } /* * Disposing of the subscription will unsubscribe. */ Console.WriteLine("Unsubscribing..."); } } finally { Console.WriteLine("Deleting example tags..."); selection.DeleteTagsFromServer(); } } } }