// Import to AF /// <summary> /// Gets value from Matlab and writes it to AF. /// </summary> /// <remarks> Will not write, if the Attribute is read-only. A Matlab Variable Name must be input.</remarks> /// <param name="path"> The path to the Element to search with.</param> /// <param name="workspaceVariableName">The variable name in Matlab being used.</param> /// <param name="AFName">The attribute name in AF being written to.</param> public void ImportToAF(string path, string workspaceVariableName, string AFName) { object val = null; double dbVal; //LOGIC: A variable name must be entered. try { MatlabAccess.GetWorkspaceData(workspaceVariableName, "base", out val); } catch { mainForm.Status("Couldn't find the variable in the Matlab Workspace"); } List <string> searchPaths = new List <string>() { path }; AFKeyedResults <string, AFElement> results = AFElement.FindElementsByPath(searchPaths, null); AFElement Element = results[path]; AFAttribute Attribute = Element.Attributes[AFName]; double.TryParse(val.ToString(), out dbVal); try { AFAccess.writeToAF(Element, Attribute, dbVal); } catch { mainForm.Status("Cannot Write to this Attribute"); } }
public GraphQlAfElement GetAfElementByPath(ResolveFieldContext context, string aAfElementPath) { aAfElementPath = cleanupPath(aAfElementPath); if (attemptLogin(context, getPiSystemName(aAfElementPath))) { var aAfElementSearch = AFElement.FindElementsByPath(new string[] { aAfElementPath }, null); if (aAfElementSearch.Count == 0) { context.Errors.Add(new ExecutionError($"AFElement path '{aAfElementPath}' not correct.")); return(null); } else { var aAfElement = aAfElementSearch.First() as AFElement; var afElementsField = GraphQlHelpers.GetFieldFromContext(context, "afElements"); var afAttributesField = GraphQlHelpers.GetFieldFromContext(context, "afAttributes"); var graphQlAfElement = new GraphQlAfElement(aAfElement, afElementsField, afAttributesField); return(graphQlAfElement); } } else { return(null); } }
internal static void GetWebApiClient(ref WebClient client, ref AFElement configElement, ref bool disableWrites, ref bool anonymousAuthentication) { PISystem pisys = AFFixture.GetPISystemFromConfig(); if (client == null) { client = new WebClient { UseDefaultCredentials = true } } ; client.Headers.Add("X-Requested-With", "XMLHttpRequest"); ServicePointManager.ServerCertificateValidationCallback = null; if (Settings.SkipCertificateValidation) #pragma warning disable CA5359 // Do Not Disable Certificate Validation { ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true; } #pragma warning restore CA5359 // Do Not Disable Certificate Validation var configurationElement = Settings.PIWebAPI.Split('.')[0]; if (!string.IsNullOrEmpty(Settings.PIWebAPIConfigurationInstance)) { configurationElement = Settings.PIWebAPIConfigurationInstance; } var path = $"\\\\{Settings.AFServer}\\Configuration\\OSIsoft\\PI Web API\\{configurationElement}\\System Configuration"; var results = AFElement.FindElementsByPath(new string[] { path }, pisys); configElement = results.FirstOrDefault(); if (!Equals(configElement, null)) { disableWrites = (bool)configElement.Attributes["DisableWrites"].GetValue().Value; var methods = (string[])configElement.Attributes["AuthenticationMethods"].GetValue().Value; if (methods.Length > 0) { if (string.Equals(methods[0], "Basic", StringComparison.OrdinalIgnoreCase)) { client.UseDefaultCredentials = false; var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(Settings.PIWebAPIUser + ":" + Settings.PIWebAPIPassword)); client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials; } else if (string.Equals(methods[0], "Anonymous", StringComparison.OrdinalIgnoreCase)) { anonymousAuthentication = true; } } else { throw new InvalidOperationException("PI Web API Authentication Methods are not specified in the Configuration database."); } } } }
// Attributes /// <summary> /// Uses the Element Path to access the Attributes. /// </summary> /// <remarks> The AFTreeView is implemented with ToolTipText is the path to the selected Element. </remarks> /// <param name="path"> The pathway to the Element</param> /// <returns> AFAttributes containing the Attributes of the selected Element. </returns> public AFAttributes getAttributes(string path) { mainForm.Status("Getting Attributes..."); List <string> searchPaths = new List <string> { path }; AFKeyedResults <string, AFElement> result = AFElement.FindElementsByPath(searchPaths, null); AFElement elem = result[path]; AFAttributes atts = elem.Attributes; return(atts); }
// Getting Data from AFServer /// <summary> /// Using AFSDK adds both PI Tags and Constant attribute values to Matlab. /// </summary> /// <remarks> Attribute.GetValues is an Important call <= Int32 determines level of specficity of returned values.</remarks> /// <param name="server_database"> String representing server and database</param> /// <param name="AttributeName"> The name of the attribute</param> /// <param name="MatlabName"> The variable name in the Matlab Workspace.</param> /// <param name="path"> The path to the AFElement.</param> /// <param name="start"> Start of Data Collection.</param> /// <param name="end"> End of Data Collection.</param> /// <param name="addToListView"> true: adds the log input to the Log. (generally true).</param> public static void getAFData(string server_database, string AttributeName, string MatlabName, string path, string start, string end, bool addToListView) { //Find Element & the Attribute List <string> searchPaths = new List <string>() { path }; AFKeyedResults <string, AFElement> results = AFElement.FindElementsByPath(searchPaths, null); AFElement Element = results[path]; AFAttribute attribute = Element.Attributes[AttributeName]; getData(server_database, AttributeName, MatlabName, start, end, attribute, true); }
public void AFReadWriteTest() { var elementName = "OSIsoftTestElement"; var elementNameEdit = $"{elementName}2"; Fixture.Client.Headers.Add(HttpRequestHeader.CacheControl, "no-cache"); // Get Database object from PI Web API to extract its WebId var databaseWebIdRequestUrl = $"{Fixture.HomePageUrl}/assetdatabases?path=\\\\{Settings.AFServer}\\{Settings.AFDatabase}"; Output.WriteLine($"Get database object for [{Settings.AFDatabase}] from Web API at Url [{databaseWebIdRequestUrl}]."); var databaseData = JObject.Parse(Fixture.Client.DownloadString(databaseWebIdRequestUrl)); var databaseWebId = (string)databaseData["WebId"]; // Skip Write/Update portion of test if writes are disabled if (Fixture.DisableWrites) { Output.WriteLine($"Writes are disabled, skipping that portion of the test."); return; } // Create test Element object under test Database var createUrl = $"{Fixture.HomePageUrl}/assetdatabases/{databaseWebId}/elements"; var elementJson = $"{{\"Name\": \"{elementName}\"}}"; Output.WriteLine($"Create element [{elementName}] under [{Settings.AFDatabase}] through Web API using [{elementJson}] at Url [{createUrl}]."); Fixture.Client.UploadString(createUrl, "POST", elementJson); // Check Element exists in AF Output.WriteLine($"Verify element object [{elementName}] exists through Web API."); var path = $"\\\\{Settings.AFServer}\\{Settings.AFDatabase}\\{elementName}"; var foundElements = AFElement.FindElementsByPath(new string[] { path }, Fixture.AFFixture.PISystem); var element = foundElements.FirstOrDefault(); Assert.True(element != null, $"Test Element [{elementName}] was not found in AF."); var elementEditJson = $"{{\"Name\": \"{elementNameEdit}\"}}"; var location = string.Empty; try { // Extract new Element URL off create response headers location = Fixture.Client.ResponseHeaders["Location"]; // Change Element name Output.WriteLine($"Rename element object [{elementName}] to [{elementNameEdit}] through Web API."); Fixture.Client.UploadString(location, "PATCH", elementEditJson); // Check Element was renamed in AF element.Refresh(); Assert.True(element.Name == elementNameEdit, $"Test Element [{elementName}] was not renamed to [{elementNameEdit}] in AF."); // Request full Element object from PI Web API to test read, check name value Output.WriteLine($"Read full element object [{elementName}] from Web API."); var readData = JObject.Parse(Fixture.Client.DownloadString(location)); Assert.True(string.Equals((string)readData["Name"], elementNameEdit, StringComparison.OrdinalIgnoreCase), $"Test Element [{elementName}] was not renamed to [{elementNameEdit}] in read data."); // Create Attribute var createAttributeUrl = $"{location}/attributes"; var attributeJson = $"{{\"Name\":\"Attribute\"}}"; Output.WriteLine($"Create attribute object 'Attribute' through Web API using [{attributeJson}] at Url [{createAttributeUrl}]."); Fixture.Client.UploadString(createAttributeUrl, "POST", attributeJson); // Check Attribute was added in AF element.Refresh(); Assert.True(element.Attributes.Count == 1, $"Test Attribute 'Attribute' was not created in AF."); } finally { // Delete test Element Fixture.Client.UploadString(location, "DELETE", string.Empty); } // Create test Event Frame object under test Database createUrl = $"{Fixture.HomePageUrl}/assetdatabases/{databaseWebId}/eventframes"; Output.WriteLine($"Create event frame object [{element}] through Web API using [{elementJson}] at Url [{createUrl}]."); Fixture.Client.UploadString(createUrl, "POST", elementJson); // Check Event Frame exists in AF path = $"\\\\{Settings.AFServer}\\{Settings.AFDatabase}\\EventFrames[{elementName}]"; var foundEvents = AFEventFrame.FindEventFramesByPath(new string[] { path }, Fixture.AFFixture.PISystem); var eventFrame = foundEvents.FirstOrDefault(); Assert.True(eventFrame != null, $"Test Event Frame [{elementName}] was not found in AF."); try { // Extract new Event Frame URL off create response headers location = Fixture.Client.ResponseHeaders["Location"]; // Change Event Frame name Output.WriteLine($"Rename event frame object [{elementName}] to [{elementEditJson}] through Web API."); Fixture.Client.UploadString(location, "PATCH", elementEditJson); // Check Event Frame was renamed in AF eventFrame.Refresh(); Assert.True(eventFrame.Name == elementNameEdit, $"Test Event Frame [{elementName}] was not renamed to [{elementNameEdit}] in AF."); // Request full Event Frame object from PI Web API to test read, check name value Output.WriteLine($"Read full event frame object [{elementName}] from Web API."); var readData = JObject.Parse(Fixture.Client.DownloadString(location)); Assert.True(string.Equals((string)readData["Name"], elementNameEdit, StringComparison.OrdinalIgnoreCase), $"Test Event Frame [{elementName}] was not renamed to [{elementNameEdit}] in read data."); } finally { // Delete test Event Frame Fixture.Client.UploadString(location, "DELETE", string.Empty); } Fixture.Client.Headers.Remove(HttpRequestHeader.CacheControl); }
/// <summary> /// Creates an instance of the PIWebAPIFixture class. /// </summary> public PIWebAPIFixture() { Client.Headers.Add("X-Requested-With", "XMLHttpRequest"); if (Settings.SkipCertificateValidation) { ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true; } var configurationElement = Settings.PIWebAPI.Split('.')[0]; if (!string.IsNullOrEmpty(Settings.PIWebAPIConfigurationInstance)) { configurationElement = Settings.PIWebAPIConfigurationInstance; } var path = $"\\\\{Settings.AFServer}\\Configuration\\OSIsoft\\PI Web API\\{configurationElement}\\System Configuration"; var results = AFElement.FindElementsByPath(new string[] { path }, AFFixture.PISystem); ConfigElement = results.FirstOrDefault(); if (!Equals(ConfigElement, null)) { DisableWrites = (bool)ConfigElement.Attributes["DisableWrites"].GetValue().Value; var methods = (string[])ConfigElement.Attributes["AuthenticationMethods"].GetValue().Value; if (methods.Length > 0) { if (string.Equals(methods[0], "Basic", StringComparison.OrdinalIgnoreCase)) { Client.UseDefaultCredentials = false; var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(Settings.PIWebAPIUser + ":" + Settings.PIWebAPIPassword)); Client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials; } else if (string.Equals(methods[0], "Anonymous", StringComparison.OrdinalIgnoreCase)) { AnonymousAuthentication = true; } } else { throw new InvalidOperationException("PI Web API Authentication Methods are not specified in the Configuration database."); } } if (SkipReason == null) { // Only need to set up skip reasons once, save results in static property SkipReason = new Dictionary <PIWebAPITestCondition, string>(); // Authenticate Skip Reason string skipReason = null; if (AnonymousAuthentication) { skipReason = "Test skipped because Anonymous Authentication is allowed."; } SkipReason.Add(PIWebAPITestCondition.Authenticate, skipReason); // Indexed Search Skip Reason skipReason = null; try { var checkForSearch = JObject.Parse(Client.DownloadString(HomePageUrl)); if (checkForSearch["Links"]["Search"] == null) { skipReason = $"Test skipped because the Search endpoint was not found at [{HomePageUrl}]."; } } catch (Exception ex) { skipReason = $"Test skipped because PI Web API could not be loaded: [{ex.Message}]."; } SkipReason.Add(PIWebAPITestCondition.IndexedSearch, skipReason); // OMF Skip Reason skipReason = null; try { var checkForOMF = JObject.Parse(Client.DownloadString(HomePageUrl)); if (checkForOMF["Links"]["Omf"] == null) { skipReason = $"Test skipped because the OMF endpoint was not found at [{HomePageUrl}]."; } } catch (Exception ex) { skipReason = $"Test skipped because PI Web API could not be loaded: [{ex.Message}]."; } SkipReason.Add(PIWebAPITestCondition.Omf, skipReason); } }