packages feed

casa-reoc-0.1.0.0: examples/src/ReOC/Example/Risk.hs

{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wall #-}

{- | Entries of a risk register that most operators share, from which each
example builds its own register, as unfilled forms. The section numbers in
the controls are those of the operations manual.
-}
module ReOC.Example.Risk (
  riskEntry,
  airspaceRisks,
  peopleRisk,
  commandLinkRisk,
  batteryRisk,
  weatherRisk,
  fitnessRisk,
  recencyRisk,
  firmwareRisk,
) where

import Control.Lens ((&), (.~), (?~))
import Data.Text (Text)
import Data.Time.Calendar.Month (Month)
import ReOC.Model

{- | A risk, entered in a month and reviewed 12 months later: its hazard,
description, existing controls, initial risk, additional controls, residual
risk and owner.
-}
riskEntry :: Month -> Text -> Text -> Text -> (Likelihood, Consequence) -> Text -> (Likelihood, Consequence) -> KeyPosition -> UnfilledRisk
riskEntry entered h d e initial a residual owner =
  mkUnfilledRisk
    & hazard ?~ h
    & riskDescription ?~ d
    & existingControls ?~ e
    & initialRisk .~ assessment initial
    & additionalControls ?~ a
    & residualRisk .~ assessment residual
    & riskOwner ?~ owner
    & dateEntered ?~ entered
    & reviewMonths ?~ 12

-- The likelihood and consequence of a risk.
assessment :: (Likelihood, Consequence) -> UnfilledRiskAssessment
assessment (l, c) =
  mkUnfilledRiskAssessment
    & riskLikelihood ?~ l
    & riskConsequence ?~ c

-- | Crewed aircraft at low level, and operations near aerodromes.
airspaceRisks :: Month -> [UnfilledRisk]
airspaceRisks m =
  [ riskEntry
      m
      "Crewed aircraft at low level (helicopters, agricultural aircraft, aerial firefighting)"
      "Mid-air collision with a crewed aircraft"
      "Below 400 ft AGL; VLOS lookout; give way to crewed aircraft (2.4.2, 2.4.7)"
      (Improbable, Catastrophic)
      "Monitor the CTAF within 3 NM of a non-controlled aerodrome or HLS; check for NOTAMs and fire activity in planning; descend and land when a crewed aircraft approaches (2.4.3)"
      (ExtremelyImprobable, Catastrophic)
      ChiefRemotePilot
  , riskEntry
      m
      "Operations near aerodromes or in controlled airspace"
      "Airspace infringement; conflict with traffic"
      "CASA-verified drone safety app; no-fly zones of the Part 101 MOS (2.4.7)"
      (Improbable, Hazardous)
      "No operations in a no-fly zone without an approval or authorisation in force; the approval is carried on site"
      (ExtremelyImprobable, Hazardous)
      ChiefRemotePilot
  ]

-- | People who are not involved in the operation.
peopleRisk :: Month -> UnfilledRisk
peopleRisk m =
  riskEntry
    m
    "Persons not involved in the operation"
    "RPA strikes a person, causing injury"
    "30 m from people; not over populous areas; onsite validation; customer briefing (2.3, 2.4.6)"
    (Remote, Moderate)
    "Launch and recovery area kept clear of people; operation paused when a person approaches the operating area"
    (Improbable, Moderate)
    ChiefRemotePilot

-- | Loss of the command and control link.
commandLinkRisk :: Month -> UnfilledRisk
commandLinkRisk m =
  riskEntry
    m
    "Loss of command link"
    "Flyaway or uncontrolled flight; collision with people or property"
    "Manufacturer pre-flight checks; signal-lost action set; VLOS (2.3.3, App C)"
    (Remote, Moderate)
    "Return altitude set above obstacles at each site; sources of radio interference identified in the site assessment"
    (Improbable, Minor)
    ChiefRemotePilot

-- | Battery failure or a low battery.
batteryRisk :: Month -> UnfilledRisk
batteryRisk m =
  riskEntry
    m
    "Battery failure or low battery"
    "Forced landing in an unsuitable area; battery fire in flight, in storage or in transport"
    "Manufacturer battery care; low-battery warnings; periodic inspection (3.1)"
    (Remote, Moderate)
    "Battery reserve on landing (App C); damaged or swollen batteries removed from service; batteries carried and charged in fire-resistant bags"
    (Improbable, Minor)
    MaintenanceController

-- | Weather.
weatherRisk :: Month -> UnfilledRisk
weatherRisk m =
  riskEntry
    m
    "Wind, gusts, rain, heat or reduced visibility"
    "Loss of control; loss of VLOS; overheating of batteries or equipment"
    "Manufacturer limits; VMC; onsite validation (2.3.1)"
    (Remote, Moderate)
    "Forecast checked in planning and on site; operation stopped when a limit is approached"
    (Improbable, Minor)
    ChiefRemotePilot

-- | Fatigue, illness or impairment of a remote pilot.
fitnessRisk :: KeyPosition -> Month -> UnfilledRisk
fitnessRisk owner m =
  riskEntry
    m
    "RP fatigue, illness or impairment"
    "Errors in planning or flight control"
    "Fitness for duty requirements; duty and rest limits (1.7)"
    (Improbable, Moderate)
    "Alcohol and duty limits (1.7); work rostered within the limits; an RP who is unfit stands down without penalty"
    (ExtremelyImprobable, Moderate)
    owner

-- | A remote pilot who has not flown recently.
recencyRisk :: Month -> UnfilledRisk
recencyRisk m =
  riskEntry
    m
    "RP lack of recency"
    "Mishandling of an abnormal situation"
    "Recency requirements; annual checking event (1.6.2, 1.8)"
    (Remote, Moderate)
    "Proficiency flight after a lapse; regular practice of manual flight without GNSS assistance"
    (Improbable, Minor)
    ChiefRemotePilot

-- | Updates to firmware and software.
firmwareRisk :: Month -> UnfilledRisk
firmwareRisk m =
  riskEntry
    m
    "Firmware or software update"
    "Unexpected RPA behaviour in flight"
    "Updates directed by the MC as maintenance (3.1.1)"
    (Remote, Minor)
    "Release notes reviewed; test flight after an update before operations (3.1.1, 3.4)"
    (Improbable, Negligible)
    MaintenanceController