Adding OpenConfig YANG models.

Change-Id: I0a2fdd5826e80933cf4b9ae939ff3051acec02aa
diff --git a/models/openconfig/src/main/yang/platform/openconfig-platform-linecard.yang b/models/openconfig/src/main/yang/platform/openconfig-platform-linecard.yang
new file mode 100644
index 0000000..939341d
--- /dev/null
+++ b/models/openconfig/src/main/yang/platform/openconfig-platform-linecard.yang
@@ -0,0 +1,117 @@
+module openconfig-platform-linecard {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/linecard";
+
+  prefix "oc-linecard";
+
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-platform-types { prefix oc-platform-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines data related to LINECARD components in the openconfig-platform model";
+
+  oc-ext:openconfig-version "0.1.0";
+
+  revision "2017-08-03" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping linecard-config {
+    description
+      "Configuration data for linecard components";
+
+    leaf power {
+      type oc-platform-types:component-power-type;
+      default POWER_ENABLED;
+      description
+        "Enable or disable power to the linecard";
+    }
+  }
+
+  grouping linecard-state {
+    description
+      "Operational state data for linecard components";
+
+    leaf slot-id {
+      type string;
+      description
+        "Identifier for the slot or chassis position in which the
+        linecard is installed";
+    }
+  }
+
+  grouping linecard-top {
+    description
+      "Top-level grouping for linecard data";
+
+    container linecard {
+      description
+        "Top-level container for linecard data";
+
+      container config {
+        description
+          "Configuration data for linecards";
+
+        uses linecard-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for linecards";
+
+        uses linecard-config;
+        uses linecard-state;
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component" {
+    description
+      "Adding linecard data to physical inventory";
+
+    uses linecard-top {
+      when "current()/oc-platform:state/" +
+        "oc-platform:type = 'LINECARD'" {
+        description
+          "Augment is active when component is of type LINECARD";
+      }
+    }
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
+
diff --git a/models/openconfig/src/main/yang/platform/openconfig-platform-port.yang b/models/openconfig/src/main/yang/platform/openconfig-platform-port.yang
new file mode 100644
index 0000000..8964637
--- /dev/null
+++ b/models/openconfig/src/main/yang/platform/openconfig-platform-port.yang
@@ -0,0 +1,119 @@
+module openconfig-platform-port {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/port";
+
+  prefix "oc-port";
+
+  // import some basic types
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-if-ethernet { prefix oc-eth; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines data related to PORT components in the openconfig-platform model";
+
+  oc-ext:openconfig-version "0.1.0";
+
+  revision "2016-10-24" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping port-breakout-config {
+    description
+      "Configuration data for the port breakout mode";
+
+    leaf num-channels {
+      type uint8;
+      description
+        "Sets the number of channels to 'breakout' on a port
+        capable of channelization";
+    }
+
+    leaf channel-speed {
+      type identityref {
+        base oc-eth:ETHERNET_SPEED;
+      }
+      description
+        "Sets the channel speed on each channel -- the
+        supported values are defined by the
+        ETHERNET_SPEED identity";
+    }
+  }
+
+  grouping port-breakout-state {
+    description
+      "Operational state data for the port breakout mode ";
+  }
+
+  grouping port-breakout-top {
+    description
+      "Top-level grouping for port breakout data";
+
+    container breakout-mode {
+      description
+        "Top-level container for port breakout data";
+
+      container config {
+        description
+          "Configuration data for port breakout";
+
+        uses port-breakout-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for port breakout";
+
+        uses port-breakout-config;
+        uses port-breakout-state;
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component" {
+    description
+      "Adding port breakout data to physical platform data";
+
+    uses port-breakout-top {
+      when "./state/type = 'PORT'" {
+        description
+          "This data is valid only for PORT components";
+      }
+    }
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
\ No newline at end of file
diff --git a/models/openconfig/src/main/yang/platform/openconfig-platform-transceiver.yang b/models/openconfig/src/main/yang/platform/openconfig-platform-transceiver.yang
new file mode 100644
index 0000000..849b534
--- /dev/null
+++ b/models/openconfig/src/main/yang/platform/openconfig-platform-transceiver.yang
@@ -0,0 +1,484 @@
+module openconfig-platform-transceiver {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/transceiver";
+
+  prefix "oc-transceiver";
+
+  // import some basic types
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-transport-types { prefix oc-opt-types; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+  import ietf-yang-types { prefix yang; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    for transceivers (i.e., pluggable optics).  The module should be
+    used in conjunction with the platform model where other
+    physical entity data are represented.
+
+    In the platform model, a component of type=TRANSCEIVER is
+    expected to be a subcomponent of a PORT component.  This
+    module defines a concrete schema for the associated data for
+    components with type=TRANSCEIVER.";
+
+  oc-ext:openconfig-version "0.3.0";
+
+  revision "2017-07-08" {
+    description
+      "Adds clarification on aggregate power measurement data";
+    reference "0.3.0";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Adds preconfiguration data and clarified units";
+    reference "0.2.0";
+  }
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping optical-power-state {
+    description
+      "Reusable leaves related to optical power state -- these
+      are read-only state values. If avg/min/max statistics are
+      not supported, the target is expected to just supply the
+      instant value";
+
+    container output-power {
+      description
+        "The output optical power of a physical channel in units
+        of 0.01dBm, which may be associated with individual
+        physical channels, or an aggregate of multiple physical
+        channels (i.e., for the overall transceiver). For an
+        aggregate, this may be a measurement from a photodetector
+        or a a calculation performed on the device by summing up
+        all of the related individual physical channels.
+        Values include the instantaneous, average, minimum, and
+        maximum statistics. If avg/min/max statistics are not
+        supported, the target is expected to just supply the
+        instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container input-power {
+      description
+        "The input optical power of a physical channel in units
+        of 0.01dBm, which may be associated with individual
+        physical channels, or an aggregate of multiple physical
+        channels (i.e., for the overall transceiver). For an
+        aggregate, this may be a measurement from a photodetector
+        or a a calculation performed on the device by summing up
+        all of the related individual physical channels.
+        Values include the instantaneous, average, minimum, and
+        maximum statistics. If avg/min/max statistics are not
+        supported, the target is expected to just supply the
+        instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container laser-bias-current {
+      description
+        "The current applied by the system to the transmit laser to
+        achieve the output power. The current is expressed in mA
+        with up to two decimal precision. Values include the
+        instantaneous, average, minimum, and maximum statistics.
+        If avg/min/max statistics are not supported, the target is
+        expected to just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-mA;
+    }
+  }
+
+  grouping output-optical-frequency {
+    description
+      "Reusable leaves related to optical output power -- this is
+      typically configurable on line side and read-only on the
+      client-side";
+
+    leaf output-frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "The frequency in MHz of the individual physical channel
+        (e.g. ITU C50 - 195.0THz and would be reported as
+        195,000,000 MHz in this model). This attribute is not
+        configurable on most client ports.";
+    }
+  }
+
+
+  grouping physical-channel-config {
+    description
+      "Configuration data for physical client channels";
+
+    leaf index {
+      type uint16 {
+        range 0..max;
+      }
+      description
+        "Index of the physical channnel or lane within a physical
+        client port";
+    }
+
+    leaf description {
+      type string;
+      description
+        "Text description for the client physical channel";
+    }
+
+    leaf tx-laser {
+      type boolean;
+      description
+        "Enable (true) or disable (false) the transmit label for the
+        channel";
+    }
+
+    leaf target-output-power {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "Target output optical power level of the optical channel,
+        expressed in increments of 0.01 dBm (decibel-milliwats)";
+    }
+  }
+
+  grouping physical-channel-state {
+    description
+      "Operational state data for client channels.";
+
+    uses output-optical-frequency;
+    uses optical-power-state;
+  }
+
+  grouping physical-channel-top {
+    description
+      "Top-level grouping for physical client channels";
+
+    container physical-channels {
+      description
+        "Enclosing container for client channels";
+
+      list channel {
+        key "index";
+        description
+          "List of client channels, keyed by index within a physical
+          client port.  A physical port with a single channel would
+          have a single zero-indexed element";
+
+        leaf index {
+          type leafref {
+            path "../config/index";
+          }
+          description
+            "Reference to the index number of the channel";
+        }
+
+        container config {
+          description
+            "Configuration data for physical channels";
+
+          uses physical-channel-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for channels";
+
+          uses physical-channel-config;
+          uses physical-channel-state;
+        }
+      }
+    }
+  }
+
+
+  grouping port-transceiver-config {
+    description
+      "Configuration data for client port transceivers";
+
+    leaf enabled {
+      type boolean;
+      description
+        "Turns power on / off to the transceiver -- provides a means
+        to power on/off the transceiver (in the case of SFP, SFP+,
+        QSFP,...) or enable high-power mode (in the case of CFP,
+        CFP2, CFP4) and is optionally supported (device can choose to
+        always enable).  True = power on / high power, False =
+        powered off";
+    }
+
+    leaf form-factor-preconf {
+      type identityref {
+        base oc-opt-types:TRANSCEIVER_FORM_FACTOR_TYPE;
+      }
+      description
+        "Indicates the type of optical transceiver used on this
+        port.  If the client port is built into the device and not
+        pluggable, then non-pluggable is the corresponding state. If
+        a device port supports multiple form factors (e.g. QSFP28
+        and QSFP+, then the value of the transceiver installed shall
+        be reported. If no transceiver is present, then the value of
+        the highest rate form factor shall be reported
+        (QSFP28, for example).
+
+        The form factor is included in configuration data to allow
+        pre-configuring a device with the expected type of
+        transceiver ahead of deployment.  The corresponding state
+        leaf should reflect the actual transceiver type plugged into
+        the system.";
+    }
+
+    leaf ethernet-pmd-preconf {
+      type identityref {
+        base oc-opt-types:ETHERNET_PMD_TYPE;
+      }
+      description
+        "The Ethernet PMD is a property of the optical transceiver
+        used on the port, indicating the type of physical connection.
+        It is included in configuration data to allow pre-configuring
+        a port/transceiver with the expected PMD.  The actual PMD is
+        indicated by the ethernet-pmd state leaf.";
+    }
+  }
+
+  grouping port-transceiver-state {
+    description
+      "Operational state data for client port transceivers";
+
+    leaf present {
+      type enumeration {
+        enum PRESENT {
+          description
+            "Transceiver is present on the port";
+        }
+        enum NOT_PRESENT {
+          description
+            "Transceiver is not present on the port";
+        }
+      }
+      description
+        "Indicates whether a transceiver is present in
+        the specified client port.";
+    }
+
+    leaf form-factor {
+      type identityref {
+        base oc-opt-types:TRANSCEIVER_FORM_FACTOR_TYPE;
+      }
+      description
+        "Indicates the type of optical transceiver used on this
+        port.  If the client port is built into the device and not
+        pluggable, then non-pluggable is the corresponding state. If
+        a device port supports multiple form factors (e.g. QSFP28
+        and QSFP+, then the value of the transceiver installed shall
+        be reported. If no transceiver is present, then the value of
+        the highest rate form factor shall be reported
+        (QSFP28, for example).";
+    }
+
+    leaf connector-type {
+      type identityref {
+        base oc-opt-types:FIBER_CONNECTOR_TYPE;
+      }
+      description
+        "Connector type used on this port";
+    }
+
+    leaf internal-temp {
+    // TODO: this should probably be removed if we add temperature
+    // as a top-level component property, i.e., transceiver temp
+    // should be reported there.
+      type int16 {
+        range -40..125;
+      }
+      description
+        "Internally measured temperature in degrees Celsius. MSA
+        valid range is between -40 and +125C. Accuracy shall be
+        better than +/- 3 degC over the whole temperature range.";
+    }
+
+    leaf vendor {
+      type string {
+        length 1..16;
+      }
+      description
+        "Full name of transceiver vendor. 16-octet field that
+        contains ASCII characters, left-aligned and padded on the
+        right with ASCII spaces (20h)";
+    }
+
+    leaf vendor-part {
+      type string {
+        length 1..16;
+      }
+      description
+        "Transceiver vendor's part number. 16-octet field that
+        contains ASCII characters, left-aligned and padded on the
+        right with ASCII spaces (20h). If part number is undefined,
+        all 16 octets = 0h";
+    }
+
+    leaf vendor-rev {
+      type string {
+        length 1..2;
+      }
+      description
+        "Transceiver vendor's revision number. 2-octet field that
+        contains ASCII characters, left-aligned and padded on the
+        right with ASCII spaces (20h)";
+    }
+
+    //TODO: these compliance code leaves should be active based on
+    //the type of port
+    leaf ethernet-pmd {
+      type identityref {
+        base oc-opt-types:ETHERNET_PMD_TYPE;
+      }
+      description
+        "Ethernet PMD (physical medium dependent sublayer) that the
+        transceiver supports. The SFF/QSFP MSAs have registers for
+        this and CFP MSA has similar.";
+    }
+
+    leaf sonet-sdh-compliance-code {
+      type identityref {
+        base oc-opt-types:SONET_APPLICATION_CODE;
+      }
+      description
+        "SONET/SDH application code supported by the port";
+    }
+
+    leaf otn-compliance-code {
+      type identityref {
+        base oc-opt-types:OTN_APPLICATION_CODE;
+      }
+      description
+        "OTN application code supported by the port";
+    }
+
+    leaf serial-no {
+      type string {
+        length 1..16;
+      }
+      description
+        "Transceiver serial number. 16-octet field that contains
+        ASCII characters, left-aligned and padded on the right with
+        ASCII spaces (20h). If part serial number is undefined, all
+        16 octets = 0h";
+    }
+
+    leaf date-code {
+      type yang:date-and-time;
+      description
+        "Representation of the transceiver date code, typically
+        stored as YYMMDD.  The time portion of the value is
+        undefined and not intended to be read.";
+    }
+
+    leaf fault-condition {
+      type boolean;
+      description
+        "Indicates if a fault condition exists in the transceiver";
+    }
+
+    uses optical-power-state;
+
+  }
+
+  grouping port-transceiver-top {
+    description
+      "Top-level grouping for client port transceiver data";
+
+    container transceiver {
+      description
+        "Top-level container for client port transceiver data";
+
+      container config {
+        description
+          "Configuration data for client port transceivers";
+
+        uses port-transceiver-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for client port transceivers";
+
+        uses port-transceiver-config;
+        uses port-transceiver-state;
+      }
+      // physical channels are associated with a transceiver
+      // component
+      uses physical-channel-top;
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component" {
+    description
+      "Adding transceiver data to physical inventory";
+
+    uses port-transceiver-top {
+      when "current()/oc-platform:state/" +
+        "oc-platform:type = 'TRANSCEIVER'" {
+        description
+          "Augment is active when component is of type TRANSCEIVER";
+      }
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:state" {
+    //TODO: add 'when' or other condition to make sure this
+    //leafref points to a component of type TRANSCEIVER.
+    description
+      "Adds a reference from the base interface to its corresponding
+      physical channels.";
+
+    leaf-list physical-channel {
+      type leafref {
+        path "/oc-platform:components/" +
+          "oc-platform:component[oc-platform:name=current()/../oc-platform:hardware-port]/" +
+          "oc-transceiver:transceiver/" +
+          "oc-transceiver:physical-channels/oc-transceiver:channel/" +
+          "oc-transceiver:index";
+      }
+      description
+        "For a channelized interface, list of references to the
+        physical channels (lanes) corresponding to the interface.";
+    }
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/models/openconfig/src/main/yang/platform/openconfig-platform-types.yang b/models/openconfig/src/main/yang/platform/openconfig-platform-types.yang
new file mode 100644
index 0000000..b73a039
--- /dev/null
+++ b/models/openconfig/src/main/yang/platform/openconfig-platform-types.yang
@@ -0,0 +1,192 @@
+module openconfig-platform-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform-types";
+
+  prefix "oc-platform-types";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines data types (e.g., YANG identities)
+    to support the OpenConfig component inventory model.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2017-08-16" {
+    description
+      "Added power state enumerated type";
+    reference "0.6.0";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Added temperature state variable to component";
+    reference "0.5.0";
+  }
+
+  // grouping statements
+
+  grouping avg-min-max-instant-stats-precision1-celsius {
+    description
+      "Common grouping for recording temperature values in
+      Celsius with 1 decimal precision. Values include the
+      instantaneous, average, minimum, and maximum statistics";
+
+    leaf instant {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      units celsius;
+      description
+        "The instantaneous value of the statistic.";
+    }
+
+    leaf avg {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      units celsius;
+      description
+        "The arithmetic mean value of the statistic over the
+        sampling period.";
+    }
+
+    leaf min {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      units celsius;
+      description
+        "The minimum value of the statistic over the sampling
+        period";
+    }
+
+    leaf max {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      units celsius;
+      description
+        "The maximum value of the statistic over the sampling
+        period";
+    }
+  }
+
+  // identity statements
+
+  identity OPENCONFIG_HARDWARE_COMPONENT {
+    description
+      "Base identity for hardware related components in a managed
+      device.  Derived identities are partially based on contents
+      of the IANA Entity MIB.";
+    reference
+      "IANA Entity MIB and RFC 6933";
+  }
+
+
+  identity OPENCONFIG_SOFTWARE_COMPONENT {
+    description
+      "Base identity for software-related components in a managed
+      device";
+  }
+
+  // hardware types
+
+  identity CHASSIS {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Chassis component, typically with multiple slots / shelves";
+  }
+
+  identity BACKPLANE {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Backplane component for aggregating traffic, typically
+      contained in a chassis component";
+  }
+
+  identity POWER_SUPPLY {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Component that is supplying power to the device";
+  }
+
+  identity FAN {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Cooling fan, or could be some other heat-reduction component";
+  }
+
+  identity SENSOR {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Physical sensor, e.g., a temperature sensor in a chassis";
+  }
+
+  identity MODULE {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Replaceable hardware module, e.g., a daughtercard";
+  }
+
+  identity LINECARD {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Linecard component, typically inserted into a chassis slot";
+  }
+
+  identity PORT {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Physical port, e.g., for attaching pluggables and networking
+      cables";
+  }
+
+  identity TRANSCEIVER {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Pluggable module present in a port";
+  }
+
+  identity CPU {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Processing unit, e.g., a management processor";
+  }
+
+  identity OPERATING_SYSTEM {
+    base OPENCONFIG_SOFTWARE_COMPONENT;
+    description
+      "Operating system running on a component";
+  }
+
+  // typedef statements
+
+  typedef component-power-type {
+    type enumeration {
+      enum POWER_ENABLED {
+        description
+          "Enable power on the component";
+      }
+      enum POWER_DISABLED {
+        description
+          "Disable power on the component";
+      }
+    }
+    description
+      "A generic type reflecting whether a hardware component
+      is powered on or off";
+  }
+
+}
diff --git a/models/openconfig/src/main/yang/platform/openconfig-platform.yang b/models/openconfig/src/main/yang/platform/openconfig-platform.yang
new file mode 100644
index 0000000..377a640
--- /dev/null
+++ b/models/openconfig/src/main/yang/platform/openconfig-platform.yang
@@ -0,0 +1,376 @@
+module openconfig-platform {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform";
+
+  prefix "oc-platform";
+
+  import openconfig-platform-types { prefix oc-platform-types; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines a data model for representing a system
+    component inventory, which can include hardware or software
+    elements arranged in an arbitrary structure. The primary
+    relationship supported by the model is containment, e.g.,
+    components containing subcomponents.
+
+    It is expected that this model reflects every field replacable
+    unit on the device at a minimum (i.e., additional information
+    may be supplied about non-replacable components).
+
+    Every element in the inventory is termed a 'component' with each
+    component expected to have a unique name and type, and optionally
+    a unique system-assigned identifier and FRU number.  The
+    uniqueness is guaranteed by the system within the device.
+
+    Components may have properties defined by the system that are
+    modeled as a list of key-value pairs. These may or may not be
+    user-configurable.  The model provides a flag for the system
+    to optionally indicate which properties are user configurable.
+
+    Each component also has a list of 'subcomponents' which are
+    references to other components. Appearance in a list of
+    subcomponents indicates a containment relationship as described
+    above.  For example, a linecard component may have a list of
+    references to port components that reside on the linecard.
+
+    This schema is generic to allow devices to express their own
+    platform-specific structure.  It may be augmented by additional
+    component type-specific schemas that provide a common structure
+    for well-known component types.  In these cases, the system is
+    expected to populate the common component schema, and may
+    optionally also represent the component and its properties in the
+    generic structure.
+
+    The properties for each component may include dynamic values,
+    e.g., in the 'state' part of the schema.  For example, a CPU
+    component may report its utilization, temperature, or other
+    physical properties.  The intent is to capture all platform-
+    specific physical data in one location, including inventory
+    (presence or absence of a component) and state (physical
+    attributes or status).";
+
+  oc-ext:openconfig-version "0.5.0";
+
+  revision "2016-12-22" {
+    description
+      "Added temperature state variable to component";
+    reference "0.5.0";
+  }
+
+  // grouping statements
+
+
+  grouping platform-component-properties-config {
+    description
+      "System-defined configuration data for component properties";
+
+    leaf name {
+      type string;
+      description
+        "System-supplied name of the property -- this is typically
+        non-configurable";
+    }
+
+    leaf value {
+      type union {
+        type string;
+        type boolean;
+        type int64;
+        type uint64;
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      description
+        "Property values can take on a variety of types.  Signed and
+        unsigned integer types may be provided in smaller sizes,
+        e.g., int8, uint16, etc.";
+    }
+  }
+
+  grouping platform-component-properties-state {
+    description
+      "Operational state data for component properties";
+
+    leaf configurable {
+      type boolean;
+      description
+        "Indication whether the property is user-configurable";
+    }
+  }
+
+  grouping platform-component-properties-top {
+    description
+      "Top-level grouping ";
+
+    container properties {
+      description
+        "Enclosing container ";
+
+      list property {
+        key "name";
+        description
+          "List of system properties for the component";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the property name.";
+        }
+
+        container config {
+          description
+            "Configuration data for each property";
+
+          uses platform-component-properties-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for each property";
+
+          uses platform-component-properties-config;
+          uses platform-component-properties-state;
+        }
+      }
+    }
+  }
+
+  grouping platform-subcomponent-ref-config {
+    description
+      "Configuration data for subcomponent references";
+
+    leaf name {
+      type leafref {
+        path "../../../../../component/config/name";
+      }
+      description
+        "Reference to the name of the subcomponent";
+    }
+  }
+
+  grouping platform-subcomponent-ref-state {
+    description
+      "Operational state data for subcomponent references";
+
+  }
+
+  grouping platform-subcomponent-ref-top {
+    description
+      "Top-level grouping for list of subcomponent references";
+
+    container subcomponents {
+      description
+        "Enclosing container for subcomponent references";
+
+      list subcomponent {
+        key "name";
+        description
+          "List of subcomponent references";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the name list key";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses platform-subcomponent-ref-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data ";
+
+          uses platform-subcomponent-ref-config;
+          uses platform-subcomponent-ref-state;
+        }
+      }
+    }
+  }
+
+  grouping platform-component-config {
+    description
+      "Configuration data for components";
+
+    leaf name {
+      type string;
+      description
+        "Device name for the component -- this will not be a
+        configurable parameter on many implementations";
+    }
+  }
+
+  grouping platform-component-state {
+    description
+      "Operational state data for device components.";
+
+    leaf type {
+      type union {
+        type identityref {
+          base oc-platform-types:OPENCONFIG_HARDWARE_COMPONENT;
+        }
+        type identityref {
+          base oc-platform-types:OPENCONFIG_SOFTWARE_COMPONENT;
+        }
+      }
+      description
+        "Type of component as identified by the system";
+    }
+
+    leaf id {
+      type string;
+      description
+        "Unique identifier assigned by the system for the
+        component";
+    }
+
+    leaf description {
+      type string;
+      description
+        "System-supplied description of the component";
+    }
+
+    leaf mfg-name {
+      type string;
+      description
+        "System-supplied identifier for the manufacturer of the
+        component.  This data is particularly useful when a
+        component manufacturer is different than the overall
+        device vendor.";
+    }
+
+    leaf version {
+      type string;
+      description
+        "System-defined version string for a hardware, firmware,
+        or software component.";
+    }
+
+    leaf serial-no {
+      type string;
+      description
+        "System-assigned serial number of the component.";
+    }
+
+    leaf part-no {
+      type string;
+      description
+        "System-assigned part number for the component.  This should
+        be present in particular if the component is also an FRU
+        (field replacable unit)";
+    }
+  }
+
+  grouping platform-component-temp-state {
+    description
+      "Temperature state data for device components";
+
+    container temperature {
+      description
+        "Temperature in degrees Celsius of the component. Values include
+        the instantaneous, average, minimum, and maximum statistics. If
+        avg/min/max statistics are not supported, the target is expected
+        to just supply the instant value";
+
+      uses oc-platform-types:avg-min-max-instant-stats-precision1-celsius;
+    }
+  }
+
+  grouping platform-component-top {
+    description
+      "Top-level grouping for components in the device inventory";
+
+    container components {
+      description
+        "Enclosing container for the components in the system.";
+
+      list component {
+        key "name";
+        description
+          "List of components, keyed by component name.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "References the component name";
+        }
+
+        container config {
+          description
+            "Configuration data for each component";
+
+          uses platform-component-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for each component";
+
+          uses platform-component-config;
+          uses platform-component-state;
+          uses platform-component-temp-state;
+        }
+
+        uses platform-component-properties-top;
+        uses platform-subcomponent-ref-top;
+      }
+    }
+  }
+
+  // data definition statements
+
+  uses platform-component-top;
+
+
+  // augments
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:state" {
+    //TODO: add 'when' or other condition to make sure this
+    //leafref points to a component of type PORT.
+    description
+      "Adds a reference from the base interface to the corresponding
+      port component in the device inventory.";
+
+    leaf hardware-port {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "References the hardware port in the device inventory";
+    }
+  }
+
+}