diff --git a/devices/toolkit/archiver.py b/devices/toolkit/archiver.py
index ec359c2a81bb427d54149275b9d4a3168c674922..0b7d8b31112f1fb9dc399bc7fc088494e48df846 100644
--- a/devices/toolkit/archiver.py
+++ b/devices/toolkit/archiver.py
@@ -3,7 +3,7 @@
 from logging import raiseExceptions
 import traceback
 from clients.attribute_wrapper import attribute_wrapper
-from tango import DeviceProxy
+from tango import DeviceProxy, AttributeProxy
 from datetime import datetime, timedelta
 
 import time
@@ -38,12 +38,37 @@ class Archiver():
             self.cm.write_attribute('SetPollingPeriod', polling_period)
             self.cm.write_attribute('SetPeriodEvent', event_period)
             self.cm.AttributeAdd()
+            print('Attribute %s added to archiving list!' % attribute_name)
         except Exception as e:
             if 'already archived' not in str(e).lower():
                 traceback.format_exc()
             else: 
                 print('Attribute %s already in archiving list!' % attribute_name)
 
+    def add_attributes_to_archiver(self,device_name,global_archive_period:int = None, exclude:list = ['Status','State']):
+        """
+        Add sequentially all the attributes of the selected device in the event subscriber list, if not already present
+        """
+        d = DeviceProxy(device_name)
+        attrs_list = list(d.get_attribute_list()) # cast to list otherwise removal is not allowed
+        try: 
+            for a in exclude: attrs_list.remove(a)
+        except:
+            pass
+        for a in attrs_list:
+            attr_fullname = str(device_name+'/'+a).lower()
+            attr_proxy = AttributeProxy(attr_fullname)
+            if attr_proxy.is_polled() is True:   # if not polled attribute is also not archived
+                try:
+                    if self.es.AttributeList is None or not(self.cm.AttributeSearch(a)):
+                        polling_period = attr_proxy.get_poll_period()  
+                        archive_period = global_archive_period or int(attr_proxy.get_property('archive_period')['archive_period'][0])                 
+                        self.add_attribute_to_archiver(attr_fullname,polling_period=polling_period,
+                            event_period=archive_period)
+                        #time.sleep(0.5)
+                except:
+                    print(traceback.format_exc())
+    
     def remove_attribute_from_archiver(self, attribute_name:str):
         """
         Stops the data archiving of the attribute passed as input, and remove it from the subscriber's list. 
@@ -53,11 +78,26 @@ class Archiver():
         try:
             self.cm.AttributeStop(attribute_name)
             self.cm.AttributeRemove(attribute_name)
+            print('Attribute %s removed!' % attribute_name)
         except Exception as e:
             if 'attribute not found' not in str(e).lower():
                 traceback.format_exc()
             else: 
                 print('Attribute %s not found!' % attribute_name)      
+    
+    def remove_attributes_by_device(self,device_name:str):
+        """
+        Stops the data archiving of all the attributes of the selected device, and remove them from the
+        subscriber's list
+        """
+        d = DeviceProxy(device_name)
+        attrs_list = d.get_attribute_list()
+        for a in attrs_list:
+            try:
+                attr_fullname = str(device_name+'/'+a).lower()
+                self.remove_attribute_from_archiver(attr_fullname)
+            except:
+                print(traceback.format_exc())
 
     def start_archiving_attribute(self, attribute_name:str):
         """
@@ -109,16 +149,16 @@ class Archiver():
         """
         try:
             self.remove_attribute_from_archiver(attribute_name)
-            time.sleep(3)
+            time.sleep(1)
             self.add_attribute_to_archiver(attribute_name,polling_period,event_period,strategy)
-            time.sleep(3)
+            time.sleep(1)
             self.start_archiving_attribute(attribute_name)
         except:
             print(traceback.format_exc())
     
     def get_subscriber_attributes(self,es_name:str = None):
         """
-        Returns the list of attributes managed by the event subscriber
+        Return the list of attributes managed by the event subscriber
         """
         if es_name is not None:
             es = DeviceProxy(es_name)
@@ -127,6 +167,48 @@ class Archiver():
         attrs = es.AttributeList or []
         return attrs
     
+    def get_subscriber_errors(self,es_name:str = None):
+        """
+        Return a dictionary of the attributes currently in error, defined as AttributeName -> AttributeError
+        """
+        if es_name is not None:
+            es = DeviceProxy(es_name)
+        else: 
+            es = self.es
+        try:
+            attrs = es.AttributeList or []
+            errs = es.AttributeErrorList or []
+            return dict((a,e) for a,e in zip(attrs,errs) if e)
+        except:
+            print('No attribute errors in the subscriber')
+            return {}
+    
+    def get_attribute_errors(self,attribute_name:str):
+        """
+        Return the error related to the attribute
+        """
+        if (len(attribute_name.split('/'))!=4): 
+            raise AttributeFormatException
+        errs_dict = self.get_subscriber_errors()
+        for e in errs_dict:
+            if attribute_name in e:
+                return errs_dict.get(e)
+        return None
+    
+    def get_subscriber_load(self,use_freq=True,es_name:str = None):
+        """
+        Return the estimated load of an archiver, in frequency of records or number
+        of attributes
+        """
+        if es_name is not None:
+            es = DeviceProxy(es_name)
+        else: 
+            es = self.es
+        if use_freq:
+            return str(es.AttributeRecordFreq)+(' events/period' )
+        else:
+            return len(es.AttributeList)
+    
 class AttributeFormatException(Exception):
     """
     Exception that handles wrong attribute naming