Jump to content

Thorsten Vogt

Super Seeqer
  • Posts

    171
  • Joined

  • Last visited

  • Days Won

    53

Everything posted by Thorsten Vogt

  1. Hi Esther, based on the information you provided I would create a condition for each of the two durations you want to calculate. To do this in formula I first recommend you to rename the variables for better readability of the formula. For the first one ("ADD Durations for when equipment is stopped and in lag OR when the equipment is stopped or standby") you may use: ($stopped && $lag) || ($stopped || $standby) //-> can be shortened to $stopped || $standby For the second one ("ADD Durations for when equipment is stopped but not in lag or standby") try: $stopped && !($lag || $standby) Depending on what you want to do with the duration you may use different tools for calculation (e.g. Signal from Condition, Scorecard Metric, use of capsule properties, ...) Let me know if you need more help. Regards, Thorsten
  2. Hi Tomasz, regarding the error message I assume you are passing a condition to the toScalars function instead of a capsule. If you want to have the first value of the capsule you can also use "Signal from Condition": Regards, Thorsten
  3. Hi Isaac, you may try this instead: Max: $days = days() $aMax = $a.aggregate(maxValue(), $days, durationKey()) $bMax = $b.aggregate(maxValue(), $days, durationKey()) $gMax = $g.aggregate(maxValue(), $days, durationKey()) $hMax = $h.aggregate(maxValue(), $days, durationKey()) $aIsMax = $aMax.isGreaterThan($bMax).intersect($aMax.isGreaterThan($gMax)).intersect($aMax.isGreaterThan($hMax)) $bIsMax = $bMax.isGreaterThan($aMax).intersect($bMax.isGreaterThan($gMax)).intersect($bMax.isGreaterThan($hMax)) $gIsMax = $gMax.isGreaterThan($aMax).intersect($gMax.isGreaterThan($bMax)).intersect($gMax.isGreaterThan($hMax)) $hIsMax = $hMax.isGreaterThan($aMax).intersect($hMax.isGreaterThan($bMax)).intersect($hMax.isGreaterThan($gMax)) "".toSignal(1d) .splice("Area A".toSignal(1d), $aIsMax) .splice("Area B".toSignal(1d), $bIsMax) .splice("Area G".toSignal(1d), $gIsMax) .splice("Area H".toSignal(1d), $hIsMax) Min: $days = days() $aMin = $a.aggregate(minValue(), $days, durationKey()) $bMin = $b.aggregate(minValue(), $days, durationKey()) $gMin = $g.aggregate(minValue(), $days, durationKey()) $hMin = $h.aggregate(minValue(), $days, durationKey()) $aIsMin = $aMin.isLessThan($bMin).intersect($aMin.isLessThan($gMin)).intersect($aMin.isLessThan($hMin)) $bIsMin = $bMin.isLessThan($aMin).intersect($bMin.isLessThan($gMin)).intersect($bMin.isLessThan($hMin)) $gIsMin = $gMin.isLessThan($aMin).intersect($gMin.isLessThan($bMin)).intersect($gMin.isLessThan($hMin)) $hIsMin = $hMin.isLessThan($aMin).intersect($hMin.isLessThan($bMin)).intersect($hMin.isLessThan($gMin)) "".toSignal(1d) .splice("Area A".toSignal(1d), $aIsMin) .splice("Area B".toSignal(1d), $bIsMin) .splice("Area G".toSignal(1d), $gIsMin) .splice("Area H".toSignal(1d), $hIsMin) Regards, Thorsten
  4. Hi Isaac, don't know why I did not came across this solution first, which is fairly the easiest to achive I think: You can use boolean operators for this. Determine Max Signal: $days = days() //Calculate maximum per day $aMax = $a.aggregate(maxValue(), $days, durationKey()) $bMax = $b.aggregate(maxValue(), $days, durationKey()) $gMax = $g.aggregate(maxValue(), $days, durationKey()) $hMax = $h.aggregate(maxValue(), $days, durationKey()) //Which is max? $aIsMax = $aMax > $bMax && $aMax > $gMax && $aMax > $hMax $bIsMax = $bMax > $aMax && $bMax > $gMax && $bMax > $hMax $gIsMax = $gMax > $aMax && $gMax > $bMax && $gMax > $hMax $hIsMax = $hMax > $bMax && $hMax > $gMax && $hMax > $gMax //Generate signal "".toSignal(1d) .splice("Area A".toSignal(1d), $aIsMax) .splice("Area B".toSignal(1d), $bIsMax) .splice("Area G".toSignal(1d), $gIsMax) .splice("Area H".toSignal(1d), $hIsMax) Determine Min Signal: $days = days() //Caulate minimum per day $aMin = $a.aggregate(minValue(), $days, durationKey()) $bMin = $b.aggregate(minValue(), $days, durationKey()) $gMin = $g.aggregate(minValue(), $days, durationKey()) $hMin = $h.aggregate(minValue(), $days, durationKey()) //Which is min? $aIsMin = $aMin < $bMin && $aMin < $gMin && $aMin < $hMin $bIsMin = $bMin < $aMin && $bMin < $gMin && $bMin < $hMin $gIsMin = $gMin < $aMin && $gMin < $bMin && $gMin < $hMin $hIsMin = $hMin < $bMin && $hMin < $gMin && $hMin < $gMin //Generate Signal "".toSignal(1d) .splice("Area A".toSignal(1d), $aIsMin) .splice("Area B".toSignal(1d), $bIsMin) .splice("Area G".toSignal(1d), $gIsMin) .splice("Area H".toSignal(1d), $hIsMin) Regards, Thorsten
  5. Hi Pablo, you can use transform() and replace() to do this. I made an example with a signal that contains the following data: To create a signal that contains only the numeric values I used the following formula: $originalSignal.transform(($p, $c) -> sample($c.getKey(), $c.getValue().replace('/\\w+\\s(\\d+)/', '$1'))) Transform is used to access every sample in the signal by specifying a lambda expression. The current sample is temporarily stored in the variable $c. $p contains the previous sample which is not used here. For each sample of the original signal a new sample is created by using the timestamp (key) of the original sample. The value for the new sample is determined by the value of the sample of the original signal on which replace() is executed. As the name suggests replace() is used to replace portions of a string. In this case I make use of a regular expression to determine the numeric value inside the original string and replace the original string by the determined value. The result looks like this: For your example (12345_20200326_PJR) you have to modify the replace part to: .replace('/(\\d+)_\\d+_\\w+/', '$1') Hope this helps. Regards, Thorsten
  6. Hi Bryan, you can do this by using Seeq Data Labs. I prepared an example based on the data @Kristopher Wiggins used. The following code creates a boundary signal (in this case the mean), which can be used for further calculations: import pandas as pd #search signals signals = spy.search(pd.DataFrame([{"Name": "/(Product_Viscosity|Grade_Code_String)/"}]), workbook="4218D647-C7CB-4062-A6CF-D114F2E5E559") #get data for last 60 days data = spy.pull(signals, grid= None, start = pd.datetime.utcnow() - pd.Timedelta("60d")) #calculate mean means = data.groupby('Grade_Code_String').mean() #create boundary signal and push back to Seeq calc_dict = dict() calc_dict['Name'] = 'BoundarySignal' calc_dict['Type'] = 'Signal' formula = "0.tosignal(5min)" for m in means.itertuples(): formula = formula + ".splice(" + str(m.Product_Viscosity) + ".toSignal(5min), $s == '" + m.Index + "')" calc_dict['Formula'] = formula calc_dict['Formula Parameters'] = { '$s': signals[signals["Name"] == 'Grade_Code_String'] } metadata_for_calcs = list() metadata_for_calcs.append(calc_dict) spy.push(metadata=pd.DataFrame(metadata_for_calcs), workbook="4218D647-C7CB-4062-A6CF-D114F2E5E559") Hope this helps. Regards, Thorsten
  7. Hi Milan, as a starting point the Knowledge Base provides an overview and covers the steps to create a Treemap: https://support.seeq.com/space/KB/486604833/Treemap Regards, Thorsten
  8. Hello Mark, like this way? The body of "Push Result" is: '{"statusMessage":"Invalid unit \\u0027/Min\\u0027"}' Regards, Thorsten
  9. Hi, I came across this issue when I used Seeq Data Labs for uploading data from an Excel file into Seeq. The file contained some signals, that used "1/Min" as UOM. While uploading the data to Seeq I got the message that the Unit is not supported. I created a sample with one signal to reproduce the issue: Is there a way to let SDL check for invalid units before pushing data back to Seeq? The bad thing is that the signal is created in Seeq and cannot be archived within SDL or Seeq Workbench: Only way to archive these items seems to be using SDK or REST API. Regards, Thorsten
  10. As far as I know this is not possible right now.
  11. Hi Kathryn, yes, there are multiple options. You can use aggregate(): This will give you a stepped signal containing the number of capsules per week. Another option would be using the Histogram tool: Or you may use a scorecard metric. When using type "Simple" it will calculate the values for the current display range. Hope this helps. Regards, Thorsten
  12. Hi, when pushing data to Seeq there is an option to attach metadata for specifying some additional properties. According to the documentation specifying "Unit of Measure" as a metadata property would enable to set the unit of measure inside Seeq server. However the property has to be named "Value Unit of Measure" otherwise Seeq server will not display the UOM in trend view. Regards, Thorsten
  13. Hi Mark, thank you. The new version works. Regards, Thorsten
  14. Hi, when I try to get data into Jupyter Notebooks by using spy.pull(), I receive no results when I omit "start" and "end" parameters. According to the documentation it should return values for the last hour. However if I specify the timestamps in UTC spy returns the desired values: Is there a way to get this working without specifying the timestamps? Regards, Thorsten
  15. Hi Morgan, I think the initial problem is that forecastSplice() seems to combine the value from the original signal and the forecast only for the next 90 (?) days and then stops combining them. Regards, Thorsten
  16. Hi, treefile connector seems to have problems when using a regex quantifier like "\d{4,5}" inside CSV file. Error message: value not one of declared Enum instance names: [Signal, Data, Condition, Scalar, Asset] I think that the "," inside the quantifier is responsible for this and the columns for the evaluation of the configuration line are misinterpreted. I was able to work around this by using "\d\d\d\d\d?". Is there a way to specify another delimiter for the treefile connector to use when working with CSV files? Regards, Thorsten
  17. Hi Robin, maybe you want to try this. For this demo I created 3 signals based on the example data of Seeq as I did not have data like yours. For each of the signals I created capsules whenever the value is above 1kW: In the next step I joined the running conditions to one parent condition: Now I am able to calculate the delay between the start of the "All running" capsules and the "Running" capsules of each signal and delay the original signal by this value: In the last step I created capsules for the delayed signal, whenever the value is about 1kW: You may have to do some adjustments to this example regarding your needs. Hope this helps. Regards, Thorsten
  18. Hi Ali, as a workaound try this one: $signal.splice($newsignal, condition(1y, capsule(now(), now()+1y))) Regards, Thorsten
  19. Hi Ali, startKey(), middleKey() and endKey() provide just the timestamp where Seeq will put the calculated value. In your example using periods(1year,6month) Seeq will always calculate the average for one year starting from January (e.g. 01/01/2018 - 01/01/2019) and the average starting from July (e.g. 07/01/2018 - 07/01/2019). For the period 01/01/2018 - 01/01/2019 using - startKey() will put the value to 01/01/2018 - middleKey() will put the value to 07/01/2018 - endKey() will put the value to 01/01/2019 The marked columns in the following Analysis all have the same value for the period of last year : Hope this helps. Regards, Thorsten
  20. Hi Joanna, thank you. Can you give me a hint on where to make this setting inside the configuration file? Regards, Thorsten
  21. Hi, I configured Seeq to use data from a SQL Server database. However, after rebooting the machine hosting SQL Server or restarting SQL Server service the connection in Seeq is not reestablished. Error message: Error getting data: The target datasource is disconnected or no longer exists I have to restart Seeq service to get this resolved. Is this a known issue and is there a way to get around this? Regards, Thorsten
  22. Hi Ali, in addition to @Sanman Mehta's answer if you need just the difference between the values: You can use runningDelta() for getting the change of the value from sample to sample or use Signal From Condition and apply "Delta" as summary statistic. That will give you the difference between values at end and start of the capsule. Regards, Thorsten
  23. Hi Chris, you can use Deviation Search for this. I altered @Lindsey.Wilcox example by using another signal that acts as the limit: Using Deviation Search you can find capsules, when the value is above the threshold: In the last step you combine the conditions to get the desired capsules. Make sure you uncheck "Inclusive of B", otherwise the resulting capsules are extended by the duration of B. Hope this helps. Regards, Thorsten
  24. Hi Sanjhosh, maybe this topic from @Allison Buenemann can help you. Regards, Thorsten
  25. You can use signal() for this But I would suggest getting the values from a data source connected to Seeq (like PI or a relational database) rather than filling them in manually. Regards, Thorsten
×
×
  • Create New...