diff --git a/openwisp_monitoring/device/admin.py b/openwisp_monitoring/device/admin.py
index 2dbd54ae0..29e202d46 100644
--- a/openwisp_monitoring/device/admin.py
+++ b/openwisp_monitoring/device/admin.py
@@ -352,15 +352,20 @@ def _get_boolean_html(self, value):
icon = static(f'admin/img/icon-{icon_type}.svg')
return mark_safe(f'')
- def ht(self, obj):
- return self._get_boolean_html(obj.wifi_client.ht)
+ def he(self, obj):
+ return self._get_boolean_html(obj.wifi_client.he)
- ht.short_description = 'HT'
+ he.short_description = 'WiFi 6 (802.11ax)'
def vht(self, obj):
return self._get_boolean_html(obj.wifi_client.vht)
- vht.short_description = 'VHT'
+ vht.short_description = 'WiFi 5 (802.11ac)'
+
+ def ht(self, obj):
+ return self._get_boolean_html(obj.wifi_client.ht)
+
+ ht.short_description = 'WiFi 4 (802.11n)'
def wmm(self, obj):
return self._get_boolean_html(obj.wifi_client.wmm)
@@ -409,8 +414,9 @@ class WiFiSessionInline(WifiSessionAdminHelperMixin, admin.TabularInline):
'vendor',
'ssid',
'interface_name',
- 'ht',
+ 'he',
'vht',
+ 'ht',
'start_time',
'get_stop_time',
]
@@ -463,8 +469,9 @@ class WifiSessionAdmin(
'related_organization',
'related_device',
'ssid',
- 'ht',
+ 'he',
'vht',
+ 'ht',
'start_time',
'get_stop_time',
]
@@ -475,8 +482,9 @@ class WifiSessionAdmin(
'related_device',
'ssid',
'interface_name',
- 'ht',
+ 'he',
'vht',
+ 'ht',
'wmm',
'wds',
'wps',
@@ -499,8 +507,9 @@ def get_readonly_fields(self, request, obj=None):
'related_organization',
'mac_address',
'vendor',
- 'ht',
+ 'he',
'vht',
+ 'ht',
'wmm',
'wds',
'wps',
diff --git a/openwisp_monitoring/device/base/models.py b/openwisp_monitoring/device/base/models.py
index 65a63362c..2fc564c03 100644
--- a/openwisp_monitoring/device/base/models.py
+++ b/openwisp_monitoring/device/base/models.py
@@ -183,27 +183,30 @@ def _transform_data(self):
for signal_key, signal_values in interface['mobile']['signal'].items():
for key, value in signal_values.items():
signal_values[key] = float(value)
- # If HT/VHT is not being used ie. htmode = 'NOHT',
- # set the HT/VHT field of WiFi clients to None.
+ # If HT/VHT/HE is not being used ie. htmode = 'NOHT',
+ # set the HT/VHT/HE field of WiFi clients to None.
# This is necessary because some clients may be
# VHT capable but VHT is not enabled at the radio level,
- # which can mislead into thinking the client is not HT/VHT capable.
- if (
- 'wireless' in interface
- and 'htmode' in interface['wireless']
- and 'clients' in interface['wireless']
- ):
- for client in interface['wireless']['clients']:
- # NOHT : disables 11n (ie. ht and vht both are False)
- if interface['wireless']['htmode'] == 'NOHT':
- client['ht'] = None
- client['vht'] = None
- # If only HT is enabled, set client vht to None
- elif (
- interface['wireless']['htmode'].startswith('HT')
- and not client['vht']
- ):
- client['vht'] = None
+ # which can mislead into thinking the client is not HT/VHT/HE capable.
+ wireless = interface.get('wireless')
+ if wireless and all(key in wireless for key in ('htmode', 'clients')):
+ for client in wireless['clients']:
+ htmode = wireless['htmode']
+ ht_enabled = htmode.startswith('HT')
+ vht_enabled = htmode.startswith('VHT')
+ noht_enabled = htmode == 'NOHT'
+ if noht_enabled:
+ client['ht'] = client['vht'] = None
+ # since 'he' field is optional
+ if 'he' in client:
+ client['he'] = None
+ elif ht_enabled:
+ if client['vht'] is False:
+ client['vht'] = None
+ if client.get('he') is False:
+ client['he'] = None
+ elif vht_enabled and client.get('he') is False:
+ client['he'] = None
# add mac vendor to wireless clients if present
if (
not mac_detection
@@ -371,8 +374,9 @@ class AbstractWifiClient(TimeStampedEditableModel):
help_text=_('MAC address'),
)
vendor = models.CharField(max_length=200, blank=True, null=True)
- ht = models.BooleanField(null=True, blank=True, default=None, verbose_name='HT')
+ he = models.BooleanField(null=True, blank=True, default=None, verbose_name='HE')
vht = models.BooleanField(null=True, blank=True, default=None, verbose_name='VHT')
+ ht = models.BooleanField(null=True, blank=True, default=None, verbose_name='HT')
wmm = models.BooleanField(default=False, verbose_name='WMM')
wds = models.BooleanField(default=False, verbose_name='WDS')
wps = models.BooleanField(default=False, verbose_name='WPS')
diff --git a/openwisp_monitoring/device/migrations/0007_add_wificlient_field_he.py b/openwisp_monitoring/device/migrations/0007_add_wificlient_field_he.py
new file mode 100644
index 000000000..3ed461f5d
--- /dev/null
+++ b/openwisp_monitoring/device/migrations/0007_add_wificlient_field_he.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.2.18 on 2023-04-20 11:07
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('device_monitoring', '0006_alter_wificlient_field_ht_vht'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='wificlient',
+ name='he',
+ field=models.BooleanField(
+ blank=True, default=None, null=True, verbose_name='HE'
+ ),
+ ),
+ ]
diff --git a/openwisp_monitoring/device/schema.py b/openwisp_monitoring/device/schema.py
index 4f411d56e..7dca317a7 100644
--- a/openwisp_monitoring/device/schema.py
+++ b/openwisp_monitoring/device/schema.py
@@ -236,6 +236,7 @@
"authorized": {"type": "boolean"},
"ht": {"type": "boolean"},
"vht": {"type": "boolean"},
+ "he": {"type": "boolean"},
"wds": {"type": "boolean"},
"wmm": {"type": "boolean"},
"wps": {"type": "boolean"},
diff --git a/openwisp_monitoring/device/tasks.py b/openwisp_monitoring/device/tasks.py
index 9355ea92e..aabaf38ab 100644
--- a/openwisp_monitoring/device/tasks.py
+++ b/openwisp_monitoring/device/tasks.py
@@ -38,7 +38,7 @@ def trigger_device_checks(pk, recovery=True):
@shared_task(base=OpenwispCeleryTask)
def save_wifi_clients_and_sessions(device_data, device_pk):
- _WIFICLIENT_FIELDS = ['vendor', 'ht', 'vht', 'wmm', 'wds', 'wps']
+ _WIFICLIENT_FIELDS = ['vendor', 'ht', 'vht', 'he', 'wmm', 'wds', 'wps']
WifiClient = load_model('device_monitoring', 'WifiClient')
WifiSession = load_model('device_monitoring', 'WifiSession')
diff --git a/openwisp_monitoring/device/templates/admin/config/device/change_form.html b/openwisp_monitoring/device/templates/admin/config/device/change_form.html
index 13ff88de8..027af7ab4 100644
--- a/openwisp_monitoring/device/templates/admin/config/device/change_form.html
+++ b/openwisp_monitoring/device/templates/admin/config/device/change_form.html
@@ -401,11 +401,14 @@