Skip to content

Commit 72fb30f

Browse files
committed
Update alarm behavior documentation and enforce valueAlarm.active defaults in code
1 parent eb6aa48 commit 72fb30f

File tree

5 files changed

+58
-7
lines changed

5 files changed

+58
-7
lines changed

docs/source/interfaces.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ Alarm Behavior
8282

8383
- Computation is scalar-only and active when ``compute_alarm: true``.
8484
- ``compute_alarm: true`` requires:
85-
``valueAlarm.active: true`` and limits
85+
``valueAlarm`` plus limits
8686
``lowAlarmLimit``, ``lowWarningLimit``, ``highWarningLimit``, ``highAlarmLimit``.
87+
- ``valueAlarm.active`` defaults to ``true`` when omitted for computed alarms.
88+
- ``valueAlarm.active: false`` is rejected when ``compute_alarm: true``.
8789
- Missing severities use defaults:
8890
``lowAlarmSeverity=2``, ``lowWarningSeverity=1``,
8991
``highWarningSeverity=1``, ``highAlarmSeverity=2``.

poly_lithic/src/interfaces/p4p_alarm_helpers.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@ def normalise_variable_settings(pv_name: str, pv_cfg: dict[str, Any]) -> dict[st
5454
if compute_alarm:
5555
if value_alarm_cfg is None:
5656
raise ValueError(f'{pv_name}: compute_alarm=true requires valueAlarm config')
57-
if value_alarm_cfg.get('active') is not True:
57+
if 'active' not in value_alarm_cfg:
58+
value_alarm_cfg['active'] = True
59+
elif value_alarm_cfg.get('active') is not True:
5860
raise ValueError(
59-
f'{pv_name}: compute_alarm=true requires valueAlarm.active=true'
61+
f'{pv_name}: compute_alarm=true does not allow valueAlarm.active=false'
6062
)
6163

6264
missing = [field for field in ALARM_LIMIT_FIELDS if field not in value_alarm_cfg]

readme.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,8 @@ Scalar PVs can compute EPICS alarm fields from ``valueAlarm`` limits:
276276

277277
When ``compute_alarm: true``:
278278

279-
- ``valueAlarm.active`` must be ``true``
279+
- ``valueAlarm.active`` defaults to ``true`` if omitted
280+
- ``valueAlarm.active: false`` is rejected
280281
- required limits: ``lowAlarmLimit``, ``lowWarningLimit``, ``highWarningLimit``, ``highAlarmLimit``
281282
- optional severities default to:
282283
``lowAlarmSeverity=2``, ``lowWarningSeverity=1``, ``highWarningSeverity=1``, ``highAlarmSeverity=2``
@@ -301,7 +302,7 @@ flowchart TD
301302
D -- No --> E[No computation<br/>Write value only]
302303
D -- Yes --> F{compute_alarm true?}
303304
F -- No --> E
304-
F -- Yes --> G{valueAlarm.active true<br/>and limits valid?}
305+
F -- Yes --> G{valueAlarm configured<br/>active not false<br/>and limits valid?}
305306
G -- No --> H[Config validation error at startup]
306307
G -- Yes --> I[Evaluate thresholds]
307308
I --> J[Set alarm severity/status/message]

tests/test_p4p.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,6 @@ def test_SimplePVAInterface_compute_alarm_defaults_missing_severities(monkeypatc
233233
'type': 'scalar',
234234
'compute_alarm': True,
235235
'valueAlarm': {
236-
'active': True,
237236
'lowAlarmLimit': -5.0,
238237
'lowWarningLimit': -2.0,
239238
'highWarningLimit': 2.0,
@@ -259,3 +258,27 @@ def fake_put(name, payload):
259258
assert sent[1]['alarm']['severity'] == 2
260259
assert sent[1]['alarm']['status'] == 3
261260
p4p.close()
261+
262+
263+
def test_SimplePVAInterface_reject_compute_alarm_with_active_false():
264+
config = {
265+
'variables': {
266+
'test:float:AA': {
267+
'name': 'test:float:AA',
268+
'proto': 'pva',
269+
'type': 'scalar',
270+
'compute_alarm': True,
271+
'valueAlarm': {
272+
'active': False,
273+
'lowAlarmLimit': -5.0,
274+
'lowWarningLimit': -2.0,
275+
'highWarningLimit': 2.0,
276+
'highAlarmLimit': 5.0,
277+
},
278+
}
279+
}
280+
}
281+
with pytest.raises(
282+
ValueError, match='compute_alarm=true does not allow valueAlarm.active=false'
283+
):
284+
SimplePVAInterface(config)

tests/test_p4p_server.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,6 @@ def test_scalar_compute_alarm_defaults_missing_severities():
386386
'type': 'scalar',
387387
'compute_alarm': True,
388388
'valueAlarm': {
389-
'active': True,
390389
'lowAlarmLimit': -5.0,
391390
'lowWarningLimit': -2.0,
392391
'highWarningLimit': 2.0,
@@ -412,3 +411,27 @@ def test_scalar_compute_alarm_defaults_missing_severities():
412411
assert alarm.message == 'HIHI'
413412
finally:
414413
p4p.close()
414+
415+
416+
def test_reject_server_compute_alarm_with_active_false():
417+
config = {
418+
'variables': {
419+
'test': {
420+
'name': 'test',
421+
'proto': 'pva',
422+
'type': 'scalar',
423+
'compute_alarm': True,
424+
'valueAlarm': {
425+
'active': False,
426+
'lowAlarmLimit': -5.0,
427+
'lowWarningLimit': -2.0,
428+
'highWarningLimit': 2.0,
429+
'highAlarmLimit': 5.0,
430+
},
431+
}
432+
}
433+
}
434+
with pytest.raises(
435+
ValueError, match='compute_alarm=true does not allow valueAlarm.active=false'
436+
):
437+
SimplePVAInterfaceServer(config)

0 commit comments

Comments
 (0)