11 Replies Latest reply on Mar 13, 2018 12:22 PM by Roger Palmen

    Best approach to generate WebID 2.0 from PI Vision symbol DataSource path strings

    Roger Palmen

      Currently looking into ways to save a few seconds when initially loading a PI Vision display with a custom symbol (or many). Not needing the round trip to get the WebID's would save some time, so let's move on to WebID 2.0!

      I know, a batch call could both get the WebIDs and the data, but i already have a complicated multi-stage batch call so i don't want to overcomplicate that one. Errorhandling is a pain with these batch calls!

       

      But a bit uncertain how to proceed:

       

      Any suggestions / experiences? (or source code... ). Did not see a PI Vision custom symbol yet that leverages the WebID 2.0 for PI Web API calls

        • Re: Best approach to generate WebID 2.0 from PI Vision symbol DataSource path strings
          Roger Palmen

          Hmm, of course stumbled over this for an n-th time: Using PI Web API Client library in PI Vision 2016 R2 and 2017 . But it still seems like overkill for generating the WebID only... And i don't want to re-write my entire code yet.

          • Re: Best approach to generate WebID 2.0 from PI Vision symbol DataSource path strings
            Marcos Vainer Loeff

            Hi Roger,

             

            Actually, the PI Web API client library for AngularJS does not have WebID 2.0 client generation yet. The only option you have is to manually generate the Web IDs 2.0 within the custom symbol itself.

             

            Here is the logic for C#. It is not difficult to translate it to AngularJS.

             

            Hope this helps!

            1 of 1 people found this helpful
              • Re: Best approach to generate WebID 2.0 from PI Vision symbol DataSource path strings
                Roger Palmen

                Hi Marcos,

                 

                I've made a first try in AngularJS, but the WebIDs are still wildly different than those returned by the PI Web API (when using ?webIDtype=pathonly).

                 

                This is the line of code that takes in the uppercase path to the AF attribute (excluding the af:\\ prefix), e.g.: "AFserver\AFDB\Element\ChildElement\Attribute|ChildAttribute"

                 

                var webIDencoded = btoa(JSON.stringify(shortPathUC)); //encode Base64, after stringification
                

                 

                NOTE: The "P1AbE" prefix will of course be added

                  • Re: Best approach to generate WebID 2.0 from PI Vision symbol DataSource path strings
                    Marcos Vainer Loeff

                    Hi Roger,

                     

                    I haven't tested it but you need to check if the JavaScript response is the same one of the C# version using the methods below:

                     

                            internal static string Encode(string value)
                            {
                                byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value.ToUpperInvariant());
                                return Encode(bytes);
                            }
                    
                    
                            internal static string Encode(byte[] value)
                            {
                                string encoded = System.Convert.ToBase64String(value);
                                return encoded.TrimEnd(new char[] { '=' }).Replace('+', '-').Replace('/', '_');
                            }
                    

                     

                    There are a lot of different types of encodes. You need to make sure you are using the correct one.

                      • Re: Best approach to generate WebID 2.0 from PI Vision symbol DataSource path strings
                        Marcos Vainer Loeff

                        I guess this function should work:

                         

                        function encodeString(value) {
                            var count = 0;
                            var encodedValue = btoa(value.toUpperCase());
                            encodedValue = encodedValue.replace('+', '-').replace('/', '_');
                            for (var i = (encodedValue.length - 1); i > 0; i--) {
                                if (encodedValue[i] == "=") {
                                    count++;
                                }
                                else {
                                    break;
                                }
                            }
                            encodedValue = encodedValue.slice(0, -count);
                            return encodedValue;
                        }
                        
                        1 of 1 people found this helpful
                          • Re: Best approach to generate WebID 2.0 from PI Vision symbol DataSource path strings
                            Roger Palmen

                            Hi Marcos,

                            My apologies, it took some time before i could follow up on this. It works great! Saved me a lot of time tryning to find and understand the encoding types.

                             

                            Below my code taking the full path received in the PI Vision DataUpdate as input:

                                    //Generate WebID2.0 for AF attribute
                                    function generateWebID(fullPath) {
                                        var webIDtype = "P"; //WebID of type Path only
                                        var webIDversion = "1"; // for WebID v2.0, this is always 1
                                        var webIDmarker = "Ab"; // Specify Object type as AF Attribute
                                        var webIDbase = "E"; //Base for the path
                                        var count = 0;
                            
                            
                                        var shortPath = fullPath.replace('af:\\\\', ''); //strip the AF prefix "af:\\"
                                        var encodedValue = btoa(shortPath.toUpperCase());
                                        encodedValue = encodedValue.replace('+', '-').replace('/', '_');
                                        for (var i = (encodedValue.length - 1); i > 0; i--) {
                                            if (encodedValue[i] == "=") {
                                                count++;
                                            }
                                            else {
                                                break;
                                            }
                                        }
                                        encodedValue = encodedValue.slice(0, i - count);
                                        // Build the WebId
                                        return webIDtype + webIDversion + webIDmarker + webIDbase + encodedValue;//webIDencoded;
                                    }
                            
                              • Re: Best approach to generate WebID 2.0 from PI Vision symbol DataSource path strings
                                Roger Palmen

                                Bugfix in line21 on the slicing. New code:

                                 

                                        //Generate WebID2.0 for AF attribute on an Element
                                        function generateWebID(fullPath) {
                                            var webIDtype = "P"; //WebID of type Path only
                                            var webIDversion = "1"; // for WebID v2.0, this is always 1
                                            var webIDmarker = "Ab"; // Specify Object type as AF Attribute
                                            var webIDbase = "E"; //Base for the path
                                            var count = 0;
                                
                                
                                            var shortPath = fullPath.replace('af:\\\\', ''); //strip the AF prefix "af:\\"
                                            var encodedValue = btoa(shortPath.toUpperCase());
                                            encodedValue = encodedValue.replace('+', '-').replace('/', '_');
                                            for (var i = encodedValue.length - 1; i > 0; i--) {
                                                if (encodedValue[i] === "=") {
                                                    count++;
                                                }
                                                else {
                                                    break;
                                                }
                                            }
                                            //only slice if count > 0
                                            if (count>0) encodedValue = encodedValue.slice(0, - count);
                                            // Build the WebId
                                            return webIDtype + webIDversion + webIDmarker + webIDbase + encodedValue;//webIDencoded;
                                        }
                                
                                1 of 1 people found this helpful