EcoStruxure Geo SCADA Expert Forum
Schneider Electric support forum about installation, configuration, integration and troubleshooting of EcoStruxure Geo SCADA Expert (ClearSCADA, ViewX, WebX).
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-23 04:16 PM . Last Modified: 2023-05-03 12:05 AM
Hi, I am trying to load history values to a tag. I refer to the last section of the below
// Get object
ScxV6DbClient.ScxV6Object O = S.FindObject( "New Analogue Point" );
// The line below doesn't work because Interface is declared in the IDL as a vanilla IDispatch, instead we need to use late-binding via Reflection
// O.Interface.LoadDataValues( Values, Times, Qualities );
// Instead, use reflection:
// Get the Historic aggregate
object Historic = O.Interface.GetType().InvokeMember( "Historic", System.Reflection.BindingFlags.GetProperty, null,O.Interface,null );
// Invoke the LoadDataValues method
if ( Historic != null )
Historic.GetType().InvokeMember( "LoadDataValues", System.Reflection.BindingFlags.InvokeMethod, null, Historic, new object[] { Values, Times, Qualities } );
I have changed the code to below
ScxV6Server S = new ScxV6Server();
S.Connect("Local", "admin", "admin");
// Get object
ScxV6DbClient.ScxV6Object O = S.FindObject("System.Xxxxx.HistoryAnalogPoint");
// Get the Historic aggregate
object Historic = O.Interface.GetType().InvokeMember("Historic", System.Reflection.BindingFlags.GetProperty, null, O.Interface, null);
//// Invoke the LoadDataValues method
if (Historic != null)
Historic.GetType().InvokeMember("LoadDataValues", System.Reflection.BindingFlags.InvokeMethod, null, Historic, new object[] { sampleGS[i], sampleStartDateTime[i], 192 });
When the code gets to the line - ScxV6Server S = new ScxV6Server();
the following error occurs (Class not registered).
System.Runtime.InteropServices.COMException
HResult=0x80040154
Message=Retrieving the COM class factory for component with CLSID {EEAD2002-0777-11D2-AF05-0000E82E7A14} failed due to the following error: 80040154 Class not registered (0x80040154 (REGDB_E_CLASSNOTREG)).
Source=DNP3FT
StackTrace:
at InsertHistoryCOMAPI.Program.Main(String[] args) in C:\Users\Administrator\source\repos\\Program.cs:line 186
Thanks,
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-24 06:13 PM
It's CHistoryBase which has the aggregate.
Why are you doing the GetType()?
Why not just obtain the Historic aggregate on the object that you want to load the historic data for, and then call InvokeMethod on that aggregate, and pass in the required items...
i.e.
aggr.InvokeMethod("LoadDataValue", new object[] {reason, quality, timestamp, value});
or
aggr.InvokeMethod("LoadDataValues", new object[] {valueArray, timestampArray, qualityArray, reasonArray});
or
aggr.InvokeMethod("LoadDataValuesEx", new object[] {valueArray, timestampArray, qualityArray, statusArray, stateArray, reasonArray, msStateArray, putAsideArray} );
My offline code example actually shows a version without the new object[] {...}..., and instead just directly passing the arguments after the methodName. It doesn't match the .NET API help method definition... but it's obviously worked for me at some time. I haven't fired up Visual Studio to check out the InvokeMethod signature.. maybe it does accept a variable number of arguments.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-23 05:42 PM
Try
new Serck.ScxV6Server()
If that doesn't work you may need to regsvr32 DBClient.dll (in the x86 ClearSCADA installation folder), the installer should do that but maybe something went wonky somewhere.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-23 06:50 PM . Last Modified: 2021-02-24 01:10 AM
Hi, I added the Serk, it still had an error.
However, I removed the Serk and after that all errors cleared.
I am now able to run the code further.
I find it unclear at the moment, what is the format it is looking for as regards to Values, Times, Qualities.
Historic.GetType().InvokeMember( "LoadDataValues", System.Reflection.BindingFlags.InvokeMethod, null, Historic, new object[] { Values, Times, Qualities } );
Should it be more { Value, Time, Quality }? Value = 4.45, Time = 2021/02/24 12:30:22:55, Quality = 192?
If I can get it to write one value to the history of a point it would be a start.
Thanks,
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-24 03:00 AM
What does the schema say the arguments to LoadDataValues should be?
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-24 12:41 PM . Last Modified: 2023-04-25 04:09 AM
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-24 12:41 PM . Last Modified: 2023-04-25 04:09 AM
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-24 12:44 PM . Last Modified: 2021-02-24 02:10 PM
Thanks Adam, I hadn't found that.
Thanks,
Hi, I notice the later article indicates four parameters
LoadDataValue( Value{Variant}, Timestamp{Time}, Quality{Long}, Reason{Byte} )
where the first indicates three
{ Values, Times, Qualities }
which should it be?
So I have tried
{ sampleGS[i], sampleStartDateTime[i], sampleQuality[i], sampleReason[i] }
which when written to the console looks like
4.0218887,2020,07,22,16,11,38,010,192,8 this may not be correct format?
This throws an error
System.Reflection.TargetInvocationException
HResult=0x80131604
Message=Exception has been thrown by the target of an invocation.
Source=System.Private.CoreLib
StackTrace:
at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args)
at InsertHistoryCOMAPI.Program.Main(String[] args) in C:\Users\Administrator\source\repos\Xxxxx\Program.cs:line 200
Inner Exception 1:
ArgumentException: Value does not fall within the expected range.
Thanks,
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-24 03:02 PM
If using C# recommendations are:
LoadDataValues requires ARRAYS, not single values
LoadDataValue requires single values, not arrays
You should use DateTimeOffset as DateTime inputs to functions, and expect DateTimeOffset as return values.
You shouldn't explicitly "box" 'Value' (variant) datatypes, you can use the native intrinsic type just fine.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-24 04:16 PM
Hi Bevan,
where in the schema were you referring to above please.
ok, I will try LoadDataValue.
Can any body give correct variable type and values that I can place into the line below, that they know works, so that I can at least see it work please.
Historic.GetType().InvokeMember("LoadDataValue", System.Reflection.BindingFlags.InvokeMethod, null, Historic, new object[] { sampleValueTest, sampleStartDateTimeTest, sampleQualityTest });
sampleValueTest
sampleStartDateTimeTest
sampleQualityTest
Thanks,
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-24 06:13 PM
It's CHistoryBase which has the aggregate.
Why are you doing the GetType()?
Why not just obtain the Historic aggregate on the object that you want to load the historic data for, and then call InvokeMethod on that aggregate, and pass in the required items...
i.e.
aggr.InvokeMethod("LoadDataValue", new object[] {reason, quality, timestamp, value});
or
aggr.InvokeMethod("LoadDataValues", new object[] {valueArray, timestampArray, qualityArray, reasonArray});
or
aggr.InvokeMethod("LoadDataValuesEx", new object[] {valueArray, timestampArray, qualityArray, statusArray, stateArray, reasonArray, msStateArray, putAsideArray} );
My offline code example actually shows a version without the new object[] {...}..., and instead just directly passing the arguments after the methodName. It doesn't match the .NET API help method definition... but it's obviously worked for me at some time. I haven't fired up Visual Studio to check out the InvokeMethod signature.. maybe it does accept a variable number of arguments.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-25 02:42 PM
Hi, I was attempting to follow the below,
// Get object
ScxV6DbClient.ScxV6Object O = S.FindObject( "New Analogue Point" );
// The line below doesn't work because Interface is declared in the IDL as a vanilla IDispatch, instead we need to use late-binding via Reflection
// O.Interface.LoadDataValues( Values, Times, Qualities );
// Instead, use reflection:
// Get the Historic aggregate
object Historic = O.Interface.GetType().InvokeMember( "Historic", System.Reflection.BindingFlags.GetProperty, null,O.Interface,null );
// Invoke the LoadDataValues method
if ( Historic != null )
Historic.GetType().InvokeMember( "LoadDataValues", System.Reflection.BindingFlags.InvokeMethod, null, Historic, new object[] { Values, Times, Qualities } );
I thought this would allow for data to be loaded into the history of the point.
Thanks,
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-25 05:34 PM
Here's something from @sbeadle , it's where I'd start from...
https://github.com/GeoSCADA/Utilities-and-Examples/blob/main/InsertHistoricData/Program.cs
His LoadDataValue example
// Add a value
Object[] p1 = new Object[4];
p1[0] = 1;
p1[1] = 192;
p1[2] = now;
p1[3] = 1;
PointObj.Aggregates["Historic"].InvokeMethod("LoadDataValue", p1);
Although I prefer the inline definition of the new object[] {} (as my previous example used)
He's got another example here:
https://github.com/GeoSCADA/Utilities-and-Examples/blob/main/SetInternalPoint/Program.cs
where he uses InvokeMethod on the base object (i.e. PointObj from the above example) but has a longer qualifier on the method name ("Historic.RawValues" in this version... but that would be "Historic.LoadDataValue" if you wanted to invoke the LoadDataValue method instead).
The tproject concept has quite a lot of jumping backwards through hoops, which seems unnecessary.
Perhaps back when it was created the Aggregates collection didn't exist.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-25 05:52 PM . Last Modified: 2021-02-25 07:47 PM
Hi, I went back through some older code I had and came across this.
I just changed the date and this worked.
Apart from having to change the date to a more recent one of course.
DBObject TestPoint;
Aggregate HistAgg;
//Object[] argsTo;
DateTime dt;
Object[] argsTo = new Object[4];
using (Connection conn = new Connection("ClearSCADA"))
{
// Connect to local server
SecureString passwd = new SecureString();
string strPassword = "admin";
foreach (char c in strPassword)
passwd.AppendChar(c);
passwd.MakeReadOnly();
conn.Connect("localhost");
conn.LogOn("admin", passwd);
//string pointValue = dict["Test2"];
// Get the point
TestPoint = conn.GetObject("System.Dashboard.Engineering Dashboard.Work Orders.Points.HistoryAnalogPoint");
// If Historic is enabled for the point, insert historic data
if (TestPoint.Aggregates.TryGetValue("Historic", out HistAgg) == true)
{
argsTo[0] = "4"; // Reason
//argsTo[0] = column1[0];
//argsTo[1] = "1"; // Quality
argsTo[1] = "192"; // Quality
//argsTo[1] = column3[0]; // Quality
dt = new DateTime(2020, 3, 02, 11, 55, 52);
argsTo[2] = new System.DateTimeOffset(dt);
//argsTo[2] = column2[0]; //DateTime
//argsTo[3] = "88";
////argsTo[3] = column4[0]; //Value
argsTo[3] = 4.45; //Value
HistAgg.InvokeMethod("LoadDataValue", argsTo);
}
conn.LogOff();
conn.Disconnect();
Thanks,
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-25 10:28 PM
Hi, these are the settings for my Geo SCADA.
This a sample of the data I want to import
4.0218887,2020,07,22,16,11,38,010,192,8
3.1718216,2020,07,22,16,11,53,010,192,8
This is what I am getting in Geo SCADA
If I use the below it wont import historic values
dt = new DateTime(2020, 2, 26, 11, 55, 52);
If I change the 2020 to 2021 it imports.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-02-26 12:47 AM
Assuming that you were running your code at close to 5pm on the 26th February 2021... and you have a historic configuration set to keep data for 52 weeks... then 52*7 = 364 days... so the 26th February 2020 is NOT within your configured historic retention window.
In fact you're two days out, since last year was a leap year..
You should go back through the help files for the settings in the Server Configuration pane, really see what it says for each of the fields, and think about how that will relate to what you are trying to do.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-07-11 08:21 PM
Hi, is it possible to change the code above to do a LoadDataFile.
Thanks,
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: 2021-07-16 08:21 PM
Yes, you'll just want to look at the schema to see what arguments you need to supply to that method, and note that the path must be:
Link copied. Please paste this link to share this article on your social media post.
Create your free account or log in to subscribe to the board - and gain access to more than 10,000+ support articles along with insights from experts and peers.