Wie kann ich Rohdaten von einem Proficy Historian abfragen?
Frage
Wie kann ich rohe Zeitreihendaten von einem Proficy Historian abrufen / iHistorian?
Idealerweise würde ich für einen bestimmten Tag zwischen zwei Daten für Daten fragen.
Lösung
Es gibt verschiedene Sampling-Modi können Sie mit experimentieren.
- Raw
- Interpolated
- Lab
- Trend
- Berechnet
Diese Modi stehen zur Verfügung alle folgenden APIs.
- User API (ihuapi.dll)
- SDK (ihsdk.dll)
- OLEDB (iholedb.dll)
- Client Acess API (Proficy.Historian.ClientAccess.API)
Von diesen sind der Trend-Sampling-Modus ist wahrscheinlich das, was Sie wollen, da es speziell für Charting / Trending ausgelegt ist. Obwohl, Labor und interpoliert kann auch nützlich sein.
Lesen Sie das elektronische Buch für mehr Informationen zu den einzelnen Sampling-Modus. Auf meinem Rechner ist es als C:\Program Files\GE Fanuc\Proficy Historian\Docs\iHistorian.chm
gespeichert, und ich habe die Version 3.5 installiert. Achten Sie besonders auf den folgenden Abschnitten.
- Verwenden des Historian OLE DB-Provider
- Weitere Themen | Retrieval
Hier ist, wie man eine OLEDB konstruieren kann Trend-Sampling zu tun.
set
SamplingMode = 'Trend',
StartTime = '2010-07-01 00:00:00',
EndTime = '2010-07-02 00:00:00',
IntervalMilliseconds = 1h
select
timestamp,
value,
quality
from
ihRawData
where
tagname = 'YOUR_TAG'
Es werden die entsprechenden Methoden, um die User-API und das SDK sind komplex (um so mehr mit dem User-API), da sie eine Menge Sanitär im Code benötigen Setup zu bekommen. Der Client Access API ist neuer und verwendet WCF hinter den Kulissen.
By the way, gibt es einige Einschränkungen mit der OLEDB Methode though.
- Trotz allem, was die Dokumentation sagt, ich habe nie in der Lage nativen Abfrageparameter an der Arbeit. Das ist ein Hemmschuh, wenn Sie es mit SQL Server Reporting Services zum Beispiel verwendet werden soll.
- Sie können nicht Proben in das Archiv schreiben oder in irgendeiner Weise auf die Historian-Konfiguration Änderungen wie das Hinzufügen / Ändern von Tags, Schreiben von Nachrichten, etc.
- Es kann ein wenig langsam in einigen Fällen sein.
- Es hat keine Bestimmung für mehrere Tagnamen in die Spalten crosstabbing und dann Vortragen Proben, so dass ein Wert für jeden Zeitstempel und Tag-Kombination besteht. Der Trend Sampling-Modus bekommt man auf halbem Weg da, aber immer noch nicht Kreuztabellen- und nicht wirklich roh Proben laden. Dann wieder die User-API und SDK kann nicht dies entweder.
Andere Tipps
Ein Kollege von mir setzt diese zusammen:
In web.config:
<add name="HistorianConnectionString"
providerName="ihOLEDB.iHistorian.1"
connectionString="
Provider=ihOLEDB.iHistorian;
User Id=;
Password=;
Data Source=localhost;"
/>
In der Datenschicht:
public DataTable GetProficyData(string tagName, DateTime startDate, DateTime endDate)
{
using (System.Data.OleDb.OleDbConnection cn = new System.Data.OleDb.OleDbConnection())
{
cn.ConnectionString = webConfig.ConnectionStrings.ConnectionStrings["HistorianConnectionString"];
cn.Open();
string queryString = string.Format(
"set samplingmode = rawbytime\n select value as theValue,Timestamp from ihrawdata where tagname = '{0}' AND timestamp between '{1}' and '{2}' and value > 0 order by timestamp",
tagName.Replace("'", "\""), startDate, endDate);
System.Data.OleDb.OleDbDataAdapter adp = new System.Data.OleDb.OleDbDataAdapter(queryString, cn);
DataSet ds = new DataSet();
adp.Fill(ds);
return ds.Tables[0];
}
}
Update:
Das funktionierte gut, aber wir liefen in ein Problem mit Tags, die nicht sehr häufig aktualisiert werden. Wenn der Tag nicht in der Nähe der Anfang oder das Ende der angeforderten und endDate startdate aktualisiert wurde, würde sich die Trends schlecht. Schlimmer noch, waren immer noch Fälle, in denen es keine expliziten Punkte während des Fensters aufgefordert waren -. We'd zurück keine Daten bekommen
ich beschließen dies durch drei Abfragen machen:
- Der vorherige Wert vor das Start-Datum
- Die Punkte zwischen startdate und endDate
- Der nächste Wert nach die endDate
Dies ist ein potenziell ineffizienter Weg, es zu tun, aber es funktioniert:
public DataTable GetProficyData(string tagName, DateTime startDate, DateTime endDate)
{
DataSet ds = new DataSet();
string queryString;
System.Data.OleDb.OleDbDataAdapter adp;
using (System.Data.OleDb.OleDbConnection cn = new System.Data.OleDb.OleDbConnection())
{
cn.ConnectionString = proficyConn.ConnectionString;
cn.Open();
// always get a start value
queryString = string.Format(
"set samplingmode = lab\nselect value as theValue,Timestamp from ihrawdata where tagname = '{0}' AND timestamp between '{1}' and '{2}' order by timestamp",
tagName.Replace("'", "\""), startDate.AddMinutes(-1), startDate);
adp = new System.Data.OleDb.OleDbDataAdapter(queryString, cn);
adp.Fill(ds);
// get the range
queryString = string.Format(
"set samplingmode = rawbytime\nselect value as theValue,Timestamp from ihrawdata where tagname = '{0}' AND timestamp between '{1}' and '{2}' order by timestamp",
tagName.Replace("'", "\""), startDate, endDate);
adp = new System.Data.OleDb.OleDbDataAdapter(queryString, cn);
adp.Fill(ds);
// always get an end value
queryString = string.Format(
"set samplingmode = lab\nselect value as theValue,Timestamp from ihrawdata where tagname = '{0}' AND timestamp between '{1}' and '{2}' order by timestamp",
tagName.Replace("'", "\""), endDate.AddMinutes(-1), endDate);
adp = new System.Data.OleDb.OleDbDataAdapter(queryString, cn);
adp.Fill(ds);
return ds.Tables[0];
}
}
Und ja, ich weiß, sollten diese Abfragen parametriert werden.
Michael - in IP21 gibt es einen „Interpolated“ Tisch, sowie die „Ist“ -Daten Punkttabelle. Hat Proficy haben das auch?
Wir schrieben ein Wrapper-DLL, die so sah wie folgt aus:
[DllImport("IHUAPI.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "ihuReadRawDataByTime@24")]
public static extern int ihuReadRawDataByTime(int serverhandle, string tagname, ref IHU_TIMESTAMP startTime, ref IHU_TIMESTAMP endTime, ref int noOfSamples, ref IHU_DATA_SAMPLE* dataValues);
...
private int _handle;
public HistorianTypes.ErrorCode ReadRawByTime(string tagName, DateTime startTime, DateTime endTime,
out double[] timeStamps, out double[] values, out IhuComment [] comments)
{
var startTimeStruct = new IhuApi.IHU_TIMESTAMP(); //Custom datetime to epoch extension method
var endTimeStruct = new IhuApi.IHU_TIMESTAMP();
int lRet = 0;
int noOfSamples = 0;
startTimeStruct = DateTimeToTimeStruct(dstZone.ToUniversalTime(startTime));
endTimeStruct = DateTimeToTimeStruct(dstZone.ToUniversalTime(endTime));
IhuApi.IHU_DATA_SAMPLE* dataSample = (IhuApi.IHU_DATA_SAMPLE*)new IntPtr(0);
try {
lRet = IhuApi.ihuReadRawDataByTime
(
_handle, // the handle returned from the connect
tagName, // the single tagname to retrieve
ref startTimeStruct, // start time for query
ref endTimeStruct, // end time for query
ref noOfSamples, // will be set by API
ref dataSample // will be allocated and populated in the user API
);
....
Einige Hinweise sind, dass iFIX überprüft, ob die DLL beim Start geladen wird, so dass Sie Dinge tun müssen, wie dynamisch das Laden / Entladen der DLL, so dass andere Anwendungen nicht abstürzen. Wir haben dies durch Löschen / Hinzufügen von Registrierungsschlüssel on the fly.
Ein weiterer ist, wenn Sie 10.000 Proben und 1 der Proben abfragen beschädigt sind, werden sie alle 10.000 Proben fallen. Sie benötigen einen schlechten Datenhandler zu implementieren, die auf beiden Seiten der schlechten Daten und Schritt in Schritten beginnen, werden alle Daten auf beiden Seiten der schlechten Probe zu erhalten.
Es gibt mehr C-Header-Dateien, die alle Fehlercodes und den Funktions-Header für den DLL enthalten.