Obsah

API

Mervis DB nabízí otevřené rozhraní protokolu SOAP. Odpovídající WSDL je k ke stažení:

Pro speciální použití existují i další rozhraní pro komunikaci s Mervis DB - pro jejich použití a popis kontaktujte prosím technickou podporu.

Seznam základních podporovaných funkcí

FunctionDescription
SaveDataSave one or multiple records from one or multiple variables
GetData/GetDataAsyncRead one or multiple records from one or multiple variables.
GetParticularData/GetParticulatDataAsyncOptimized method for reading of „special“ data - last value, last value after certain time moment etc.
GetVariablesGet the list of variables.
GetAllVariables
ServerAliveObsolete
DeleteVariables
DeleteData
ReplaceDataDelete data from time range and save one or multiple records from one or multiple variables in one API call
EnsureVariables
GetTransformedData/GetTransformedDataAsyncMethod for reading of aggregated results with given time period, the aggregation may be Min, Max, Integral, Weighted average, First, Last and Median
GetServerVersion
GetVariableStatsObsolete
GetVariableStatsAsyncObsolete
CheckCredentials

Vlastnosti objektu

Příklady použití

C#

Download

mervisdb_getdata_example.zip
mervisdb_savedata_example.zip

Kód

MervisDB_GetData_Example.cs
using ESG.Core.Access.Client;
using ESG.Db.Server.Shared;
using ESG.Db.ServerAccess;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
 
namespace DbClientTest
{
	class Program
	{
		static async Task Main(string[] args)
		{
			try
			{
				//
				// Create access to the real server.
				// Without SSL connections, you have to remove binding parameters "<security mode="Transport"/>" in the App.config.
				// The client is automatically generated from the WSDL file available here: https://kb.mervis.info/doku.php/en:mervis-db:10-api
				//
				using (HistoryDbAccessClient client = new HistoryDbAccessClient(HistoryDbAccessClient.EndpointConfiguration.HistoryAccess, "https://localhost:9876/RcWareDbAccess"))
				{
					// Authentication credetials in the database.
					Credentials credentials = new Credentials
					{
						Name = "XXXX",
						Password = "YYYY"
					};
 
					// Specification of the variables through Key-Value.
					// Here we use 2 variables.
					ESG.Db.Server.Shared.KeyValuePair[][] keys = new ESG.Db.Server.Shared.KeyValuePair[][] {
						 new ESG.Db.Server.Shared.KeyValuePair[] {
						 new ESG.Db.Server.Shared.KeyValuePair(true, "DPGuid","338E2882-D72B-4D17-A241-73E8BC30F458"),
						 new ESG.Db.Server.Shared.KeyValuePair(true, "StationName", "AAABBB")
					 },
					   new ESG.Db.Server.Shared.KeyValuePair[] {
					 	 new ESG.Db.Server.Shared.KeyValuePair(true, "DPGuid", "CC80211D-3D29-4CC2-91A2-F69483D566B5"),
						 new ESG.Db.Server.Shared.KeyValuePair(true, "StationName", "AAABBB")
					 }
				 };
 
					// From-To dates. The dates must be specified in the UTC time zone.
					DateTime utcTo = DateTime.UtcNow;
					DateTime utcFrom = DateTime.UtcNow.AddDays(-1);
 
					// Retrieving the data goes through cycling of values and variables. The server returns recommended values needed for the the next cycle.
					int variableOffset = 0; // the offset of the variable
					int variableCount = 10; // maximal number of variables returned in one request
					int valueOffset; // the offset of the value
					int valueCount = 1000; // maximal values in on request
 
					Console.WriteLine("Reading values...");
 
					do
					{
						valueOffset = 0;
						do
						{
							// Execute the request.
							var result = await client.GetDataAsyncAsync(credentials, keys, utcFrom, utcTo, variableOffset, variableCount, valueOffset, valueCount);
 
							// Check the return code. "0;OK" is what we want.
							if (!result.ReturnCode.StartsWith("0;"))
							{
								Console.WriteLine("Error on reading: {0}", result.ReturnCode);
							}
 
							// Cycle through the data and print it out.
							foreach (var valRecord in result.Data)
							{
								Console.WriteLine("Variable: {0}", String.Concat(valRecord.Keys.Select((i) =>
								{
									return String.Format("{0}={1}; ", i.Key, i.Value);
								})));
 
								foreach (var value in valRecord.Values)
								{
									Console.WriteLine("{0}->{1} [{2}] {3}", value.UtcTimeStamp, value.GoodThrough, value.HistoryValueType, value.DoubleValue /* Use value type according to the Hvt (History Value Type) */ );
								}
							}
 
							valueOffset = result.NextValueOffset;
							variableOffset = result.NextVariableOffset;
						}
						while (valueOffset != -1);
					}
					while (variableOffset != -1);
				}
 
			}
			catch (Exception exc)
			{
				Console.WriteLine("Exception: {0}", exc.ToString());
			}
 
			Console.WriteLine("DB communication finished");
 
			Console.ReadLine();
		}
 
 }
}
MervisDB_SaveData_Example.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MervisDb_SaveData_Example.MervisDbService;
 
