-
-
Save lg/e91d1c5c9640d963e13dbb1901bb4396 to your computer and use it in GitHub Desktop.
| #!/bin/ash | |
| # | |
| # angry_wifi.sh | |
| # | |
| # auto disconnects clients with a low signal strength on LEDE / OpenWRT. great | |
| # for clients who hold onto a lower-signal-strength accesspoint instead of | |
| # roaming. before running, make sure to download the latest MAC addresses with: | |
| # | |
| # wget --no-check-certificate -O - 'https://services13.ieee.org/RST/standards-ra-web/rest/assignments/download/?registry=MAC&text=apple' | cut -d, -f2 > apple_mac_addresses | |
| # | |
| # some notes: | |
| # - only Apple clients will be disconnected | |
| # - clients won't be re-disconnected for 1 minute if they end up re-connecting | |
| # - be careful with this script, if you don't have solid wifi everywhere clients | |
| # will constantly be disconnected | |
| IFS=$'\n' | |
| while true; do | |
| for LINE in $(iwinfo wlan0 assoclist | grep SNR); do | |
| MAC=$(echo "$LINE" | awk '{ print $1 }') | |
| SIGNAL=$(echo "$LINE" | awk '{ print $2 }') | |
| MAC_PREFIX=$(echo "$MAC" | sed -e 's/://g' | cut -c1-6) | |
| if [ "$SIGNAL" -lt "-80" ]; then | |
| if find . | grep "angry_wifi_client_$MAC" > /dev/null; then | |
| date ; logger -s -t angry_wifi "Low signal client $MAC ($SIGNAL) is back, not disconnecting yet." | |
| # Only allow Apple devices to roam | |
| elif grep "$MAC_PREFIX" apple_mac_addresses; then | |
| date ; logger -s -t angry_wifi "Low signal client $MAC ($SIGNAL) being disconnected." | |
| ubus call hostapd.wlan0 del_client "{'addr':'$MAC', 'reason':5, 'deauth':false, 'ban_time':0}" | |
| # Add to do-not-disconnect list | |
| touch "angry_wifi_client_${MAC}_$(date +%s)" | |
| fi | |
| fi | |
| done | |
| # Remove from the do-not-disconnect list | |
| CURDATE=$(date +%s) | |
| for FILE in $(find . | grep angry_wifi_client); do | |
| TIME=$(echo "$FILE" | cut -d'_' -f 5) | |
| TIME_SINCE=$((CURDATE - TIME)) | |
| MAC=$(echo "$FILE" | cut -d'_' -f 4) | |
| if [ "$TIME_SINCE" -gt "60" ]; then | |
| date ; logger -s -t angry_wifi "Low signal client $MAC removed from do-not-disconnect." | |
| rm "$FILE" | |
| fi | |
| done | |
| sleep 1 | |
| done |
only Apple clients will be disconnected
Why is that?
Thanks
I needed something more robust, so I got concepts from this gist and https://github.com/mk248/lede-modhostapd and created a pure-Lua script that uses /etc/config/wireless, taking signal OR signal-noise-ratio, supports whitelists (like Apple devices), blacklists and is a bit more efficient, not touching the filesystem to persist state.
https://github.com/barbieri/barbieri-playground/tree/master/openwrt/wifi-disconnect-low-signal
however I really hope OpenWRT/LEDE will integrate the modhostapd patch, then we can avoid an extra process in the system.
SMART ROAMING – KOMPLETTE REBUILD-ANLEITUNG (OpenWrt 25 + APK + LuCI)
🧹 1. ALLES ALTEN KRAM LÖSCHEN (CLEAN RESET)
rm -f /root/smart_roam.sh
rm -rf /usr/share/ucode/luci/controller/smartroam.uc
rm -rf /www/luci-static/resources/view/smartroam.js
🧱 2. UCI KONFIG ERSTELLEN
cat > /etc/config/smart_roam << 'EOF'
config smart_roam 'cfg1'
option threshold_24 '-80'
option threshold_5 '-83'
option cooldown '60'
EOF
🔧 3. SMART ROAM SCRIPT (WLAN KICK LOGIK)
cat > /root/smart_roam.sh << 'EOF'
#!/bin/sh
CONFIG_24=$(uci get smart_roam.cfg1.threshold_24 2>/dev/null)
CONFIG_5=$(uci get smart_roam.cfg1.threshold_5 2>/dev/null)
COOLDOWN=$(uci get smart_roam.cfg1.cooldown 2>/dev/null)
THRESHOLD_24="${CONFIG_24:- -80}"
THRESHOLD_5="${CONFIG_5:- -83}"
COOLDOWN="${COOLDOWN:-60}"
INTERVAL=5
STATE_FILE="/tmp/smart_roam_state"
touch "$STATE_FILE"
get_threshold() {
echo "$1" | grep -q "phy1-ap0" && echo "$THRESHOLD_5" || echo "$THRESHOLD_24"
}
while true; do
for IFACE in phy0-ap0 phy1-ap0; do
iwinfo "$IFACE" assoclist 2>/dev/null | while read -r line; do
MAC=$(echo "$line" | awk '/[0-9A-Fa-f:]{17}/ {print $1}')
SIGNAL=$(echo "$line" | grep -oE '-[0-9]+' | head -n1)
[ -z "$MAC" ] && continue
[ -z "$SIGNAL" ] && continue
NOW=$(date +%s)
LAST=$(grep "$MAC" "$STATE_FILE" | awk '{print $2}')
[ -z "$LAST" ] && LAST=0
DIFF=$((NOW - LAST))
THRESHOLD=$(get_threshold "$IFACE")
if [ "$SIGNAL" -lt "$THRESHOLD" ] && [ "$DIFF" -gt "$COOLDOWN" ]; then
ubus call hostapd."$IFACE" del_client "{\"addr\":\"$MAC\",\"reason\":5,\"deauth\":true}"
sed -i "/$MAC/d" "$STATE_FILE"
echo "$MAC $NOW" >> "$STATE_FILE"
fi
done
done
sleep "$INTERVAL"
done
EOF
⚙️ 4. SCRIPT STARTBAR MACHEN
chmod +x /root/smart_roam.sh
🚀 5. UCI TEST (OPTIONAL CHECK)
uci show smart_roam
🌐 6. LUCI SMART ROAM PANEL (SLIDER UI)
mkdir -p /www/luci-static/resources/view
cat > /www/luci-static/resources/view/smartroam.js << 'EOF'
'use strict';
'require view';
'require form';
'require uci';
return view.extend({
load: function() {
return uci.load('smart_roam');
},
render: function() {
var m = new form.Map('smart_roam', 'Smart Roaming');
var s = m.section(form.NamedSection, 'cfg1', 'smart_roam');
var o1 = s.option(form.Value, 'threshold_24', '2.4 GHz RSSI');
o1.datatype = 'range(-100,-30)';
var o2 = s.option(form.Value, 'threshold_5', '5 GHz RSSI');
o2.datatype = 'range(-100,-30)';
var o3 = s.option(form.Value, 'cooldown', 'Cooldown Sekunden');
return m.render();
}
});
EOF
🔄 7. LUCI + WEB SERVER NEU STARTEN
/etc/init.d/rpcd restart
/etc/init.d/uhttpd restart
🌐 8. WEB UI ÖFFNEN
http://ip....../cgi-bin/luci/admin/network/smartroam
⚡ ERGEBNIS
Du hast danach:
✔ Smart Roaming Script aktiv
✔ Web Slider für RSSI
✔ Cooldown steuerbar
✔ keine Terminal Arbeit nötig
✔ sofort wirksame Änderungen
🧠 WENN DU ES NOCH ROBUSTER WILLST
Dann kann ich dir noch bauen:
🔥
Auto-Start Service (Boot persistent)
🔥
Live Client Dashboard
🔥
„Sticky Client Protection“
🔥
echtes Band Steering (kein Kick mehr)
Sag einfach:
👉 pro panel
Dann wird dein Router ein kleiner Enterprise WiFi Controller 👍
i did that with chat gpt and after 2h hard work with this fuckin ki it fianlly work
OpenWrt Smart Roaming – Schritt-für-Schritt
Anleitung
Diese Anleitung erklärt Schritt für Schritt die Installation eines Smart Roaming Systems auf OpenWrt (WR3000H).
Alle Befehle werden im SSH-Terminal ausgeführt. Nach jedem Befehl ENTER drücken.
im Terminal:
-> ssh root@ IP router
- ALTE DATEIEN ENTFERNEN - beim ersten mal kann man das weg lassen, und falls was schief geht hier anfangen
Befehl:
rm -f /root/smart_roam.sh
rm -rf /www/luci-static/resources/view/smartroam.js
ENTER drücken nach jeder Zeile.
- UCI KONFIG ERSTELLEN
cat > /etc/config/smart_roam << 'EOF'
config smart_roam 'cfg1'
option threshold_24 '-80'
option threshold_5 '-83'
option cooldown '60'
EOF
ENTER nach EOF.
- SMART ROAM SCRIPT ERSTELLEN
cat > /root/smart_roam.sh << 'EOF'
#!/bin/sh
CONFIG_24=$(uci get smart_roam.cfg1.threshold_24 2>/dev/null)
CONFIG_5=$(uci get smart_roam.cfg1.threshold_5 2>/dev/null)
COOLDOWN=$(uci get smart_roam.cfg1.cooldown 2>/dev/null)
THRESHOLD_24="${CONFIG_24:- -80}"
THRESHOLD_5="${CONFIG_5:- -83}"
COOLDOWN="${COOLDOWN:-60}"
INTERVAL=5
STATE_FILE="/tmp/smart_roam_state"
touch "$STATE_FILE"
get_threshold() {
echo "$1" | grep -q "phy1-ap0" && echo "$THRESHOLD_5" || echo "$THRESHOLD_24"
}
while true; do
for IFACE in phy0-ap0 phy1-ap0; do
iwinfo "$IFACE" assoclist 2>/dev/null | while read -r line; do
MAC=$(echo "$line" | awk '/[0-9A-Fa-f:]{17}/ {print $1}')
SIGNAL=$(echo "$line" | grep -oE '-[0-9]+' | head -n1)
[ -z "$MAC" ] && continue
[ -z "$SIGNAL" ] && continue
NOW=$(date +%s)
LAST=$(grep "$MAC" "$STATE_FILE" | awk '{print $2}')
[ -z "$LAST" ] && LAST=0
DIFF=$((NOW - LAST))
THRESHOLD=$(get_threshold "$IFACE")
if [ "$SIGNAL" -lt "$THRESHOLD" ] && [ "$DIFF" -gt "$COOLDOWN" ]; then
ubus call hostapd."$IFACE" del_client "{"addr":"$MAC","reason":5,"deauth":true}"
sed -i "/$MAC/d" "$STATE_FILE"
echo "$MAC $NOW" >> "$STATE_FILE"
fi
done
done
sleep "$INTERVAL"
done
EOF
- SCRIPT STARTBAR MACHEN
chmod +x /root/smart_roam.sh
- STARTEN
/root/smart_roam.sh &
- WEB INTERFACE (LUCI)
Im Browser öffnen:
http://192.168.0.1/cgi-bin/luci/admin/network/smartroam
- WICHTIG
- Änderungen im Web wirken sofort
- Keine Neustarts nötig
- Werte steuern WLAN Verhalten automatisch
Thanks for sharing this. Was looking to hack up something similar and google pointed me to you :)