How should I convert Wifi signal strength from a Quality in percentage, usually 0% to 100% into an RSSI value, usually a negative dBm number (i.e. -96db
)?
In JS I prefer doing something like:
Math.min(Math.max(2 * (x + 100), 0), 100)
My personal opinion is that it's more elegant way to write it, instead of using if
's.
Also, you can try inverse this Bash function which converts dBm to percentage:
#!/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
}
Usage:
echo $(dbmtoperc -48)% # returns 81%
From experience:
The below is not good enough for Apple devices
I know this may be late but this may help someone in the future.
I took the value of dBm 30-90 for RSSI and correlated it to 100-0 %.
I used the basic linear equation to get the answer.
y = mx + b
We know our x values for dBm as 30 and 90. We know our y values for % as 100 and 0.
We just need to find the slope. So we can make it linear.
m = 100-0/30-90
= 100/-60
= -5/3
b = y - mx
= 0 + 5/3*90
= 150
Final equation to put in code when you know the RSSI value.
% = 150 - (5/3) * RSSI
Note I did take the RSSI value that is normally negative and multiplied by the absolute value to get positive numbers.
quality = abs(RSSI)
% = 150 - (5/3) * quality
From RSSI vs RSS:
RSSI - Received Signal Strength Indicator RSS - Received Signal Strength
RSSI is an indicator and RSS is the real value. Ok, now what do you mean by indicator, indicator mean it can be a relative value and RSSI is always a positive value and there is no unit for the RSSI.
We can say RSSI is for common man to understand. RF values are always told in dBm and the values are negative values most of the time. To make it easy for the people to understand these negative values are converted to positive values through scaling.
Say for example, if the maximum signal strength is
0 dBm
and minimum is-100 dBm
. We can scale it like as explained. We can put0 dBm
and more (RSS) as100
RSSI (i. e. maximum RSSI) and-100 dBm
(or less) as0 RSSI
(minimum RSS).
This article is a more detailed explanation of mW, dBm and RSSI
http://madwifi-project.org/attachment/wiki/UserDocs/RSSI/Converting_Signal_Strength.pdf?format=raw
According to it RSSI do not have a unit. It's a value defined in 802.11 standard and calculated by nic card and sent to OS. The nic card vendor should provide a mapping table of dBm-RSSI values.
Sorry for the direct link, but I can not found the original page for the file link.