---
$schema: "http://json-schema.org/draft-07/schema#"
$id: "https://oimlsmart.org/schemas/R134.yaml"
title: "OIML R134 (Automatic instruments for weighing road vehicles in motion) Certificate Schema"
description: |
  OIML R134:2006 "Automatic instruments for weighing road vehicles in motion
  and measuring axle loads". Three independent accuracy-class axes per
  instrument, one for each measured quantity:
    - vehicle mass (numeric class: 0.2 / 0.5 / 1 / 2 / 5 / 10)
    - single axle load (letter class: A / B / C / D / E / F)
    - axle group load (letter class: A / B / C / D / E / F)

  R134 §2 — speed and temperature ranges and weighing capacity are
  declared per-axis at type_level; per-model capacity and scale interval
  are recorded at model_level.

type: object
required: [certificate, certified_type, characteristics, recommendation]
properties:
  certificate:           { $ref: "_core.yaml#/definitions/Certificate" }
  issuing_authority:     { $ref: "#/definitions/IssuingAuthority" }
  applicants:            { $ref: "_core.yaml#/definitions/PartyList" }
  manufacturers:         { $ref: "_core.yaml#/definitions/PartyList" }
  certified_type:        { $ref: "#/definitions/CertifiedType" }
  characteristics:       { $ref: "#/definitions/Characteristics" }
  recommendation:
    type: object
    required: [id, edition, scheme]
    properties:
      id:          { type: string, const: R134 }
      edition:     { type: integer, enum: [2006] }
      amendment:   { type: [integer, string, "null"] }
      scheme:      { type: string, enum: [A, B] }
      accuracy_classes:
        description: |
          Flat list of accuracy-class tokens covered by the certificate.
          The token encodes both axis and value (e.g. "10" = vehicle mass
          class 10, "F" = axle load class F). Consumers needing per-axis
          queries should use `characteristics.type_level.{accuracy_class_*}`.
        type: array
        items: { $ref: "#/definitions/AccuracyClassValue" }
  test_reports:          { $ref: "_core.yaml#/definitions/TestReportList" }
  revision_history:      { $ref: "_core.yaml#/definitions/RevisionHistory" }
  model_family:          { $ref: "_core.yaml#/definitions/ModelFamily" }
  components:
    type: array
    items: { $ref: "_core.yaml#/definitions/Component" }
  footnotes:             { $ref: "_core.yaml#/definitions/FootnoteList" }
  matrix_tables:
    type: array
    items:
      type: object
      required: [name, columns, rows]
      properties:
        name: { type: string }
        columns:
          type: array
          items: { type: string }
        rows:
          type: array
          items: { type: object }
        description: { type: string }
        footnotes:
          type: array
          items: { $ref: "_core.yaml#/definitions/Footnote" }
  d011_tests_applicable:
    description: Tests mandated by R134:2006 type evaluation (D 11:2013 subset).
    type: array
    items: { $ref: "#/definitions/D011TestReference" }
    default:
    - { test_id: d011_t06_static_temperature }
    - { test_id: d011_t07_static_temperature }
    - { test_id: d011_t08_damp_heat_steady_state }
    - { test_id: d011_t09_damp_heat_cyclic }
    - { test_id: d011_t11_atmospheric_pressure }
    - { test_id: d011_t15_vibration_random }
    - { test_id: d011_t16_vibration_sinusoidal }
    - { test_id: d011_t17_mechanical_shock }
    - { test_id: d011_t18_dc_mains_voltage_variation }
    - { test_id: d011_t20_ac_mains_voltage_variation }
    - { test_id: d011_t22_dc_mains_dips_interruptions }
    - { test_id: d011_t23_ac_mains_dips_interruptions }
    - { test_id: d011_t26_bursts_ac_dc_mains }
    - { test_id: d011_t27_surges_ac_dc_mains }
    - { test_id: d011_t28_bursts_signal_data_control }
    - { test_id: d011_t29_surges_signal_data_control }
    - { test_id: d011_t33_rf_em_fields_general }
    - { test_id: d011_t35_electrostatic_discharges }

