static void Main(string[] args) { Console.WriteLine("Creating a .NET Qi Client..."); string server = ConfigurationManager.AppSettings["QiServerUrl"]; // set up a client to the Qi Service -- it is essential that you set the QiTenant header QiHttpClientFactory<IQiServer> clientFactory = new QiHttpClientFactory<IQiServer>(); clientFactory.ProxyTimeout = new TimeSpan(0, 1, 0); clientFactory.OnCreated((p) => p.DefaultHeaders.Add("QiTenant", "sampletenant")); IQiServer qiclient = clientFactory.CreateChannel(new Uri(server)); try { // TODO -- remove tenant creation when provisioning is accomplished Console.WriteLine("Creating a tenant named sampletenant"); QiTenant tenant = new QiTenant("sampletenant"); // submit to PI Cloud Historian to create the tenant in storage qiclient.GetOrCreateTenant(tenant); // Create a Qi Type -- the Qi Libraries let you do this via reflection // First, create a type builder, then pass it the name of the class you are using for events. // This greatly simplifies type creation QiTypeBuilder typeBuilder = new QiTypeBuilder(); QiType evtType = typeBuilder.Create<SimpleEvent>(); evtType.Name = "SimpleEvent"; evtType.Id = "SimpleEvent"; QiType tp = qiclient.GetOrCreateType(evtType); Console.WriteLine("Creating a stream in this tenant for simple event measurements"); QiStream sampleStream = new QiStream(); sampleStream.Name = "evtStream"; sampleStream.Id = "evtStream"; // set the TypeId property to the value of the Id property of the type you submitted // All events submitted to this stream must be of this type // Note there are Async versions of the client methods, too, using .NET TPL sampleStream.TypeId = "SimpleEvent"; sampleStream.Description = "This is a sample stream for storing SimpleEvent type measurements"; QiStream strm = qiclient.GetOrCreateStream(sampleStream); #region CRUD Operations #region Create Events (Insert) Console.WriteLine("Artificially generating 100 events at one second intervals and inserting them into the Qi Service"); Random rnd = new Random(); // How to insert a single event SimpleEvent evt = new SimpleEvent(rnd.NextDouble() * 100, "deg C"); // for our contrived purposes, let's manually set the timestamp to 100 seconds in the past DateTime start = DateTime.UtcNow.AddSeconds(-100.0); evt.Timestamp = start; qiclient.InsertValue("evtStream", evt); List<SimpleEvent> events = new List<SimpleEvent>(); // how to insert an a collection of events for (int i = 1; i < 100; i++) { evt = new SimpleEvent(rnd.NextDouble() * 100, "deg C"); evt.Timestamp = start.AddSeconds((double)i); events.Add(evt); } qiclient.InsertValues<SimpleEvent>("evtStream", events); Thread.Sleep(2000); #endregion #region Retrieve events for a time range // use the round trip formatting for time Console.WriteLine("Retrieving the inserted events"); Console.WriteLine("=============================="); IEnumerable<SimpleEvent> foundEvts = qiclient.GetWindowValues<SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o")); DumpEvents(foundEvts); #endregion #region Update an event Console.WriteLine(); Console.WriteLine("Updating values"); // take the first value inserted and update the value and UOM evt = foundEvts.First<SimpleEvent>(); evt.Units = "deg F"; evt.Value = 212.0; qiclient.UpdateValue<SimpleEvent>("evtStream", evt); // update the collection of events (convert to deg F) foreach (SimpleEvent evnt in events) { evnt.Units = "deg F"; evnt.Value = evnt.Value * 9 / 5 + 32.0; } qiclient.UpdateValues<SimpleEvent>("evtStream", events); Thread.Sleep(2000); Console.WriteLine("Retrieving the updated values"); Console.WriteLine("============================="); foundEvts = qiclient.GetWindowValues<SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o")); DumpEvents(foundEvts); #endregion #region Delete events Console.WriteLine(); Console.WriteLine("Deleting events"); qiclient.RemoveValue<DateTime>("evtStream", evt.Timestamp); qiclient.RemoveWindowValues("evtStream", foundEvts.First<SimpleEvent>().Timestamp.ToString("o"), foundEvts.Last<SimpleEvent>().Timestamp.ToString("o")); Thread.Sleep(2000); Console.WriteLine("Checking for events"); Console.WriteLine("==================="); foundEvts = qiclient.GetWindowValues<SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o")); DumpEvents(foundEvts); #endregion #endregion } catch (QiHttpClientException qiex) { Console.WriteLine("Error in Qi Service Client: " + qiex.Message); } catch (Exception ex) { Console.WriteLine("Other error: " + ex.Message); } finally { // clean up all created entities so you can run this again // all entities are reference counted, so you must delete the stream, then the type it uses try { qiclient.DeleteStream("evtStream"); } catch (Exception exStrm) { Console.WriteLine("Error deleting stream, type is left: " + exStrm.Message); } try { qiclient.DeleteType("SimpleEvent"); } catch (Exception exTyp) { Console.WriteLine("Error deleting stream: " + exTyp.Message); } try { qiclient.DeleteTenant("sampletenant"); } catch (Exception exTnt) { Console.WriteLine("Error deleting tenant: " + exTnt.Message); } Console.WriteLine("Press ENTER to finish"); Console.ReadLine(); } }
static void Main(string[] args) { Console.WriteLine("Creating a .NET Qi Client..."); string server = ConfigurationManager.AppSettings["QiServerUrl"]; QiType evtType = null; // acquire an authentication token from Azure AD string token = AcquireAuthToken(); // set up a client to the Qi Service -- it is essential that you set the QiTenant header QiHttpClientFactory <IQiServer> clientFactory = new QiHttpClientFactory <IQiServer>(); clientFactory.ProxyTimeout = new TimeSpan(0, 1, 0); clientFactory.OnCreated((p) => p.DefaultHeaders.Add("Authorization", new AuthenticationHeaderValue("Bearer", token).ToString())); IQiServer qiclient = clientFactory.CreateChannel(new Uri(server)); try { // Create a Qi Type -- the Qi Libraries let you do this via reflection // First, create a type builder, then pass it the name of the class you are using for events. // This greatly simplifies type creation Console.WriteLine("Creating a Qi type for WaveData instances"); QiTypeBuilder typeBuilder = new QiTypeBuilder(); evtType = typeBuilder.Create <WaveData>(); evtType.Id = "WaveType"; QiType tp = qiclient.GetOrCreateType(evtType); Console.WriteLine("Creating a stream in this tenant for simple event measurements"); QiStream sampleStream = new QiStream(); sampleStream.Name = "evtStream"; sampleStream.Id = "evtStream"; // set the TypeId property to the value of the Id property of the type you submitted // All events submitted to this stream must be of this type // Note there are Async versions of the client methods, too, using .NET TPL sampleStream.TypeId = tp.Id; sampleStream.Description = "This is a sample stream for storing WaveData type measurements"; QiStream strm = qiclient.GetOrCreateStream(sampleStream); #region CRUD Operations #region Create Events (Insert) Console.WriteLine("Artificially generating 100 events and inserting them into the Qi Service"); // How to insert a single event TimeSpan span = new TimeSpan(0, 1, 0); WaveData evt = WaveData.Next(span, 2.0, 0); qiclient.InsertValue("evtStream", evt); List <WaveData> events = new List <WaveData>(); // how to insert an a collection of events for (int i = 2; i < 200; i += 2) { WaveData newEvt = WaveData.Next(span, 2.0, i); events.Add(newEvt); Thread.Sleep(400); } qiclient.InsertValues <WaveData>("evtStream", events); Thread.Sleep(2000); #endregion #region Retrieve events for a time range // use the round trip formatting for time Console.WriteLine("Retrieving the inserted events"); Console.WriteLine("=============================="); IEnumerable <WaveData> foundEvts = qiclient.GetWindowValues <WaveData>("evtStream", "0", "198"); DumpEvents(foundEvts); #endregion #region Update an event Console.WriteLine(); Console.WriteLine("Updating values"); // take the first value inserted and update the value using a multiplier of 4, while retaining the order evt = foundEvts.First <WaveData>(); evt = WaveData.Next(span, 4.0, evt.Order); qiclient.UpdateValue <WaveData>("evtStream", evt); // update the collection of events (same span, multiplier of 4, retain order) List <WaveData> newEvents = new List <WaveData>(); foreach (WaveData evnt in events) { WaveData newEvt = WaveData.Next(span, 4.0, evnt.Order); newEvents.Add(newEvt); Thread.Sleep(500); } qiclient.UpdateValues <WaveData>("evtStream", newEvents); Thread.Sleep(2000); Console.WriteLine("Retrieving the updated values"); Console.WriteLine("============================="); foundEvts = qiclient.GetWindowValues <WaveData>("evtStream", "0", "198"); DumpEvents(foundEvts); // illustrate how stream behaviors modify retrieval // First, pull three items back with GetRangeValues for range values between events. // The default behavior is continuous, so ExactOrCalculated should bring back interpolated values Console.WriteLine(); Console.WriteLine(@"Retrieving three events without a stream behavior"); foundEvts = qiclient.GetRangeValues <WaveData>("evtStream", "1", 0, 3, false, QiBoundaryType.ExactOrCalculated); DumpEvents(foundEvts); // now, create a stream behavior with Discrete and attach it to the existing stream QiStreamBehavior behavior = new QiStreamBehavior(); behavior.Id = "evtStreamStepLeading"; behavior.Mode = QiStreamMode.StepwiseContinuousLeading; behavior = qiclient.GetOrCreateBehavior(behavior); // update the stream to include this behavior sampleStream.BehaviorId = behavior.Id; qiclient.UpdateStream("evtStream", sampleStream); // repeat the retrieval Console.WriteLine(); Console.WriteLine("Retrieving three events with a stepwise stream behavior in effect -- compare to last retrieval"); foundEvts = qiclient.GetRangeValues <WaveData>("evtStream", "1", 0, 3, false, QiBoundaryType.ExactOrCalculated); DumpEvents(foundEvts); #endregion #region Delete events Console.WriteLine(); Console.WriteLine("Deleting events"); qiclient.RemoveValue <int>("evtStream", 0); qiclient.RemoveWindowValues <int>("evtStream", 2, 198); Thread.Sleep(2000); Console.WriteLine("Checking for events"); Console.WriteLine("==================="); foundEvts = qiclient.GetWindowValues <WaveData>("evtStream", "0", "198"); DumpEvents(foundEvts); #endregion #endregion } catch (QiHttpClientException qiex) { Console.WriteLine("Error in Qi Service Client: " + qiex.Message); } catch (Exception ex) { Console.WriteLine("Other error: " + ex.Message); } finally { // clean up all created entities so you can run this again // all entities are reference counted, so you must delete the stream, then the type it uses try { qiclient.DeleteStream("evtStream"); qiclient.DeleteBehavior("evtStreamStepLeading"); qiclient.DeleteType(evtType.Id); } catch (Exception) { } } }
static void Main(string[] args) { Console.WriteLine("Creating a .NET Qi Client..."); string server = ConfigurationManager.AppSettings["QiServerUrl"]; // set up a client to the Qi Service -- it is essential that you set the QiTenant header QiHttpClientFactory <IQiServer> clientFactory = new QiHttpClientFactory <IQiServer>(); clientFactory.ProxyTimeout = new TimeSpan(0, 1, 0); clientFactory.OnCreated((p) => p.DefaultHeaders.Add("QiTenant", "sampletenant")); IQiServer qiclient = clientFactory.CreateChannel(new Uri(server)); try { // TODO -- remove tenant creation when provisioning is accomplished Console.WriteLine("Creating a tenant named sampletenant"); QiTenant tenant = new QiTenant("sampletenant"); // submit to PI Cloud Historian to create the tenant in storage qiclient.GetOrCreateTenant(tenant); // Create a Qi Type -- the Qi Libraries let you do this via reflection // First, create a type builder, then pass it the name of the class you are using for events. // This greatly simplifies type creation QiTypeBuilder typeBuilder = new QiTypeBuilder(); QiType evtType = typeBuilder.Create <SimpleEvent>(); evtType.Name = "SimpleEvent"; evtType.Id = "SimpleEvent"; QiType tp = qiclient.GetOrCreateType(evtType); Console.WriteLine("Creating a stream in this tenant for simple event measurements"); QiStream sampleStream = new QiStream(); sampleStream.Name = "evtStream"; sampleStream.Id = "evtStream"; // set the TypeId property to the value of the Id property of the type you submitted // All events submitted to this stream must be of this type // Note there are Async versions of the client methods, too, using .NET TPL sampleStream.TypeId = "SimpleEvent"; sampleStream.Description = "This is a sample stream for storing SimpleEvent type measurements"; QiStream strm = qiclient.GetOrCreateStream(sampleStream); #region CRUD Operations #region Create Events (Insert) Console.WriteLine("Artificially generating 100 events at one second intervals and inserting them into the Qi Service"); Random rnd = new Random(); // How to insert a single event SimpleEvent evt = new SimpleEvent(rnd.NextDouble() * 100, "deg C"); // for our contrived purposes, let's manually set the timestamp to 100 seconds in the past DateTime start = DateTime.UtcNow.AddSeconds(-100.0); evt.Timestamp = start; qiclient.InsertValue("evtStream", evt); List <SimpleEvent> events = new List <SimpleEvent>(); // how to insert an a collection of events for (int i = 1; i < 100; i++) { evt = new SimpleEvent(rnd.NextDouble() * 100, "deg C"); evt.Timestamp = start.AddSeconds((double)i); events.Add(evt); } qiclient.InsertValues <SimpleEvent>("evtStream", events); Thread.Sleep(2000); #endregion #region Retrieve events for a time range // use the round trip formatting for time Console.WriteLine("Retrieving the inserted events"); Console.WriteLine("=============================="); IEnumerable <SimpleEvent> foundEvts = qiclient.GetWindowValues <SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o")); DumpEvents(foundEvts); #endregion #region Update an event Console.WriteLine(); Console.WriteLine("Updating values"); // take the first value inserted and update the value and UOM evt = foundEvts.First <SimpleEvent>(); evt.Units = "deg F"; evt.Value = 212.0; qiclient.UpdateValue <SimpleEvent>("evtStream", evt); // update the collection of events (convert to deg F) foreach (SimpleEvent evnt in events) { evnt.Units = "deg F"; evnt.Value = evnt.Value * 9 / 5 + 32.0; } qiclient.UpdateValues <SimpleEvent>("evtStream", events); Thread.Sleep(2000); Console.WriteLine("Retrieving the updated values"); Console.WriteLine("============================="); foundEvts = qiclient.GetWindowValues <SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o")); DumpEvents(foundEvts); #endregion #region Delete events Console.WriteLine(); Console.WriteLine("Deleting events"); qiclient.RemoveValue <DateTime>("evtStream", evt.Timestamp); qiclient.RemoveWindowValues("evtStream", foundEvts.First <SimpleEvent>().Timestamp.ToString("o"), foundEvts.Last <SimpleEvent>().Timestamp.ToString("o")); Thread.Sleep(2000); Console.WriteLine("Checking for events"); Console.WriteLine("==================="); foundEvts = qiclient.GetWindowValues <SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o")); DumpEvents(foundEvts); #endregion #endregion } catch (QiHttpClientException qiex) { Console.WriteLine("Error in Qi Service Client: " + qiex.Message); } catch (Exception ex) { Console.WriteLine("Other error: " + ex.Message); } finally { // clean up all created entities so you can run this again // all entities are reference counted, so you must delete the stream, then the type it uses try { qiclient.DeleteStream("evtStream"); } catch (Exception exStrm) { Console.WriteLine("Error deleting stream, type is left: " + exStrm.Message); } try { qiclient.DeleteType("SimpleEvent"); } catch (Exception exTyp) { Console.WriteLine("Error deleting stream: " + exTyp.Message); } try { qiclient.DeleteTenant("sampletenant"); } catch (Exception exTnt) { Console.WriteLine("Error deleting tenant: " + exTnt.Message); } Console.WriteLine("Press ENTER to finish"); Console.ReadLine(); } }
static void Main(string[] args) { Console.WriteLine("Creating a .NET Qi Client..."); string server = ConfigurationManager.AppSettings["QiServerUrl"]; QiType evtType = null; // acquire an authentication token from Azure AD string token = AcquireAuthToken(); // set up a client to the Qi Service -- it is essential that you set the QiTenant header QiHttpClientFactory<IQiServer> clientFactory = new QiHttpClientFactory<IQiServer>(); clientFactory.ProxyTimeout = new TimeSpan(0, 1, 0); clientFactory.OnCreated((p)=>p.DefaultHeaders.Add("Authorization", new AuthenticationHeaderValue("Bearer", token).ToString())); IQiServer qiclient = clientFactory.CreateChannel(new Uri(server)); try { // Create a Qi Type -- the Qi Libraries let you do this via reflection // First, create a type builder, then pass it the name of the class you are using for events. // This greatly simplifies type creation Console.WriteLine("Creating a Qi type for WaveData instances"); QiTypeBuilder typeBuilder = new QiTypeBuilder(); evtType = typeBuilder.Create<WaveData>(); evtType.Id = "WaveType"; QiType tp = qiclient.GetOrCreateType(evtType); Console.WriteLine("Creating a stream in this tenant for simple event measurements"); QiStream sampleStream = new QiStream(); sampleStream.Name = "evtStream"; sampleStream.Id = "evtStream"; // set the TypeId property to the value of the Id property of the type you submitted // All events submitted to this stream must be of this type // Note there are Async versions of the client methods, too, using .NET TPL sampleStream.TypeId = tp.Id; sampleStream.Description = "This is a sample stream for storing WaveData type measurements"; QiStream strm = qiclient.GetOrCreateStream(sampleStream); #region CRUD Operations #region Create Events (Insert) Console.WriteLine("Artificially generating 100 events and inserting them into the Qi Service"); // How to insert a single event TimeSpan span = new TimeSpan(0, 1, 0); WaveData evt = WaveData.Next(span, 2.0, 0); qiclient.InsertValue("evtStream", evt); List<WaveData> events = new List<WaveData>(); // how to insert an a collection of events for (int i = 2; i < 200; i+=2) { WaveData newEvt = WaveData.Next(span, 2.0, i); events.Add(newEvt); Thread.Sleep(400); } qiclient.InsertValues<WaveData>("evtStream", events); Thread.Sleep(2000); #endregion #region Retrieve events for a time range // use the round trip formatting for time Console.WriteLine("Retrieving the inserted events"); Console.WriteLine("=============================="); IEnumerable<WaveData> foundEvts = qiclient.GetWindowValues<WaveData>("evtStream", "0", "198"); DumpEvents(foundEvts); #endregion #region Update an event Console.WriteLine(); Console.WriteLine("Updating values"); // take the first value inserted and update the value using a multiplier of 4, while retaining the order evt = foundEvts.First<WaveData>(); evt = WaveData.Next(span, 4.0, evt.Order); qiclient.UpdateValue<WaveData>("evtStream", evt); // update the collection of events (same span, multiplier of 4, retain order) List<WaveData> newEvents = new List<WaveData>(); foreach (WaveData evnt in events) { WaveData newEvt = WaveData.Next(span, 4.0, evnt.Order); newEvents.Add(newEvt); Thread.Sleep(500); } qiclient.UpdateValues<WaveData>("evtStream", newEvents); Thread.Sleep(2000); Console.WriteLine("Retrieving the updated values"); Console.WriteLine("============================="); foundEvts = qiclient.GetWindowValues<WaveData>("evtStream", "0", "198"); DumpEvents(foundEvts); // illustrate how stream behaviors modify retrieval // First, pull three items back with GetRangeValues for range values between events. // The default behavior is continuous, so ExactOrCalculated should bring back interpolated values Console.WriteLine(); Console.WriteLine(@"Retrieving three events without a stream behavior"); foundEvts = qiclient.GetRangeValues<WaveData>("evtStream", "1", 0, 3, false, QiBoundaryType.ExactOrCalculated); DumpEvents(foundEvts); // now, create a stream behavior with Discrete and attach it to the existing stream QiStreamBehavior behavior = new QiStreamBehavior(); behavior.Id = "evtStreamStepLeading"; behavior.Mode = QiStreamMode.StepwiseContinuousLeading; behavior = qiclient.GetOrCreateBehavior(behavior); // update the stream to include this behavior sampleStream.BehaviorId = behavior.Id; qiclient.UpdateStream("evtStream", sampleStream); // repeat the retrieval Console.WriteLine(); Console.WriteLine("Retrieving three events with a stepwise stream behavior in effect -- compare to last retrieval"); foundEvts = qiclient.GetRangeValues<WaveData>("evtStream", "1", 0, 3, false, QiBoundaryType.ExactOrCalculated); DumpEvents(foundEvts); #endregion #region Delete events Console.WriteLine(); Console.WriteLine("Deleting events"); qiclient.RemoveValue<int>("evtStream", 0); qiclient.RemoveWindowValues<int>("evtStream", 2, 198); Thread.Sleep(2000); Console.WriteLine("Checking for events"); Console.WriteLine("==================="); foundEvts = qiclient.GetWindowValues<WaveData>("evtStream", "0", "198"); DumpEvents(foundEvts); #endregion #endregion } catch (QiHttpClientException qiex) { Console.WriteLine("Error in Qi Service Client: " + qiex.Message); } catch (Exception ex) { Console.WriteLine("Other error: " + ex.Message); } finally { // clean up all created entities so you can run this again // all entities are reference counted, so you must delete the stream, then the type it uses try { qiclient.DeleteStream("evtStream"); qiclient.DeleteBehavior("evtStreamStepLeading"); qiclient.DeleteType(evtType.Id); } catch (Exception) { } } }