namespace MervisDb_SaveData_Example
{
	class Program
	{
		static async Task Main(string[] args)
		{
			try
			{
				//
				// Create access to the real server.
				// Without SSL connections, you have to remove binding parameters "<security mode="Transport"/>" in the App.config.
				// The client is automatically generated from the WSDL file available here: https://kb.mervis.info/doku.php/en:mervis-db:10-api
				//
				using (HistoryDbAccessClient client = new HistoryDbAccessClient(HistoryDbAccessClient.EndpointConfiguration.HistoryAccess, "https://localhost:9876/RcWareDbAccess"))
				{
					// Authentication credetials in the database.
					Credentials credentials = new Credentials { Name = "XXXX", Password = "YYYY" };
 
					// Adding records...
					List<ValueRecord> records = new List<ValueRecord>();
 
					DateTime utcTimeStamp = new DateTime(2018, 1, 1, 12, 0, 0, DateTimeKind.Utc);
 
					// Each value is stored in a ValueRecord structure
					ValueRecord rec = new ValueRecord();
 
					rec.UtcTimeStamp = utcTimeStamp;                // time stamp of the value, UTC date time must be used
					rec.HistoryValueType = HistoryValueType.Double; // type of the value
					rec.DoubleValue = 23.4;                         // value itself
					rec.Interval = 60.0;                            // sampling period in seconds. When the difference of timestamps of subsequent values if greater than 1.1 multiple of the interval, the data should be considered incomplete.
					rec.Keys = new ESG.Db.Server.Shared.KeyValuePair[]										// identification of the variable. At least one key-value pair must be "IsKey" to identify a variable.
					{
						new ESG.Db.Server.Shared.KeyValuePair(true, "Root", "Building A"),
						new ESG.Db.Server.Shared.KeyValuePair(true, "Level1", "Floor 1"),
						new ESG.Db.Server.Shared.KeyValuePair(true, "Level2", "Room 7"),
						new ESG.Db.Server.Shared.KeyValuePair(true, "Level3", "Temperature"),
						new ESG.Db.Server.Shared.KeyValuePair(false, "Description", "Temperature in the room 7"),
						new ESG.Db.Server.Shared.KeyValuePair(false, "Unit", "°C"),
					};
 
					records.Add(rec);
 
					// Save data method returns the number of stored records					
					int recordsSaved = await client.SaveDataAsync(credentials, records.ToArray());
 
					Console.WriteLine("Records saved: {0}", recordsSaved);
				}
 
			}
			catch (Exception exc)
			{
				Console.WriteLine("Exception: {0}", exc.ToString());
			}
 
			Console.WriteLine("DB communication finished");
 
			Console.ReadLine();
		}
	}
}
MervisDb_ReplaceData_Example.cs
using ESG.Core.Access.Client;
using ESG.Db.Server.Shared;
using ESG.Db.ServerAccess;
using System;
using System.Collections.Generic;
 
namespace DbClientTest
{
	class Program
	{
		static async Task Main(string[] args)
		{
			RcWareDbClient dbClient = new RcWareDbClient(false, "RcWareDbAccess", new Uri("http://localhost:9876/RcWareDbAccess"));
			dbClient.Credentials = new ESG.Db.Server.Shared.Credentials("xxxxxxx", "xxxxxxx");
 
			DateTime utcNow = DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(5));
 
