Index: /branches/amp_4_0/platform/tools/container/services/telegraf/telegraf.conf
===================================================================
--- /branches/amp_4_0/platform/tools/container/services/telegraf/telegraf.conf	(revision 2961)
+++ /branches/amp_4_0/platform/tools/container/services/telegraf/telegraf.conf	(working copy)
@@ -17,8 +17,6 @@
 [[outputs.postgresql]]
   connection = "host=${TSDB_HOST:-127.0.0.1} port=${TSDB_PORT:-5432} user=${TSDB_USER:-amp_ts_user} password=${TSDB_PASSWORD:-Array@123$} dbname=${TSDB_NAME:-amp_ts} sslmode=disable"
   schema     = "public"
-  # method     = "insert"  # Unsupported in this version
-  # Route metrics to Timescale, configured to drop logs
   namedrop = ["docker_log"]
 
 # === Output: Logstash (Socket Writer) ===
Index: /branches/amp_4_0/platform/tools/container/services/telegraf/telegraf.d/avx.toml
===================================================================
--- /branches/amp_4_0/platform/tools/container/services/telegraf/telegraf.d/avx.toml	(nonexistent)
+++ /branches/amp_4_0/platform/tools/container/services/telegraf/telegraf.d/avx.toml	(working copy)
@@ -0,0 +1,53 @@
+[[inputs.snmp]]
+agents = []
+agent_host_tag = "source"
+community = "public"
+name = "an_device_metrics"
+timeout = "5s"
+
+# CPU usage % (UCD-SNMP-MIB::ssCpuIdle — we store raw idle, convert via starlark)
+[[inputs.snmp.field]]
+name = "cpu_usage_raw"
+oid = ".1.3.6.1.4.1.2021.11.11.0"
+
+# Memory: total and available in kB (UCD-SNMP-MIB)
+[[inputs.snmp.field]]
+name = "mem_total"
+oid = ".1.3.6.1.4.1.2021.4.5.0"
+
+[[inputs.snmp.field]]
+name = "mem_avail"
+oid = ".1.3.6.1.4.1.2021.4.6.0"
+
+# Network throughput counters for the primary uplink (enp11s0f0 = ifIndex 2)
+# Using scalar form .OID.INDEX to get a single value — no SNMP table scan needed
+[[inputs.snmp.field]]
+name = "total_in"
+oid = ".1.3.6.1.2.1.31.1.1.1.6.2"
+
+[[inputs.snmp.field]]
+name = "total_out"
+oid = ".1.3.6.1.2.1.31.1.1.1.10.2"
+
+# Starlark: derive cpu_usage and mem_usage from raw SNMP values, then clean up temp fields
+[[processors.starlark]]
+  namepass = ["an_device_metrics"]
+  source = '''
+def apply(metric):
+    # CPU: convert idle% -> used%
+    if "cpu_usage_raw" in metric.fields:
+        idle = float(metric.fields["cpu_usage_raw"])
+        metric.fields["cpu_usage"] = 100.0 - idle
+        metric.fields.pop("cpu_usage_raw")
+
+    # Memory: compute usage %
+    if "mem_total" in metric.fields and "mem_avail" in metric.fields:
+        total = float(metric.fields["mem_total"])
+        avail = float(metric.fields["mem_avail"])
+        if total > 0:
+            metric.fields["mem_usage"] = ((total - avail) / total) * 100.0
+        metric.fields.pop("mem_total")
+        metric.fields.pop("mem_avail")
+
+    return metric
+'''
Index: /branches/amp_4_0/platform/tools/container/stack.yml.template
===================================================================
--- /branches/amp_4_0/platform/tools/container/stack.yml.template	(revision 2961)
+++ /branches/amp_4_0/platform/tools/container/stack.yml.template	(working copy)
@@ -399,7 +399,7 @@
       - label:disable
     deploy:
       mode: global # Run on EVERY node to monitor docker
-    entrypoint: ["telegraf", "--config", "/etc/telegraf/telegraf.conf", "--config", "/etc/telegraf/telegraf.d/apv.toml", "--config", "/etc/telegraf/telegraf.d/ag.toml", "--config", "/etc/telegraf/telegraf.d/asf.toml"]
+    entrypoint: ["telegraf", "--config", "/etc/telegraf/telegraf.conf", "--config", "/etc/telegraf/telegraf.d/apv.toml", "--config", "/etc/telegraf/telegraf.d/ag.toml", "--config", "/etc/telegraf/telegraf.d/asf.toml", "--config", "/etc/telegraf/telegraf.d/avx.toml"]
     environment:
       PG_PASSWORD_FILE: /run/secrets/pg_password
       DOCKER_API_VERSION: "1.44"
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/init_ftp_server.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/init_ftp_server.py	(revision 2961)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/init_ftp_server.py	(working copy)
@@ -7,13 +7,14 @@
 from pyftpdlib.servers import MultiprocessFTPServer
 
 CM_UpdateBuilds_PATH = r'/ca/package'
-FTP_LOG = '/var/log/ftpd.log'
+FTP_LOG = '/var/log/amp/ftpd.log'
 
 
 class FTP_Server(object):
     def __init__(self):
         if not os.path.exists(CM_UpdateBuilds_PATH):
             os.mkdir(CM_UpdateBuilds_PATH)
+        os.makedirs(os.path.dirname(FTP_LOG), exist_ok=True)
         authorizer = DummyAuthorizer()
         authorizer.add_user("array", "admin", CM_UpdateBuilds_PATH, perm="elr")
         handler = FTPHandler
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/init_tftp_server.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/init_tftp_server.py	(revision 2961)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/init_tftp_server.py	(working copy)
@@ -5,13 +5,14 @@
 import tftpy
 
 CM_CONFIGBACKUP_PATH = r'/ca/config/backup'
-TFTP_LOG = '/var/log/tftpd.log'
+TFTP_LOG = '/var/log/amp/tftpd.log'
 
 
 class TFTP_Server(object):
     def __init__(self):
         if not os.path.exists(CM_CONFIGBACKUP_PATH):
             os.makedirs(CM_CONFIGBACKUP_PATH)
+        os.makedirs(os.path.dirname(TFTP_LOG), exist_ok=True)
         try:
             server = tftpy.TftpServer(CM_CONFIGBACKUP_PATH)
         except Exception as e:
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/task_scheduler.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/task_scheduler.py	(revision 2961)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/task_scheduler.py	(working copy)
@@ -10,6 +10,7 @@
 import uuid
 import re
 import threading
+import ast
 
 import requests
 from apscheduler.events import *
@@ -2397,27 +2398,33 @@
 
 
 def set_host_sys_status(host_id, data):
-    regex = re.compile(r'\\(?![/u"])')
-    data['cpu_usage'] = json.loads(regex.sub(r"\\\\", data['cpu_usage']).replace("'", '"'))
-    data['memory_usage'] = json.loads(regex.sub(r"\\\\", data['memory_usage']).replace("'", '"'))
-    data['disk_usage'] = json.loads(regex.sub(r"\\\\", data['disk_usage']).replace("'", '"'))
-    result = {
-        'id': host_id,
-        'cpu_usage': int(data['cpu_usage']['percent']),
-        'memory_usage': int(data['memory_usage']['percent']),
-        'disk_usage': int(data['disk_usage']['percent'])
-    }
-    db = DB.get_connected_db()
-    update_sql = "UPDATE host SET cpu_usage=%(cpu_usage)s, mem_usage=%(memory_usage)s, disk_usage=%(disk_usage)s WHERE id='%(id)s'" % result
-    db.execute_sql(update_sql)
-    db.close()
+    try:
+        # Use ast.literal_eval for safer parsing of dictionary-like strings
+        cpu_data = ast.literal_eval(data['cpu_usage']) if isinstance(data['cpu_usage'], str) else data['cpu_usage']
+        mem_data = ast.literal_eval(data['memory_usage']) if isinstance(data['memory_usage'], str) else data['memory_usage']
+        disk_data = ast.literal_eval(data['disk_usage']) if isinstance(data['disk_usage'], str) else data['disk_usage']
 
+        result = {
+            'id': str(host_id),
+            'cpu_usage': float(cpu_data.get('percent', 0.0)),
+            'memory_usage': float(mem_data.get('percent', 0.0)),
+            'disk_usage': float(disk_data.get('percent', 0.0))
+        }
+        db = DB.get_connected_db()
+        update_sql = "UPDATE host SET cpu_usage=%(cpu_usage)s, mem_usage=%(memory_usage)s, disk_usage=%(disk_usage)s WHERE id='%(id)s'" % result
+        db.execute_sql(update_sql)
+        db.close()
+        logger.info(f"Updated host {host_id} sys status: CPU={result['cpu_usage']}%, Mem={result['memory_usage']}%, Disk={result['disk_usage']}%")
+    except Exception as e:
+        logger.error(f"Failed to update host sys status for {host_id}: {str(e)}")
 
+
 def set_host_vm_number(host_id, number):
     db = DB.get_connected_db()
     update_sql = "UPDATE host SET vm_number=%s WHERE id='%s'" % (number, host_id)
     db.execute_sql(update_sql)
     db.close()
+    logger.info(f"Updated host {host_id} VM number: {number}")
 
 
 class HostInfoThread(threading.Thread):
@@ -2462,7 +2469,15 @@
                     mark_expire_all(get_model('cm', ['virtualization', 'Host']))
                 else:
                     if rest_response_data['status'] == 200:
-                        set_host_vm_number(self.data['id'], len(json.loads(rest_response_data['body'])['VAInstance']))
+                        try:
+                            resp_body = json.loads(rest_response_data['body'])
+                            if 'VAInstance' in resp_body:
+                                vm_count = len(resp_body['VAInstance'])
+                                set_host_vm_number(self.data['id'], vm_count)
+                            else:
+                                logger.warning(f"Host<{self.data['ip']}> VM numbers resp missing 'VAInstance' key: {resp_body}")
+                        except Exception as parse_err:
+                            logger.error(f"Failed to parse VM number response for host<{self.data['ip']}>: {str(parse_err)} (Raw response: {rest_response_data['body']})")
                     mark_expire_all(get_model('cm', ['virtualization', 'Host']))
             mark_expire_all(get_model('cm', ['virtualization', 'Host']))
 
@@ -2572,15 +2587,28 @@
         db.close()
 
     def init_log(self):
-        logger = logging.getLogger('apscheduler')
-        logger.setLevel(logging.INFO)
-        fmt = "%(asctime)s - %(name)s - %(filename)s[line:%(lineno)d] - %(levelname)s - %(message)s"
-        log_format = logging.Formatter(fmt)
-        loghandler = logging.handlers.RotatingFileHandler('/var/log/schedule.log', maxBytes=1024 * 1024 * 100,
-                                                          backupCount=3)
-        loghandler.setFormatter(log_format)
-        logger.addHandler(loghandler)
+        os.makedirs('/var/log/amp', exist_ok=True)
+        # Configure as_logger
+        as_logger = logging.getLogger('apscheduler')
+        as_logger.setLevel(logging.INFO)
+        # Configure hd_logger
+        hd_logger = logging.getLogger('hive.debug')
+        hd_logger.setLevel(logging.INFO)
 
+        # Only add handler if not already present
+        if not as_logger.handlers or not hd_logger.handlers:
+            fmt = "%(asctime)s - %(name)s - %(filename)s[line:%(lineno)d] - %(levelname)s - %(message)s"
+            log_format = logging.Formatter(fmt)
+            loghandler = logging.handlers.RotatingFileHandler('/var/log/amp/schedule.log', 
+                                                              maxBytes=1024 * 1024 * 100,
+                                                              backupCount=3)
+            loghandler.setFormatter(log_format)
+            
+            if not as_logger.handlers:
+                as_logger.addHandler(loghandler)
+            if not hd_logger.handlers:
+                hd_logger.addHandler(loghandler)
+
     def get_schedule(self, title):
         if title in self.data:
             return self.data[title]
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/models/virtualization/__init__.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/models/virtualization/__init__.py	(revision 2961)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/models/virtualization/__init__.py	(working copy)
@@ -1,7 +1,7 @@
 import uuid
 import json
+import ast
 
-from django.db.models.query import QuerySet
 from django.utils.translation import gettext_lazy as _
 
 from cm.lib.communication import call_restapi
@@ -12,6 +12,7 @@
 from hive.model.fields import *
 from hive.model.manager import CLIManager
 from hive.model.legacycli import cli_parse, RegexParser, MATCHONE, CLICmdError
+from hive.model.query import QuerySet
 from hive.exceptions import ModelQueryException
 
 __ = _
@@ -77,84 +78,57 @@
     class Manager(CLIManager):
         def _get_query_set(self):
             db = DB.get_connected_db()
-            sql = '''
-                SELECT id, name, ip, restapi_port, restapi_username, restapi_password,
-                       connection, version, vm_number, cpu_usage, mem_usage, disk_usage
-                FROM host
-            '''
-            rows = db.fetchall(sql)  # returns list of tuples
+            fetchall_sql = '''SELECT id, name, ip, restapi_port, restapi_username, restapi_password, connection, version, vm_number, cpu_usage, mem_usage, disk_usage FROM host'''
+            data = db.fetchall(fetchall_sql)
             db.close()
