---
$schema: "http://json-schema.org/draft-07/schema#"
$id: "https://oimlsmart.org/schemas/R49.yaml"
title: "OIML R49 (Water Meters) Certificate Schema"
description: |
  OIML R49 "Water meters intended for the metering of cold potable water and hot water".
  Covers multi-jet, single-jet, volumetric, Woltman and ultrasonic water meters in
  accuracy classes 1, 2 and 3 per R49-1 §3.2.4.
type: object
required: [certificate, certified_type, characteristics, recommendation]
properties:
  certificate:           { $ref: "_core.yaml#/definitions/Certificate" }
  issuing_authority:     { $ref: "_core.yaml#/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: R49 }
      edition:     { type: integer, enum: [2001, 2006, 2013, 2024] }
      amendment:   { type: [string, integer, "null"] }
      scheme:      { type: string, enum: [A, B] }
      accuracy_classes:
        type: array
        items:
          oneOf:
          - type: string
          - type: number
          - $ref: "#/definitions/AccuracyClass"
  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:         { $ref: "#/definitions/MatrixTableList" }
  d011_tests_applicable:
    description: Tests mandated by R49-3 type evaluation.
    type: array
    items: { $ref: "#/definitions/D011TestReference" }
    default:
    - { test_id: d011_t06_static_temperature }
    - { test_id: d011_t07_static_temperature }
    - { test_id: d011_t10_water }
    - { test_id: d011_t11_atmospheric_pressure }
    - { test_id: d011_t08_damp_heat_steady_state }
    - { test_id: d011_t09_damp_heat_cyclic }
    - { test_id: d011_t20_ac_mains_voltage_variation }
    - { 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_t30_mains_power_frequency_em_field }
    - { test_id: d011_t33_rf_em_fields_general }
    - { test_id: d011_t35_electrostatic_discharges }

definitions:
  AccuracyClass:
    description: OIML R49-1 §3.2.4 water meter accuracy class.
    allOf:
    - $ref: "_core.yaml#/definitions/StructuredValue"
    - properties:
        value:
          type: [string, number, "null"]
          oneOf:
          - const: "1"
            description: Class 1 — lower accuracy; typically volumetric or Woltman meters
          - const: "2"
            description: Class 2 — medium accuracy; multi-jet, single-jet and combination meters
          - const: "3"
            description: Class 3 — lowest accuracy; low-flow and irrigation meters

  TemperatureClass:
    description: |
      R49-1 §4.1.7 temperature class. T0..T90 defines admissible water temperature range.
    allOf:
    - $ref: "_core.yaml#/definitions/StructuredValue"
    - properties:
        value:
          type: [string, "null"]
          oneOf:
          - const: T0
            description: 0.1 to 30 °C — cold water only
          - const: T30
            description: 0.1 to 30 °C — cold potable water
          - const: T50
            description: 0.1 to 50 °C — cold + warmed water
          - const: T70
            description: 0.1 to 70 °C — hot water
          - const: T90
            description: 0.1 to 90 °C — high-temperature hot water

  PressureLossClass:
    description: R49-1 §4.1.8 pressure loss class.
    allOf:
    - $ref: "_core.yaml#/definitions/StructuredValue"
    - properties:
        value:
          type: [string, "null"]
          oneOf:
          - const: "ΔP10"
            description: Maximum pressure loss 10 kPa
          - const: "ΔP16"
            description: Maximum pressure loss 16 kPa
          - const: "ΔP25"
            description: Maximum pressure loss 25 kPa
          - const: "ΔP40"
            description: Maximum pressure loss 40 kPa
          - const: "ΔP63"
            description: Maximum pressure loss 63 kPa
          - const: "ΔP100"
            description: Maximum pressure loss 100 kPa

  WaterPressureClass:
    description: R49-1 §4.1.9 admissible working pressure class (MAP rating).
    allOf:
    - $ref: "_core.yaml#/definitions/StructuredValue"
    - properties:
        value:
          type: [string, "null"]

  FlowProfileSensitivityClass:
    description: |
      R49-1 §4.1.5 flow disturbance sensitivity classes — upstream (U0..U10)
      and downstream (D0..D10) classes per ISO 4064 / OIML R49.
    allOf:
    - $ref: "_core.yaml#/definitions/StructuredValue"
    - properties:
        value:
          type: [string, "null"]

  CertifiedType:
    type: object
    required: [category, type_designations]
    properties:
      category: { type: string }
      type_designations:
        type: array
        minItems: 1
        items: { type: string }
      module_designation: { type: [string, "null"] }
      description: { type: [string, "null"] }

  Characteristics:
    type: object
    properties:
      type_level:
        type: object
        additionalProperties: { $ref: "_core.yaml#/definitions/StructuredValue" }
        properties:
          accuracy_class:                          { $ref: "#/definitions/AccuracyClass" }
          temperature_class:                       { $ref: "#/definitions/TemperatureClass" }
          water_pressure_class:                    { $ref: "#/definitions/WaterPressureClass" }
          pressure_loss_class:                     { $ref: "#/definitions/PressureLossClass" }
          flow_profile_sensitivity_class:          { $ref: "#/definitions/FlowProfileSensitivityClass" }
          maximum_admissible_temperature:          { $ref: "_core.yaml#/definitions/StructuredValue" }
          maximum_admissible_pressure:             { $ref: "_core.yaml#/definitions/StructuredValue" }
          orientation_limitation:                  { $ref: "_core.yaml#/definitions/StructuredValue" }
          orientation:                             { $ref: "_core.yaml#/definitions/StructuredValue" }
          mounting:                                { $ref: "_core.yaml#/definitions/StructuredValue" }
          reverse_flow:                            { $ref: "_core.yaml#/definitions/StructuredValue" }
          resolution_of_indicating_device:         { $ref: "_core.yaml#/definitions/StructuredValue" }
          resolution_of_the_indicating_device:     { $ref: "_core.yaml#/definitions/StructuredValue" }
          indicating_range:                        { $ref: "_core.yaml#/definitions/StructuredValue" }
          measuring_principle:                     { $ref: "_core.yaml#/definitions/StructuredValue" }
          flow_conditioner:                        { $ref: "_core.yaml#/definitions/StructuredValue" }
          minimum_straight_length_inlet_pipe:      { $ref: "_core.yaml#/definitions/StructuredValue" }
          minimum_straight_length_outlet_pipe:     { $ref: "_core.yaml#/definitions/StructuredValue" }
          minimum_straight_length_of_inlet_pipe:   { $ref: "_core.yaml#/definitions/StructuredValue" }
          minimum_straight_length_of_outlet_pipe:  { $ref: "_core.yaml#/definitions/StructuredValue" }
          data_output_options:                     { $ref: "_core.yaml#/definitions/StructuredValue" }
          mechanical_environment_class:            { $ref: "_core.yaml#/definitions/StructuredValue" }
          temperature_range:                       { $ref: "_modules/d011_environmental.yaml#/definitions/TemperatureRange" }
          electromagnetic_environment_class:       { $ref: "_modules/d011_environmental.yaml#/definitions/EMClass" }
          software_identification:                 { $ref: "_core.yaml#/definitions/SoftwareIdentification" }
      model_level:
        type: array
        items: { $ref: "#/definitions/ModelLevelEntry" }
      config_level:
        type: array
        items: { $ref: "#/definitions/ConfigLevelEntry" }

  ModelLevelEntry:
    type: object
    required: [attribute, values]
    properties:
      attribute: { type: string }
      unit_symbol: { type: [string, "null"] }
      unit_id:    { type: [string, "null"] }
      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_symbol: { type: [string, "null"] }
      unit_id:    { type: [string, "null"] }
      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" }

  MatrixTableList:
    description: Multi-axis tables preserved from the source PDF (e.g. q-value matrices).
    type: array
    items:
      type: object
      required: [name, columns, rows]
      properties:
        name:        { type: string }
        description: { type: [string, "null"] }
        columns:
          type: array
          items: { type: string }
        rows:
          type: array
          items:
            type: object
            additionalProperties: true
        footnotes:
          type: array
          items: { type: string }

  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 }