			ESG.Db.Server.Shared.KeyValuePair[] varKeysNew = new ESG.Db.Server.Shared.KeyValuePair[]
			{
				new ESG.Db.Server.Shared.KeyValuePair(true, "DPGuid", "51111111-1234-1234-1234-123456789012"),
				new ESG.Db.Server.Shared.KeyValuePair(true, "StationName", "db_replace_test")
			};
 
			ESG.Db.Server.Shared.KeyValuePair[] varKeys1 = new ESG.Db.Server.Shared.KeyValuePair[]
			{
				new ESG.Db.Server.Shared.KeyValuePair(true, "DPGuid", "60ace716-5e1e-4cf8-ab05-947dce0caf77"),
				new ESG.Db.Server.Shared.KeyValuePair(true, "SoftPlcRtId", "db_replace_test")
			};
 
			ESG.Db.Server.Shared.KeyValuePair[] varKeys = varKeys1;
 
			// generate some records
			List<ValueRecord> recsToSave = new List<ValueRecord>();
			TimeSpan recsLength = TimeSpan.FromMinutes(2);
			int recsPerMinute = 4;
 
			Random r = new Random((int)DateTime.UtcNow.Ticks);
			double rBase = r.NextDouble() * 10;
 
			for (int i = 0; i < (recsLength.TotalSeconds / 60) * recsPerMinute; i++)
			{
				recsToSave.Add(new ValueRecord(utcNow - recsLength + TimeSpan.FromMinutes(i * (1.0 / recsPerMinute)), rBase + ((i % 2) + 1) * (-4)));
				recsToSave[recsToSave.Count - 1].Keys = varKeys;
				recsToSave[recsToSave.Count - 1].Interval = 60 / recsPerMinute;
 
				recsToSave.Add(new ValueRecord(utcNow - recsLength + TimeSpan.FromMinutes(i * (1.0 / recsPerMinute)), rBase + ((i % 2) + 1) * (-4)));
				recsToSave[recsToSave.Count - 1].Keys = varKeysNew;
				recsToSave[recsToSave.Count - 1].Interval = 60 / recsPerMinute;
			}
 
			var res = await dbClient.ReplaceDataAsync(new List<ESG.Db.Server.Shared.KeyValuePair[]> { varKeys }, utcNow.Subtract(recsLength), utcNow, recsToSave.ToArray());
		}
	}
}
MervisDb_GetTransformedData_Example.cs
using System;
using System.Linq;
using System.Threading.Tasks;
using MervisDb_GetTransformedData_Example.MervisDbService;
 
namespace MervisDb_GetTransformedData_Example
{
	class Program
	{
		static async Task Main(string[] args)
		{
			//
			// Create access to the real server.
			// Without SSL connections, you have to remove binding parameters "<security mode="Transport"/>" in the App.config.
			// The client is automatically generated from the WSDL file available here: https://kb.mervis.info/doku.php/en:mervis-db:10-api
			//
			try
			{
				using (HistoryDbAccessClient client = new HistoryDbAccessClient(HistoryDbAccessClient.EndpointConfiguration.HistoryAccess, "http://localhost:9876/RcWareDbAccess"))
				{
					// Authentication credentials in the database.
					Credentials credentials = new Credentials { Name = "XXXXX", Password = "YYYYY" };
 
					// Specification of the variables through Key-Value.
					// Here we use 2 variables.
					ESG.Db.Server.Shared.KeyValuePair[][] variableKeys = new ESG.Db.Server.Shared.KeyValuePair[][] {
						new ESG.Db.Server.Shared.KeyValuePair[] {
							new ESG.Db.Server.Shared.KeyValuePair (/*IsKeyId*/ false, /*Key*/ "DPGuid", /*Value*/ "338E2882-D72B-4D17-A241-73E8BC30F458"),
							new ESG.Db.Server.Shared.KeyValuePair (/*IsKeyId*/ false, /*Key*/ "StationName", /*Value*/ "AAABBB")
						},
						new ESG.Db.Server.Shared.KeyValuePair[] {
							new ESG.Db.Server.Shared.KeyValuePair (/*IsKeyId*/ false, /*Key*/ "DPGuid", /*Value*/ "CC80211D-3D29-4CC2-91A2-F69483D566B5"),
							new ESG.Db.Server.Shared.KeyValuePair (/*IsKeyId*/ false, /*Key*/ "StationName", /*Value*/ "AAABBB")
						}
					};
 
					// Aggregation request
					var aggregation = new AggregationRequest();
					aggregation.Types = new AggregationType[] { AggregationType.Last };
					aggregation.Interpolation = InterpolationType.None;
					//aggregation.MaxNeighborDistance = ..only for interpolation;
					aggregation.IsoPattern = new string[] { "PT15M" }; // 15 min period (ISO 8601 duration pattern)
					aggregation.From = new DateTime(2018, 11, 24, 0, 0, 0, 0, DateTimeKind.Unspecified);
					aggregation.To = new DateTime(2018, 11, 25, 0, 0, 0, 0, DateTimeKind.Unspecified);
					aggregation.TimeZone = @"Europe/Prague";
 
					// Retrieving the data goes through cycling of intervals and variables. The server returns recommended intervals needed for the the next cycle.
					int variableOffset = 0; // the offset of the variable
					int variableCount = 10; // maximal number of variables returned in one request
					int intervalOffset;       // the offset of the interval
					int intervalCount = 1000; // maximal values in on request
 
					Console.WriteLine("Reading values...");
 
					do
					{
						intervalOffset = 0;
 
						do
						{
							// Execute the request.
							var result = await client.GetTransformedDataAsyncAsync(credentials, aggregation, variableKeys, variableOffset, variableCount, intervalOffset, intervalCount);
 
							// Check the return code. "0;OK" is what we want.
							if (!result.ReturnCode.StartsWith("0;"))
							{
								Console.WriteLine("Error on reading: {0}", result.ReturnCode);
							}
 
							// Cycle through the data and print it out.
							if (result.Data != null)
							{
								foreach (VariableAggregate vag in result.Data)
								{
									Console.WriteLine("Variable: {0}", String.Concat(vag.Keys.Select((i) => { return String.Format("{0}={1}; ", i.Key, i.Value); })));
 
									foreach (Interval value in vag.Data)
									{
										Console.Write(" {0}->{1} quality: {2:0.00} ", value.Begin, value.End, value.DataQuality);
 
										if (value.Last != null)
										{
											Console.Write(" Last Value: {0} (stamp {1}, origin {2})", value.Last.Value, value.Last.Stamp, value.Last.Origin);
										}
 
										Console.WriteLine();
									}
								}
							}
 
							variableOffset = result.NextVariableOffset;
							intervalOffset = result.NextIntervalOffset;
 
						} while (intervalOffset != -1);
 
					} while (variableOffset != -1);
				}
 
			Console.WriteLine("DB communication is running in background");
 
			}
			catch (Exception exc)
			{
				Console.WriteLine("Exception: {0}", exc.ToString());
			}
 
			Console.WriteLine("DB communication finished");
 
			Console.ReadLine();
		}
	}
}

Matlab

Podporované funkce

FunctionDescription
SaveDataSave one or multiple records from one or multiple variables
GetDataRead one or multiple records from one or multiple variables.
GetDataUnmergedRead one or multiple records from one or multiple variables. Allow more setting options than GetData function
GetDataOriginRead data exactly as are stored in the database.
DeleteVariableDelete entire variable or some certain interval.
GetRequiredTimestampGet time stamp depending on input options.

Toolbox

Pro komunikaci Matlabu s Mervis DB potřebujete nainstalovat toolbox:

Kód

MervisDB_GetData_example.m
% Instance of Mervis DB 
mervisDB = MervisDatabase('username', 'password', 'dbUrl');
 
% Time interval definition
from = localMatlab2utcMatlab(datenum(2017, 1, 1)); %1.1.2017 in utc
to = localMatlab2utcMatlab(datenum(2017, 31, 1)); %31.1.2017 in utc
samplePeriod = 5*60; % 5 minutes
outputTimeZone = 'Local'; % possible 'Local' or  'Utc' parameter;
 
