VOL-2046 Update MIB Table types properly during attribute reconcile

If an entity instance is the same but only attributes have changed
the reconcile process attempts to reconcile those attributes.

This fix allows table attributes to be updated.

Ultimately allows fiber pull and restore to work for the onu

Also release 2.2.4

Change-Id: Idac92f3bd4cdf81ee8f17855e523b4e765c30620
diff --git a/VERSION b/VERSION
index 3afe9ad..530cdd9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.4-dev0
+2.2.4
diff --git a/pyvoltha/adapters/extensions/omci/tasks/mib_reconcile_task.py b/pyvoltha/adapters/extensions/omci/tasks/mib_reconcile_task.py
index b2eedd2..046d306 100644
--- a/pyvoltha/adapters/extensions/omci/tasks/mib_reconcile_task.py
+++ b/pyvoltha/adapters/extensions/omci/tasks/mib_reconcile_task.py
@@ -611,19 +611,45 @@
             if not still_the_same:
                 returnValue((0, len(onu_data)))    # Wait for it to stabilize
 
+            writeable_data = dict()
+            table_data = dict()
+            for key, value in onu_data.items():
+                for attr in me_entry.attributes:
+                    if attr.field.name == key:
+                        if isinstance(attr.field, OmciTableField):
+                            table_data[key] = value
+                        else:
+                            writeable_data[key] = value
+
             # OLT data still matches, do the set operations now
             # while len(onu_data):
-            attributes_mask = me_entry.mask_for(*onu_data.keys())
-            frame = OmciFrame(transaction_id=None,
-                              message_type=OmciSet.message_id,
-                              omci_message=OmciSet(entity_class=cid,
-                                                   entity_id=eid,
-                                                   attributes_mask=attributes_mask,
-                                                   data=onu_data))
+            if len(writeable_data):
+                attributes_mask = me_entry.mask_for(*writeable_data.keys())
+                frame = OmciFrame(transaction_id=None,
+                                  message_type=OmciSet.message_id,
+                                  omci_message=OmciSet(entity_class=cid,
+                                                       entity_id=eid,
+                                                       attributes_mask=attributes_mask,
+                                                       data=onu_data))
 
-            results = yield self._device.omci_cc.send(frame)
-            self.check_status_and_state(results, 'onu-attribute-update')
-            successes += len(onu_data)
+                results = yield self._device.omci_cc.send(frame)
+                self.check_status_and_state(results, 'onu-attribute-update')
+                successes += len(writeable_data)
+
+            for key, value in table_data.items():
+                for row in value:
+                    setvalue = {key: row}
+                    attributes_mask = me_entry.mask_for(*setvalue.keys())
+                    frame = OmciFrame(transaction_id=None,
+                                      message_type=OmciSet.message_id,
+                                      omci_message=OmciSet(entity_class=cid,
+                                                           entity_id=eid,
+                                                           attributes_mask=attributes_mask,
+                                                           data=setvalue))
+                    self._local_deferred = yield self._device.omci_cc.send(frame)
+                    self.check_status_and_state(self._local_deferred, 'onu-attribute-table-update')
+                    successes += 1
+
             self._db_updates = 0
 
         except Exception as e: