diff --git a/python/extensions/omci/onu_configuration.py b/python/extensions/omci/onu_configuration.py
new file mode 100644
index 0000000..2bd82ce
--- /dev/null
+++ b/python/extensions/omci/onu_configuration.py
@@ -0,0 +1,509 @@
+#
+# Copyright 2018 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import structlog
+
+from voltha.protos.device_pb2 import Image
+from omci_entities import *
+from database.mib_db_api import *
+from enum import IntEnum
+
+
+class OMCCVersion(IntEnum):
+    Unknown                 = 0     # Unknown or unsupported version
+    G_984_4                 = 0x80  # (06/04)
+    G_984_4_2005_Amd_1      = 0x81  # Amd.1 (06/05)
+    G_984_4_2006_Amd_2      = 0x82  # Amd.2 (03/06)
+    G_984_4_2006_Amd_3      = 0x83  # Amd.3 (12/06)
+    G_984_4_2008            = 0x84  # (02/08)
+    G_984_4_2009_Amd_1      = 0x85  # Amd.1 (06/09)
+    G_984_4_2009_Amd_2_Base = 0x86  # Amd.2 (2009)  Baseline message set only, w/o the extended message set option
+    G_984_4_2009_Amd_2      = 0x96  # Amd.2 (2009)  Extended message set option +  baseline message set.
+    G_988_2010_Base         = 0xA0  # (2010) Baseline message set only, w/o the extended message set option
+    G_988_2011_Amd_1_Base   = 0xA1  # Amd.1 (2011) Baseline message set only
+    G_988_2012_Amd_2_Base   = 0xA2  # Amd.2 (2012) Baseline message set only
+    G_988_2012_Base         = 0xA3  # (2012) Baseline message set only
+    G_988_2010              = 0xB0  # (2010) Baseline and extended message set
+    G_988_2011_Amd_1        = 0xB1  # Amd.1 (2011) Baseline and extended message set
+    G_988_2012_Amd_2        = 0xB2  # Amd.2 (2012) Baseline and extended message set
+    G_988_2012              = 0xB3  # (2012)Baseline and extended message set
+
+    @staticmethod
+    def values():
+        return {OMCCVersion[member].value for member in OMCCVersion.__members__.keys()}
+
+    @staticmethod
+    def to_enum(value):
+        return next((v for k, v in OMCCVersion.__members__.items()
+                     if v.value == value), OMCCVersion.Unknown)
+
+
+class OnuConfiguration(object):
+    """
+    Utility class to query OMCI MIB Database for various ONU/OMCI Configuration
+    and capabilties. These capabilities revolve around read-only MEs discovered
+    during the MIB Upload process.
+
+    There is also a 'omci_onu_capabilities' State Machine and an
+    'onu_capabilities_task.py' OMCI Task that will query the ONU, via the
+    OMCI (ME#287) Managed entity to get the full list of supported OMCI ME's
+    and available actions/message-types supported.
+
+    NOTE: Currently this class is optimized/tested for ONUs that support the
+          OpenOMCI implementation.
+    """
+    def __init__(self, omci_agent, device_id):
+        """
+        Initialize this instance of the OnuConfiguration class
+
+        :param omci_agent: (OpenOMCIAgent) agent reference
+        :param device_id: (str) ONU Device ID
+
+        :raises KeyError: If ONU Device is not registered with OpenOMCI
+        """
+        self.log = structlog.get_logger(device_id=device_id)
+        self._device_id = device_id
+        self._onu_device = omci_agent.get_device(device_id)
+
+        # The capabilities
+        self._attributes = None
+        self.reset()
+
+    def _get_capability(self, attr, class_id, instance_id=None):
+        """
+        Get the OMCI capabilities for this device
+
+        :param attr: (str) OnuConfiguration attribute field
+        :param class_id: (int) ME Class ID
+        :param instance_id: (int) Instance ID. If not provided, all instances of the
+                            specified class ID are returned if present in the DB.
+
+        :return: (dict) Class and/or Instances. None is returned if the CLASS is not present
+        """
+        try:
+            assert self._onu_device.mib_synchronizer.last_mib_db_sync is not None, \
+                'MIB Database for ONU {} has never been synchronized'.format(self._device_id)
+
+            # Get the requested information
+            if self._attributes[attr] is None:
+                value = self._onu_device.query_mib(class_id, instance_id=instance_id)
+
+                if isinstance(value, dict) and len(value) > 0:
+                    self._attributes[attr] = value
+
+            return self._attributes[attr]
+
+        except Exception as e:
+            self.log.exception('onu-capabilities', e=e, class_id=class_id,
+                               instance_id=instance_id)
+            raise
+
+    def reset(self):
+        """
+        Reset the cached database entries to None.  This method should be
+        called after any communications loss to the ONU (reboot, PON down, ...)
+        in case a new software load with different capabilities is available.
+        """
+        self._attributes = {
+            '_ont_g': None,
+            '_ont_2g': None,
+            '_ani_g': None,
+            '_uni_g': None,
+            '_cardholder': None,
+            '_circuit_pack': None,
+            '_software': None,
+            '_pptp': None,
+            '_veip': None
+        }
+
+    @property
+    def version(self):
+        """
+        This attribute identifies the version of the ONU as defined by the vendor
+        """
+        ontg = self._get_capability('_ont_g', OntG.class_id, 0)
+        if ontg is None or ATTRIBUTES_KEY not in ontg:
+            return None
+
+        return ontg[ATTRIBUTES_KEY].get('version')
+
+    @property
+    def serial_number(self):
+        """
+        The serial number is unique for each ONU
+        """
+        ontg = self._get_capability('_ont_g', OntG.class_id, 0)
+        if ontg is None or ATTRIBUTES_KEY not in ontg:
+            return None
+
+        return ontg[ATTRIBUTES_KEY].get('serial_number')
+
+    @property
+    def traffic_management_option(self):
+        """
+        This attribute identifies the upstream traffic management function
+        implemented in the ONU. There are three options:
+
+            0 Priority controlled and flexibly scheduled upstream traffic. The traffic
+              scheduler and priority queue mechanism are used for upstream traffic.
+
+            1 Rate controlled upstream traffic. The maximum upstream traffic of each
+              individual connection is guaranteed by shaping.
+
+            2 Priority and rate controlled. The traffic scheduler and priority queue
+              mechanism are used for upstream traffic. The maximum upstream traffic
+              of each individual connection is guaranteed by shaping.
+        """
+        ontg = self._get_capability('_ont_g', OntG.class_id, 0)
+        if ontg is None or ATTRIBUTES_KEY not in ontg:
+            return None
+
+        return ontg[ATTRIBUTES_KEY].get('traffic_management_options')
+
+    @property
+    def onu_survival_time(self):
+        """
+        This attribute indicates the minimum guaranteed time in milliseconds
+        between the loss of external power and the silence of the ONU. This does not
+        include survival time attributable to a backup battery. The value zero implies that
+        the actual time is not known.
+
+        Optional
+        """
+        ontg = self._get_capability('_ont_g', OntG.class_id, 0)
+        if ontg is None or ATTRIBUTES_KEY not in ontg:
+            return None
+
+        return ontg[ATTRIBUTES_KEY].get('ont_survival_time', 0)
+
+    @property
+    def equipment_id(self):
+        """
+        This attribute may be used to identify the specific type of ONU. In some
+        environments, this attribute may include the equipment CLEI code.
+        """
+        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
+        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
+            return None
+
+        return ont2g[ATTRIBUTES_KEY].get('equipment_id')
+
+    @property
+    def omcc_version(self):
+        """
+        This attribute identifies the version of the OMCC protocol being used by the
+        ONU. This allows the OLT to manage a network with ONUs that support different
+        OMCC versions. Release levels of [ITU-T G.984.4] are supported with code
+        points of the form 0x8y and 0x9y, where y is a hexadecimal digit in the range
+        0..F.  Support for continuing revisions of this Recommendation is defined in
+        the 0xAy range.
+        """
+        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
+        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
+            return None
+
+        return OMCCVersion.to_enum(ont2g[ATTRIBUTES_KEY].get('omcc_version', 0))
+
+    @property
+    def vendor_product_code(self):
+        """
+        This attribute contains a vendor-specific product code for the ONU
+        """
+        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
+        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
+            return None
+
+        return ont2g[ATTRIBUTES_KEY].get('vendor_product_code')
+
+    @property
+    def total_priority_queues(self):
+        """
+        This attribute reports the total number of upstream priority queues
+        that are not associated with a circuit pack, but with the ONU in its entirety
+        """
+        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
+        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
+            return None
+
+        return ont2g[ATTRIBUTES_KEY].get('total_priority_queue_number')
+
+    @property
+    def total_traffic_schedulers(self):
+        """
+        This attribute reports the total number of traffic schedulers that
+        are not associated with a circuit pack, but with the ONU in its entirety.
+        """
+        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
+        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
+            return None
+
+        return ont2g[ATTRIBUTES_KEY].get('total_traffic_scheduler_number')
+
+    @property
+    def total_gem_ports(self):
+        """
+        This attribute reports the total number of GEM port-IDs supported
+        by the ONU.
+        """
+        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
+        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
+            return None
+
+        return ont2g[ATTRIBUTES_KEY].get('total_gem_port_id_number')
+
+    @property
+    def uptime(self):
+        """
+        This attribute counts 10 ms intervals since the ONU was last initialized.
+        It rolls over to 0 when full
+        """
+        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
+        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
+            return None
+
+        return ont2g[ATTRIBUTES_KEY].get('sys_uptime')
+
+    @property
+    def connectivity_capability(self):
+        """
+        This attribute indicates the Ethernet connectivity models that the ONU
+        can support. The value 0 indicates that the capability is not supported; 1 signifies
+        support.
+
+             Bit    Model [Figure reference ITU-T 988]
+              1     (LSB) N:1 bridging, Figure 8.2.2-3
+              2     1:M mapping, Figure 8.2.2-4
+              3     1:P filtering, Figure 8.2.2-5
+              4     N:M bridge-mapping, Figure 8.2.2-6
+              5     1:MP map-filtering, Figure 8.2.2-7
+              6     N:P bridge-filtering, Figure 8.2.2-8
+              7  to refer to    N:MP bridge-map-filtering, Figure 8.2.2-9
+            8...16  Reserved
+        """
+        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
+        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
+            return None
+
+        return ont2g[ATTRIBUTES_KEY].get('connectivity_capability')
+
+    @property
+    def qos_configuration_flexibility(self):
+        """
+        This attribute reports whether various managed entities in the
+        ONU are fixed by the ONU's architecture or whether they are configurable. For
+        backward compatibility, and if the ONU does not support this attribute, all such
+        attributes are understood to be hard-wired.
+
+            Bit      Interpretation when bit value = 1
+             1 (LSB) Priority queue ME: Port field of related port attribute is
+                     read-write and can point to any T-CONT or UNI port in the
+                     same slot
+             2       Priority queue ME: The traffic scheduler pointer is permitted
+                     to refer to any other traffic scheduler in the same slot
+             3       Traffic scheduler ME: T-CONT pointer is read-write
+             4       Traffic scheduler ME: Policy attribute is read-write
+             5       T-CONT ME: Policy attribute is read-write
+             6       Priority queue ME: Priority field of related port attribute is
+                     read-write
+             7..16   Reserved
+        """
+        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
+        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
+            return None
+
+        return ont2g[ATTRIBUTES_KEY].get('qos_configuration_flexibility')
+
+    @property
+    def priority_queue_scale_factor(self):
+        """
+        This specifies the scale factor of several attributes of the priority
+        queue managed entity of section 5.2.8
+        """
+        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
+        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
+            return None
+
+        return ont2g[ATTRIBUTES_KEY].get('priority_queue_scale_factor', 1)
+
+    @property
+    def cardholder_entities(self):
+        """
+        Return a dictionary containing some overall information on the CardHolder
+        instances for this ONU.
+        """
+        ch = self._get_capability('_cardholder', Cardholder.class_id)
+        results = dict()
+
+        if ch is not None:
+            for inst, inst_data in ch.items():
+                if isinstance(inst, int):
+                    results[inst] = {
+                        'entity-id':              inst,
+                        'is-single-piece':        inst >= 256,
+                        'slot-number':            inst & 0xff,
+                        'actual-plug-in-type':    inst_data[ATTRIBUTES_KEY].get('actual_plugin_unit_type', 0),
+                        'actual-equipment-id':    inst_data[ATTRIBUTES_KEY].get('actual_equipment_id', 0),
+                        'protection-profile-ptr': inst_data[ATTRIBUTES_KEY].get('protection_profile_pointer', 0),
+                    }
+        return results if len(results) else None
+
+    @property
+    def circuitpack_entities(self):
+        """
+        This specifies the scale factor of several attributes of the priority
+        queue managed entity of section 5.2.8
+        """
+        cp = self._get_capability('_circuit_pack', CircuitPack.class_id)
+        results = dict()
+
+        if cp is not None:
+            for inst, inst_data in cp.items():
+                if isinstance(inst, int):
+                    results[inst] = {
+                        'entity-id': inst,
+                        'number-of-ports': inst_data[ATTRIBUTES_KEY].get('number_of_ports', 0),
+                        'serial-number': inst_data[ATTRIBUTES_KEY].get('serial_number', 0),
+                        'version': inst_data[ATTRIBUTES_KEY].get('version', 0),
+                        'vendor-id': inst_data[ATTRIBUTES_KEY].get('vendor_id', 0),
+                        'total-tcont-count': inst_data[ATTRIBUTES_KEY].get('total_tcont_buffer_number', 0),
+                        'total-priority-queue-count': inst_data[ATTRIBUTES_KEY].get('total_priority_queue_number', 0),
+                        'total-traffic-sched-count': inst_data[ATTRIBUTES_KEY].get('total_traffic_scheduler_number', 0),
+                    }
+
+        return results if len(results) else None
+
+    @property
+    def software_images(self):
+        """
+        Get a list of software image information for the ONU.  The information is provided
+        so that it may be directly added to the protobuf Device information software list.
+        """
+        sw = self._get_capability('_software', SoftwareImage.class_id)
+        images = list()
+
+        if sw is not None:
+            for inst, inst_data in sw.items():
+                if isinstance(inst, int):
+                    is_active = inst_data[ATTRIBUTES_KEY].get('is_active', False)
+
+                    images.append(Image(name='running-revision' if is_active else 'candidate-revision',
+                                        version=str(inst_data[ATTRIBUTES_KEY].get('version',
+                                                                                  'Not Available').rstrip('\0')),
+                                        is_active=is_active,
+                                        is_committed=inst_data[ATTRIBUTES_KEY].get('is_committed',
+                                                                                   False),
+                                        is_valid=inst_data[ATTRIBUTES_KEY].get('is_valid',
+                                                                               False),
+                                        install_datetime='Not Available',
+                                        hash=str(inst_data[ATTRIBUTES_KEY].get('image_hash',
+                                                                               'Not Available').rstrip('\0'))))
+        return images if len(images) else None
+
+    @property
+    def ani_g_entities(self):
+        """
+        This managed entity organizes data associated with each access network
+        interface supported by a G-PON ONU. The ONU automatically creates one
+        instance of this managed entity for each PON physical port.
+        """
+        ag = self._get_capability('_ani_g', AniG.class_id)
+        results = dict()
+
+        if ag is not None:
+            for inst, inst_data in ag.items():
+                if isinstance(inst, int):
+                    results[inst] = {
+                        'entity-id':               inst,
+                        'slot-number':             (inst >> 8) & 0xff,
+                        'port-number':             inst & 0xff,
+                        'total-tcont-count':       inst_data[ATTRIBUTES_KEY].get('total_tcont_number', 0),
+                        'piggyback-dba-reporting': inst_data[ATTRIBUTES_KEY].get('piggyback_dba_reporting', 0),
+                    }
+        return results if len(results) else None
+
+    @property
+    def uni_g_entities(self):
+        """
+        This managed entity organizes data associated with user network interfaces
+        (UNIs) supported by GEM. One instance of the UNI-G managed entity exists
+        for each UNI supported by the ONU.
+
+        The ONU automatically creates or deletes instances of this managed entity
+        upon the creation or deletion of a real or virtual circuit pack managed
+        entity, one per port.
+        """
+        ug = self._get_capability('_uni_g', UniG.class_id)
+        results = dict()
+
+        if ug is not None:
+            for inst, inst_data in ug.items():
+                if isinstance(inst, int):
+                    results[inst] = {
+                        'entity-id':               inst,
+                        'management-capability':   inst_data[ATTRIBUTES_KEY].get('management_capability', 0)
+                    }
+        return results if len(results) else None
+
+    @property
+    def pptp_entities(self):
+        """
+        Returns discovered PPTP Ethernet entities.  TODO more detail here
+        """
+        pptp = self._get_capability('_pptp', PptpEthernetUni.class_id)
+        results = dict()
+
+        if pptp is not None:
+            for inst, inst_data in pptp.items():
+                if isinstance(inst, int):
+                    results[inst] = {
+                        'entity-id':                inst,
+                        'expected-type':            inst_data[ATTRIBUTES_KEY].get('expected_type', 0),
+                        'sensed-type':              inst_data[ATTRIBUTES_KEY].get('sensed_type', 0),
+                        'autodetection-config':     inst_data[ATTRIBUTES_KEY].get('autodetection_config', 0),
+                        'ethernet-loopback-config': inst_data[ATTRIBUTES_KEY].get('ethernet_loopback_config', 0),
+                        'administrative-state':     inst_data[ATTRIBUTES_KEY].get('administrative_state', 0),
+                        'operational-state':        inst_data[ATTRIBUTES_KEY].get('operational_state', 0),
+                        'config-ind':               inst_data[ATTRIBUTES_KEY].get('config_ind', 0),
+                        'max-frame-size':           inst_data[ATTRIBUTES_KEY].get('max_frame_size', 0),
+                        'dte-dce-ind':              inst_data[ATTRIBUTES_KEY].get('dte_dce_ind', 0),
+                        'pause-time':               inst_data[ATTRIBUTES_KEY].get('pause_time', 0),
+                        'bridged-ip-ind':           inst_data[ATTRIBUTES_KEY].get('bridged_ip_ind', 0),
+                        'arc':                      inst_data[ATTRIBUTES_KEY].get('arc', 0),
+                        'arc-interval':             inst_data[ATTRIBUTES_KEY].get('arc_interval', 0),
+                        'pppoe-filter':             inst_data[ATTRIBUTES_KEY].get('ppoe_filter', 0),
+                        'power-control':            inst_data[ATTRIBUTES_KEY].get('power_control', 0)
+                    }
+        return results if len(results) else None
+
+    @property
+    def veip_entities(self):
+        """
+        Returns discovered VEIP entities.  TODO more detail here
+        """
+        veip = self._get_capability('_veip', VeipUni.class_id)
+        results = dict()
+
+        if veip is not None:
+            for inst, inst_data in veip.items():
+                if isinstance(inst, int):
+                    results[inst] = {
+                        'entity-id':                inst,
+                        'administrative-state':     inst_data[ATTRIBUTES_KEY].get('administrative_state', 0),
+                        'operational-state':        inst_data[ATTRIBUTES_KEY].get('operational_state', 0),
+                        'interdomain-name':         inst_data[ATTRIBUTES_KEY].get('interdomain_name', ""),
+                        'tcp-udp-pointer':          inst_data[ATTRIBUTES_KEY].get('tcp_udp_pointer', 0),
+                        'iana-assigned-port':       inst_data[ATTRIBUTES_KEY].get('iana_assigned_port', 0)
+                    }
+        return results if len(results) else None
