小米WR30U上面有個“Mesh”按鈕,但是刷了 OpenWRT的 Ups-WR30U 這個按鈕有什麼用呢?答案是:你想怎麼用就怎麼用!OpenWRT中按鈕的功能是可以自定義的!本文就和你分享OpenWRT自定義機身按鍵功能的方法,可以說是發揮 OpenWRT 強大客製化自由度的典範。
題外話:在搜集資料的時候竟然找到自己10年前的文章:OpenWRT、dd-wrt自設定路由按鈕功能,而且我完全忘了自己寫過。。。看裡面的內容,嗯,我這十年是有進步的。
摘要節點
OpenWRT自定義按鍵功能的思路
在OpenWRT中自定義按鍵功能的思路有兩種:
路由器按鍵類型 | 客製化功能方法 |
已預設的按鈕 例如 RESET | 修改已有的 /etc/rc.button/ 中的代碼 |
未使用的按鈕 例如 MESH | 定義按鈕並添加腳本代碼 |
Ups-WR30U的「Mesh」就屬於第二種按鈕,根據官網的WIKI:[OpenWrt Wiki] Attach functions to a push button,爲這個按鈕定義按鍵功能需要兩個步驟:
- 找到按鈕的編號
- 定義按鈕的功能
必須掌握的OpenWRT工具
本文有兩個工具/技能是必須要學的,第一是 命令行操作 OpenWRT,可以透過 Ups-WR30 已預裝的 Terminal 功能,在 192.168.0.1 的控制後臺選 Services -> Terminal
:
還有就是要會修改 OpenWRT 系統裡面文件,建議使用WinSCP這個免費軟件 WinSCP :: Official Site :: Download:
找到OpenWRT按鈕編號的方法
如果你是使用WR30U就不用再找按鈕編號了,網上已經有資料提示了「Mesh」的號碼是 BTN-9 。你可以直接跳到下一段。
如果不知道按鍵號碼,請岸OpenWRT的WIKI教在 SSH 或 Terminal 運行這段代碼:
# 安裝插件
opkg update
opkg install kmod-button-hotplug
# 新建目錄
mkdir -p /etc/hotplug.d/button
# 寫入以下內容到 /etc/hotplug.d/button/buttons 文件,直至遇到"EOF"停止
cat << "EOF" > /etc/hotplug.d/button/buttons
logger "the button was ${BUTTON} and the action was ${ACTION}"
EOF
這個代碼分成三個部分:
- 安裝
kmod-button-hotplug
插件 - 創建一個叫 button的目錄
- 寫入
logger
命令串 爲button文件的內容,讓系統記錄按鍵時候的動作
完成後,在 SSH 或 Terminal 輸入 logread
會看到:
Jan 1 00:01:15 OpenWrt user.notice root: the button was BTN_9 and the action was pressed
就能找到對應的 BTN_X 號碼和動作(pressed/released)。
OpenWRT自定義按鍵功能
找到了按鍵編號,要給他安排按鍵功能的方法,按照WIKI在 SSH 或 Terminal 運行這段代碼:
cat << "EOF" > /etc/hotplug.d/button/00-button
source /lib/functions.sh
do_button () {
local button
local action
local handler
local min
local max
config_get button "${1}" button
config_get action "${1}" action
config_get handler "${1}" handler
config_get min "${1}" min
config_get max "${1}" max
[ "${ACTION}" = "${action}" -a "${BUTTON}" = "${button}" -a -n "${handler}" ] && {
[ -z "${min}" -o -z "${max}" ] && eval ${handler}
[ -n "${min}" -a -n "${max}" ] && {
[ "${min}" -le "${SEEN}" -a "${max}" -ge "${SEEN}" ] && eval ${handler}
}
}
}
config_load system
config_foreach do_button button
EOF
uci add system button
uci set system.@button[-1].button="BTN_9"
uci set system.@button[-1].action="pressed"
uci set system.@button[-1].handler="logger this is a BTN_9 pressed handler command"
uci commit system
這段代碼的分兩個部分:
- 創建一個 00-button 的腳本,裡面定義了按鈕的動作,包括按下、鬆開、以及”長按秒數“
- 通過 uci 命令給系統添加按鍵(BTN_9)和對應的動作(pressed)和功能(logger BTN_9 pressed)
這樣操作後,你再用logread 應該能看到:
Jan 1 00:01:15 OpenWrt user.notice root: this is a BTN_9 pressed handler command
下面,我們只需要修改 uci set system.@button[-1].handler=
這句的命令,就能讓 BTN_9 按下去執行我們需要的功能。
Mesh按鈕變WIFI開關
OpenWRT中只需要在 SSH 或 Terminal 運行這段代碼輸入一句命令: wifi down
,WIFI信號就會關閉。所以我們可以嘗試:
uci set system.@button[-1].handler="wifi down"
uci commit system
這時候你按一下WR30U上的「Mesh」,WIFI信號就會關閉。成功的話就說明腳本已經生效。
但如何開WIFI呢?我們可以定義”長按“(3秒以上)爲打開WIFI (wifi up)在 SSH 或 Terminal 運行這段代碼:
uci add system button
uci set system.@button[-1].button="BTN_9"
uci set system.@button[-1].action="released"
uci set system.@button[-1].handler="wifi up"
uci set system.@button[-1].min="3"
uci set system.@button[-1].max="10"
uci commit system
這樣子你就有了一個按一下關WIFI,長按開WIFI的「Mesh」按鈕!
OpenWRT不僅支持按鍵執行單句命令,還可以執行腳本,這樣子就可以加入判斷語句,讓你只需要按一下就能「切換」WIFI的開關,不需要記住是長按還是短按,在 SSH 或 Terminal 運行這段代碼:
uci add system button
uci set system.@button[-1].button="BTN_9"
uci set system.@button[-1].action="released"
uci set system.@button[-1].handler="/usr/bin/wifionoff"
uci set system.@button[-1].min="0"
uci set system.@button[-1].max="3"
uci commit system
cat << "EOF" > /usr/bin/wifionoff
#!/bin/sh
STATEFILE="/tmp/wifionoff.state"
if [ "${#}" -eq 1 ]; then
case "${1}" in
"up"|"on") GOAL="on" ;;
"down"|"off") GOAL="off" ;;
esac
else
if [ -e "${STATEFILE}" ]; then
GOAL="on"
else
# if the statefile doesn't exist, turn wifi off
GOAL="off"
fi
fi
if [ "${GOAL}" = "off" ]; then
/sbin/wifi down
touch "${STATEFILE}"
else
/sbin/wifi up
# file may not exist if we're given args
rm "${STATEFILE}" 2> /dev/null || true
fi
EOF
chmod u+x /usr/bin/wifionoff
這段代碼的意思是:
- 按下BTN_9的時候執行 /usr/bin/wifionoff
- 寫入代碼到 /usr/bin/wifionoff
[OpenWrt Wiki] 上還有好幾個開關WIFI的腳本,使用上文這個 wifi up 和 wifi down 而不是 wireless.radio.disable 的原因是他重啓之後會恢復到有WIFI的狀態,而 wireless.radio.disable 重啓只有不會自動開啓wifi (如果之前已經關閉)。
Mesh按鈕變2.4G WIFI開關
因爲小U家的無線設備都支援5Ghz WIFI,只有部Brother Laser Printer只支援2.4Ghz WIFI,所以我家的2.4Ghz是長期關閉,避免無謂的WIFI輻射,只有在要打印時候才會開2.4Ghz WIFI。那麼正好WR30U上面的這個按鈕就設定爲2.4Ghz WIFI的開關吧!
但是要單獨控制2.4Ghz WIFI用 wifi radio0 up / down 這個命令有時候會影響到 5Ghz,不知道爲什麼,所以經過研究,小U自己寫了以下的腳本,而且可以和luci網頁界面的聯動,不會出現按鈕生效了但是luci頁面不同步、控制不了的問題(因爲luci的enable/disable是同時控制 device和interface)。按鈕腳本如下:
#!/bin/sh
ISTATUS="$(uci -q get wireless.default_radio0.disabled)"
DSTATUS="$(uci -q get wireless.radio0.disabled)"
if [ "${ISTATUS}" = "1" ] && [ "${DSTATUS}" = "1" ]; then
uci del wireless.default_radio0.disabled
uci del wireless.radio0.disabled
wifi reload
else
uci set wireless.default_radio0.disabled='1'
uci set wireless.radio0.disabled='1'
wifi reload
fi
EOF
因爲使用了wireless.xxx.disabled,所以需要加一個重啓時候確保2.4G WIFI狀態的boot/init script,這個script是放在 /etc/init.d/
目錄。並且通過 /etc/init.d/xxx enable
來實現啓動自動執行 :
#!/bin/sh /etc/rc.common
# Example script
# Copyright (C) 2007 OpenWrt.org
START=100
STOP=15
start() {
echo start
uci set wireless.default_radio0.disabled='1'
uci set wireless.radio0.disabled='1'
wifi reload
}
stop() {
echo stop
# commands to kill application
}
但是一測試,怎麼不行?開機了2.4G WIFI依然“健在”?原來Init.d的腳本是在啓動過程中進行(也就是在WIFI啓動之前)所以不能用在init.d,而是要加在 /etc/rc.local 中。修改 /etc/rc.local :
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
logger start rc local
/etc/wifi2goffdelay
exit 0
然後將 /etc/wifi2goffdelay 改爲:
logger wait 60s to disable 2.4g wifi
sleep 60
uci set wireless.default_radio0.disabled='1'
uci set wireless.radio0.disabled='1'
wifi reload
logger 2.4g wifi is disable
我加入了logger來追蹤腳本運行的情況,可以在 System log中看到記錄:
到此你應該感受到,OpenWRT是允許你添加任何命令、任何想法到這個小小的按鈕上。甚至如果你嫌按鈕不夠,還能夠定義外接鍵盤的功能!有誰能想到有什麼實際應用例子呢?
結尾:
本文是小U的「玩開源、從OpenWRT開始」系列文章的其中一篇。自從Ups-WR30U開源路由器得到大家的熱烈支持,小U也收到了客戶的各種使用OpenWRT的問題查詢,順勢就着手把大家會遇到的,想要用的,都集結成這個系列的文章,希望讓各位從OpenWRT體驗和玩樂開源系統。不需要靠AI,你就能讓路由器變得更”聰明“!
- OpenWRT路由器WiFi名、密碼、速度的設定教學
- OpenWRT使用TailScale VPN教學
- 擋廣告神器「AdguardHome」在OpenWRT上使用方法教學
- 用OpenWRT劃分出訪客Guest LAN、隔離外網伺服器的兩種方法(不是無線訪客WIFI)
- OpenWRT防火牆:限制IP訪問Internet的最佳設置方法(無需打命令行)
- 一鍵連回家里內網:OpenWRT上部署Wireguard VPN服務器的三個要點、減少折騰時間
如果你還未有OpenWRT路由器,不妨從 Ups-WR30U 上手吧: