Jump to content

Kristopher Wiggins

Seeq Team
  • Posts

    52
  • Joined

  • Last visited

  • Days Won

    18

Everything posted by Kristopher Wiggins

  1. For others running into this, the export was being performed in Capsule Time view. As of R62, Capsule Time only display capsules that are fully enclosed in the display, and as a result the subsequent export also only showed these capsules. To see these capsules, the display range had to be increased. In the case of the current capsule, we had to expand the display range to be slightly in the future.
  2. Can you submit a support ticket at https://success.seeq.com/? There you can include proprietary information like the Excel export and the link to the analysis. The Grid tab should have a column per signal and condition you're exporting, with a 1 or 0 being in the condition column depending on if that condition is present at that time.
  3. Hi Mark, I tested this out on our systems and the export (both the capsule table and sample table) had data even if the event started or ended off the screen. Can you share a screenshot of your Export tool configuration so I can try to reproduce it?
  4. Hey Michael, This may be easier to communicate over a meeting so feel free to sign up for an Office Hours session if you need additional help in implementing this. As for the steps to do this Step 0: Data Cleansing Your sensor does not look to be noisy here but often when you need to calculate rates of changes, sensors can be noisy causing your rate of change to also be noisy. We recommend using the Signal Smoothing tool to smooth your sensor to reduce those oscillations Step 1: Derivative This can be done in Formula using a syntax similar to $signal.derivative() where $signal is the tag you have displayed Step 2: Capture periods where weight is being added This can be done with the Value Search tool to capture periods where your derivative is increasing. You may not be able to use 0 exactly but a small number close to 0 should be fine Step 3: Capture times between your loading This can be done in Formula. There are multiple ways of doing this depending upon the result you'd want. I've added some examples below where $increases is the result of Step 2. You may want to use different parts depending on what you're looking for $increases.growEnd(1wk) - $increases // Extends increase capsule to next increase only if it is within 1 week of each other. For the most recent increase, it gets extended into the future until a week from when it started //$increases.inverse() and past() // Captures time between increases, only considers capsules during the past
  5. Feel free to use the ipywidgets code instead. The spy.widgets are built on top of ipywidgets to make it easier for people to use but if you're already using ipywidgets, go ahead. If you're looking for a new challenge, you can try using the ipyvuetify library, which has more modern widgets but can often be more difficult to learn and use than ipywidgets.
  6. Hi Nitish, I was able to run your code successfully after tchanging the property in your spy.search to be Name since your if statement only works if the property searched for include Name. Even when having the Data ID as the property, running the code didn't return an error, just no search results. Can you send your full code and what version of SPy you're using by running spy.__version__
  7. Hi David, In my testing on a subset of your tree, the insertion worked when removing the forward slashes from the roll_up_parameters. If this doesn't work for you it may be easier to work through it together over an Office Hours session. DCS_Cont_Tree.insert(name = 'Unit Total', roll_up_statistic = 'Counts', roll_up_parameters = '.*x.* >> Nonconforming', parent='Unit_??')
  8. Hi tai, As noted in the error, the issue is due to you not having data during these error windows. By default, the .toSignal() function places samples every 1 day and since your error condition tends to last less than a minute, the .toSignal() may not have samples during this window. To fix this, you can supply a time parameter into .toSignal() to have a more frequent sampling. For example, 1.toSignal(10s) to have it samples every 10 seconds. Some other things you may want to consider are For your error condition, rather than just making a value search on when the value is 0, also restricting it to past data. replaceNotValid will also place results in the future when there isn't data but appending .within(past()) to your "replace error power totalizer" should only show these 0 values for past data validValues() is another useful function when you run into data gaps. It "connects the dots" by ignoring the gaps and connecting samples if they're within the maximum interpolation of the signal. You can change this interpolation using .setMaxInterpolation(time_input)
  9. Hi Taylor, below are some steps to achieve this. Feel free to sign up for Office Hours if you'd like help implementing this. Use Value Search to determine when your Rate < Trigger Use Signal from Condition to totalize your Target during the output of Step 1. Repeat for Actual. Note your tags have unrecognized units of Metric Tons/hour. If you'd like to make these into units Seeq recognizes, you can include a Step 1b where you use Formula and $tag.setUnits('t/hr') to apply these units. The outputs of Step 2 would then have units of metric tons. Subtract outputs of Step 2 to find your loss and divide by the target to get weighted duration
  10. Hello, Can you confirm that you're on a version of Seeq with built-in notifications (i.e. R60+)? Also, are you clicking your profile name and not the three bar icon? Your user profile will be where you'll see Notifications Management.
  11. Hi Manoel, In the case of multiple images you'll need to get more complex with how you capture sections of the HTML. Below are two routes I thought of but I'm sure there are others that may be better suited based on your particular scenario. Feel free to file a ticket at support.seeq.com for help. The options mentioned are based on a scenario where we're looking to update 2 images. Option 1: Continue logic from previous comment and manually specify portions of HTML to capture before and after each image (good for a few number of replacements with standardized names) # Similar code to previous comment pulled_workbooks = spy.workbooks.pull(spy.workbooks.search({'Name':'Organizer Topic Name'})) org_topic = pulled_workbooks[0] # Note you may need to confirm that the first item in pulled_workbooks is the topic of interest ws_to_update = org_topic.worksheets[0] # Choose the index based on the worksheet intended to be updated replace_html_1 = ws_to_update.report.add_image(filename = "ImageName1.png") replace_html_2 = ws_to_update.report.add_image(filename = "ImageName2.png") import re image_name_1 = "ImageName1" image_name_2 = "ImageName2" before_html = re.findall(r"(.*)<img.*?src=.*{image_name_1}_v\d*.png.*?>".format(image_name_1 = image_name_1), ws_to_update.html)[0] # Capture everything before the 1st image middle_html = re.findall(r"<img.*?src=.*{image_name_1}_v\d*.png.*?>(.*)<img.*?src=.*?{image_name_2}_v\d*.png.*?>".format(image_name_1 = image_name_1, image_name_2 = image_name_2), ws_to_update.html)[0] # Captures between the 1st and 2nd image after_html = re.findall(r".*<img.*?src=.*?{image_name_2}_v\d*.png.*?>(.*)".format(image_name_2 = image_name_2), ws_to_update.html)[0] # Captures everything after the image full_html = before_html + replace_html_1 + middle_html + replace_html_2 + after_html # Combine the before and after with the html generated for the new picture ws_to_update.html = full_html # Reassign the html to the worksheet and push it back to Seeq spy.workbooks.push(pulled_workbooks) Option 2: Bulk find all images and capture the HTML for them. Insert new image HTML based on position/order (better for large number of replacements where image name can change) # Same code as previous comment pulled_workbooks = spy.workbooks.pull(spy.workbooks.search({'Name':'Organizer Topic Name'})) org_topic = pulled_workbooks[0] # Note you may need to confirm that the first item in pulled_workbooks is the topic of interest ws_to_update = org_topic.worksheets[0] # Choose the index based on the worksheet intended to be updated replace_html_1 = ws_to_update.report.add_image(filename = "ImageName1.png") replace_html_2 = ws_to_update.report.add_image(filename = "ImageName2.png") import re image_name_1 = "ImageName1" image_name_2 = "ImageName2" before_html_new = re.findall(r"(.*?)<img.*?src=.*?_v\d*.png.*?>", ws_to_update.html) # Capture everything before and in between each image after_html_new = re.findall(r".*<img.*?src=.*?_v\d*.png.*?>(.*)", ws_to_update.html)[0] # Captures everything after the image replace_html_list = [replace_html_1, replace_html_2] full_html_list = [] for num, entry in enumerate(before_html_new): # Iterates through the non-image HTML and new image HTML, combining them based on their order in the list full_html_list.append(before_html_new[num]) full_html_list.append(replace_html_list[num]) if num == len(before_html_new)-1: full_html_list.append(after_html_new) full_html = "".join(full_html_list) ws_to_update.html = full_html # Reassign the html to the worksheet and push it back to Seeq spy.workbooks.push(pulled_workbooks)
  12. With spy.assets.Tree() there isn't a direct route to reference attributes belonging to child attributes in calculations. Instead you can create a rollup that will create an attribute based on the child attributes, and then use that roll-up attribute as an input into your calculations. For example in the code below, we need to create roll-up attributes that reference the child attributes. In this case I'm looking at a particular Area's but you can refine the roll_up_parameters to find the item you're looking for. Once the roll-up attribute is created you can then include it in other calculations at that level of the tree, as is done in the last tree insertion step. test.insert(name='Cooling Tower Temp', roll_up_statistic='Average', roll_up_parameters='Area B >> Temperature', parent='Cooling Tower 1') test.insert(name='Cooling Tower Temp', roll_up_statistic='Average', roll_up_parameters='Area D >> Temperature', parent='Cooling Tower 2') test.insert(name='Doing Something to Temperature', formula='$temp*100', formula_parameters={'$temp':'Cooling Tower Temp'}, parent='Cooling Tower ?')
  13. Correct the statistic will mirror what's seen in the GUI. To find out which ones are available, I ran the code mentioned above with an incorrect statistic and SPy returned an error with the possible options. Note that just like in the GUI only certain stats can be used for signals and condition Measured Items.
  14. I'd recommend filing a ticket by emailing support@seeq.com so we can schedule a meeting to troubleshoot. You could also sign up for an Office Hours session.
  15. Typically you'd see a 0000... ID when you have an error in your duplicated workbook. There are probably items in the original workbook that you don't have access to and can't use in your duplicate. Are you the owner of the original workbook or are you able to contact that person so they can look over what you don't have access to
  16. When generating a prediction in Seeq, some users often come across the error The number of target samples is not sufficient to conduct a regression. As the error suggests, there isn't enough data to perform the prediction but it can be difficult to determine the particular cause, especially when there are numerous inputs into the prediction. The steps below can be used to troubleshoot why a prediction is receiving this error and help suggest steps to resolve it. Step 1: Confirm data in your signals Seeq's prediction tool requires there to be interpolatable data at the timestamps of the target signal during the training window at least N+1 times, where N is the number of inputs into the model. These inputs aren't necessarily the number of signals, but the number of terms in the model (so for a polynomial scale, N = 2 * number of signals). In the case of a linear model that has 3 inputs, there needs to be at least 4 times when all of the inputs have data at the target's timestamps. If one of the signals never has data then the above requirement is not possible and that signal should be removed. If there is data in every signal, the next thing to look at if there is data within the training window. Seeq's Prediction tool by default accepts a time range as the training window but this can be further refined by limiting your training window to a condition. To check if the requirement is still met, the formula below can be used, where each $signal_i is a signal used in the model, $conditon is the training window condition and $target is the target of the model. ($signal_1 * $signal_2 ... * $signal_N).within($condition).resample($target).validValues() You can then match your display range with the time range chosen in the prediction and check the count of the resulting formula. This count either be determined using a Simple Scorecard Metric or in the Details Pane to check if it meets the requirement Step 2: Evaluate the Prediction If Step 1 suggests that all of your signals has data and should meet the necessary number of samples, then there could be an issue with the Prediction that prevents the requirement from being met. Some examples of this are Logarithmic Scale and Inputs with Zero or Negative Data: Its mathematically impossible to take a logarithm of zero or negative number so signals with data like this can't have these samples considered. To eliminate data like this from the inputs, formulas like $signal.within($signal > 0) can be used in conjunction with the previously mentioned formula to get an accurate count. Divide By Zero: There are cases when the prediction model can evaluate and fail to include samples due to divide by zero errors. To check if this is the problem, try using Principle Component Regression (PCR) instead of the standard Ordinary Least Squares (OLS) that's used by default in the Prediction tool.
  17. Hey Pat, just confirming that this fix resolved your original problem?
  18. The Users.AuthenticationFailures.Meter only provides as system wide view of how many users login attempts fail. To determine causes of these failures, you'll need to go into the logs as you mentioned. The particular log to look at varies based on your authentication mechanism though. Feel free to send an email to support@seeq.com and we can dive into the details of how your Seeq server is configured to determine which log file you'll need to look at.
  19. Vibration data is a common ask to be brought into Seeq. It all depends on where the data is stored; if its stored in one of Seeq's supported connections then yes. If its stored as CSV/Excel files, then yes they can be imported via our CSV Import Tool. If neither of the above, we'd need to look into the details of this vibration data to confirm/deny if it possible.
  20. Hi Andrew, Seeq has scripts that would move this condition beneath particular elements of asset trees. If you're still interested in having this done, feel free to email support@seeq.com and we can provide and customize the script to address your particular needs.
  21. Users of OSIsoft Asset Framework often want to filter elements and attributes based on the AF Templates they were built on. At this time though, the spy.search command in Seeq Data Lab only filters based on the properties Type, Name, Description, Path, Asset, Datasource Class, Datasource ID, Datasource Name, Data ID, Cache Enabled, and Scoped To. This post discusses a way in which we can still filter elements and/or attributes based on AF Template. Step 1: Retrieve all elements in the AF Database The code below will return all assets in an AF Database that are based on a AF Template whose name contains Location. asset_search = spy.search({"Path":"Example-AF", "Type":"Asset"}, all_properties=True) #Make sure to include all properties since this will also return the AF Template asset_search.dropna(subset=['Template'], inplace=True) # Remove assets not based on a template since we can't filter with NaN values asset_search_location = asset_search[asset_search['Template'].str.contains('Location')] # Apply filter to only consider Location AF Template assets Step 2: Find all relevant attributes This code will retrieve the desired attributes. Note wildcards and regular expression can be used to find multiple attributes. signal_search = spy.search({"Path":"Example-AF", "Type":"Signal", "Name":"Compressor Power"}) #Find desired attributes Step 3: Filter attributes based on if they come from an element from the desired AF template Last step cross references the signals returned with the desired elements. This is done by looking at their paths. # Define a function to recreate paths, items directly beneath the database asset don't have a Path def path_merger(row): row = row.dropna() return ' >> '.join(row) asset_search_location['Full Path'] = asset_search_location[['Path', 'Asset', 'Name']].apply(lambda row: path_merger(row),axis=1) # Create path for the asset that includes its name signal_search['Parent Path'] = signal_search[['Path', 'Asset']].apply(lambda row: path_merger(row),axis=1) # Create path for the parents of the signals signal_search_location = signal_search[signal_search['Parent Path'].isin((asset_search_location['Full Path']))] # Cross reference parent path in signals with full paths in assets to see if these signals are children of the desired elements
  22. Hi Dharun, It looks you won't be able to use the folium package in Seeq DataLab due to Content Security Policy issues. Feel free to read more about the issue in https://github.com/nteract/hydrogen/issues/1069 . I'd recommend using another geospatial library since workarounds to this issue would probably introduce security vulnerabilities.
  23. Hi Renzo. Feel free to come to our Office Hours where we can troubleshoot this particular issue but one thing I'd recommend looking at is if the signal where you pushed data to is scoped to a particular workbook. To access the data, you'll need to modify your spy.search to include the workbook.
  24. Hi Stephen, At this time it is not possible in a supported way via SPy to manipulate these aspects of your display. The worksheet properties that can be modified are display_items, display_range, scatter_plot_series (items displayed in scatter plot), scorecard_date_display, scorecard_date_format (for pre-51 Seeq versions), table_date_display, table_date_format, table_mode (R52+ Seeq), time_zone, and the view (Table, Trend, Treemap, etc.). There are ways to manipulate other worksheet properties by editing the workstep data but those methods may no longer work in future Seeq versions if we change things on the backend as we introduce new features. If you would like assistance in seeing how these particular properties you mentioned can be changed, please send a request to support@seeq.com.
  25. I tried this on R54.1.4 and came across a similar error but fixed it by appending .toString() to $seq. Below is the updated formula code. //creates a condition for 1 minute of time encompassing 30 seconds on either side of a transition $Transition = $CompressorStage.toCondition().beforeStart(0.5min).afterStart(1min) //Assigns the mode on both sides of the step change to a concatenated string that is a property of the capsule. $Transition .transform( $cap -> $cap.setProperty('StartModeEndMode', $CompressorStage.toCondition() .toGroup($cap, CAPSULEBOUNDARY.INTERSECT) .reduce("", ($seq, $stepCap) -> $seq.toString() + $stepCap.getProperty('Value') //Changes the format of the stage names for more clear de-lineation as a property in the capsules pane. .replace('STAGE 1','-STAGE1-').replace('STAGE 2','-STAGE2-').replace('TRANSITION','-TRANSITION-').replace('OFF','-OFF-') )))
×
×
  • Create New...