Alarm reset for slow data acquisition

Recommended Posts


My system has very slow data acquisition rate - every 15 minutes. I want to install alarms so worked through your example in the manual which works great (with a data acquisition rate of 1 per 2 seconds) but I noticed that if I decreased the acquisition rate to say , every 10 seconds then when the alarm Reset button is pressed it is not reset until the next data value arrives.

Obviously for my app with 15 minute data this is a problem. I haven't ben able to see an equivalent of the command alarm.ack(alarmname) for reset.

My aim is to have a page displaying all the alarms for each parameter (at this stage there are 9 parameters), with a Reset and Acknowledge buttons. For each parameter I want to have the ability to have two levels of alarms for both Low and High such that when a level 1 alarm is fired then an email will be sent and if a level 2 alarm is exceeded then an SMS text will be sent. No problem to do that but I need to have the first person who responds to Acknowledge the alarm, check to see what the problem is then Reset the alarm (which needs to reset immediately so that if another person responds they know it has been reset).

Any ideas?



Link to comment
Share on other sites

The problem is that evaluating alarms for the fired and reset condition is typically only done when new data arrives. So, if you use a variable to reset an alarm, even if the variable changes, the alarm won't reset until new data (from any channel) arrives. There are two solutions:

1) use alarm.checkAlarms() after you set the reset variable to reset the alarm. You may then want to reset the reset variable after checking alarms so the alarm can trigger again:

MyResetVar = 1


MyResetVar = 0

2) create a Test channel with Timing = 1 and just let it run (don't log it or do anything with it). This will cause the alarms to evaluate every second, even if they don't use that Test channel.

Link to comment
Share on other sites

  • 3 weeks later...


Tried both these possible solutions and they don't work.

The problem is when I have multiple alarms set up. For example I have alarms for

Temperature Low alarm

Temperature High Alarm

Salinity Low Alarm

Salinity High Alarm.

I set up a Reset and Acknowledge button for each of these alarms and using the code below attached to each of the Reset buttons (with the reset variable changed)

TempLowAlarm = 1


TempLowAlarm = 0

When it does the alarm.checkAlarms() it checks all alarms using the latest set of data for each channel even though the alarm has already being acknowledged and reset. The problem is that it always checks the last value for that channel whether is has just arrived or been in the channel fo 10 minutes.

Ideally I would like to be able to check each alarm individually at my data acquistion frequency and fire it then and when the operator acknowledges and/or resets it, it cannot fire again until I get the next set of channel values when the alarms are checked again. I thought a function similar to the acknowledge function - alarm.ack("AlarmName") could be used.

The extra channel with Timing = 1 sec doesn't help because all the alarms are checked each second so it does Reset the alarm immediately the Reset is clicked but then fires the next second because all the alarms are checked and the other channels data value is out of spec.

Hmm, I don't see an answer for this except to write screeds of code to check each of my alarms manually when I obtain a new set of channel data.

Link to comment
Share on other sites

Hmm, good point. Fortunately there is a solution. It requires a couple steps though. First, for each alarm, where you have the Reset condition as something like:


and your alarm condition is something like:

MyTempChannel > 30

change your Alarm condition to:

(MyTempChannel > 30) && !ResettingAlarms

This will keep the alarm from firing when you reset the alarms. You could then set ResettingAlarms in each of your buttons, but read on first:

The issue now is that if you set and reset ResettingAlarms with your reset alarm buttons, when the timing loop comes around again and reads the first channel, it will evaluate the ALL the alarms, including ones for channels that haven't been updated, thus possibly refiring the alarms. To avoid this you need to use a sequence instead of channel Timing:

1) Put all your input channels with the same timing/offset in a single Channel Group. Let's say you call it "InputChannels"

2) Set the Timing on all those channels to 0.

3) Create a polling sequence:

alarm.paused = 1
global ResettingAlarms = 1
	  ResettingAlarms = 0
	  ResettingAlarms = 1
	  ? strLastError

The first line turns off automatic alarm checking. The second declares our ResettingAlarms flag. Then we go into a loop. I used a simply try/catch to avoid the loop ever stopping, being sure to add ? strLastError so I know if an error does occur, at least in the Command/Alert window. Then I do Channel.Readgroup(), which reads all the channels in the specified group. Using readGroup, in addition to being easier than listing every channel, ensures that any optimizations (such as combining reads for Modbus) are performed. Then I clear my ResettingAlarms flag, check my alarms, and then set the flag again so any reset button presses won't mess things up.

That should do it, though, I'm afraid as I often do here, this is off the cuff, so you might have to tweak it a bit...

One final note: you'll see that I used wait() despite all the warnings in DAQFactory, the manual and here in the forum. This is one case where wait() is appropriate as it ensures that we read our channels every 15 minutes and not every 15 minutes and 3 seconds or however long it takes to read the channels and evaluate the alarms. Its pretty much impossible for what is inside the loop to take 15 minutes unless you had 1000's of channels and they all timed out, but even then, the timeout releases the processor for the duration, so you don't end up hanging the DAQFactory.

Link to comment
Share on other sites


This topic is now archived and is closed to further replies.