Jump to content

Siti Tay

Seeq Team
  • Posts

    16
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by Siti Tay

  1. Hi Martin, 

    Here's the full script that I did to replicate the issue. The organizer topic template require dummy image for an image content. 

    Step 1. Build a organizer topic template. For a text, add curly braces, and for an image content/chart, add dummy image then set the image text alternative with curly braces and save this organizer topic as Organizer_Template.

    image.png

    Step 2. Search, pull and save the Organizer_Template in a zip file. (e.g.: Template_20March.zip)

    workbooks_df = spy.workbooks.search({'ID':'0EEE504F-96B9-6030-9FA3-1612720FB9B9'})
    workbooks = spy.workbooks.pull(workbooks_df)
    spy.workbooks.save(workbooks,'Template_20March.zip', overwrite=True)
    workbooklist = spy.workbooks.load('Template_20March.zip', as_template_with_label=f'{spy.user.username} Template_20March')

    Step 3. Load the zip file 

    workbooklist = spy.workbooks.load('Template_20March.zip', as_template_with_label=f'{spy.user.username} Template_20March')

    Step 4. Use the template and define it as data_lab_visualization_template. Then look at the code for the parameters

    data_lab_visualization_template = workbooklist['Organizer_Template'] #this need to be the same as topic name 
    print(data_lab_visualization_template.code)

    output :

    topic.parameters = {
        "Title": None,
        "[Image] cell1": None,
        "[AltText] cell1": None,
        "[Image] Chart1": None,
        "[AltText] Chart1": None,
        "[Image] Chart2": None,
        "[AltText] Chart2": None
    }

    Step 5. Populate the parameters

    data_lab_visualization_template.parameters = {
        "Title": "Prod1",
        "[Image] cell1": "./Support Files/charts/Area E Histogram.png",
        "[AltText] cell1": "Area E Histogram",
        "[Image] Chart1": "./Support Files/charts/Area G Histogram.png",
        "[AltText] Chart1": "Area G Histogram",
        "[Image] Chart2": "./Support Files/charts/Area H Histogram.png",
        "[AltText] Chart2": "Area H Histogram"
    }
    print(data_lab_visualization_template.parameters)

    output

    {'Title': 'Prod1', 
    '[Image] cell1': './Support Files/charts/Area E Histogram.png', 
    '[AltText] cell1': 'Area E Histogram', 
    '[Image] Chart1': './Support Files/charts/Area G Histogram.png', 
    '[AltText] Chart1': 'Area G Histogram', 
    '[Image] Chart2': './Support Files/charts/Area H Histogram.png', 
    '[AltText] Chart2': 'Area H Histogram'}

    Step 6. Push the organizer topic to Seeq

    spy.workbooks.push(data_lab_visualization_template)

    image.png

    Creating a second topic using the same template. (Repeat step 3 until 6)

    Step 3

    #load the template zip file
    workbooklist = spy.workbooks.load('Template_20March.zip', as_template_with_label=f'{spy.user.username} Template_20March')

    Step 4

    #Use the template and define it as data_lab_visualization_template2, Then look at the code for the parameters
    data_lab_visualization_template2 = workbooklist['Organizer_Template'] #this need to be the same as topic name 
    print(data_lab_visualization_template2.code)

    Step 5

    #populate the parameters
    data_lab_visualization_template2.parameters = {
        "Title": "Prod2",
        "[Image] cell1": "./Support Files/Area A Histogram1.png",
        "[AltText] cell1": "Area A Histogram",
        "[Image] Chart1": "./Support Files/Area C Histogram1.png",
        "[AltText] Chart1": "Area C Histogram",
        "[Image] Chart2": "./Support Files/Area D Histogram1.png",
        "[AltText] Chart2": "Area D Histogram"
    }
    print(data_lab_visualization_template2.parameters)

    Step 6

    #push the organizer to seeq
    spy.workbooks.push(data_lab_visualization_template2)

    image.png

  2. Hi Brandon Vincent, 

    May I clarify the question? the issue arises when the drums loading occur in the middle of the day which causes your daily condition to split? If this is the case, one way to calculate the total material flow out of the tank daily could be as follows:

    Step 1.  Use Composite Condition with intersection logic between "not loading condition" and "daily condition". 

    image.png

    This will result in splitting the daily condition based on the not loading conditionimage.png

    Step 2. Use Signal from Condition to calculate the tank level delta (End value - Start value) bounded to the condition (1) and place the statistic at the start of the capsule. The result below shows 2 value for Sep 2023 capsules, one at 00:00 and another one at 13:32 timestamp. 

    image.png

    Step 3. The delta value will be negative as the End value is smaller than Start value. Use Formula, abs() function to take the absolute value (positive value) 

    $end_start.abs()

    image.png

    Step 4. Find the Sum of delta (End value - Start value) using Signal from Condition and bound the calculation to the "daily condition". This should be the total amount of material flow out from the tank daily despite having drum loading in the middle of the day.

    image.png

     

    If the steps mentioned earlier don't apply to the problem you're facing, here's how you can calculate how many drums have been loaded.

    Step 1. Use Signal from Condition to calculate the tank level delta (End value - Start value) during "drum loading" condition. 

    image.png

    Step 2. Use formula to calculate the number of drums loaded by dividing it with 21% (as mentioned in the question, 21% level increased per drum loaded). The floor() function is used to round a numeric value down to the next smallest integer.

    For example if the tank level during drum loading is 68.69%, 68.69%/21% = 3.27. The floor function round the value down to 3 drum. 

    ($level/21).floor().setunits('')

    image.png

     

    Let me know if this helps.

    • Like 1
  3. Hi Tranquil Oshan, 

    I have a workaround but as you can see from the below steps, it may not be the best either. Can you share with me what you hope to achieve with this polynomial fitting of min and max? , maybe there's another way we can approach this if i can understand your objective. 

    Step 1 : Create the binning condition using value search. In this example I have 8 conditions with the bin size of 5.

    image.png

    Step 2 : Calculate Max and Min value during each bin. 

    combinewith(
    $t.aggregate(maxValue(),$a.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(maxValue(),$b.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(maxValue(),$c.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(maxValue(),$d.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(maxValue(),$e.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(maxValue(),$f.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(maxValue(),$g.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(maxValue(),$h.removeLongerThan(5d),startkey(),0s))

     

    combinewith(
    $t.aggregate(minValue(),$a.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(minValue(),$b.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(minValue(),$c.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(minValue(),$d.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(minValue(),$e.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(minValue(),$f.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(minValue(),$g.removeLongerThan(5d),startkey(),0s),
    $t.aggregate(minValue(),$h.removeLongerThan(5d),startkey(),0s))

    image.png

    Step 3 : Create the X-axis using setProperty() function with the 'bin' as value, corresponding to the Max value.

    combinewith(
    $t.aggregate(maxValue(),$a.removeLongerThan(5d),startKey(),0s).toCapsules().setProperty('Bin',5),
    $t.aggregate(maxValue(),$b.removeLongerThan(5d),startKey(),0s).toCapsules().setProperty('Bin',10),
    $t.aggregate(maxValue(),$c.removeLongerThan(5d),startKey(),0s).toCapsules().setProperty('Bin',15),
    $t.aggregate(maxValue(),$d.removeLongerThan(5d),startKey(),0s).toCapsules().setProperty('Bin',20),
    $t.aggregate(maxValue(),$e.removeLongerThan(5d),startKey(),0s).toCapsules().setProperty('Bin',25),
    $t.aggregate(maxValue(),$f.removeLongerThan(5d),startKey(),0s).toCapsules().setProperty('Bin',30),
    $t.aggregate(maxValue(),$g.removeLongerThan(5d),startKey(),0s).toCapsules().setProperty('Bin',35),
    $t.aggregate(maxValue(),$h.removeLongerThan(5d),startKey(),0s).toCapsules().setProperty('Bin',40))
    .toSignal('Bin',startKey()).toDiscrete()

    image.png

    Step 4 : Switch to the XY Plot. 

    image.png

    Step 5 : Click on the f(x) button, Create a New Prediction for min and max polynomial. 

    image.png

    image.png

    Expand the training window. In this example the training window is set to 1 year (7/6/2022 11:26-6/9/2023 17:26). 

    image.png

     

  4. Hi Koki, 

    You can export the tables to excel manually via copy to clipboard button as the Export to Excel tool for table is currently not available. We did logged a feature request to Export Table View results to OData, Excel, etc. If you are interested to receive an email when there's an update on this, please do submit a seeq ticket at https://seeq.atlassian.net/servicedesk/customer/portal/3,  we'll link your ticket to the feature request so that you'll get update once it's available. 

    image.thumb.png.629a23db0b13d536675cc2a0052cc232.png

    • Thanks 1
  5. I understand that the example didn't suit your case. Please try these two methods and see which one better suits your data.

    Method 1 : 

    1. Calculate the derivative for the speed data.

    image.thumb.png.16c7665b459b991c27981d7cd0f7bcc8.png

    2. Apply value search when the derivative is not equal to 0 (you might need to adjust this value search criteria depending on your derivative signal).

    This result in red conditions before and after the unit is down, with a duration of 0 seconds, as displayed in the capsule pane.

    image.thumb.png.904cf8748a29fd7459cc43a5ff8a746c.png

    Method 2 :

    Use beforeStart() and afterEnd() functions as shown below. You will need to specify the duration of the capsule, and in this example, the duration is 1 minute before and after the unit down. 

    $before_down = $unit_down.beforeStart(1min)
    $restart = $unit_down.afterEnd(1min)
    $before_down.combineWith($restart)

    image.thumb.png.8564a4c3567f5965f1dd20955a10bde9.png

     

    Give these methods a try, and let me know if you encounter any issues or you can also join our Seeq Office Hours (https://info.seeq.com/office-hours) for further discussion. 

  6. Hello,

    Based on your question, there are 2 conditions that define your down time periods. 

    1.  Speed RPM < 10 
      •  image.thumb.png.fe9b830a235c14a2e619bd8d13faa52f.png
    2. Code = 0
      • image.thumb.png.d9d1f553d6e3b363baef686f11f5d8c1.png

    Next, to identify period when the unit down ends to the starts of code down period, you can use composite condition (Join) which result in red condition below.

    image.thumb.png.d4466d1473c451479fca2415dececfa0.png

    Then repeat the same composite condition to identify period when the  code down ends to the starts of unit down period, which result in yellow condition below.

    • You can choose to include or exclude A or B condition if needed. 
    • Adjust the maximum capsule duration depending on the gap between A to B condition. 

    image.thumb.png.2c2e46efe509c608b55f953aff1afad4.png

     

    Let me know if this helps.

  7. An oil and gas engineer would like to reproduce below Batch monitoring table for vessels in Seeq. Green color indicates that the valve for the respective batch step is open, while red color indicates the valve status is close.

    image.png.5c85abb94f4322a335db503799443d4c.png

    1. Use Condition with Properties to create conditions with regen steps as property name.  image.thumb.png.bfaa2cd948300b1dac2a44c7519be16f.png

    2. Define the respective valves position at each regen step.

    $Running = ($Prod_Valve ~= "Open").intersect($Step.keep('Batch Step',isEqualTo('RUNNING')))
    $Isopropyl = ($Prod_Valve ~= "Open").intersect($Step.keep('Batch Step',isEqualTo('ISOPROPYL FLUSH')))
    $Startup = ($Prod_Valve ~= "Open").intersect($Step.keep('Batch Step',isEqualTo('STARTUP')))
    $Down = ($Prod_Valve ~= "Close").intersect($Step.keep('Batch Step',isEqualTo('DOWN')))
    
    combineWith
    ($Running,$Isopropyl,$Startup,$Down)

    image.thumb.png.483353461816c6813b7938ffbc700c2c.png

    3. Create a scorecard metric with colour threshold for each valve: 

    • Count =1; Green – good with single valve opening 
    • Count >1 or <1; Red – alarm as potential multiple valves opening or issue with signal status  

    image.thumb.png.b79361bebafd098a79abb6ef7d141766.png

    4. In condition Table view, select the Capsule Property at the Headers.

    image.png.594b0c63971c3422156818e6c40d9696.png

    Optionally, the count value can be hidden by editing

    ""

    in the Number Format in the Item Properties as shown below. 

    image.png.48ec52b64ca590ce33f120785a647138.png

     

    With this method, if all the valves indicates green means the valve Open/Close correctly. Thus user just need to focus on the red indicator. 

    • Like 1
  8. Hi Ruby Han,

    Step 1. Create capsules for every 7 valid samples ($toCapsulesbyCount) for every sample

    *Note that the function toCapsulesByCount() is available in Seeq versions R54+

    $signal.toCapsulesByCount(7, 10d)

    Step 2. Use signal from condition to determine the X days of 7days valid data

    image.thumb.png.656587db5a00c4c05258a518c39c09c4.png

    If you would like to aggregate every 7 valid samples, you can use aggregateByCount  function which also introduced in version R54. 
    Example using this function can be found here : 

    Hope this help.

  9. Hello there, 

    I followed your work step and it works. the error you're seeing related to parameter specified in setproperty formula. 

    can you try again using this formula : $bitc.setMaximumDuration(10d).setproperty('visc avg', $vs, average()). 

    $bitc is your Batch ID condition which was created using  $bs.tocondition('BATCH_ID')

    $vs is the Viscosity-Seeq signal

    Let me know if this works. 

    image.thumb.png.7f0476f54349338129170810d55ab6c0.png

  10. Hi Javad, 

    Here are the steps to get Condition C: 

    Step 1: Create ''Condition C1'' by joining ''Condition A'' and ''Condition B'' using this formula :

    $a.afterEnd(0ns).join($b.beforeStart(0ns), 40h, false)

     image.thumb.png.6e4b62c3fe0de069e3115ccf92135aa6.png

     

    Step 2: Create ''Condition C2'' using inverse function in formula and specify the duration. For example 10 min. Only capsule shorter than 10 min will be returned. 

    $conditionA.inverse().removeLongerThan(10min)

    image.thumb.png.c2662bc788b2024bb168c3e61b610366.png

    Step 3. Combine ''Condition C1'' and ''Condition C2'' using CombineWith function in formula

    combineWith($C1, $C2)

    image.thumb.png.3031c584ad8c82401f3bcb3b71b22b38.png

    Let me know if this works. 

  11. Hi Javad Kondori, 

    This can be achieved by using Composite Condition tools. Select combination method of Join. Please make sure you uncheck "Inclusive of A" and "Inclusive of B" in order to create capsule between A and B.
    image.thumb.png.cffa88f33850234fcc224907872eaf34.png
     

    You can also refer to this example on how to use composite condition with join function: 

    https://www.seeq.org/index.php?/forums/topic/625-creating-a-condition-for-equipment-start-up/&do=findComment&comment=1105 

    Hope this answer your question. 

  12. Hi Matthias, 

    The first question is to identify each maximum peak of the blue trend 

    1. First apply an agileFilter to remove noisy signal and calculate the derivative of the signal. Please refer to formula documentation for derivative. Example: 

    $signal.agileFilter(15min).derivative('min')

    2. Then use value search to identify increasing trend, example as below and you can optimize accordingly. 

    image.thumb.png.e731c0bafabf527a126e226bd8a677bb.png

    or you can refer to step 4 and 5 from this post : 

    3. Use Signal from condition to find the maximum value bounded to the condition created in step 2 and place the timestamp at point of max value: 

    image.thumb.png.83a6b85537f40c7883f4fa0d946e6997.png

     

    Second Question : Rate of change of one peak and the upcoming peak

    4.  We can apply the same derivative function. Example: 

    $max.derivative('min')

     

    Third Question to detect a significant change of the signal (marked by red X's)

    5. The max derivative will increase or decrease significantly when there's a sudden change. Example here, we're using the threshold of +-0.005 to detect the changes for max rate decrease and increase respectively. 

    image.thumb.png.e2bd7e0d49c376b3ff66db85684c4756.png

     

    Forth Question to know its Duration (marked by the red arrows) : 

    6. Use Composite condition to join ''Rate Decreased'' and ''Rate Increased"

    image.thumb.png.797a68279938572be21638abbf9f9c85.png

    8. Calculate Total Duration of ''Join Decreased to Increased'' condition using signal from condition tool. 

    image.thumb.png.0e8fcb9c1c81c9ea2af42217cd67edb5.png

    Please give this a try to your signal and let us know if you have further question. 

     

     

    • Like 2
×
×
  • Create New...