Developing a C# .NET Hello World (telemedical) application
Prequisites
- We assume that you have downloaded and installed Net4Care.
- To build the code you need Microsoft Visual Studio 2010 or 2012 (with Visual C# 2010 / Microsoft .NET Framework 4.0). The free Express version is sufficient
- You need the NuGet Visual Studio extension installed. NuGet can handle installing and updating third-party libraries and tools in Visual Studio. You can download and install NuGet from: http://nuget.org/.
(The C# .NET examples have been tested with Microsoft Visual Studio 2010 Professional on Windows 7)
Overview
In this example, we will review two simple C# .NET "Hello World" clients that communicate with the Net4Care server side (n4c_receiver). You will find Visual Studio solution file and example programs in the n4c_contrib/csharp-client folder of the distribution.
One client "HelloUpload" demonstrates how to write C# code using the Net4Care framework classes that define a tele observation (that is, a set of clinical measurements for a patient) and uploads it to the Net4Care server.
The other client "HelloQuery" demonstrates how to program a query for all tele observations made during the last 10 minutes.
Buildling and Starting the server
To be able to run the C# examples you first need to build and start the Net4Care server. For instructions on this see Building and Starting the server (ignore from "Building and Executing the HelloWorld clients" onwards on that page, as this pertains to building and creating a Java client).
Building and Executing the HelloWorld clients
Building the code
- Open the solution file "net4care.sln" (from the folder n4c_contrib/csharp-client) in Visual Studio.
- Select "Build Solution" to build the projects contained in the solution.
(The included '.nuget' project should ensure that external packages depended on are automatically downloaded and installed when building the solution.)
Running the examples
The HelloUpload and HelloQuery examples contact a net4care server. Currently the examples assume a local server running at "http://localhost:8082/observation" (see above).
The HelloUpload and HelloQuery examples can either be run from inside Visual Studio (by setting the project you wish to run as 'Startup project') or from a command line. In the following we will use a command line.
Now, start a command prompt and execute the "HelloUpload" program:
cd (root)\n4c_contrib\csharp-client\n4c_examples\HelloUpload\bin\Debug HelloUpload.exe
Output should be something like:
Hello Net4Care World: Uploading an observation to server at address: http://localhost:8082/observation (Make sure the Net4Care server is running!) Upload result: True Upload connection result: OKOK
Next, let us try to query for observations for the last 10 minutes:
cd (root)\n4c_contrib\csharp-client\n4c_examples\HelloQuery\bin\Debug HelloQuery.exe
This should result in something like:
Hello Net4Care World: Query all observations for last 10 minutes to server at address: http://localhost:8082/observation (Make sure the Net4Care server is running!) The query is: Forwarder.QueryPersonTimeInterval for 251248-4916 in time (1387364182930-1387364782930) === Observations from the last 10 minutes === --- RAW FORMAT - using ToString() --- STO: 251248-4916/MyOrgID/Device: Manufac1/MODEL1/1/obs=(Spiro: FEV1:2,8 L/FVC:3,5 L(False)) --- OWN FORMAT - using API --- -*-*-*-*-*- At date/time: 18-12-2013 11:03 Measured: FVC:3,5 L / FEV1:2,8 L(False) End.
Code walkthrough
HelloUpload
The HelloUpload client does three things
- Configure the DataUploader which is responsible for uploading observations to the server
- Define a tele observation with proper information on the patient, devices used, and of course measured values
- Perform the actual upload, testing that it went well
Configure the DataUploader
As both the upload and query application needs to configure the uploader, this is encapsulated in a global function.
// Configure the architecture IDataUploader dataUploader = Shared.setupN4CConfiguration(serverAddress);
This function looks like this:
public static IDataUploader setupN4CConfiguration(String serverAddress, params Type[] knownObservationTypes) { IDataUploader dataUploader = null; ISerializer serializer = new JSONSerializer(knownObservationTypes); dataUploader = new StandardDataUploader(serializer, new HttpConnector(serverAddress)); return dataUploader; }
Basically, we use a default implementation and configure it with a serializer role and a connector role. Presently the Net4Care framework only contains a single serializer implementation that uses JSON as on-the-wire format. There is currently only one implementation for the connector with HTTP as the transport protocol.
Define a tele observation
// Define the actual measured values for the patient, here 3.5L for // full lung capacity and 2.8L for 1 second lung capacity Spirometry sp = new Spirometry(3.5, 2.8, false); // Define the information regarding the used device var devdesc = new DeviceDescription("Spirometry", "MODEL1", "Manufac1", "1", "1", "1.0", "1.0", "Classification", DateTime.Now.Ticks); // And finally define the observation itself. The patient ID is that // of the 'standard' patient Nancy. var sto = new StandardTeleObservation("251248-4916", "MyOrgID", "myTreatmentId", Codes.LOINC_OID, devdesc, sp, "I have difficulties in breathing.");
You use two standard classes from the framework StandardTeleObservation
and DeviceDescription
which define patient identity, organizational identity, etc., and device characteristics. Finally, to adapt the framework to a specific set of measurements, you define your own class (here Spirometry
) that must implement the ObservationSpecifics
interface. Much more detail can be found in How to define and upload observations (although the code examples there are in Java, it should not be hard to generalize for use with C#).
Perform the actual upload
// Upload the observation to the server... IFutureResult result = dataUploader.Upload(sto); result.Wait(); if (result == null) Console.WriteLine("Upload returned a null result (was the server running?)."); else { Console.WriteLine("Upload result: " + result.IsSuccess); Console.WriteLine("Upload connection result: " + result.Result); }
The basic upload is done using the upload(sto)
method of the dataUploader. It will return a IFutureResult
which can be queried for the result of the operation.
HelloQuery
The HelloQuery program does
- Configure the DataUploader
- Define a query for the last ten minutes of observations on the given person
- Send the query to the server and
- Process the returned observations
Configure the DataUploader
This step is identical to the one defined in the HelloUpload program.
Define a query
The interface IQuery
has a set of implementing classes that define the queries that are possible. Here we demonstrate a query for a given patient ID and given time interval (from ten minutes ago up until now), which is defined by the query class QueryPersonTimeInterval
.
long now = timestampStrategy.getCurrentTimeInMillis(); long minutes = 10; long minutesago = now - 1000*60*minutes; // Select the requrired query by picking the proper class implementing // the query interface QueryPersonTimeInterval query = new QueryPersonTimeInterval(personId, minutesago, now); Console.WriteLine("The query is: " + query + "\n");
Send the query
Next we send the query to the server using our dataUploader
instance, and validate the returned response, defined by an instance of the QueryResult
interface.
// Send the query to the server. IQueryResult res = dataUploader.Query(query); res.Wait();
Process the returned observations
Finally, we retrive the list of StandardTeleObservation
that match the query from the response. We next iterate this list in two ways, one using the internal ToString()
method, and one using the API's of the tele observation class. Note how we cast the tele observation's observation specifics object to our own Spirometry
class. For how deserialization back to our own class happens see the Deserialize(String messagePayload)
member function of the JSONSerializer
class defined in the n4c_serializer
project.
// Retrieve the list of observations... Console.WriteLine("=== Observations from the last " + minutes + " minutes ==="); List<StandardTeleObservation> obslist = res.ObservationList; // First output observations using just the ToString() method Console.WriteLine(" --- RAW FORMAT - using ToString() ---"); foreach (StandardTeleObservation sto in obslist) { Console.WriteLine(sto == null ? "Ignoring observation" : sto.ToString()); } // Next output observations using the API of StandardTeleObservation // as well as the special Spirometry class we ourselves have defined. Console.WriteLine(" --- OWN FORMAT - using API ---"); DateTime dateTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0); foreach (StandardTeleObservation sto in obslist) { if (sto == null) continue; Console.WriteLine("-*-*-*-*-*-"); long timestamp = sto.Time; DateTime d = dateTime.AddSeconds(timestamp / 1000); string nicedate = d.ToShortDateString() + " " + d.ToShortTimeString(); Console.WriteLine(" At date/time: " + nicedate + "\n"); Console.WriteLine(sto.ObservationSpecifics.ObservationAsHumanReadableText); } Console.WriteLine("End.");
HelloPHMRQuery
This program is nearly identical to HelloQuery except that the query is for the Personal Health Monitoring Record (PHMR) version of the tele observations instead of the C# objects. PHMR is a Continua Alliance defined extension of the Clinical Document Architecture that is part of HL7.
Experiments
You may experiment with the code as you like but beware of the following implementation constraints in the present release
- Only a few person IDs are known by the server as it does not have a real lookup of person identities in national registers. You can find the list of known persons in Java class
FakeObjectExternalDataSource
in the n4c_storage bundle. - If you want to erase the database, you will find it in the folder "(root)\n4c_osgi\n4c_receiver\runner". It is called "xds.db".
- If your experiments really mix up things, a clean and reinstall often helps. Issue "mvn clean install" in the n4c_osgi folder, and rerun the server.
Other language binding
It is possible to interface a Net4Care server using other languages. You must then negotiate the HTTP protocol and JSON format directly. Please consult the documentation Server Protocol.