This sample walkthru is written to be used by Try .NET. This means that the rendering in general purpose markdown readers, including GitHub webUI, might not work properly. See the readme.md for details on Try .NET and how to use it.
The first time you press "TestSample >" on the page it might take a few minutes for it compile and do its magic before it runs and writes something to the console writing part of it. Subsequent runs are faster (this appears true across dotnet try sessions and browswer refreshes)
For this sample we are someone who wants to store and retrieve data from 3 different tanks; vessel, tank1 and tank2. These 3 different tanks have 2 value readings; pressure and temperature. To start we are only concerned with tank1, because we know once we get it setup we can easily scale to get the other data. We are collecting this data ourselves from the sensors directly. In this sample we explore different ways we can store the data in Cds and different ways we can retrieve the data.
The first thing we need to do is setup the application to run. We need to know where we want to store this information in Cds. This includes knowing our TenantID, Namespace, and retreiving a Client ID and Client Key
These variables are used to hold the configuration settings. Update these as appropriate.
With that information we now need to define the names of what we will store in Cds.
These variables are used to create the Types and Strings. Update these as appropriate.
With basic settings and configuration ready we can now authenticate against Cds and initlize the Cds client library
We decide we are going to store the Cds as a Simple type that only has a value and a time-stamp. First we need to create the CLR type we want to represent in Cds.
Once we have that we create the type in Cds using the SdsTypeBuilder to build the SdSType and then use the metadataservice to create the type.
Since we are wanting to store Tank1's data we need to create 2 streams for Tank1, one for the pressure and one for the temperature.
With the streams created we can now insert the data into the streams. In our example we are simulating the data collection as being returned from a static historical collection. The data form of data of a type, in JSON form
{ "pressure": 346, "temperature": 91, "time": "2017-01-11T22:21:23.430Z" }
In anything real, this would be a call to an outside system (whether that be to a file, or an outside service like OPC UA, or off of the GPIO directly). It would also likely be something that is streaming, so we would need architect a solution to have a dedicated collecting application. In this simulation a missing reading is recorded as a 0.
Note: we are using the type PressureTemperatureData
that is editable in Step 5 below.
We need to get the values we want and assign them to our Simple Type.
With them in the right format, we can then send them in.
At this point we decide we want to try storing a complex type. So we can store the data exactly like we get back from the sensor. To do this, we now need to create the appropriate type
With the class defined we take advantage of how we can create the type in Cds using the SdsTypeBuilder to build the SdSType and then the metadataservice to create the type.
We can use the same approach we did in Step 3 and create the tank stream.
If you want to see the data that is being collected, look back at Step 4. Otherwise this a straightforward call based on what we have done previously.
At this point we should look to see how the data is stored on Cds and how we can view it. There are many different API calls and options for reading data. For simplicity we are going to get the timestamps from the data and use this to call for the full window data.
Note because of the JSON conversions done by this library there is no need to turn on AcceptVerbosity as the conversions handle this for us automatically. Therefore step 9 is sufficiently covered by step 8.
In some instances it is important to get a summary of the data you are viewing. Maybe you want an average or the count of what is in there over a timeframe.
Now we want to create the streams for storing our other tanks too, and populate them with data.
With those created we can now get our data back from tank2 and vessel in 1 call.
Note that since we did an outer join we get data for all points in the timeframe. If a stream doesn't have data at that timepoint then we get back Null.
As part of the sample we clean up after ourselves.