+            key = ['id', 'name', 'ip', 'restapi_port', 'restapi_username', 'restapi_password', 'connection', 'version', 'vm_number', 'cpu_usage', 'memory_usage', 'disk_usage']
+            result = [dict(zip(key, each)) for each in data]
+            for each in result:
+                each['vm_number'] = int(each['vm_number'] or 0)
+                each['cpu_usage'] = float(each['cpu_usage'] or 0.0)
+                each['memory_usage'] = float(each['memory_usage'] or 0.0)
+                each['disk_usage'] = float(each['disk_usage'] or 0.0)
+                each['restapi_account'] = {'restapi_username': each['restapi_username'], 'restapi_password': each['restapi_password']}
+                del each['restapi_username']
+                del each['restapi_password']
 
-            # Columns in the same order as the SELECT
-            cols = [
-                'id', 'name', 'ip', 'restapi_port', 'restapi_username', 'restapi_password',
-                'connection', 'version', 'vm_number', 'cpu_usage', 'mem_usage', 'disk_usage'
-            ]
-
-            hosts = []
-
-            for each in rows:
-                row = dict(zip(cols, each))
-
-                host = Host()
-
-                # Base Settings
-                host.id = row.get('id') or ''
-                host.name = row.get('name') or ''
-                host.ip = row.get('ip') or ''
-                host.restapi_port = int(row.get('restapi_port') or 9997)
-                host.restapi_account = {
-                    'restapi_username': row.get('restapi_username') or '',
-                    'restapi_password': row.get('restapi_password') or '',
-                }
-                host.connection = row.get('connection') or 'Unconnected'
-                host.vm_number = int(row.get('vm_number') or 0)
-
-                # Metrics (mem_usage -> memory_usage in model)
-                host.cpu_usage = float(row.get('cpu_usage') or 0.0)
-                host.memory_usage = float(row.get('mem_usage') or 0.0)
-                host.disk_usage = float(row.get('disk_usage') or 0.0)
-
-                # Parse "version" text into stats fields (if present)
-                version_blob = row.get('version')
-                if version_blob:
-                    txt = version_blob.replace('\\n', '\n')
-                    rtn = cli_parse(txt, [
-                        RegexParser('Host name : (.+?)\\n', MATCHONE),
-                        RegexParser('System CPU : (.+?)\\n', MATCHONE),
-                        RegexParser('System RAM : (.+?)\\n', MATCHONE),
-                        RegexParser('System boot time : (.+?)\\n', MATCHONE),
-                        RegexParser('System up time : (.+?)\\n', MATCHONE),
-                        RegexParser('Platform Bld Date : (.+?)\\n', MATCHONE),
-                        RegexParser('SSL HW : (.+?)\\n', MATCHONE),
-                        RegexParser('Compression HW : (.+?)\\n', MATCHONE),
-                        RegexParser('Power supply : (.+?)\\n', MATCHONE),
-                        RegexParser('Network Interface : (.+?)\\n', MATCHONE),
-                        RegexParser('Model : (.+?)\\n', MATCHONE),
-                        RegexParser('Serial Number : (.+?)\\n', MATCHONE),
-                        RegexParser('License Key : (.*?)\\n', MATCHONE),
-                        RegexParser('Expiration Date : (.*?)\\n', MATCHONE),
-                        RegexParser('(AVX.+?)\\n', MATCHONE),
-                    ])
-                    host.host_name = rtn[0][0] if rtn[0] else ''
-                    host.system_cpu = rtn[1][0] if rtn[1] else ''
-                    host.system_ram = rtn[2][0] if rtn[2] else ''
-                    host.system_boot_time = rtn[3][0] if rtn[3] else ''
-                    host.system_up_time = rtn[4][0] if rtn[4] else ''
-                    host.platform_bld_date = rtn[5][0] if rtn[5] else ''
-                    host.ssl_hw = rtn[6][0] if rtn[6] else ''
-                    host.compression_hw = rtn[7][0] if rtn[7] else ''
-                    host.power_supply = rtn[8][0] if rtn[8] else ''
-                    host.network_interface = rtn[9][0] if rtn[9] else ''
-                    host.model = rtn[10][0].split(',')[0] if rtn[10] else ''
-                    host.serial_number = rtn[11][0] if rtn[11] else ''
-                    host.license_key = rtn[12][0] if rtn[12] else ''
-                    host.license_date = rtn[13][0] if rtn[13] else ''
-                    host.build_version = rtn[14][0] if rtn[14] else ''
-
-                hosts.append(host)
-
-            return hosts
+                if each['version']:
+                    replace_result = each['version'].replace('\\n', '\n')
+                    rtn = cli_parse(replace_result, [
+                                 RegexParser('Host name : (.+?)\n', MATCHONE),
+                                 RegexParser('System CPU : (.+?)\n', MATCHONE),
+                                 RegexParser('System RAM : (.+?)\n', MATCHONE),
+                                 RegexParser('System boot time : (.+?)\n', MATCHONE),
+                                 RegexParser('System up time : (.+?)\n', MATCHONE),
+                                 RegexParser('Platform Bld Date : (.+?)\n', MATCHONE),
+                                 RegexParser('SSL HW : (.+?)\n', MATCHONE),
+                                 RegexParser('Compression HW : (.+?)\n', MATCHONE),
+                                 RegexParser('Power supply : (.+?)\n', MATCHONE),
+                                 RegexParser('Network Interface : (.+?)\n', MATCHONE),
+                                 RegexParser('Model : (.+?)\n', MATCHONE),
+                                 RegexParser('Serial Number : (.+?)\n', MATCHONE),
+                                 RegexParser('License Key : (.*?)\n', MATCHONE),
+                                 RegexParser('Expiration Date : (.*?)\n', MATCHONE),
+                                 RegexParser('(AVX.+?)\n', MATCHONE),
+                             ])
+                    each['host_name'] = rtn[0][0] if rtn[0] else ''
+                    each['system_cpu'] = rtn[1][0] if rtn[1] else ''
+                    each['system_ram'] = rtn[2][0] if rtn[2] else ''
+                    each['system_boot_time'] = rtn[3][0] if rtn[3] else ''
+                    each['system_up_time'] = rtn[4][0] if rtn[4] else ''
+                    each['platform_bld_date'] = rtn[5][0] if rtn[5] else ''
+                    each['ssl_hw'] = rtn[6][0] if rtn[6] else ''
+                    each['compression_hw'] = rtn[7][0] if rtn[7] else ''
+                    each['power_supply'] = rtn[8][0] if rtn[8] else ''
+                    each['network_interface'] = rtn[9][0] if rtn[9] else ''
+                    each['model'] = rtn[10][0].split(',')[0] if rtn[10] else ''
+                    each['serial_number'] = rtn[11][0] if rtn[11] else ''
+                    each['license_key'] = rtn[12][0] if rtn[12] else ''
+                    each['license_date'] = rtn[13][0] if rtn[13] else ''
+                    each['build_version'] = rtn[14][0] if rtn[14] else ''
+                del each['version']
+                self._model._meta.mark_delay_query(each)
+            return QuerySet(self._model, result)
 
         def _get_stats(self):
             return self._get_query_set()
