← All showcases
symbol · line · test anchorsIndustrial control
industrialsafetysequencing

The interlock that must not fail

A safety requirement bound to ST by line range, to a test by name, and back by an rq: comment.

One name — EmergencyStop — from requirement to PLC to proof.

safety/interlock.rq

EmergencyStop {
    E-stop must drop heater enable within one scan
    valve must close before heater enables
    pressure must reach setpoint before valve opens
    implemented in ["./plc/interlock.st".EmergencyStop]
    proven by ["./plc/interlock.test.ts:drops heater within one scan"]
    @status verified
    @tags (
        iec-61131
        critical
        safety
    )
}

safety_interlock {
    guards [EmergencyStop] on every phase transition
    @status verified
}

plc/interlock.st

(* rq:["../safety/interlock.rq".EmergencyStop] *)
FUNCTION_BLOCK EmergencyStop
VAR_INPUT
    Estop_NC : BOOL;
END_VAR
VAR_OUTPUT
    HeaterEnable : BOOL;
    ValveOpen    : BOOL;
END_VAR

HeaterEnable := Estop_NC AND NOT ValveOpen;
ValveOpen    := Estop_NC AND PressureOk;
END_FUNCTION_BLOCK

plc/interlock.test.ts

test("drops heater within one scan", () => {
  const fb = new EmergencyStop();
  fb.Estop_NC = false;
  fb.cycle();
  expect(fb.HeaterEnable).toBe(false);
});

trace

EmergencyStop
  ├── ["./plc/interlock.st".EmergencyStop]
  ├── ["./plc/interlock.test.ts:drops heater within one scan"]
  └── rq: comment in ST → back to the idea