Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
en:sw:01-mervis:03-mervis-db [2019/03/05 09:16]
jan_kozak
en:sw:01-mervis:03-mervis-db [2021/05/18 10:57]
avsetula
Line 1: Line 1:
 ====== Mervis DB ====== ====== Mervis DB ======
-The Mervis DB is software for long-term saving of data from the PLCIt is available ​as cloud service ​and also as an on-premises installation+{{ :​cs:​sw:​01-mervis:​mervis_db.png?​nolink&​400 |}} 
 + 
 +Mervis DB je vysoce optimalizovaná databáze určená pro dlouhodobé ukládání dat z kontrolerů,​ aplikací ​mnoha jiných zařízení,​ které využívají otevřeného API databáze.  
 + 
 +Hlavní využití s kontroléry Unipi je ukládání historických dat a jejich analýza pomocí [[cs:​sw:​01-mervis:​05-mervis-scada|Mervis SCADA]].  
 + 
 + 
 +===== Služba je dostupná v cloudové i lokální variantě ===== 
 + 
 +<​html><​span class="​kbBlue-H5alt">​Cloudová varianta</​span></​html>​\\ 
 +Standardním způsobem použití Mervis DB je varianta cloudové služby. Přístup do databáze je umožněn po [[https://​www.unipi.technology/​cs/​mervis-p56|zakoupení]] a [[cs:​sw:​01-mervis:​getting-mervis-licence-hidden|aktivaci licence Mervis]]. 
 + 
 +Návod pro nastavení PLC a ukládání dat do Mervis DB naleznete v návodu: [[cs:​sw:​01-mervis:​storing-data-to-mervis-db-hidden|]] 
 + 
 +---- 
 + 
 +<​html><​span class="​kbBlue-H5alt">​Varianta lokální instalace</​span></​html>​\\ 
 +Službu Mervis DB lze provozovat i na lokálním serveru. Pro více informací kontaktujte naše [[[email protected]|obchodní oddělení]]. 
 + 
 +/* 
 +<​html><​span class="​kbBlueLightText">​Minimální požadavky serveru Mervis DB pro lokální instalaci:</​span></​html>​ 
 +  * OS: Windows 7 nebo Windows Server 2012 a nainstalovaný framework .NET4.5 
 +  * IIS - doporučeno 
 +  * HDD: 2 GB + prostor pro data 
 +  * RAM: 1 GB 
 +*/ 
 + 
 +===== Migrace a správa dat ===== 
 +V rámci placené služby nabízíme také několik variant správy dat: 
 +  * Přesun dat mezi účty Mervis DB, včetně možné úpravy časového razítka 
 +  * Import dat z Excelového,​ nebo CSV souboru 
 +  * Export dat do Excelového,​ nebo CSV souboru 
 +  * Vymazání nechtěných dat z Mervis DB 
 + 
 +V případě zájmu o některou z výše zmíněných služeb kontaktujte naše [[[email protected]|obchodní oddělení]]. 
 + 
 +\\ 
 +{{cs:​sw:​01-mervis:​migrace_mervis-db_cz.png?​direct|}} 
 + 
 + 
 +===== Mervis DB Viewer ===== 
 +K prohlížení ukládaných dat z cloudové instance Mervis DB na serverech Unipi lze využít Mervis DB Viewer. Jedná se o on-line aplikaci, která se spojí s databází a zobrazí dle zadaných parametrů (např. časového rozmězí) data které obsahuje.  
 + 
 +URL adresa: [[https://​db.unipi.technology/​viewer]]. 
 + 
 +{{cs:​sw:​01-mervis:​db-mervis-info-viewer.png?​direct|}} 
 + 
 + 
 +===== API ===== 
 +Mervis DB nabízí otevřené rozhraní protokolu SOAP. Odpovídající WSDL je k ke stažení:​ 
 + 
 +  * {{:​cs:​sw:​01-mervis:​mervisdb_wsdl-2017-07-12.zip|}} 
 + 
 +Pro speciální použití existují i další rozhraní pro komunikaci s Mervis DB - pro jejich použití a popis kontaktujte prosím [[cs:​contact:​00-start|technickou podporu]]. 
 + 
 +==== Seznam základních podporovaných funkcí ==== 
 + 
 +^ Funkce ​                                     ^ Popis                                                                                                                                                 ^ 
 +| SaveData ​                                   | Uloží jeden, nebo více záznamů z jedné nebo více proměnných. ​                                                                                         | 
 +| GetData/​GetDataAsync ​                       | Přečte jeden, nebo více záznamů z jedné nebo více proměnných. ​                                                                                        | 
 +| GetParticularData/​GetParticulatDataAsync ​   | Optimalizovaná metoda pro čtení „speciálních“ dat - poslední hodnota, poslední hodnota po určitém časovém okamžiku atd.                               | 
 +| GetVariables ​                               | Získá seznam proměnných. ​                                                                                                                           | 
 +| GetAllVariables ​                            ​| ​                                                                                                                                                      | 
 +| ServerAlive ​                                | Zastaralé ​                                                                                                                                            | 
 +| DeleteVariables ​                            ​| ​                                                                                                                                                      | 
 +| DeleteData ​                                 |                                                                                                                                                       | 
 +| EnsureVariables ​                            ​| ​                                                                                                                                                      | 
 +| GetTransformedData/​GetTransformedDataAsync ​ | Metoda čtení agregovaných výsledků s daným časovým obdobím, agregace může být min, max, integrál, vážený průměr, první, poslední a medián ​  | 
 +| GetServerVersion ​                           |                                                                                                                                                       | 
 +| GetVariableStats ​                           | Zastaralé ​                                                                                                                                            | 
 +| GetVariableStatsAsync ​                      | Zastaralé ​                                                                                                                                            | 
 +| CheckCredentials ​                           |                                                                                                                                                       | 
 + 
 +==== Příklady použití ==== 
 + 
 +=== C# === 
 + 
 +{{cs:​sw:​01-mervis:​mervis_db_csharp.png?​direct|}} 
 + 
 +<​html><​span class="​kbBlueText">​Příklady ke stažení:</​span></​html>​ \\ 
 +  * {{cs:​sw:​01-mervis:​mervisdb_getdata_example.zip|}} 
 +  * {{cs:​sw:​01-mervis:​mervisdb_savedata_example.zip|}} ​    
 +     
 +<​html><​span class="​kbBlueText">​Příklad kódu:</​span></​html>​ \\ 
 + 
 +<code csharp| MervisDB_GetData_Example.cs>​ 
 +using System; 
 +using System.Linq;​ 
 +using System.Threading.Tasks;​ 
 +using MervisDb_GetData_Example.MervisDbService;​ 
 +  
 +namespace MervisDb_GetData_Example { 
 + class Program { 
 +  static void Main(string[] args) { 
 +   // 
 +   // Demo of asynchronous methods. 
 +   // 
 +   var task = Task.Run(async() => { 
 + // 
 + // 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("​HistoryAccess",​ "​http://​db.unipi.technology/​dbaccess"​)) { 
 + // 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. 
 + KeyValuePair[][] keys = new KeyValuePair[][] { 
 +   new KeyValuePair[] { 
 + new KeyValuePair { 
 + Key = "​DPGuid",​ Value = "​338E2882-D72B-4D17-A241-73E8BC30F458"​ 
 + }, new KeyValuePair { 
 + Key = "​StationName",​ Value = "​AAABBB"​ 
 +
 +    }, 
 +    new KeyValuePair[] { 
 + new KeyValuePair { 
 + Key = "​DPGuid",​ Value = "​CC80211D-3D29-4CC2-91A2-F69483D566B5"​ 
 + }, new KeyValuePair { 
 + Key = "​StationName",​ Value = "​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.Vals) { 
 + Console.WriteLine("​{0}->​{1} [{2}] {3}", value.Ts, value.Gt, value.Hvt, value.Dv /* Use value type according to the Hvt (History Value Type) */ ); 
 +
 +    } 
 +  
 +    ​valueOffset = result.NextValueOffset;​ 
 +    ​variableOffset = result.NextVariableOffset;​ 
 +   } 
 +   while (valueOffset != -1); 
 +
 + while (variableOffset != -1); 
 +
 +   }); 
 +  
 +   ​Console.WriteLine("​DB communication is running in background"​);​ 
 +  
 +   try { 
 + task.Wait();​ 
 +   } catch (Exception exc) { 
 + Console.WriteLine("​Exception:​ {0}", exc.ToString());​ 
 +   } 
 +  
 +   ​Console.WriteLine("​DB communication finished"​);​ 
 +  
 +   ​Console.ReadLine();​ 
 +  } 
 + } 
 +
 +</​code>​ 
 + 
 +<code csharp| 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 void Main(string[] args) 
 +
 + // 
 + // Demo of asynchronous methods. 
 + // 
 + var task = Task.Run(async () => 
 +
 + // 
 + // 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("​HistoryAccess",​ "​http://​db.unipi.technology/​dbaccess"​)) 
 +
 + // 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 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 KeyValuePair[] //​ identification of the variable. At least one key-value pair must be "​IsKey"​ to identify a variable. 
 +
 + new KeyValuePair { IsKey = true, Key = "​Root",​ Value = "​Building A"}, 
 + new KeyValuePair { IsKey = true, Key = "​Level1",​ Value = "Floor 1"}, 
 + new KeyValuePair { IsKey = true, Key = "​Level2",​ Value = "Room 7"}, 
 + new KeyValuePair { IsKey = true, Key = "​Level3",​ Value = "​Temperature"​},​ 
 + new KeyValuePair { IsKey = false, Key = "​Description",​ Value = "​Temperature in the room 7"}, 
 + new KeyValuePair { IsKey = false, Key = "​Unit",​ Value = "​°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);​ 
 +
 + }); 
 +  
 + Console.WriteLine("​DB communication is running in background"​);​ 
 +  
 + try 
 +
 + task.Wait();​ 
 +
 + catch (Exception exc) 
 +
 + Console.WriteLine("​Exception:​ {0}", exc.ToString());​ 
 +
 +  
 + Console.WriteLine("​DB communication finished"​);​ 
 +  
 + Console.ReadLine();​ 
 +
 +
 +
 +</​code>​ 
 + 
 + 
 +<code csharp| 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 void Main(string[] args) 
 +
 + // 
 + // Demo of asynchronous method. 
 + // 
 + var task = Task.Run(async () => 
 +
 + // 
 + // 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("​HistoryAccess",​ "​http://​db.unipi.technology/​dbaccess"​)) 
 +
 + // 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. 
 + KeyValuePair[][] variableKeys = new KeyValuePair[][] { 
 + new KeyValuePair[] { 
 + new KeyValuePair (false, /*Key*/ "​DPGuid",​ /*Value*/ "​338E2882-D72B-4D17-A241-73E8BC30F458"​),​ 
 + new KeyValuePair (false, /*Key*/ "​StationName",​ /*Value*/ "​AAABBB"​) 
 + }, 
 + new KeyValuePair[] { 
 + new KeyValuePair (false, /*Key*/ "​DPGuid",​ /*Value*/ "​CC80211D-3D29-4CC2-91A2-F69483D566B5"​),​ 
 + new KeyValuePair (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"​);​ 
 +  
 + try 
 +
 + task.Wait();​ 
 +
 + catch (Exception exc) 
 +
 + Console.WriteLine("​Exception:​ {0}", exc.ToString());​ 
 +
 +  
 + Console.WriteLine("​DB communication finished"​);​ 
 +  
 + Console.ReadLine();​ 
 +
 +  
 +
 +
 +</​code>​ 
 + 
 + 
 +=== Matlab === 
 + 
 +{{cs:​sw:​01-mervis:​mervisdb_matlab_api.png?​direct|}} 
 + 
 +== Podporované funkce: == 
 +^ Funkce ​                ^ Popis                                                          ^ 
 +| SaveData ​              | Uloží jeden, nebo více záznamů z jedné nebo více proměnných. ​  | 
 +| GetData ​               | Přečte jeden, nebo více záznamů z jedné nebo více proměnných. ​ | 
 +| GetDataUnmerged ​       | Přečte jeden, nebo více záznamů z jedné nebo více proměnných. Umožňuje nastavit více možností než funkce GetData. | 
 +| GetDataOrigin ​         | Přečte data přesně tak, jak jsou uložena v databázi. ​          | 
 +| DeleteVariable ​        | Smažte celou proměnnou nebo určitý interval. ​                  | 
 +| GetRequiredTimestamp ​  | Získej časové razítko v závislosti na nastavení vstupu. ​       | 
 + 
 +== Toolbox == 
 +Pro komunikaci Matlabu s Mervis DB potřebujete nainstalovat toolbox:  
 +  * {{cs:​sw:​01-mervis:​mervisdb_matlabtoolbox.zip|}} 
 +  * Zobrazení nápovědy ke každé z funkcí je možné: <code matlab>​ 
 +help MervisDatabse.supported_function_name 
 +</​code>​ 
 + 
 +== Kód == 
 +<code matlab| 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);​ 
 +</​code>​ 
 + 
 +=== PHP === 
 + 
 +== Kód == 
 +<code php| 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://​db.unipi.technology/​dbaccess'​);​ 
 +  
 +  $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);​ 
 +
 +?> 
 +</​code>​ 
 + 
 + 
 +/* 
 +===== Excel Exporter ===== 
 +K dispozici je také nástroj pro příkazovou řádku s názvem Excel Exporter, který může z vašich dat v Mervis DB vytvořit plně přizpůsobitelný soubor aplikace Microsoft Excel. 
 + 
 +Jeho základem je šablona XLSX souboru, ve kterém můžete pomocí speciální syntaxe umisťovat data z Mervis DB. 
 + 
 +==== Příklad: ==== 
 +V tomto příkladu si ukážeme, jak exportovat jednu proměnnou z Mervis DB do Excelového souboru. 
 + 
 +    Obrázek 
 + 
 +=== Soubor s konfigurací === 
 +Nejprve je třeba vytvořit konfigurační soubor XML, kde se definuje mapování mezi sadou klíčů popisujících jednotlivé proměnné Mervis DB a některými názvy proměnných,​ které budou použity později v šabloně aplikace Excel. 
 + 
 +Můžete také definovat název výstupního souboru a také zda má být soubor pouze aktualizován nebo přepsán.  
 + 
 +<code xml| ExcelDemo.xml>​ 
 +<?xml version="​1.0"​ encoding="​utf-8"?>​ 
 +<​RcWareDbExporterVariableTemplateFile>​ 
 + <​exportTemplate>​exceldemo.xlsx</​exportTemplate>​ 
 + <​exportOutput>​exceldemo_[yyyy-MM-dd_HH-mm].xlsx</​exportOutput>​ 
 + <​fillIncrementaly>​false</​fillIncrementaly>​ 
 + <​variables>​ 
 +   <​variable name="​OutsideTemperature">​ 
 +    <​keyValuePairs>​ 
 + <​keyValuePair key="​DPGuid"​ value="​338E2882-D72B-4D17-A241-73E8BC30F458"​ isId="​true"​ /> 
 + <​keyValuePair key="​StationName"​ value="​ENERGO"​ isId="​true"​ /> 
 +    </​keyValuePairs>​ 
 +   </​variable>​ 
 +   <​variable name="​HereCouldBeSomeOtherVariable">​ 
 +    <​keyValuePairs>​ 
 + <​keyValuePair key="​DPGuid"​ value="​338E2882-D72B-4D17-A241-73E8BC30F458"​ isId="​true"​ /> 
 + <​keyValuePair key="​StationName"​ value="​ENERGO"​ isId="​true"​ /> 
 +    </​keyValuePairs>​ 
 +   </​variable>​ 
 + </​variables>​ 
 +</​RcWareDbExporterVariableTemplateFile>​ 
 +</​code>​ 
 + 
 +=== Excelová šablona === 
 +Pomocí jednoduchého jazyka šablony můžete definovat, které hodnoty z Mervis DB se maji umístit na jaké místo ve výstupním souboru aplikace Excel.  
 + 
 +<​code>​ 
 +[YEAR:​2016|MONTH:​1|DAY:​15|HOUR:​12|MINUTE:​0|VARIABLE:​OutsideTemperature] 
 +</​code>​ 
 + 
 +Libovolnou z hodnot definujících čas lze vynechat a bude nahrazena aktuálním datem, časem nebo hodnotami předanými prostřednictvím parametrů příkazového řádku.  
 + 
 +    obrázek 
 + 
 + 
 +=== Spuštění exportéru === 
 +<code | runExcelDemo.bat>​ 
 +.\ESG.RcWareDb.DataExporter\ESG.RcWareDb.DataExporter.exe tmpPath:"​ExcelDemo.xml"​ srvUrl:"​http://​db.unipi.technology/​dbaccess"​ srvUser:"​exceldemo"​ srvPsw:"​pfi4cj4qrj"​ timeTolerance:​300 toleranceType:​before 
 +</​code>​ 
 + 
 +Pro více informací spusťte: 
 +<code | runHelpInfo.bat>​ 
 +.\ESG.RcWareDb.DataExporter\ESG.RcWareDb.DataExporter.exe --help 
 +</​code>​ 
 + 
 +=== Výstup === 
 +Výstupní soubor je definován v konfiguračním souboru XML. Ukázkový výstup by měl vypadat následovně:​  
 + 
 +    obrázek 
 + 
 +=== Celý příklad ke stažení: === 
 + 
 +Příklad: excelexporterdemo.zip 
 +*/ 
 + 
  
-To view your data use the online Viewer: [[https://​db.unipi.technology/​viewer]]