Как преобразовать уровень сигнала Wi-Fi из качества (в процентах) в RSSI (дБм)?
Как мне преобразовать уровень сигнала Wi-Fi из качества в процентах, обычно от 0% до 100%, в значение RSSI, обычно это отрицательное значение в дБм (т.е. -96db
)?
13 ответов
Процент мощности сигнала Wi-Fi по отношению к RSSI, дБм
Microsoft определяет качество сигнала Wifi в их структуре WLAN_ASSOCIATION_ATTRIBUTES следующим образом:
wlanSignalQuality:
Процентное значение, которое представляет качество сигнала сети. WLAN_SIGNAL_QUALITY имеет тип ULONG. Этот элемент содержит значение от 0 до 100. Значение 0 подразумевает фактическую силу сигнала RSSI -100 дБм. Значение 100 подразумевает фактическую силу сигнала RSSI -50 дБм. Вы можете рассчитать значение силы сигнала RSSI для значений wlanSignalQuality от 1 до 99, используя линейную интерполяцию.
RSSI (или "Индикатор силы радиосигнала (принятого)") выражается в единицах "дБ" (децибел) или аналогичных "дБм" (дБ на милливатт) (см. ДБ относительно дБм), в которых отрицательные числа меньшей величины имеют высочайший уровень сигнала или качество.
Поэтому преобразование между quality
(в процентах) и dBm
как следует:
quality = 2 * (dBm + 100) where dBm: [-100 to -50]
dBm = (quality / 2) - 100 where quality: [0 to 100]
Псевдокод (с примером закрепления):
// dBm to Quality:
if(dBm <= -100)
quality = 0;
else if(dBm >= -50)
quality = 100;
else
quality = 2 * (dBm + 100);
// Quality to dBm:
if(quality <= 0)
dBm = -100;
else if(quality >= 100)
dBm = -50;
else
dBm = (quality / 2) - 100;
Примечание:
Проверьте определение Quality
что вы используете для своих расчетов тщательно. Также проверьте ассортимент dB
(или же dBm
). Пределы могут отличаться.
Примеры:
Medium quality: 50% -> -75dBm = (50 / 2) - 100 Low quality: -96dBm -> 8% = 2 * (-96 + 100)
В JS я предпочитаю делать что-то вроде:
Math.min(Math.max(2 * (x + 100), 0), 100)
Мое личное мнение таково, что это более элегантный способ написать это, чем использовать if
"S.
Из опыта:
- Менее -50 дБ (-40, -30 и -20) = 100% уровня сигнала
- От -51 до -55 дБ = 90%
- От -56 до -62 дБ = 80%
- От -63 до -65 дБ = 75%
Ниже не достаточно для устройств Apple
- От -66 до 68 дБ = 70%
- От -69 до 74 дБ = 60%
- От -75 до 79 дБ = 50%
- От -80 до -83 дБ = 30%
Ноутбуки с Windows могут нормально работать на -80 дБ, но с более медленными скоростями
Я рад, что нашел этот пост, потому что я искал способ конвертировать dbm в процентах. Используя пост Дэвида, я написал быстрый скрипт на python, чтобы рассчитать процент качества.
#!/usr/bin/python
import os
cmd = "iwconfig wlan0 | grep Signal | /usr/bin/awk '{print $4}' | /usr/bin/cut -d'=' -f2"
strDbm = os.popen(cmd).read()
if strDbm:
dbm = int(strDbm)
quality = 2 * (dbm + 100)
print("{0} dbm = {1}%".format(dbm, quality))
else:
print("Wifi router connection signal strength not found")
Чтобы получить наивысшее качество Wi-Fi от того места, где находится мой компьютер, я перемещал / поворачивал свою антенну до тех пор, пока не получил самое высокое качество. Чтобы увидеть качество в реальном времени, я запустил вышеуказанный скрипт, используя:
watch -n0.1 "python getwifiquality.py"
Я знаю, что это может быть поздно, но это может помочь кому-то в будущем.
Я взял значение дБм 30-90 для RSSI и скорректировал его до 100-0 %.
Я использовал основное линейное уравнение, чтобы получить ответ.
y = mx + b
Мы знаем наши значения x для дБм как 30 и 90. Мы знаем наши значения y для% как 100 и 0.
Нам просто нужно найти склон. Таким образом, мы можем сделать это линейным.
m = 100-0/30-90
= 100/-60
= -5/3
b = y - mx
= 0 + 5/3*90
= 150
Окончательное уравнение для ввода в код, когда вы знаете значение RSSI.
% = 150 - (5/3) * RSSI
Обратите внимание, что я взял значение RSSI, которое обычно отрицательно и умножено на абсолютное значение, чтобы получить положительные числа.
quality = abs(RSSI)
% = 150 - (5/3) * quality
Из RSSI против RSS:
RSSI - показатель силы полученного сигнала RSS - показатель силы полученного сигнала
RSSI - это индикатор, а RSS - это реальная ценность. Хорошо, теперь, что вы подразумеваете под индикатором, индикатор означает, что он может быть относительным значением, а RSSI всегда является положительным значением, и для RSSI нет единицы измерения.
Мы можем сказать, что RSSI для простого человека, чтобы понять. Значения RF всегда указываются в дБм, а значения в большинстве случаев являются отрицательными значениями. Чтобы людям было легко понять, эти отрицательные значения преобразуются в положительные значения посредством масштабирования.
Скажем, например, если максимальный уровень сигнала
0 dBm
и минимум-100 dBm
, Мы можем масштабировать это как объяснено. Мы можем поставить0 dBm
и больше (RSS) как100
RSSI (т.е. максимальный RSSI) и-100 dBm
(или меньше) как0 RSSI
(минимум RSS).
Вот что я сделал:
long rssi = WiFi.RSSI();
rssi=-rssi;
int WiFiperct;
if (rssi<27){
WiFiperct =100;
}
else if(rssi>=27&&rssi<33){
WiFiperct=150-(5/2.7)*rssi;
}
else if(rssi>=33&&rssi<36){
WiFiperct=150-(5/3)*rssi;
}
else if(rssi>=36&&rssi<40){
WiFiperct=150-(5/3.3)*rssi;
}
else if(rssi>=40&&rssi<80){
WiFiperct=150-(5/3.5)*rssi;
}
else if(rssi>=80&&rssi<90){
WiFiperct=150-(5/3.4)*rssi;
}
else if(rssi>=90&&rssi<99){
WiFiperct=150-(5/3.3)*rssi;
}
else{
WiFiperct=0;
}
Эта статья является более подробным объяснением мВт, дБм и RSSI
http://madwifi-project.org/attachment/wiki/UserDocs/RSSI/Converting_Signal_Strength.pdf?format=raw
В соответствии с этим RSSI не имеют единицы. Это значение, определенное в стандарте 802.11, рассчитанное по карте и отправленное в ОС. Поставщик оригинальной карты должен предоставить таблицу сопоставления значений dBm-RSSI.
Извините за прямую ссылку, но я не могу найти исходную страницу для ссылки на файл.
Упомянутый псевдокод не будет работать для всех диапазонов, например, для диапазонов (от -80 дБм до 0 и от -40 дБм до 100).
Общая простая логика для сопоставления любого диапазона от 0 до 100. Пример использования, для приведенного ниже кода ConvertRangeToPercentage(-80,-40,-50)
int ConvertRangeToPercentage (int a_value_map_to_zero, int a_value_map_to_100, int a_value_to_convert)
{
int percentage = 0;
if (a_value_map_to_zero < a_value_map_to_100)
{
if (a_value_to_convert <= a_value_map_to_zero)
{
percentage = 0;
}
else if (a_value_to_convert >= a_value_map_to_100)
{
percentage = 100;
}
else
{
percentage = (a_value_to_convert - a_value_map_to_zero) * 100 / (a_value_map_to_100 - a_value_map_to_zero);
}
}
else if (a_value_map_to_zero > a_value_map_to_100)
{
if (a_value_to_convert >= a_value_map_to_zero)
{
percentage = 0;
}
else if (a_value_to_convert <= a_value_map_to_100)
{
percentage = 100;
}
else
{
percentage = (a_value_to_convert - a_value_map_to_zero) * 100 / (a_value_map_to_100 - a_value_map_to_zero);
}
}
else
{
percentage = 0;
}
return percentage;
}
Вот быстрый скрипт Python для преобразования RSSi в мощность сигнала...
import sys
def convert_rssi_to_quality(rssi):
dbm_num = int(rssi)
quality = 2 * (dbm_num + 100)
print("{0} dbm_num = {1}%".format(dbm_num, quality))
if __name__ == "__main__":
if len(sys.argv) != 2:
rssi_value = input("Please enter an RSSI value: ")
else:
rssi_value = sys.argv[1]
convert_rssi_to_quality(rssi_value)
Хорошо.. согласен... но почему тогда
Quality=29/100 Signal level=-78 dBm
Quality=89/100 Signal level=-55 dBm
Quality=100/100 Signal level=-21 dBm
это не согласуется с формулой процент = качество /2 - 100.
Airodump RXQ действительно полезен в реальных условиях... «Качество приема, измеряемое процентом пакетов (кадров управления и данных), успешно полученных за последние 10 секунд ». «Он измеряется по всем кадрам управления и данных. Полученные кадры содержат порядковый номер, который добавляется отправляющей точкой доступа. RXQ = 100 означает, что все пакеты были получены от точки доступа в числовой последовательности, и ни один из них не был пропущен .. Это подсказка, это позволяет вам читать больше вещей из этого значения. Допустим, вы получили 100-процентный RXQ и все 10 (или любую другую скорость) поступающих маяков в секунду. Теперь внезапно RXQ падает ниже 90, но вы по-прежнему захватываете все отправленные маяки. Таким образом, вы знаете, что точка доступа отправляет кадры клиенту, но вы не слышите ни клиента, ни точку доступа, отправляющую клиенту (нужно подойти ближе)».
Кроме того, вы можете попробовать инвертировать эту функцию Bash, которая преобразует дБм в процент:
#!/bin/bash
function dbmtoperc { # Convert dBm to percentage (based on https://www.adriangranados.com/blog/dbm-to-percent-conversion)
dbmtoperc_d=$(echo "$1" | tr -d -)
dbmtoperc_r=0
if [[ "$dbmtoperc_d" =~ [0-9]+$ ]]; then
if ((1<=$dbmtoperc_d && $dbmtoperc_d<=20)); then dbmtoperc_r=100
elif ((21<=$dbmtoperc_d && $dbmtoperc_d<=23)); then dbmtoperc_r=99
elif ((24<=$dbmtoperc_d && $dbmtoperc_d<=26)); then dbmtoperc_r=98
elif ((27<=$dbmtoperc_d && $dbmtoperc_d<=28)); then dbmtoperc_r=97
elif ((29<=$dbmtoperc_d && $dbmtoperc_d<=30)); then dbmtoperc_r=96
elif ((31<=$dbmtoperc_d && $dbmtoperc_d<=32)); then dbmtoperc_r=95
elif ((33==$dbmtoperc_d)); then dbmtoperc_r=94
elif ((34<=$dbmtoperc_d && $dbmtoperc_d<=35)); then dbmtoperc_r=93
elif ((36<=$dbmtoperc_d && $dbmtoperc_d<=38)); then dbmtoperc_r=$((92-($dbmtoperc_d-36)))
elif ((39<=$dbmtoperc_d && $dbmtoperc_d<=51)); then dbmtoperc_r=$((90-($dbmtoperc_d-39)))
elif ((52<=$dbmtoperc_d && $dbmtoperc_d<=55)); then dbmtoperc_r=$((76-($dbmtoperc_d-52)))
elif ((56<=$dbmtoperc_d && $dbmtoperc_d<=58)); then dbmtoperc_r=$((71-($dbmtoperc_d-56)))
elif ((59<=$dbmtoperc_d && $dbmtoperc_d<=60)); then dbmtoperc_r=$((67-($dbmtoperc_d-59)))
elif ((61<=$dbmtoperc_d && $dbmtoperc_d<=62)); then dbmtoperc_r=$((64-($dbmtoperc_d-61)))
elif ((63<=$dbmtoperc_d && $dbmtoperc_d<=64)); then dbmtoperc_r=$((61-($dbmtoperc_d-63)))
elif ((65==$dbmtoperc_d)); then dbmtoperc_r=58
elif ((66<=$dbmtoperc_d && $dbmtoperc_d<=67)); then dbmtoperc_r=$((56-($dbmtoperc_d-66)))
elif ((68==$dbmtoperc_d)); then dbmtoperc_r=53
elif ((69==$dbmtoperc_d)); then dbmtoperc_r=51
elif ((70<=$dbmtoperc_d && $dbmtoperc_d<=85)); then dbmtoperc_r=$((50-($dbmtoperc_d-70)*2))
elif ((86<=$dbmtoperc_d && $dbmtoperc_d<=88)); then dbmtoperc_r=$((17-($dbmtoperc_d-86)*2))
elif ((89<=$dbmtoperc_d && $dbmtoperc_d<=91)); then dbmtoperc_r=$((10-($dbmtoperc_d-89)*2))
elif ((92==$dbmtoperc_d)); then dbmtoperc_r=3
elif ((93<=$dbmtoperc_d)); then dbmtoperc_r=1; fi
fi
echo $dbmtoperc_r
}
Использование:
echo $(dbmtoperc -48)% # returns 81%