@@ -166,8 +140,6 @@
             data['restapi_username'] = data['restapi_account']['restapi_username']
             data['restapi_password'] = data['restapi_account']['restapi_password']
 
-            # data['console_username'] = data['console_account']['console_username']
-            # data['console_password'] = data['console_account']['console_password']
             def check_ip_name_from_device(ip, name):
                 db = DB.get_connected_db()
                 select_sql = "SELECT name FROM host where ip='%s' or name='%s'" % (ip, name)
@@ -200,20 +172,42 @@
                 else:
                     raise ModelQueryException(CLICmdError(__('Add Failed!')))
 
+                # Fetch initial system status metrics to avoid 0.0 values on UI
+                data['cpu_usage'] = 0.0
+                data['mem_usage'] = 0.0
+                data['disk_usage'] = 0.0
+                data['vm_number'] = 0
+                try:
+                    status_data = call_restapi('GET', '/rest/avx/system/SystemStatus/status', '', data['ip'],
+                                               data['restapi_port'], data['restapi_username'],
+                                               data['restapi_password'], 'https')
+                    if status_data['status'] == 200:
+                        status_body = json.loads(status_data['body'])['SystemStatus']
+                        # Handle stringified dicts from AVX API
+                        cpu_data = ast.literal_eval(status_body['cpu_usage']) if isinstance(status_body['cpu_usage'], str) else status_body['cpu_usage']
+                        mem_data = ast.literal_eval(status_body['memory_usage']) if isinstance(status_body['memory_usage'], str) else status_body['memory_usage']
+                        disk_data = ast.literal_eval(status_body['disk_usage']) if isinstance(status_body['disk_usage'], str) else status_body['disk_usage']
+                        data['cpu_usage'] = float(cpu_data.get('percent', 0.0))
+                        data['mem_usage'] = float(mem_data.get('percent', 0.0))
+                        data['disk_usage'] = float(disk_data.get('percent', 0.0))
+                except Exception:
+                    pass
+
+                try:
+                    vm_data = call_restapi('GET', '/rest/avx/va/instance/VAInstance/_get_list_data', '', data['ip'],
+                                           data['restapi_port'], data['restapi_username'],
+                                           data['restapi_password'], 'https')
+                    if vm_data['status'] == 200:
+                        data['vm_number'] = len(json.loads(vm_data['body'])['VAInstance'])
+                except Exception:
+                    pass
+
             db = DB.get_connected_db()
