// This example shows how to create and read an Item_TimeSeriesFlexible. public void Create() { // Creating the timestamps of values var timestamp1 = DateTime.Parse("2018-02-16T09:00:00+02:00").ToUniversalTime(); var timestamp2 = DateTime.Parse("2018-02-16T10:00:00+02:00").ToUniversalTime(); var timestamp3 = DateTime.Parse("2018-02-16T11:00:00+02:00").ToUniversalTime(); var timestamp4 = DateTime.Parse("2018-02-16T12:00:00+02:00").ToUniversalTime(); // Creating a time series with the unit of measure "Cel" (Celsius) var series = new MsgMeas.Item_TimeSeriesFlexible("Cel") { { timestamp1, 22.3, MsgMeas.DataQuality.CreateBad() }, { timestamp2, 24.5 }, // No data quality specified -> "good" assumed { timestamp3, 24.8, MsgMeas.DataQuality.CreateGood() } }; // The "Add" method can also be used series.Add(timestamp4, 24.7); // Enclosing the series into an Observation var myObservation = new MsgMeas.Observation(series) { FeatureOfInterest = "ti300", ObservedProperty = "temperature", Description = "Bottom temperature in T300" }; byte[] xmlBytes = myObservation.ToXmlBytes(); // Do something with the XML data, e.g., send to AMQP topic... }
public void Read(byte[] xmlBytes) { // Assuming the time series comes enclosed in an Observation MsgMeas.Observation myObservation; try { myObservation = new MsgMeas.Observation(xmlBytes); } catch (MsgMeas.Neutral.InvalidMessageException e) { throw new InvalidOperationException("Failed to read observation: " + e.Message); } var series = (MsgMeas.Item_TimeSeriesFlexible)myObservation.Result; Console.WriteLine("Hourly surface level values: "); Console.WriteLine("(" + series.ValueCount + " values in total)"); // Printing the values in the time series foreach (MsgMeas.Item_TimeSeriesFlexible.TimeSeriesFlexItem item in series) { // Print timestamp, measured value, measurement unit and data quality information var line = string.Format("{0} {1} {2} {3}", item.Timestamp.ToString("yyyy-MM-dd HH:mm"), item.Value, series.UnitOfMeasure, item.DataQualityObj.Value); Console.WriteLine(line); } }
public void ReadXml(byte[] xmlBytes) { MsgMeas.Observation myObservation; // Try to process the message try { myObservation = new MsgMeas.Observation(xmlBytes); } catch (MsgMeas.Neutral.InvalidMessageException e) { throw new InvalidOperationException("Failed to read observation: " + e.Message, e); } // Check if the metadata is as expected const string ExpectedFeature = "factory_x/department_a/ti-22"; if (!myObservation.FeatureOfInterest.Equals(ExpectedFeature)) { throw new Exception("Expected " + ExpectedFeature + " but got " + myObservation.FeatureOfInterest); } // Accessing the actual measurement value. The type could as well be any of the Item_* classes. var measurement = (MsgMeas.Item_Measurement)myObservation.Result; var msgToConsole = string.Format("The value is {0} {1}", measurement.Value, measurement.UnitOfMeasure); Console.WriteLine(msgToConsole); }
public void Read(MsgMeas.Observation observation) { const string InstantField = "MyTime"; const string NestedRecordField = "NestedRecord"; const string NestedMeasurementField = "Meas"; // If the data record resides in an observation, you can read it as follows. var dataRecord = (MsgMeas.Item_DataRecord)observation.Result; // Getting the names of the fields in the data record SysColl.HashSet <string> itemNames = dataRecord.ItemNames; if (!itemNames.Contains(InstantField) || !itemNames.Contains(NestedRecordField) || !itemNames.Contains(NestedMeasurementField)) { throw new InvalidOperationException("Expected field is missing from data record"); } // Getting a time instant value in the data record var timeInstantItem = (MsgMeas.Item_TimeInstant)dataRecord[InstantField]; // Getting a measurement value in the nested data record var nestedDataRecord = (MsgMeas.Item_DataRecord)dataRecord[NestedRecordField]; var nestedMeasurement = (MsgMeas.Item_Measurement)nestedDataRecord[NestedMeasurementField]; // Do what you want with the values... }
private void VisualiseObservation(string filepath) { MessageTreeView.Items.Clear(); try { // Deserialising the document var msg = System.IO.File.ReadAllBytes(filepath); var observation = new MsgMeas.Observation(msg); // Adding metadata AddNodeToTreeview(MessageTreeView, "Type", "Observation"); AddNodeToTreeview(MessageTreeView, "Description", observation.Description); AddNodeToTreeview(MessageTreeView, "Name", observation.Name); AddNodeToTreeview(MessageTreeView, "Phenomenon time", FormatDateTimeForTreeview(observation.PhenomenonTime)); AddNodeToTreeview(MessageTreeView, "Result time", FormatDateTimeForTreeview(observation.ResultTime)); AddNodeToTreeview(MessageTreeView, "Procedure", observation.Procedure); AddNodeToTreeview(MessageTreeView, "Observed property", observation.ObservedProperty); AddNodeToTreeview(MessageTreeView, "Feature of interest", observation.FeatureOfInterest); AddNodeToTreeview(MessageTreeView, "Result quality", observation.ResultQuality.Value); // Adding payload var resultNode = AddNodeToTreeview(MessageTreeView, "Result", observation.Result); } catch (Exception e) { AddMessageToTreeview("Error: " + e.Message); m_appLogic.AddUnexpectedErrorToLog(e); } }
public void Observation() { // Observation test // Creating an observation for testing var dataRecord = new MsgMeas.Item_DataRecord() { { "mass", new MsgMeas.Item_Measurement("t", 1.2) }, { "thickness", new MsgMeas.Item_Measurement("cm", 3.5) } }; var observation = new MsgMeas.Observation(dataRecord) { Name = "Some name" }; var msg = observation.ToXmlBytes(); // Extracting metadata var testObject = MetadataExtractor.Build(msg); Assert.AreEqual(ContentTypeType.Xml, testObject.ContentType); Assert.AreEqual("Some name", testObject.Name); Assert.AreEqual("Data record (2 fields)", testObject.PayloadSummary); Assert.AreEqual(PayloadTypeType.ObservationXml, testObject.PayloadType); }
// This example shows // 1) how to create an observation object and serialise it to XML // 2) how to read an observation object from XML public byte[] CreateXml() { // Starting by creating the actual measurement item. // The type of this could as well be another class called "Item_*". var myMassMeasurement = new MsgMeas.Item_Measurement("Cel", 22.4); // Creating an observation to contain the measurement. // Also, specifying metadata. var timestamp = DateTime.Parse("2018-02-23T10:00:00Z").ToUniversalTime(); var myObservation = new MsgMeas.Observation(myMassMeasurement) { // All of this metadata is optional. If the XML schema requires // a value, a default is assigned. Please see the Observations and // Measurements standard for a description of these fields. Description = "Temperature measurement from the TI-22", FeatureOfInterest = "factory_x/department_a/ti-22", ObservedProperty = "temperature", Procedure = "sensors/pt100", PhenomenonTime = timestamp, // UTC time required ResultTime = timestamp, // UTC time required ResultQuality = MsgMeas.DataQuality.CreateGood() }; // Serializing the observation to XML return(myObservation.ToXmlBytes()); }
// This example shows how to create and read an Item_TimeSeriesConstant. public void Create() { // This time series represents the hourly accumulation of rainfall in millimeters (mm) var series = new MsgMeas.Item_TimeSeriesConstant("m", DateTime.Now.ToUniversalTime(), TimeSpan.FromHours(1)) { { 0.4 }, // No data quality specified -> "good" is assumed { 0.5 }, { 1.1, MsgMeas.DataQuality.CreateBad() }, { 1.7, MsgMeas.DataQuality.CreateGood() } }; // Can also use the "Add" method series.Add(1.5, MsgMeas.DataQuality.CreateGood()); // Enclosing the series into an Observation var myObservation = new MsgMeas.Observation(series) { FeatureOfInterest = "li300", ObservedProperty = "surface-level", Description = "Surface level of T300 once every hour" }; byte[] xmlBytes = myObservation.ToXmlBytes(); // Do something with the XML data, e.g., send to AMQP topic... }
public void Create() { // Create columns (3 in total). // Please see the documentation of constructors in Item_Array.ArrayColumn to // see which data types are supported. var myColumns = new SysColl.List<MsgMeas.Item_Array.ArrayColumn>() { new MsgMeas.Item_Array.ArrayColumn(typeof(DateTime), "timestamp"), new MsgMeas.Item_Array.ArrayColumn(typeof(double), "temperature", "Cel"), new MsgMeas.Item_Array.ArrayColumn(typeof(long), "batchcount") }; // Create the array item and its rows (2 rows in total). // These must match respective column types. var myArray = new MsgMeas.Item_Array(myColumns) { { DateTime.Now.ToUniversalTime().AddHours(-1), -4.2, (long)29 }, { DateTime.Now.ToUniversalTime(), -3.8, (long)32 } }; // You can also use the "Add" method instead of the array initialiser shown above. // The Add method can take any number of arguments. myArray.Add(DateTime.Now.ToUniversalTime(), -2.1, (long)36); // Now, you can enclose the array in an Observation or Item_DataRecord. E.g., var myObservation = new MsgMeas.Observation(myArray); byte[] xmlBytes = myObservation.ToXmlBytes(); }
public void Serve() { while (true) { // Waiting for a request to come from the network byte[] requestXml = WaitForRequest(); MsgMeas.GetObservationRequest requestObj; try { requestObj = new MsgMeas.GetObservationRequest(requestXml); } catch (MsgMeas.Neutral.InvalidMessageException e) { Console.WriteLine("Failed to read request: " + e.Message); continue; } // Assuming a certain feature of interest if (!requestObj.FeaturesOfInterest.Contains("myplant/myprocess/mytemperature")) { // Error! var errorResponse = new MsgMeas.GetObservationResponse() { RequestResult = MsgMeas.RequestResultType.NotFound }; SendResponse(errorResponse); continue; } // Looking at the temporal filter received from the client var temporalFilter = requestObj.TemporalFilters[0]; // Retrieving data (e.g., from a database). Filtering with the temporal filter. // ... // Building a response object var responseObj = new MsgMeas.GetObservationResponse() { RequestResult = MsgMeas.RequestResultType.Ok }; // Setting observation data. Suppose these have been retrieved from a database, for instance. var observation1 = new MsgMeas.Observation(new MsgMeas.Item_Measurement("s", 2.2)); var observation2 = new MsgMeas.Observation(new MsgMeas.Item_Measurement("s", 2.4)); responseObj.Observations.Add(observation1); responseObj.Observations.Add(observation2); // Sending the response SendResponse(responseObj); } }
public void Read(MsgMeas.Observation myObservation) { // This function assumes that you get the array in an Observation. var myArray = (MsgMeas.Item_Array)myObservation.Result; // Access one field in the array - [row][column]: double temperature1 = (double)myArray[0][1]; double temperature2 = (double)myArray[1][1]; // Do what you want with the values // ... }
private byte[] GetObservation(int taskId) { // Fabricating a message var dataRecord = new MsgMeas.Item_DataRecord() { { "TaskId", new MsgMeas.Item_Text(taskId.ToString()) }, { "SomeField", new MsgMeas.Item_Category("my-category") } }; var observation = new MsgMeas.Observation(dataRecord) { Name = "Task " + taskId }; return(observation.ToXmlBytes()); }
/// <summary> /// Creates an instance. /// </summary> /// <param name="msg">Message data.</param> /// <returns>Instance.</returns> public static MetadataExtractor Build(byte[] msg) { const string UnknownValue = "Unknown"; // These are the defaults var contentType = ContentTypeType.Other; var name = UnknownValue; var payloadSummary = UnknownValue; var payloadType = PayloadTypeType.Other; try { var messageString = System.Text.Encoding.UTF8.GetString(msg); // Using a dirty method to recognise the content type if (messageString.Contains("<?xml")) { contentType = ContentTypeType.Xml; // Using a dirty method to search a certain string in XML if (messageString.Contains("OM_Observation>")) // Matches the end tag of the XML doc { // Observation var observation = new MsgMeas.Observation(msg); name = observation.Name ?? ""; payloadSummary = observation.Result.ToDisplayString(); payloadType = PayloadTypeType.ObservationXml; } else if (messageString.Contains("ProcessProductionSchedule>")) // Matches the end tag of the XML doc { // Production schedule name = "Production schedule"; payloadSummary = "Production schedule"; payloadType = PayloadTypeType.ProcessProductionScheduleXml; } } } catch { } // Use defaults return(new MetadataExtractor(contentType, name, payloadSummary, payloadType)); }
private void SendMeasurement(Rmq.IModel channel) { // In this example, sending an imaginary tank state that consists of a few measurements. // Changing tank measurements randomly. m_tankTemperature = ChangeValueRandomly(m_tankTemperature, 6, 19, 49); m_tankLiquidLevel = ChangeValueRandomly(m_tankLiquidLevel, 27, 12, 100); // Creating state object. var tankStateValues = new MsgMeas.Item_DataRecord() { // Adding measurements. { "TI-300", new MsgMeas.Item_Measurement("Cel", m_tankTemperature) }, { "LI-300", new MsgMeas.Item_Measurement("cm", m_tankLiquidLevel) }, // Adding state. { "state", new MsgMeas.Item_Category(GetRandomTankState()) }, // Adding alarms. These alarms depend on the level value. { "LA-300", new MsgMeas.Item_Boolean(m_tankLiquidLevel < 30) }, { "LA+300", new MsgMeas.Item_Boolean(m_tankLiquidLevel > 70) } }; // Creating an Observation to enable encoding to XML and adding metadata. var timestamp = DateTime.Now; var observation = new MsgMeas.Observation(tankStateValues) { Name = "T300", Description = "State of T300 at " + timestamp.ToString(), FeatureOfInterest = "t300", ObservedProperty = "state", // By default, PhenomenonTime is always the creation time, but assigning it explicitly PhenomenonTime = timestamp.ToUniversalTime() }; // Sending the message to the message bus. SendToMessageBus(channel, TopicNameTankState, observation.ToXmlBytes()); }
// This example shows // 1) How to create an Item_DataRecord object and enclose it in an Observation // 2) How to read an Item_DataRecord enclosed in an Observation public void Create() { // This example creates a data record with the following structure: // - dataRecord // - MyMeas: Item_Measurement, 45.3 s, good quality (implicit) // - MyTime: Item_TimeInstant, 2018-03-02T14:22:05Z, bad quality (explicit) // - NestedRecord: Item_DataRecord // - NestedMeas: Item_Measurement, -0.34 m, good quality (implicit) // The easiest way to add fields is to use the collection initialiser as below. // In each row, the items are as follows: // 1) the name of the data record field, // 2) the related Item_* object, // 3) data quality information (optional) var dataRecord = new MsgMeas.Item_DataRecord() { // Adding a measurement value { "MyMeas", new MsgMeas.Item_Measurement("s", 45.3) }, // Adding a time instant { "MyTime", new MsgMeas.Item_TimeInstant(DateTime.Parse("2018-03-02T14:22:05Z").ToUniversalTime()), MsgMeas.DataQuality.CreateBad() } }; // You can also use the "Add" method. The code below shows this. In addition, // it shows that a data record can nest another data record. var nestedDataRecord = new MsgMeas.Item_DataRecord() { { "NestedMeas", new MsgMeas.Item_Measurement("m", -0.34) } }; dataRecord.Add("NestedRecord", nestedDataRecord); // Now, you can include the data record in an Observation, for instance. var observation = new MsgMeas.Observation(dataRecord); var xmlBytes = observation.ToXmlBytes(); // Send XML bytes to network... }