definitions:
  IssuingAuthority:
    description: |
      Body that issued the certificate. Extends _core IssuingAuthority with
      R134-specific `conformity_evaluation_body` field observed in Swiss certs.
    type: object
    required: [name]
    properties:
      name:                      { type: string }
      address_lines:             { type: array, items: { type: string } }
      person_responsible:       { type: string }
      person_title:             { type: string }
      phone:                    { type: string }
      email:                    { type: string }
      website:                  { type: string }
      oiml_issuer_id:           { type: string }
      conformity_evaluation_body: { type: string }
    additionalProperties: false

  AccuracyClassVehicleMass:
    description: |
      R134:2006 §2 — accuracy class for total vehicle mass measurement.
      Encoded as a fractional error bound; six classes from 0.2 (best) to
      10 (coarsest). Values in this enum are nominal class identifiers;
      the actual error formula is given in R134 §3.
    allOf:
    - $ref: "_core.yaml#/definitions/StructuredValue"
    - properties:
        value:
          oneOf:
          - type: string
            oneOf:
            - const: "0.2"
              description: Class 0.2 — best precision, fractional error ≤ 0.2 %
            - const: "0.5"
              description: Class 0.5 — fractional error ≤ 0.5 %
            - const: "1"
              description: Class 1 — fractional error ≤ 1 %
            - const: "2"
              description: Class 2 — fractional error ≤ 2 %
            - const: "5"
              description: Class 5 — fractional error ≤ 5 %
            - const: "10"
              description: Class 10 — coarsest, fractional error ≤ 10 %
            - const: "N/A"
              description: Not applicable
          - type: number
            description: Numeric form of class identifier (e.g. 10, 5, 2).
          - $ref: "_core.yaml#/definitions/RangeValue"
            description: Min/max range of class identifiers (e.g. min 0.5, max N/A).
          - type: array
            minItems: 1
            items:
              oneOf:
              - type: string
              - type: number
            description: Array of class identifiers (multi-class certificate).

  AccuracyClassAxleLoad:
    description: |
      R134:2006 §2 — accuracy class for single axle load (and, by
      extension, axle group load). Letter classes A (best) through F
      (coarsest). Per R134 §3 the corresponding error bound doubles per
      step.
    allOf:
    - $ref: "_core.yaml#/definitions/StructuredValue"
    - properties:
        value:
          oneOf:
          - type: string
            oneOf:
            - const: A
              description: Class A — best, error ≤ 1 %
            - const: B
              description: Class B — error ≤ 2 %
            - const: C
              description: Class C — error ≤ 4 %
            - const: D
              description: Class D — error ≤ 8 %
            - const: E
              description: Class E — error ≤ 12.5 %
            - const: F
              description: Class F — coarsest, error ≤ 25 %
            - const: "N/A"
              description: Not applicable
            # Range-expression surface forms from extraction data
            - const: "D or higher"
              description: Surface form — class D or better; normalize to D
            - const: "E or higher"
              description: Surface form — class E or better; normalize to E
            - const: "F or higher"
              description: Surface form — class F or better; normalize to F
            - const: "A or higher"
              description: Surface form — class A or better; normalize to A
            - const: "B or higher"
              description: Surface form — class B or better; normalize to B
            - const: "C or higher"
              description: Surface form — class C or better; normalize to C
          - type: array
            minItems: 1
            items:
              type: string
              enum: [A, B, C, D, E, F, "N/A"]
            description: Array of letter-class identifiers (multi-class certificate).
          - $ref: "_core.yaml#/definitions/RangeValue"
            description: Min/max range of letter-class identifiers (e.g. min B, max N/A).

  AccuracyClassValue:
    description: |
      Bare accuracy class token for `recommendation.accuracy_classes`.
      Axis attribution is lost in this flat list — see
      `AccuracyClassVehicleMass`, `AccuracyClassAxleLoad` for axis-aware
      values used in `characteristics.type_level`.
    type: string
    anyOf:
    - enum:
      - "0.2"
      - "0.5"
      - "1"
      - "2"
      - "5"
      - "10"
      - A
      - B
      - C
      - D
      - E
      - F
      - "N/A"
    # Combined vehicle-mass + axle-load tokens (e.g. "10F" = vehicle mass
    # class 10 + axle load class F, "5E" = class 5 + class E).
    - pattern: '^[0-9]+[A-F]$'
    - pattern: '^[A-F][0-9]+$'

  DirectionOfWeighing:
    description: |
      Direction of vehicle travel when weight is measured. Accepts either a
      bare canonical string or a StructuredValue wrapping it. Surface forms
      observed in extraction data (e.g. "Both", "Dual", "Single") are
      tolerated pending normalization.
    oneOf:
    - type: string
      oneOf:
      - const: single_direction
        description: Only one direction of travel
      - const: both_directions
        description: Both directions of travel
      - const: free
        description: Either direction is acceptable
      - const: "N/A"
        description: Not applicable
      # Surface forms — normalize to canonical tokens above.
      - const: single
        description: Surface form of single_direction
      - const: Single
        description: Surface form of single_direction
      - const: both
        description: Surface form of both_directions
      - const: Both
        description: Surface form of both_directions
      - const: dual
        description: Surface form of both_directions
      - const: Dual
        description: Surface form of both_directions
      - const: "Dual direction"
        description: Surface form of both_directions
      - const: "Single or Dual direction"
        description: Surface form of free
      - const: "bi-directional"
        description: Surface form of both_directions
    - allOf:
      - $ref: "_core.yaml#/definitions/StructuredValue"
      - properties:
          value:
            type: string
            oneOf:
            - const: single_direction
            - const: both_directions
            - const: free
            - const: "N/A"
            - const: single
            - const: Single
            - const: both
            - const: Both
            - const: dual
            - const: Dual
            - const: "Dual direction"
            - const: "Single or Dual direction"
            - const: "bi-directional"
            - const: "Bi-directional"
            - const: "bi-directional (both directions)"

  CertifiedType:
    type: object
    required: [category, type_designations]
    properties:
      category: { type: string }
      type_designations:
        type: array
        minItems: 1
        items: { type: string }
      module_designation:
        description: |
          R134 distinguishes single-platform and multi-platform instruments
          and various sensor technologies. Free-text in the corpus.
        type: [string, "null"]
      description: { type: string }

  Characteristics:
    type: object
    properties:
      type_level: { $ref: "#/definitions/TypeLevel" }
      model_level:
        type: array
        items: { $ref: "#/definitions/ModelLevelEntry" }
      config_level:
        type: array
        items: { $ref: "#/definitions/ConfigLevelEntry" }

  TypeLevel:
    type: object
    properties:
      # Three independent accuracy-class axes (R134:2006 §2)
      accuracy_class_vehicle_mass:        { $ref: "#/definitions/AccuracyClassVehicleMass" }
      accuracy_class_axle_load:           { $ref: "#/definitions/AccuracyClassAxleLoad" }
      accuracy_class_axle_group_load:     { $ref: "#/definitions/AccuracyClassAxleLoad" }
      # Common synonyms used by various issuers (each maps to one of the
      # three canonical axes above; GLM extractor emits the variant label).
      accuracy_class:                     { $ref: "_core.yaml#/definitions/StructuredValue" }
      accuracy_class_for_vehicle_mass:    { $ref: "#/definitions/AccuracyClassVehicleMass" }
      accuracy_class_for_axle_load:       { $ref: "#/definitions/AccuracyClassAxleLoad" }
      accuracy_class_for_axle_group_load: { $ref: "#/definitions/AccuracyClassAxleLoad" }
      accuracy_class_for_single_axle_load:    { $ref: "#/definitions/AccuracyClassAxleLoad" }
      accuracy_class_for_single_axle_loads:   { $ref: "#/definitions/AccuracyClassAxleLoad" }
      accuracy_class_single_axle_load:        { $ref: "#/definitions/AccuracyClassAxleLoad" }
      accuracy_class_single_axle_loads:       { $ref: "#/definitions/AccuracyClassAxleLoad" }
      accuracy_class_for_total_weight:         { $ref: "#/definitions/AccuracyClassVehicleMass" }
      accuracy_class_for_total_vehicle_mass:   { $ref: "#/definitions/AccuracyClassVehicleMass" }
      accuracy_class_total_weight:             { $ref: "#/definitions/AccuracyClassVehicleMass" }
      accuracy_class_total_vehicle_mass:       { $ref: "#/definitions/AccuracyClassVehicleMass" }
      # Environmental
      temperature_range:                  { $ref: "_modules/d011_environmental.yaml#/definitions/TemperatureRange" }
      temperature_range_electronic:       { $ref: "_core.yaml#/definitions/StructuredValue" }
      temperature_range_sensor:           { $ref: "_core.yaml#/definitions/StructuredValue" }
      temperature_range_load_receptors:   { $ref: "_core.yaml#/definitions/StructuredValue" }
      temperature_range_cabinet_equipment: { $ref: "_core.yaml#/definitions/StructuredValue" }
      temperature_range_inside_cabinet:   { $ref: "_core.yaml#/definitions/StructuredValue" }
      humidity_class:                     { $ref: "_modules/d011_environmental.yaml#/definitions/ClimaticClass" }
      electromagnetic_environment_class:  { $ref: "_modules/d011_environmental.yaml#/definitions/EMClass" }
      mechanical_environment_class:       { $ref: "_modules/d011_environmental.yaml#/definitions/MechanicalClass" }
      # Speed
      maximum_operating_speed_vmax:       { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_operating_speed_vmin:       { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_speed:                      { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_speed:                      { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_transit_speed:              { $ref: "_core.yaml#/definitions/StructuredValue" }
      operating_speed_range:              { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_operation_speed:            { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_operation_speed:            { $ref: "_core.yaml#/definitions/StructuredValue" }
      # Capacity (per-axis)
      maximum_capacity:                   { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_capacity:                   { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_capacity_axle_load:         { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_capacity_axle_load:         { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_capacity_vehicle_mass:      { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_capacity_vehicle_mass:      { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_capacity_vehicle:           { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_capacity_vehicle:           { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_capacity_axle:              { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_capacity_axle:              { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_capacity_gvw:               { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_capacity_gvw:               { $ref: "_core.yaml#/definitions/StructuredValue" }
      max_gvw:                            { $ref: "_core.yaml#/definitions/StructuredValue" }
      min_gvw:                            { $ref: "_core.yaml#/definitions/StructuredValue" }
      max_axle:                           { $ref: "_core.yaml#/definitions/StructuredValue" }
      min_axle:                           { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_vehicle_mass:               { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_axle_group_load:            { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_capacity_per_wheel:         { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_capacity_per_wheel:         { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_capacity_totalized:         { $ref: "_core.yaml#/definitions/StructuredValue" }
      # Scale
      scale_interval:                     { $ref: "_core.yaml#/definitions/StructuredValue" }
      scale_interval_d:                   { $ref: "_core.yaml#/definitions/StructuredValue" }
      scale_interval_t:                   { $ref: "_core.yaml#/definitions/StructuredValue" }
      scale_interval_for_stationary_load: { $ref: "_core.yaml#/definitions/StructuredValue" }
      scale_intervals:                    { $ref: "_core.yaml#/definitions/StructuredValue" }
      number_of_scale_intervals:          { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_number_of_scale_intervals:  { $ref: "_core.yaml#/definitions/StructuredValue" }
      verification_scale_interval_d:      { $ref: "_core.yaml#/definitions/StructuredValue" }
      # Axle / load configuration
      maximum_number_of_axles:            { $ref: "_core.yaml#/definitions/StructuredValue" }
      max_number_of_axles:                { $ref: "_core.yaml#/definitions/StructuredValue" }
      max_number_of_axles_a_max:          { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_number_of_axles_a_max:      { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_number_of_axles_per_vehicle: { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_number_of_axles_per_vehicle_a_max: { $ref: "_core.yaml#/definitions/StructuredValue" }
      number_of_sensor_rows:              { $ref: "_core.yaml#/definitions/StructuredValue" }
      load_receptor_configuration:        { $ref: "_core.yaml#/definitions/StructuredValue" }
      load_cells:                         { $ref: "_core.yaml#/definitions/StructuredValue" }
      connected_load_cells:               { $ref: "_core.yaml#/definitions/StructuredValue" }
      connected_load_cells_compliance:    { $ref: "_core.yaml#/definitions/StructuredValue" }
      load_cell_excitation_voltage:       { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_load_cell_impedance:        { $ref: "_core.yaml#/definitions/StructuredValue" }
      maximum_load_cell_impedance:        { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_input_voltage_per_verification_scale_interval: { $ref: "_core.yaml#/definitions/StructuredValue" }
      measuring_range_maximum_voltage:    { $ref: "_core.yaml#/definitions/StructuredValue" }
      fraction_of_maximum_permissible_error: { $ref: "_core.yaml#/definitions/StructuredValue" }
      load_cell_connection:               { $ref: "_core.yaml#/definitions/StructuredValue" }
      load_cell_cable_length:             { $ref: "_core.yaml#/definitions/StructuredValue" }
      # Motion / direction
      direction_of_travel:                { $ref: "#/definitions/DirectionOfWeighing" }
      direction_of_weighing:              { $ref: "#/definitions/DirectionOfWeighing" }
      vehicle_position_detection:         { $ref: "_core.yaml#/definitions/StructuredValue" }
      compensating_axle_groups:           { $ref: "_core.yaml#/definitions/StructuredValue" }
      type_approval_sign:                 { $ref: "_core.yaml#/definitions/StructuredValue" }
      minimum_operating_speed_nu_min:     { $ref: "_core.yaml#/definitions/StructuredValue" }
      # Power
      power_supply_voltage:               { $ref: "_core.yaml#/definitions/StructuredValue" }
      power_supply_frequency:             { $ref: "_core.yaml#/definitions/StructuredValue" }
      power_supply_type:                  { $ref: "_core.yaml#/definitions/StructuredValue" }
      power_supply_battery:               { $ref: "_core.yaml#/definitions/StructuredValue" }
      electrical_power_supply_voltage:    { $ref: "_core.yaml#/definitions/StructuredValue" }
      electrical_power_supply_frequency:  { $ref: "_core.yaml#/definitions/StructuredValue" }
      # Software / firmware
      software_identification:            { $ref: "_core.yaml#/definitions/SoftwareIdentification" }
      software_version:                   { $ref: "_core.yaml#/definitions/StructuredValue" }
      software_hash:                      { $ref: "_core.yaml#/definitions/StructuredValue" }
      operating_system:                   { $ref: "_core.yaml#/definitions/StructuredValue" }
      ram:                                { $ref: "_core.yaml#/definitions/StructuredValue" }
      processor:                          { $ref: "_core.yaml#/definitions/StructuredValue" }
      hard_disk_capacity:                 { $ref: "_core.yaml#/definitions/StructuredValue" }
      screen_resolution:                  { $ref: "_core.yaml#/definitions/StructuredValue" }
      communication_ports:                { $ref: "_core.yaml#/definitions/StructuredValue" }
      application:                        { $ref: "_core.yaml#/definitions/StructuredValue" }
      warm_up_time:                       { $ref: "_core.yaml#/definitions/StructuredValue" }
      software_identification_code:       { $ref: "_core.yaml#/definitions/StructuredValue" }
      type_specific_parameters_identification_code: { $ref: "_core.yaml#/definitions/StructuredValue" }

  ModelLevelEntry:
    type: object
    required: [attribute, values]
    properties:
      attribute: { type: string }
      unit:
        $ref: "_units.yaml#/definitions/Unit"
      values:
        type: array
        items:
          type: object
          required: [model, value]
          properties:
            model:            { type: string }
            value:            { $ref: "_core.yaml#/definitions/ValueOrScalar" }
            footnote_markers:
              type: array
              items: { type: string }

  ConfigLevelEntry:
    type: object
    required: [attribute, axis, values]
    properties:
      attribute: { type: string }
      axis:      { oneOf: [ { type: string }, { type: "null" } ] }
      unit:
        $ref: "_units.yaml#/definitions/Unit"
      values:
        type: array
        items:
          type: object
          anyOf:
          - required: [condition, value]
            properties:
              condition: { type: string }
              value:     { $ref: "_core.yaml#/definitions/ValueOrScalar" }
          - required: [model, value]
            properties:
              model:     { type: string }
              value:     { $ref: "_core.yaml#/definitions/ValueOrScalar" }

  D011TestReference:
    description: Reference to an OIML D 11:2013 performance test.
    type: object
    required: [test_id]
    properties:
      test_id:          { type: string, pattern: '^d011_t\d{2}_' }
      test_level_index: { type: integer, minimum: 1, maximum: 5 }
      notes:            { type: string }

allOf:
- description: |
    R134:2006 weighs vehicles in motion, so mechanical-environment
    classes M2/M3 (vibration/shock from passing vehicles or direct
    mounting) trigger mechanical test requirements:
    M2 → t15 (random vibration); M3 → t16 (sinusoidal) and t17 (shock).
  if:
    properties:
      characteristics:
        properties:
          type_level:
            properties:
              mechanical_environment_class:
                properties:
                  value: { const: M2 }
  then:
    properties:
      d011_tests_applicable:
        contains: { properties: { test_id: { const: d011_t15_vibration_random } } }
- if:
    properties:
      characteristics:
        properties:
          type_level:
            properties:
              mechanical_environment_class:
                properties:
                  value: { const: M3 }
  then:
    allOf:
      - properties:
          d011_tests_applicable:
            contains: { properties: { test_id: { const: d011_t16_vibration_sinusoidal } } }
      - properties:
          d011_tests_applicable:
            contains: { properties: { test_id: { const: d011_t17_mechanical_shock } } }
- description: |
    D 11 §9.2 damp-heat tests apply per humidity class:
    H2 → t08 (steady state); H3 → t09 (cyclic).
  if:
    properties:
      characteristics:
        properties:
          type_level:
            properties:
              humidity_class:
                properties:
                  value: { const: H2 }
  then:
    properties:
      d011_tests_applicable:
        contains: { properties: { test_id: { const: d011_t08_damp_heat_steady_state } } }
- if:
    properties:
      characteristics:
        properties:
          type_level:
            properties:
              humidity_class:
                properties:
                  value: { const: H3 }
  then:
    properties:
      d011_tests_applicable:
        contains: { properties: { test_id: { const: d011_t09_damp_heat_cyclic } } }
