CODESYS Example Projectを調べてみた#9 (Alarm Manager)
Alarm Manager
今回は、Alarm ManagerのExample Projectを見ていきます。CODESYSのAlarm Managerは、PLCの制御システムにおいて発生する異常状態や重要なイベントを管理するための機能・ライブラリです。Alarm Managerは、主に以下の機能を提供します。
項目 | 説明 |
---|---|
アラームの定義 | PLCプログラム内で発生する異常やイベントをアラームとして定義し、レベル(緊急・警告・情報など)やカテゴリを設定できる。 |
アラームの検出と発生 | 設定された条件(センサー異常・閾値超過など)を満たすと自動的にアラームが発生する。 |
アラーム通知と表示 | 発生したアラームはCODESYS Visualizationでリアルタイムに一覧表示され、視覚的・音響的に通知可能。 |
アラームの確認とリセット | オペレーターがアラームを確認(Acknowledge)し、認識済みとする。また、問題解決後にリセット処理で解除可能。 |
アラーム履歴とログ管理 | アラームは日時や状態とともに自動的に履歴として記録され、後から表示・分析やCSV形式でのエクスポートが可能。 |
アラームのグループ化 | 関連するアラームをグループ化し、一括して通知や表示を管理できる。 |
Alarm Managerを使う場合の一般的な開発の流れは以下の通りです。
- Alarm Configurationの追加
- Alarm管理用のオブジェクトをApplication内に作成します。
- Alarm Groupの追加(任意)
- 必要に応じてAlarm Configuration内でAlarmをグループ化します。
- Alarm Classの設定
- Error, Warningなどのクラスを設定します。
- クラスは、Alarm Configuration内で定義し、表示色や通知方法と関連付けます。
- Alarmの定義
- Alarm Configuration → Alarm Groupの下に管理したい個々のAlarmを追加します。
- 名前、説明、Alarm Class、Trigger条件を設定します。
- Alarmトリガ条件をプログラムで実装
- Alarm発生条件をPLCプログラムとして実装します。
- 例:Alarm定義のBOOL変数を温度が閾値を超えたらTRUEに設定するなど。
- Visualizationへのアラーム表示の追加
- Alarm TableなどをVisualizationに追加します。
Setup
これまでの記事を参照。
Contents of the example
Alarm ManagerのExample Projectの中には、Applicationの下に以下のコードが配置されています。
Alarm Configuration
AlarmFilterCriteria(FB)
AlarmManagerClient(FB)
PLC_PRG(PRG)
ProcessAlarms(FUN)
最初にAlarm Configurationの中身を確認し、その後、FBやFUNの中身を調べていきたいと思います。
Alarm Configuration
Alarm Configurationの説明は、CODESYSのhelpmeサイトや、Youtubeの解説動画、他の方の記事が参考になります。
Alarm Configurationを開くと、Alarm Instance、Settingsのタブがあります。
その下に、Warning, Alarm1zeilig, AlarmStorageなどがありますが、これはAlarm ClassとAlarm Groupです。ちょっと暗めのアイコン(Warningなど)がAlarm Classです。
Alarm Group
Alarm Groupには、ObservationTypeという項目にDigitalが設定された項目が9つあります。Detailsの部分にトリガー条件が設定され、あとは、ClassとMessageの値がそれぞれ設定されます。Observation Typeには、Digitalの他、Upper LimitやEventなども選択可能です。ID=11のアラームについては、ラッチ変数が2つ関連付けられています。ラッチ変数は、スカラー型の変数、STRING、またはWSTRINGです。ラッチ変数は、アラームがアクティブなときに追加の値を記録するために使用されます。例えば、モータ速度のアラームを監視していて、アラーム発生時の温度とモータ電流を記録するような用途が想定されます。
Alarm Class
Alarm Classには、WarningとWarningOrangeが定義されています。Alarm Groupで使用されていたものと同じです。
Acknowledgementのところに「Normalー>Activeー>Normal」のような遷移図がありますが、これは、Alarm発生後の状態遷移を表しています。このExample Projectの場合、アラーム発生条件が満たされなくなると、アラームは解除されます。この他、Helpmeページによると4種類くらいあるようです。
PLC_PRG(PRG)
以下にプログラム中の気になるところを抜粋しています。
instAlarmFilterCriteriaAll : AlarmFilterCriteria;
AlarmFilterCriteria は、Alarm Managerが持つアラームのリストから、特定の条件に基づいて表示したいアラームを絞り込むためのフィルタ条件を定義するFunction Blockです。
上記のインスタンス instAlarmFilterCriteriaAll は、「すべてのアラーム」を対象にフィルターを適用したい場合や特定条件の指定時に使用します。
iarrAlarmGroupIDs12 : ARRAY [0..1] OF UDINT := [Alm_AlarmConfiguration_Alarmgroup_InternalIDs.ID_Alarme1zeilig, Alm_AlarmConfiguration_Alarmgroup_InternalIDs.ID_Alarme2zeilig];
iarrAlarmGroupIDs12 は、Alarm Managerで定義した特定のAlarm Group(アラームをグループ化したもの)のIDを格納する配列です。この配列はAlarm Managerの処理において、特定のAlarm Groupを指定し、これらに関連するアラームだけを操作(取得・表示・確認など)するために使用されます。
instAlarmManagerClient12 : AlarmManagerClient;
itfAlarmManagerClient12 : IAlarmManagerClient := instAlarmManagerClient12;
AlarmManagerClientはAlarm Managerとやり取りをするためのクライアント機能を提供するFunction Blockです。IAlarmManagerClientはAlarm Managerの標準インターフェースで、このインターフェースを経由してAlarm Managerからアラーム情報を取得したり、Visualizationに表示するためのデータをやり取りしたりします。instAlarmManagerClient12というインスタンスは、Alarm Managerとの接続管理を行い、Visualization画面へのアラーム表示やアラーム状態操作(確認・リセット)をサポートします。
diScrollbarPageSize : INT := iMaxCountAlarmsFromHistoryAll;
diScrollbarPageSizeは、Visualization画面(AlarmTableなど)に表示するアラーム一覧のページサイズを設定するための変数です。例えば、この値が50なら、画面に最大50個のアラームを一度に表示できます。Alarm Managerが履歴や多数のアラームを持つ場合、スクロールバーのページ送り機能で使用されます。
// Arrays to hold the alarms from the alarm storage
arrAlarmsFromHistoryAll : ARRAY [0 .. iMaxCountAlarmsFromHistoryAll - 1] OF Alarm;
arritfAlarmsFromHistoryAll : ARRAY [0 .. iMaxCountAlarmsFromHistoryAll - 1] OF IAlarm2;
itfAlarmManagerClientAll : IAlarmManagerClient := instAlarmManagerClientAll;
Alarm型の配列の定義が不明確なため、Alarm型の詳細については今後調査します(調査課題)。
AlarmFilterCriteria(FB)
FUNCTION_BLOCK AlarmFilterCriteria IMPLEMENTS IAlarmFilterCriteria
VAR_INPUT
piarrAlarmGroupIDs : POINTER TO ARRAY [0..0] OF UDINT;
iCountAlarmGroups : INT;
END_VAR
このFunction BlockはAlarm Managerに表示するアラームをグループ単位で絞り込むためのフィルタ条件を提供します。入力としてAlarm Group IDの配列とその要素数を受け取り、それを元にAlarm Managerがアラーム表示時に対象を制限します。例えば特定のAlarm Groupに属するアラームのみをVisualizationに表示したい場合に使用します。
AlarmManagerClient(FB)
FUNCTION_BLOCK AlarmManagerClient IMPLEMENTS IAlarmManagerClient
VAR_INPUT
m_itfAlarmFilterCriteria : IAlarmFilterCriteria;
m_sDescription : STRING;
m_iMaxCountAlarmsFromHistoryAll : INT;
xIsAlarmStorageClient : BOOL := FALSE;
END_VAR
VAR
// Temporary string used to format timestamps
m_itfAlarmManagerClient : IAlarmManagerClient := THIS^;
END_VAR
このFunction Blockは、CODESYSのAlarm Manager機能と連携するためのクライアントインターフェースです。Alarm Managerが管理するアラーム情報にアクセスするための機能を提供します。
入力パラメータとして、フィルタ条件(m_itfAlarmFilterCriteria)や説明文、最大履歴数(m_iMaxCountAlarmsFromHistoryAll)を指定します。
xIsAlarmStorageClientがTRUEの場合、アラーム履歴の記録用クライアントとして機能し、履歴情報の取得などが可能になります。
また内部的に自身のインターフェース(IAlarmManagerClient)を保持し、Alarm Managerと継続的にデータをやり取りします。
ProcessAlarm(FUN)
ProcessAlarms関数は、Alarm Managerから取得した複数のアラームを1つずつループ処理し、それぞれのアラームの状態、メッセージ、ラッチ変数などの情報を整理・整形します。その後、Visualizationやコンソール上に出力すると同時に、後で利用できるよう構造体にも格納する役割を担っています。
FUNCTION ProcessAlarms : BOOL
VAR_INPUT
sDescription : STRING;
parritfAlarms : POINTER TO ARRAY[0..0] OF IAlarm;
iCountAlarms : INT;
parrAlarmTableSimulation : POINTER TO ARRAY[0..0] OF AlarmTableSimulationRow;
iCountAlarmTableSimulationRows : INT;
END_VAR
VAR
i : INT;
itfAlarmGroup : IAlarmGroup;
itfAlarmClass : IAlarmClass;
liTimestamp : AlarmManager.Timestamp;
psMessage : POINTER TO STRING;
itfTypedValue : ITypedValue;
// Temporary string used to format timestamps
dbsTempString : Stu.CharBufferString(uiBufferSize := 200, stringType := __SYSTEM.TYPE_CLASS.TYPE_STRING);
// We use this severity, so that the output will be visible on the console without modifying the
// configuration file of the PLC
udiSeverity : UDINT := VisuElems.LogClass.LOG_ERROR;
alarmTableSimRow : AlarmTableSimulationRow;
END_VAR
アラームグループとアラームクラスは、IAlarm型のメソッド使い以下のように取得できます。
itfAlarmGroup := parritfAlarms^[i].GetAlarmGroup();
itfAlarmClass := parritfAlarms^[i].GetAlarmClass();
アラームの状態・IDは、IAlarmのメソッドで取得した後、STRINGに変換します。
alarmTableSimRow.sState := GetAlarmStateString(parritfAlarms^[i].GetState());
alarmTableSimRow.sID := UINT_TO_STRING(parritfAlarms^[i].GetID());
alarmTableSimRow.sInternalID := UDINT_TO_STRING(parritfAlarms^[i].GetInternalID());
ラッチ変数はアラーム発生時の追加情報(温度、電流など)を保持しているため、値を取得し文字列化できます。
itfTypedValue := parritfAlarms^[i].GetLatchVar1Value();
FormatTypedValue(itfTypedValue, dbsTempString);
alarmTableSimRow.sLatchVar1 := dbsTempString.m_AsString^;
itfTypedValue := parritfAlarms^[i].GetLatchVar2Value();
FormatTypedValue(itfTypedValue, dbsTempString);
alarmTableSimRow.sLatchVar2 := dbsTempString.m_AsString^;
現在値の取得・整形もできます。
itfTypedValue := parritfAlarms^[i].GetCurrentValue();
FormatTypedValue(itfTypedValue, dbsTempString);
alarmTableSimRow.sCurrValue := dbsTempString.m_AsString^;
Alarm Visualization
Visualization中のAlarmTableのPropertyは以下のスクリーンショットのような内容でした。詳しい設定方法は、CODESYSのHelpページを参照。
学びと気づき
- Alarm Managerの設定方法、STプログラムからAlarm Managerへのアクセス方法を学びました。
- Alarm Manager Clientのインターフェース経由での操作は、最初はやや複雑に感じられましたが、使っていけば慣れてくると思います。
まとめ
- Alarm Configurationを追加してAlarm Managerオブジェクトを作る
- Alarm Manager Client InterfaceをつかってAlarm Managerとやりとりする。
- より詳細な情報はAlarmManager Library Documentationを参照。
Discussion