Applies To:
  • CitectSCADA 6.xx
  • CitectHMI 6.xx

Summary:
The following functions used to work when called from a Foreground Cicode object, or as a 'While Shown' event, however, in v6.0 onwards they do not work when called this way:

AlarmAck(), AlarmEnable(), AlarmDisable(), AlarmClear(), AlarmSplit(), AlarmSetPriority(), AlarmSetPriorityRec(), AlarmDelete(), SetArea(), AlarmNext(), AlarmSetInfo.

Solution:
If called from a Foreground Cicode object, these functions would be called every PageScan. In order for the function to finish, a sleep is required. Since 'Sleep' is a blocking function, this cannot be called from a foreground object, so TaskNew is required in order to run the function in conjunction with a sleep statement, i.e:

FUNCTION
SleepDspLastStdAlm1
(
INT iStartAN, INT iGrp)

    TaskNew("TaskDspLastStdAlm1",IntToStr(IStartAN) + "," + IntToStr(iGrp),8);
END

FUNCTION
TaskDspLastStdAlm1
(
INT iStartAN, INT iGrp)

    AlarmDspLast(iStartAN, 1, 1);
    Sleep
(0);
    AlarmSetInfo
(iStartAN, 2, iGrp);
END

In the above example, the foreground Cicode object would be changed to call SleepDspLastStdAlm(…)
Now, this scenario works OK if there is only one foreground Cicode object on the page, but If you have multiple similar foreground cicode objects, they cannot reference the same function. This is because Tasknew() cannot make the same function run in multiple threads at the same time.

So, for multiple instances on the same page, you would need to create multiple functions, such as:

FUNCTION
SleepDspLastStdAlm1
(
INT iStartAN, INT iGrp)

    TaskNew
("TaskDspLastStdAlm1",IntToStr(IStartAN) + "," + IntToStr(iGrp),8);
END

FUNCTION
SleepDspLastStdAlm2
(
INT iStartAN, INT iGrp)

    TaskNew("TaskDspLastStdAlm2",IntToStr(IStartAN) + "," + IntToStr(iGrp),8);
END

FUNCTION
SleepDspLastStdAlm3
(
INT iStartAN, INT iGrp)

    TaskNew("TaskDspLastStdAlm3",IntToStr(IStartAN) + "," + IntToStr(iGrp),8);
END

FUNCTION
TaskDspLastStdAlm1
(
INT iStartAN, INT iGrp)

    AlarmDspLast(iStartAN, 1, 1);
    Sleep
(0);
    AlarmSetInfo
(iStartAN, 2, iGrp);
END

FUNCTION
TaskDspLastStdAlm2
(
INT iStartAN, INT iGrp)

    AlarmDspLast(iStartAN, 1, 1);
    Sleep
(0);
    AlarmSetInfo
(iStartAN, 2, iGrp);
END

FUNCTION
TaskDspLastStdAlm3
(
INT iStartAN, INT iGrp)

    AlarmDspLast(iStartAN, 1, 1);
    Sleep
(0);
    AlarmSetInfo
(iStartAN, 2, iGrp);
END

Now, a call to one of these Alarm functions below will cancel any outstanding requests for an alarm list. This won't impact a project where these functions are only called on changes, so the best option is to engineer projects to ensure these functions are only called when necessary. If these functions are called every scan time however, it will mean that previous calls to AlarmDsp etc.... will never be processed.
The functions could be re-written to either run once:

IF StrToInt(PageInfo(7)) = 5 THEN
    AlarmSetInfo
()
END

Or they could be written to be triggered by Alarm Category's 'ON ACTION' and 'OFF ACTIONS'  


Keywords:
Alarm functions foreground CiCode objects while shown events 
 

Attachments