% Specifying varibles to download
varKeys1 = {'DPGuid', '338E2882-D72B-4D17-A241-73E8BC30F458';...
            'StationName', 'XXXXXXX'}; % Keys definition of first variable
varKeys2 = {'DPGuid', 'CC80211D-3D29-4CC2-91A2-F69483D566B5';...
            'StationName', 'YYYYYYY'}; % Keys definition of second variable
 
variable1 = MervisDbVariable(varKeys1); % Create MervisDbVariable object from defined keys
variable2 = MervisDbVariable(varKeys2);
 
arrayOfVarKeys = [variable1; variable2]; % array of MervisDbVariables objects
 
% help for function getData
help MervisDatabase.getData 
 
% Download required data
[data, time] = mervisDB.getData(arrayOfVarKeys, from, to, samplePeriod, outputTimeZone);
 
% Get all variables with defined keys
allVaribales = mervisDB.getAllVars(varKeys1);

PHP

Kód

MervisDB_GetData_example.php
<?php
/*
Mervis DB PHP example - getdata
*/
try {
 
  $soapClient = new SoapClient('./wsdl/singlewsdl.xml', array(
    'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP,
    'trace' => 0,
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS
  ));
  $soapClient->__setLocation('http://localhost:9876/RcWareDbAccess');
 
  $credentials = array(
    'Name' => 'XXXXXXX',
    'Password' => 'YYYYYYY'
  );
 
  $utcTZ   = new DateTimezone('UTC'); //all time realted values are expected in UTC
  $utcFrom = new DateTime('-120minutes', $utcTZ); //
  $utcTo   = new DateTime('now', $utcTZ); //
 
  $valOffset = 0;
  $valCount  = 20; //how many values should be returned in one request at most. Recommended value: 5000
  $varOffset = 0;
  $varCount  = 4; //how many variable should be returned in on request at most
 
  $variablesKey = array(
    array(
      array(
        'IsKey' => true,
        'Key' => 'DPGuid',
        'Value' => '338E2882-D72B-4D17-A241-73E8BC30F458'
      ),
      array(
        'IsKey' => true,
        'Key' => 'StationName',
        'Value' => 'AAAAAAAAAA'
      )
    ),
    array(
      array(
        'IsKey' => true,
        'Key' => 'DPGuid',
        'Value' => 'CC80211D-3D29-4CC2-91A2-F69483D566B5'
      ),
      array(
        'IsKey' => true,
        'Key' => 'StationName',
        'Value' => 'BBBBBBB'
      )
    )
  );
 
  echo "Reading values from: {$utcFrom->format('c')} to: {$utcTo->format('c')}\n\n";
 
  $counter = 0;
 
  do {
    $response  = null;
    $valOffset = 0;
    do {
      $response  = $soapClient->GetData(array(
        'credentials' => $credentials,
        'variablesKey' => $variablesKey,
        'utcFrom' => $utcFrom->format('Y-m-d\TH:i:s\Z'),
        'utcTo' => $utcTo->format('Y-m-d\TH:i:s\Z'),
        'valueOffset' => $valOffset,
        'valueCount' => $valCount,
        'variableCount' => $varCount,
        'variableOffset' => $varOffset
      ));
      $valOffset = $response->nextValueOffset;
      $varOffset = $response->nextVariableOffset;
 
      foreach ($response->GetDataResult->Mvr as $varArray) {
        foreach ($varArray->Keys->KeyValuePair as $kvp) //the set of keys depends on the source of the data
          {
          if ($kvp->Key == 'DPName') {
            echo "\n{$kvp->Value}\n";
            $counter++;
          }
        }
 
        if (isset($varArray->Vals->I)) {
          foreach ($varArray->Vals->I as $val) {
            echo "  t: {$val->Ts}   Interval: {$val->Ivl}  {$valOffset} {$varOffset}\n";
          }
        } else {
          echo "empty\n";
        }
 
      }
 
    } while ($response->nextValueOffset != -1); //-1 - no more data available
  } while ($response->nextVariableOffset != -1); //-1 - no more data available
}
catch (Exception $e) {
  print_r($e);
}
?>