|
|
Rank: Newbie Groups: Member
Joined: 8/3/2010 Posts: 6
|
I am looking for a way to create a multi-state time delay sensor, probably using VBA. Currently, I have multi-state values on my sheet - green if in a good range(<92 dB), and red if above the alarm threshold(>=92 dB). What I need to do is find out a way to make the value first turn yellow for a period of 2 hours if the value crosses the alarm threshold, then if it is still above the threshold after 2 hours, it needs to turn red. If during this 2 hour 'warning' period the value drops below the alarm threshold, it will return to green. This time delay is used to make sure false alarms aren't reported. Any help would be greatly appreciated. Thanks!
|
|
|
|
|
OSIsoft vCampus is a subscription-based, online offering that consists of providing everything people need to develop applications on the PI System. We invite you to take a "tour" of the OSIsoft Virtual Campus - also feel free to consult the FAQ or contact OSIsoft vCampus for more details.
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
Hello, Welcome to the forum. From what you describe, I would create a digital state: Alarm_Warning Alarm Then I would write a performance equation for a PI tag that would check the current value against your limit (your limit could be another PI tag) and if in alarm, use PE functions like "TimeGE" for the time since it went in to alarm. If the result is greater than 2 hours set to "Alarm" otherwise set to "Alarm_Warning". That way you just multi-state based on one tag's digital state. (When I get a sec I will post up an example PE to do just this.) Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 8/3/2010 Posts: 6
|
Thanks for the quick response. Your thought process makes sense to me, though I am not sure how to implement it. I look forward to your next post.
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
No problem. If you have the ability to create PI Points then great, otherwise you will need to get your PI administrator to create the PI Point. First thing you need to do is create a Digital State Set via PI-SMT, for my example I have called it "AlarmCheck" and it has the states: 0: Normal 1: Alarm_Warning 2: Alarm Next, you need to build a performance equation PI Point (via PI-SMT) that makes use of the digital state you just created. Set the PE point to be event based on the PI Point that you want to monitor, then you build up your expression for the performance equation. Something like the following (but you need to test it for your needs) that I built based on what you said... if 'sensortag' > 75 then (if timege('sensortag',findge('sensortag','*','*-1d',75),'*',75) >= 7200 then digstate("Alarm") else digstate("Alarm_Warning")) else digstate("Normal") Then the PI Point you created you can multi-state it on your display with no VBA and it will be available for any other kind of analysis by another user. Hope this helps. Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 8/3/2010 Posts: 6
|
Your solution sounds like it would work great, unfortunately I do not have the ability to create PI Points either through myself or the PI administrator. This being the case, it seems that VBA is my only option. I realize this solution could get lengthy and time consuming. Any further suggestions would be greatly appreciated.
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
In that case you can do the following (no VBA  ) Create a PI Calculation DataSet as follows: if 'sinusoid' > 75 then (if timege('sinusoid',nextevent('sinusoid',findlt('sinusoid','*','*-1d',75)),'*',75) >= 7200 then 2 else 1) else 0 (Change sinusoid for your tag). Then on the symbol that you want to multi-state for the above, set the multi-state source as the PI Calculation and do the following: 1. Create 3 states for the multi-state. 2. Change the upper value of state 1 to "0.001". 3. Change the upper value of state 2 to "1". 4. Change the upper value of state 3 to "2". 5. Change colour of state 1 to "Green". 6. Change colour of state 1 to "Yellow". 7. Change colour of state 1 to "Red". Now your symbol will behave as if you had created the digital PE pi point. You might need to tweak the PE but it should work fine. Hope this helps. Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 8/3/2010 Posts: 6
|
After a few hours of messing with this, I am having some trouble understanding and manipulating the code you gave me. In the code:
if 'sinusoid' > 75 then (if timege('sinusoid',nextevent('sinusoid',findlt('sinusoid','*','*-1d',75)),'*',75) >= 7200 then 2 else 1) else 0
I assumed '75' is the alarm, so I changed it to my value of 92 throughout the code. This worked fine, I was getting either 0 or 1 based on the current data. If I tried changing the alarm level to a level that should output 2, say 85, I get "Error Evaluating Tag or Expression." Not sure why that is. Also, if I want the warning time to be 2 hours, should I change '*-1d' to '*-2h'? Where does '7200' come from? Is there a way to output the a colored tag instead of a number - for example "then 'sinusoid','red' - or something to that exent?
|
|
|
Rank: Member Groups: Member
Joined: 7/19/2010 Posts: 20
|
Couldn't you also check the minimum value of the tag for the previous 2 hours? If the minimum for those 2 hours is > 92, then you are in the alarm state. If the current value is > 92 and the 2 hour minimum is < 92, you are in the warning state. And of course if the current value is < 92 you are in the status-ok state. Code inspired by http://www.rjksolutionsltd.co.uk/forum/yaf_postst210_Find-MinMax-Value.aspxCode:Sub temp() 'Replace MyServer with your own server name in quotes mysrv = "MyServer" If Not PISDK.Servers(mysrv).Connected Then PISDK.Servers(mysrv).Open
Dim MinVal As Double MinVal = PISDK.Servers(mysrv).PIPoints("sinusoid").Data.Summary("*", "*-2h", astMinimum)
Dim AlarmLevel As Integer AlarmLevel = 2 'Alarm ON If MinVal < 92 Then AlarmLevel = 1 'Warning ON End If If PISDK.Servers(mysrv).PIPoints("sinusoid").Data.ArcValue("*", rtAuto) < 92 Then AlarmLevel = 0 'All clear End If
End Sub Disclaimer: Any code presented by myself might be unconventional because of the lack of formal training. Any corrections are welcome. =)
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
To help you understand the PE here is a breakdown: Code:if 'sinusoid' > 75 then ( if timege('sinusoid',nextevent('sinusoid',findlt('sinusoid','*','*-1d',75)),'*',75) >= 7200 then 2 else 1 ) else 0 You want to pay particular interest to: Code:timege('sinusoid',nextevent('sinusoid',findlt('sinusoid','*','*-1d',75)),'*',75) >= 7200 Where the functions used break it down further: Code:timege('sinusoid', nextevent('sinusoid', findlt('sinusoid','*','*-1d',75) ) ,'*',75) >= 7200 findlt will find the time when the value of the PI tag was less than your alarm limit from the current time and work backwards over the last day. If a value is found then the next event from that time should be the first occurence when your alarm limit was breached. NextEvent will simply return the time of the next event from the time you pass in - the time passed in comes from the findlt function. If findlt fails, then the calc fails so if your alarm has been in alarm for over 1 day the calc will fail and you need to extend the *-1d to *-7d or similar. timge will return the total time in seconds that a tag has been greater than or equal to your alarm limit. As we have used nested functions to find the time when the PI tag first went in to alarm from the current time (as it has currently breached your limit), timege will give you the total time it has been in alarm. 2 hours = 7200 seconds. You should just be able to change the tag names and the limits (anywhere you see 75) to get your alarm state. It works great on my side. Add the following as a seperate dataset so you can see the number of seconds it is calculating: Code:timege('sinusoid',nextevent('sinusoid',findlt('sinusoid','*','*-1d',75)),'*',75) >= 7200 Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
Actually, Tommy is probably right. I have over-engineered the PE, you can just use something like: Code:if 'sinusoid' >= 75 then (if tagmin('sinusoid','*','*-2h') >= 75 then 2 else 1) else 0 Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 8/3/2010 Posts: 6
|
Quote:Couldn't you also check the minimum value of the tag for the previous 2 hours? If the minimum for those 2 hours is > 92, then you are in the alarm state. If the current value is > 92 and the 2 hour minimum is < 92, you are in the warning state. And of course if the current value is < 92 you are in the status-ok state. This is almost correct. Assume the alarm is 92. If the minimum for the past 2 hours is >92, then it is in warning state. If the minimum is >92 for greater than 2 hours, it is in alarm state. And if anytime it goes under 92, it is ok. So it goes: ok(<92), warning for first 2 hours when above 92, then alarm if it remains over 92 for more than 2 hours. After reading through RJK Solutions code and break down, I understand it better and believe it will work. It will take me a while to apply the code to everything in my Processbook and monitor it, but I will check back with my status and further questions if need be.
|
|
|
Rank: Member Groups: Member
Joined: 7/19/2010 Posts: 20
|
discgolfer, Read the logic carefully. RJK posted a simpler syntax for his method, too. Again, the logic is to take a 2 hour chunk of time and find the minimum value for that chunk. If that minimum is > 92, then you know that the level has never been below that time for that 2 hour time period, and thus you are in alarm state. If the minimum for that chunk is less than 92, you know that there was at least one point in time where you were below that threshold and thus are in warning state. And of course if your current value is below 92, you are in the clear.    Disclaimer: Any code presented by myself might be unconventional because of the lack of formal training. Any corrections are welcome. =)
|
|
|
Rank: Newbie Groups: Member
Joined: 8/3/2010 Posts: 6
|
Yes, Tommy, you were correct. I misread your previous post. RJK's solution worked out great. Thanks a lot for all the help!
|
|
|
|
Guest
|