-            save_sql = "INSERT INTO host(id, name, ip, restapi_port, restapi_username, restapi_password, connection, version) Values " + "('%(id)s', '%(name)s', '%(ip)s', '%(restapi_port)s', '%(restapi_username)s', '%(restapi_password)s', 'Connected', '%(version)s')" % data
+            save_sql = "INSERT INTO host(id, name, ip, restapi_port, restapi_username, restapi_password, connection, version, vm_number, cpu_usage, mem_usage, disk_usage) Values " + "('%(id)s', '%(name)s', '%(ip)s', '%(restapi_port)s', '%(restapi_username)s', '%(restapi_password)s', 'Connected', '%(version)s', %(vm_number)s, %(cpu_usage)s, %(mem_usage)s, %(disk_usage)s)" % data
             db.execute_sql(save_sql)
             db.close()
             return
 
-        # def _update_webui_port(self, instance):
-        #     device_id = instance.id
-        #     db = DB.get_connected_db()
-        #     update_sql = "UPDATE host SET webui_port='%d' WHERE id='%s'" % (instance.webui_port, device_id)
-        #     db.execute_sql(update_sql)
-        #     db.close()
-        #     return
-
         def _update_restapi_account(self, instance):
             device_id = instance.id
             db = DB.get_connected_db()
@@ -223,15 +217,6 @@
             db.close()
             return
 
-            # def _update_console_account(self, instance):
-
-        #     device_id = instance.id
-        #     db = DB.get_connected_db()
-        #     update_sql = "UPDATE host SET console_username='%s', console_password='%s' WHERE id='%s'" % (instance.console_account['console_username'], instance.console_account['console_password'], device_id)
-        #     db.execute_sql(update_sql)
-        #     db.close()
-        #     return
-
         def _delete(self, pk_list):
             db = DB.get_connected_db()
             for each_pk in pk_list:
@@ -256,7 +241,7 @@
                 if 'timed out' in str(e):
                     raise ModelQueryException(CLICmdError(
                         __('Timed out! Please check the ip address and make sure the RESTful API service configuration of target device is correct!')))
-                raise ModelQueryException(CLICmdError(__('Add Failed. Reason: %s') % str(e)))
+                raise ModelQueryException(CLICmdError(__('GET Failed. Reason: %s') % str(e)))
             else:
                 if rest_response_data['status'] == 200:
                     rest_body = json.loads(rest_response_data['body'])
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/avx-device-detail-overview/avx-device-detail-overview.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/avx-device-detail-overview/avx-device-detail-overview.ts	(revision 2961)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/avx-device-detail-overview/avx-device-detail-overview.ts	(working copy)
@@ -1,8 +1,9 @@
-import { Component, inject, OnInit } from '@angular/core';
+import { Component, inject, OnInit, OnDestroy } from '@angular/core';
 import { DeviceFacade } from '../../../services/facades/device.facade';
 import { CoreUiFacade } from '../../../services/facades/core-ui.facade';
 import { ActivatedRoute, Router } from '@angular/router';
 import { take } from 'rxjs/operators';
+import { forkJoin } from 'rxjs';
 import { SharedModule } from '../../../shared/shared-module';
 import { NgxEchartsModule } from 'ngx-echarts';
 import { MatTableDataSource } from '@angular/material/table';
@@ -17,7 +18,7 @@
   templateUrl: './avx-device-detail-overview.html',
   styleUrl: './avx-device-detail-overview.scss'
 })
-export class AvxDeviceDetailOverview implements OnInit {
+export class AvxDeviceDetailOverview implements OnInit, OnDestroy {
 
   dataColumns: Array<string> = ['key', 'value'];
   dataSource = new MatTableDataSource([]);
@@ -42,6 +43,7 @@
 
   dialog = inject(MatDialog);
   dialogConfig = new MatDialogConfig();
+  private statsRefreshInterval: any = null;
 
   ngOnInit() {
     this.deviceName = this._route.snapshot.paramMap.get('deviceName');
@@ -56,9 +58,19 @@
       this.getAVXDeviceSystemInfoOverview();
       this.getAVXDeviceResourceOccupation();
       this.getDeviceStatistics();
-    })
+    });
+    // Auto-refresh statistics charts every 10 seconds
+    this.statsRefreshInterval = setInterval(() => {
+      this.getDeviceStatistics();
+    }, 10000);
   }
 
