示例#1
0
        // 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...
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
        }
示例#4
0
        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...
        }
示例#5
0
        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);
            }
        }
示例#6
0
        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);
        }
示例#7
0
        // 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());
        }
示例#8
0
        // 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...
        }
示例#9
0
        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();
        }
示例#10
0
        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);
            }
        }
示例#11
0
        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
            // ...
        }
示例#12
0
        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());
        }
示例#13
0
        /// <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));
        }
示例#14
0
        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());
        }
示例#15
0
        // 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...
        }