Jump to content

Thorsten Vogt

Super Seeqer
  • Posts

    171
  • Joined

  • Last visited

  • Days Won

    53

Posts posted by Thorsten Vogt

  1. Hi Ali,

    I think the green trend is calculating the average from 12/11/2018 6:16 pm to 12/11/2019 6:16 pm. The formula I gave you is resetting at 01/01/2019 and therefore calculating the average from 01/01/2019 00:00 to 12/11/2019 6:16 pm which might cause the difference. To use the formula with the intended range you may change it to

    $signal.runningAggregate(average(), condition(1y, capsule(now()-1y, now())))

    That will create a condition with one capsule beginning 1 year ago and ending now which will be used for the calculation. The value at the end of the capsule then matches the average calculated by Seeq for the display range.

    image.thumb.png.7686f30b2fd77afa54eabf9b5cd2c0f1.png

    However, as the window for the calculation (now - 1y) is changing, the calculated values for a specific timestamp are uncertain and may change frequently. Therefore I think you should disable the cache for the calculated item. 

    See discussion in following topic: 

     

    Regards, 

    Thorsten

    • Like 1
  2. Hi Sean,

    I want the calculation to be made by Seeq if possible. I have an Asset Tree like the one below (generated from the Example Data of Seeq) :

    image.png.58b0acd6ff4e81dbc2c57f3d2283a15a.png

    Under each Area (A-D) is a Power Signal:

    image.png.833ea35b89aef17e710cc2ee1268f749.png

    What I would like to have is an automatic calculation for all Power-Attributes placed here (e.g. Sum of Signals):

    image.png.c6380847e13d697ae26fea97feaf2210.png

    What I tried so far was creating a global scoped Formula-Signal doing the calculation and referencing that in the Tree File Connector - Configuration. This is a workaround for small areas. But for my use case at the customer we are talking about 200 Signals under a certain area, which is hard to deal with in manual formula creation ?

    Regards,

    Thorsten

     

     

     

    • Like 1
  3. Hi Sanjhosh,

    you can try to remove the values from the signal as @Joanna Zinsli described above. Another way would be using within(). In this example I display only values from the "Temperature" signal, when the signal "Relative Humidity" is above 75 %.

    image.thumb.png.9ff14610156bbbebdf5dc0d1949baf00.png

    I used remove() and within() in the following formulas:

     image.png.cb7637966e711b4dda0bf2746dcc2b79.png image.png.d4e4ee0ae7531956a678335aabf870a7.png

    The condition is determined by a simple "Value Search":

    image.png.f8c62e435ed3ed1b4d84aba98ab7c494.png

    Regards,

    Thorsten

     

  4. Hi Ali,

    Seeq tries to interpolate missing values. In the following example I removed the values from the temperature curve, if the value is less than 73°F. I get a curve with the expected gap and Seeq informs with that message that it is not able to interpolate the values:

    image.thumb.png.db755d95cccf46393faf44ba60f2f262.png

    If you do the same with a signal that has a maximum interpolation of greater than the gap, Seeq interpolates the values and does not show the message:

    image.thumb.png.56aefe08f5b532782df200be28ec4313.png

    If you do not want to interpolate you should use the within() function. Seeq than does not show the message.

    image.thumb.png.0fc9ed749802b2a8bb287919b93c0d03.png

    Regards,

    Thorsten

  5. Hi Atul,

    as far as I know there is currently no way to import the data out of an Excel file in a Seeq native way. I would suggest contacting Seeq support regarding this topic.

    However you can evaluate the following options:

    - If you are able to transform the data into CSV format you can use the CSV import.

    - Another possibility would be using the way that Brian described here (with using Excel instead of Access):

    - If you have access to Seeq Data Labs you could use Python and Pandas to read the data from Excel and write it back to Seeq (https://datatofish.com/read_excel/).

    - Using Seeq Connector SDK to implement your own connector or using Seeq Server SDK/REST API to push data to Seeq

    Regards,

    Thorsten

    • Like 1
  6. Hi Jitesh,

    I tried to develop a nested if with the following logic:

    if (temp > 66)
    {
        if (rh > 50)
        {
            temp = 1/temp    ;
        }
        else if (wetbulb < 75)
        {
            temp *= 2; 
        }
    }

    If no condition is met, the temperature should not be modified.

    image.png.d685cd18f0945745c63f44eb32a176a7.png

    image.thumb.png.bd2c6877085a277946acab766f29e2f5.png

    However it would be great if you could provide an example of what you are trying to achieve.

    Regards,

    Thorsten

     

    • Like 3
  7. Hi Marcie, 

    for exporting the data of a Histogram you can use the Seeq REST API / Seeq Server SDK to develop a custom solution. I created a "quick and dirty" sample based on C# for demonstration:

    using OfficeOpenXml;
    using Seeq.Sdk.Api;
    using Seeq.Sdk.Client;
    using Seeq.Sdk.Model;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Histogram2Xls
    {
        class Program
        {
    
            private static ApiClient apiClient { get; set; }
    
            static void Main(string[] args)
            {
                ConnectToSeeq();
    
                FormulaRunOutputV1 output = GetDataFromSeeq();
    
                ExportToExcel(output);
            }
    
    
            private static void ConnectToSeeq()
            {
    
                apiClient = new ApiClient(string.Format("{0}api", "http://<your Seeq Server>:34216/"));
    
                AuthApi authApi = new AuthApi(apiClient);
                AuthInputV1 input = new AuthInputV1();
                input.Username = "<your Seeq Username>";
                input.Password = "<your Seeq Password>";
    
                authApi.Login(input);
            }
    
            private static FormulaRunOutputV1 GetDataFromSeeq()
            {
                FormulaRunInputV1 input = new FormulaRunInputV1();
                input.Function = "6ED15A0C-0FBB-4D22-A0A3-D32AF43CC904";
                input.Parameters = new List<string>{
                    "condition2=140CB04E-3DC3-4363-8D49-4D950A47FDDA",
                    "signalToAggregate=0955829B-BBDC-4130-8204-ABAAB469BDBE"
                };
                input.Fragments = new List<string>{
                    "viewCapsule=capsule('2019-04-22T00:00:00Z', '2019-04-29T00:00:00Z')"
                };
    
                FormulasApi formulasApi = new FormulasApi(apiClient);
                FormulaRunOutputV1 output = formulasApi.RunFormula_0(input);
                return output;
            }
    
            private static void ExportToExcel(FormulaRunOutputV1 output)
            {
                List<DataItem> items = new List<DataItem>();
    
                foreach (List<Object> objList in output.Table.Data)
                {
                    DataItem item = new DataItem();
    
                    item.Day = Convert.ToInt32(objList[0]);
                    item.Stage = objList[1].ToString();
                    item.Value = Convert.ToDouble(objList[2]);
    
                    items.Add(item);
                }
    
    
                ExcelPackage excelPackage = new ExcelPackage(new System.IO.FileInfo("D:\\Temp\\Histogram.xlsx"));
    
                ExcelWorksheet workSheet = excelPackage.Workbook.Worksheets.Add("Data");
    
                int row = 1;
                workSheet.Cells[row, 1].Value = "Day of week";
                workSheet.Cells[row, 2].Value = "OFF";
                workSheet.Cells[row, 3].Value = "STAGE 1";
                workSheet.Cells[row, 4].Value = "STAGE 2";
                workSheet.Cells[row, 5].Value = "TRANSITION";
    
                List<int> days = items.OrderBy(x => x.Day).Select(x => x.Day).Distinct().ToList();
    
                foreach (int day in days)
                {
                    row++;
                    List<DataItem> itemsForDay = items.Where(x => x.Day == day).ToList();
                    workSheet.Cells[row, 1].Value = day;
                    foreach (DataItem item in itemsForDay)
                    {
    
                        int colIdx = GetColIdx(item.Stage);
                        workSheet.Cells[row, colIdx].Value = item.Value;
                    }
    
                }
    
    
                excelPackage.Save();
            }
    
            private static int GetColIdx(string stage)
            {
                if (stage == "OFF")
                    return 2;
                if (stage == "STAGE 1")
                    return 3;
                if (stage == "STAGE 2")
                    return 4;
                if (stage == "TRANSITION")
                    return 5;
                return -1;
            }
    
        }
        
        public class DataItem
        {
            public int Day { get; set; }
            public string Stage { get; set; }
            public double Value { get; set; }
        }
    }

    This sample is very static and exports the data of a specific histogram. The configuration is made in the function GetDataFromSeeq():

    input.Function takes the ID of the Histogram
    input.Parameters takes a list of parameters that the histogram uses for calculation
    input.Fragments takes the list of FormulaParameters

    All this information can be retrieved from the properties of 
     - the histogram
     - the signal used for calculation
     - the condition used for grouping

    image.thumb.png.22f9e3ed9c200f084002ba2d48fc730e.png

    The resulting Excel file looks like this:
    image.thumb.png.13c501298dc960f22b85bcd0b5dfb466.png

    As mentioned before this is just a sample which is very static and needs some adjustments regarding your needs.

    Regards,

    Thorsten

    • Like 1
  8. Hi,

    you can get the start and end value the following way:

    1. Import data from CSV and create a capsule for complete range of data by doing a simple Value Search:
    image.thumb.png.763e981128e6f07938590d8f17f744d8.png

    2. In order to get only the first and the last value of the imported data create another two capsules that represent a small interval just after start and just before end of the capsule created in step 1. 
    image.png.7e68a3f96418d920aa7e8424182f7003.pngimage.png.1b1be987434cbd8c20dff2a1dcd6ac10.png

    3. Use the "Signal from Condition" tool to calculate the start and end values:
    image.png.cbd7c9b747fe602d0822f70d6562d804.pngimage.png.727b7822bcc77c7cacd27672d11539d0.png

    You could also skip step 2 and use the capsule created in step 1 inside step 3 as the bounding condition. But then you have to specify a maximum duration of the capsule which may decrease performance.

    Regards,

    Thorsten

     

     


     

    • Like 2
  9. Hi Jitesh,

    you could do a simple Value Search to get a batch whenever the Compressor stage does not match "OFF". The duration of the resulting batches is displayed in the capsules window:

    image.thumb.png.43fbc581c99cd66a60bd105a16648b6a.png

    By using signal from condition you can calculate the total duration of each batch:

    image.thumb.png.3f428cd142620e01a2a8711bc99bb08d.png

    In case you want a new batch starting with each value change you can use toCondition():

    image.thumb.png.60e303f7072117316e15219b29ffae2a.png

    Hope this helps.

    Regards, 

    Thorsten

     

    • Like 2
  10. Hi Drew,

    if I understand the problem correctly, you want the current value to be displayed. As far as I know it is not possible to display the last value in the chart all the time. But you can get an overwiew of the last values of your signals by creating some Scorecard Metrics that display the current value at the end of the display range. These values are being updated if the Auto Update setting is active:

    image.png.1783ee514ee20c3041fa2058a5c68ab2.png

    Hope this helps.

    Regards,

    Thorsten

    • Like 1
  11. Hi Jitesh,

    you can achieve this by filtering the values with the filter() function:

    $stage.toCapsules().filter($x -> $x.getProperty("Value") != "OFF")

    You should think of using toCondition() instead of using toCapsules(), as toCapsules() generates a capsule for each interval between recorded points even if the value stays the same. You can see this in the Capsules window of your screenshot. By using toCondition() you will get only one capsule per change of value:

    $stage.toCondition()

    image.png.12d5f14b06a2f090f05b6b907aa9bd39.png

    If you want to filter the results of toCondition() you have to specify a maximum duration for the capsules before using filter():

    $stage.toCondition().setMaximumDuration(1wk).filter($x -> $x.getProperty("Value") != "OFF")

    Regards,

    Thorsten

     

     

    • Thanks 1
  12. Hi Ruben, 

    you can do it by using this formula. The formula gets the values for the last eight hours, picks the last sample and gets its key (timestamp). Based on that timestamp the condition of the previous 24 hours is build.

    image.png.220596862e149f8bac6641bcca52d3e8.png

    You can also use pick(-1) instead of last(). You should keep in mind that the capsule itself is uncertain because of the use of now().

    Regards,

    Thorsten

     

  13. Hi Chris,

    I was able to achive this by using Property Transforms on the specific datasources: https://seeq12.atlassian.net/wiki/spaces/KB/pages/127009211/Connector+Property+Transforms

    But I think you have to be careful with this setting as you can easily define a possibly wrong setting for your data items. In my case, the interpolation value for the data item was preserved, although I removed the transformation.

    Regards,

    Thorsten

     

×
×
  • Create New...