+  ngOnDestroy() {
+    if (this.statsRefreshInterval) {
+      clearInterval(this.statsRefreshInterval);
+    }
+  }
+
   getAVXDeviceSystemInfoOverview() {
     this.deviceFacade.getAVXDeviceSystemInfoOverview(this.deviceId).pipe(take(1)).subscribe({
       next: (result: any) => {
@@ -86,8 +98,68 @@
   }
 
   getDeviceStatistics() {
-    // ToDo: Integrate with APIs once ready.
-    this.updateStatisticsCharts({});
+    const from = 'now-15m';
+    const to = 'now';
+
+    const throughputPayload = {
+      metric_name: 'network_throughput',
+      agent_host: this.deviceIp,
+      device_type: 'avx',
+      interval: '10s',
+      from: from,
+      to: to
+    };
+
+    const cpuPayload = {
+      metric_name: 'cpu_usage',
+      agent_host: this.deviceIp,
+      device_type: 'avx',
+      interval: '10s',
+      from: from,
+      to: to
+    };
+
+    const memoryPayload = {
+      metric_name: 'memory_usage',
+      agent_host: this.deviceIp,
+      device_type: 'avx',
+      interval: '10s',
+      from: from,
+      to: to
+    };
+
+    forkJoin({
+      throughput: this.deviceFacade.getDeviceMonitoringMetrics(throughputPayload).pipe(take(1)),
+      cpu: this.deviceFacade.getDeviceMonitoringMetrics(cpuPayload).pipe(take(1)),
+      memory: this.deviceFacade.getDeviceMonitoringMetrics(memoryPayload).pipe(take(1))
+    }).subscribe({
+      next: (results: any) => {
+        let _data: any = {};
+        try {
+          const tpRes = results?.throughput?.data || [];
+          const factor: any = 1024 * 1024; // MB
+          const sentData = tpRes.map((d: any) => [new Date(d.ts).getTime(), d.sent / factor]);
+          const receivedData = tpRes.map((d: any) => [new Date(d.ts).getTime(), d.received / factor]);
+          _data.throughput = { sent: sentData, received: receivedData };
+
+          const cpuRes = results?.cpu?.data || [];
+          const cpuData = cpuRes.map((d: any) => [new Date(d.ts).getTime(), d.cpu]);
+          _data.cpu = cpuData;
+
+          const memRes = results?.memory?.data || [];
+          const memData = memRes.map((d: any) => [new Date(d.ts).getTime(), d.memory_usage]);
+          _data.memory = memData;
+        } catch (e) {
+          console.error('Error parsing device statistics', e);
+        }
+        this.updateStatisticsCharts(_data);
+      },
+      error: (error: any) => {
+        this.ui.notifyError(`Error: ${error?.message || 'Failed to fetch device statistics'}`);
+        console.error(error);
+        this.updateStatisticsCharts({});
+      }
+    });
   }
 
   convertApiResponseToChartData(apiResponse: any) {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/avx-va-backup/avx-va-backup.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/avx-va-backup/avx-va-backup.ts	(revision 2961)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/avx-va-backup/avx-va-backup.ts	(working copy)
@@ -183,9 +183,9 @@
   constructor() {
     this.configForm = this._fb.group({
       avxId: [null, [Validators.required]],
-      vaName: [null, [Validators.required]],
-      backupName: ['', [Validators.required]],
-      description: [''],
+      va_name: [null, [Validators.required]],
+      backup_name: ['', [Validators.required]],
+      pack_base_image: [false],
     })
   }
 
@@ -194,7 +194,7 @@
       if (this.data?.deviceId) {
         this.configForm.patchValue({
           avxId: this.data?.deviceId,
-          vaName: this.data?.instanceName,
+          va_name: this.data?.instanceName,
         })
         this.getAVXVAInstances();
       }
@@ -226,9 +226,9 @@
     }
     // Prepare payload for createAVXVABackup
     let rawPayload = `action=Backup&options=${JSON.stringify({
-      __pk_list: [{ va_name: this.configForm.value.vaName }],
-      backup_name: this.configForm.value.backupName,
-      enable: false // description/pack_base_image logic might need check, defaulting to false based on old code
+      __pk_list: [{ va_name: this.configForm.value.va_name }],
+      backup_name: this.configForm.value.backup_name,
+      enable: this.configForm.value.pack_base_image
     })}`;
 
     this.deviceFacade.createAVXVABackup(this.configForm.value.avxId, rawPayload)
@@ -246,7 +246,7 @@
         },
         error: (error: any) => {
           console.log(error);
-          this.ui.notifyError('Failed to create backup!.');
+          this.ui.notifyError('Failed to create backup!');
         }
       })
   }
@@ -343,6 +343,7 @@
 
   constructor() {
     this.configForm = this._fb.group({
+      backup_name: [null, [Validators.required]],
       url: [null, [Validators.required]],
       username: [null, [Validators.required]],
       password: [null, [Validators.required]],
@@ -350,6 +351,11 @@
   }
 
   ngOnInit() {
+    if (this.data?.backup) {
+      this.configForm.patchValue({
+        backup_name: this.data.backup.backup_name
+      });
+    }
   }
 
   onSubmit() {
@@ -360,7 +366,7 @@
     }
 
     let rawPayload = `action=Export&options=${JSON.stringify({
-      __pk_list: [{ backup_name: this.data.backup.backup_name }],
+      __pk_list: [{ backup_name: this.configForm.value.backup_name }],
       type: 'url',
       url: this.configForm.value.url,
       user_name: this.configForm.value.username,
@@ -409,11 +415,17 @@
 
   constructor() {
     this.configForm = this._fb.group({
+      backup_name: [null, [Validators.required]],
       domain: [0, [Validators.required]], // Default domain 0
     })
   }
 
   ngOnInit() {
+    if (this.data?.backup) {
+      this.configForm.patchValue({
+        backup_name: this.data.backup.backup_name
+      });
+    }
     setTimeout(() => {
       this.getAVXDeviceSystemInfo();
     })
@@ -443,7 +455,7 @@
       return;
     }
 
-    let backup_name = this.data?.backup?.backup_name;
+    let backup_name = this.configForm.value.backup_name;
     let rawPayload = `action=Restore&options=${JSON.stringify({
       __pk_list: [{ backup_name: backup_name }],
       domain: this.configForm.value.domain
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/chart-options.service.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/chart-options.service.ts	(revision 2961)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/chart-options.service.ts	(working copy)
@@ -269,7 +269,9 @@
       },
       legend: {
         data: ['Inbound', 'Outbound'],
-        bottom: 0,
+        top: 0,
+        itemGap: 20,
+        icon: 'circle',
         textStyle: {
           color: this.getTextColor(),
           fontFamily: 'Roboto'
@@ -396,7 +398,7 @@
       grid: {
         left: '7%',
         right: '1%',
-        bottom: '1%',
+        bottom: '12%',
         containLabel: true
       },
       tooltip: {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/hive/db/device_metric_queries.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/hive/db/device_metric_queries.py	(revision 2961)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/hive/db/device_metric_queries.py	(working copy)
@@ -14,13 +14,17 @@
             "ag": "ag_device_metrics",
             "vxag": "ag_device_metrics",
             "asf": "asf_device_metrics",
-            "vasf": "asf_device_metrics"
+            "vasf": "asf_device_metrics",
+            "avx": "an_device_metrics",
+            "vavx": "an_device_metrics"
         }
         storage_map = {
             "apv": "an_device_storage",
             "vapv": "an_device_storage",
             "asf": "asf_device_storage",
-            "vasf": "asf_device_storage"
+            "vasf": "asf_device_storage",
+            "avx": "an_device_storage",
+            "vavx": "an_device_storage"
         }
         self.metrics_table = table_map.get(device_type, "an_device_metrics")
         self.storage_table = storage_map.get(device_type, None)  # shared storage table
@@ -69,8 +73,8 @@
                 SELECT
                     time_bucket_gapfill('{interval}', time, {time_from}, {time_to}) AS ts,
                     agent_host,
-                    first(total_in, time)::double precision AS total_in,
-                    first(total_out, time)::double precision AS total_out
+                    max(total_in)::double precision AS total_in,
+                    max(total_out)::double precision AS total_out
                 FROM {self.metrics_table}
                 WHERE time >= {time_from}
                   AND time <= {time_to}
@@ -223,8 +227,8 @@
                 SELECT
                     time_bucket_gapfill('{interval}', time, {time_from}, {time_to}) AS ts,
                     agent_host,
-                    first(total_out, time) AS total_out,
-                    first(total_in, time)  AS total_in
+                    max(total_out)::double precision AS total_out,
+                    max(total_in)::double precision  AS total_in
                 FROM {self.metrics_table}
                 WHERE time >= {time_from}
                   AND time <= {time_to}
