What's new

ChannelHog - Monitor And Force Maximum 5GHz Bandwidth

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Keep in mind that the log may not always show "Radar detected". Nine out of 10 times I see wl_chanspec_changed_action as the only entry prior to a channel change.

So users that use the script above may want to consider that grep term.

Before coming across @ColinTaylor 's script, I was testing out an email notification of channel change using several hacks including pruning the log after grepping the chanspec entry. But his is so much more elegant.
I modified the code to check for both 'Radar detected' and 'wl_chanspec_changed_action' and use the timestamp of the most current. I haven't run this through extensive testing yet but so far haven't seen any issues.

Bash:
#Check log for 'Radar detected' and 'wl_chanspec_changed_action' before wifi is taken Up/Down.
lastRadarFoundLine="$(grep "Radar detected" /tmp/syslog.log | tail -1)"
lastChanChangeLine="$(grep "wl_chanspec_changed_action" /tmp/syslog.log | tail -1)"

if [ "$restart5ghz1" = "true" ]; then  
    logger -st ChannelHog "[*] $currentbandwidth Channel Width Detected - Restarting ${restartradio} Radio"
    wl -i "$port5ghz1" down
    wl -i "$port5ghz1" up
fi
if [ "$restart5ghz2" = "true" ]; then
    logger -st ChannelHog "[*] $currentbandwidth Channel Width Detected - Restarting ${restartradio} Radio"
    wl -i "$port5ghz2" down
    wl -i "$port5ghz2" up
fi

#After down/up event
#Get targeted and current WIFI channel
#Currently only checks $port5ghz1.

targetChanSpec="$(nvram get wl1_chanspec)"
targetChan=${targetChanSpec%/*}
currentChanSpec="$(wl -i $port5ghz1 chanspec | awk '{print $1}')"
currentChan=${currentChanSpec%/*}

#Nested Function to get event time from log file
Get_ChanChange_Time () {
    local lastEventFoundLine="$1"
    if [ ! -z "$lastEventFoundLine" ]; then
        #Parse date from last event detected log line
        local lastEventFoundY="$(date +"%Y")"
        local lastEventFoundM="$(echo $lastEventFoundLine | awk '{print $1}')"              
        case $lastEventFoundM in
            Jan) MON="01" ;;
            Feb) MON="02" ;;
            Mar) MON="03" ;;
            Apr) MON="04" ;;
            May) MON="05" ;;
            Jun) MON="06" ;;
            Jul) MON="07" ;;
            Aug) MON="08" ;;
            Sep) MON="09" ;;
            Oct) MON="10" ;;
            Nov) MON="11" ;;
            Dec) MON="12" ;;
        esac  
        local lastEventFoundM=$MON
        local lastEventFoundD="$(echo $lastEventFoundLine | awk '{print $2}')"
        local lastEventFoundT="$(echo $lastEventFoundLine | awk '{print $3}')"  
        local lastEventFoundCombined="$(date +%s -d "$(echo $lastEventFoundY"."$lastEventFoundM"."$lastEventFoundD"-"$lastEventFoundT)")"

        #No year is listed in log so apply current year as a work-around. If combined found date is greater than current date then change year to previous year.
        local currentTime=$(date +%s)          
        if [ "$lastEventFoundCombined" -gt "$currentTime" ]; then
            local lastEventFoundPY=$((lastEventFoundY-1))
            local lastEventFoundCombinedPY="$(date +%s -d "$(echo $lastEventFoundPY"."$lastEventFoundM"."$lastEventFoundD"-"$lastEventFoundT)")"
            local lastEventFoundCombined=$lastEventFoundCombinedPY
        fi
        echo "$lastEventFoundCombined"
    fi              
}

#Compare if current channel differs from target channel
if [ "$targetChan" != "0" ] && [ "$currentChan" != "$targetChan" ]; then  
   
    #Select most current event  
    if [ ! -z "$lastRadarFoundLine" ]; then
        lastRadarFoundCombined=$(Get_ChanChange_Time "$lastRadarFoundLine")
    else
        lastRadarFoundCombined="0"
    fi
    if [ ! -z "$lastChanChangeLine" ]; then
        lastCCFoundCombined=$(Get_ChanChange_Time "$lastChanChangeLine")
    else
        lastCCFoundCombined="0"
    fi

    if [ "$lastRadarFoundCombined" -eq "0" ] && [ "$lastCCFoundCombined" -eq "0" ]; then
        lastEventTime=""
    elif [ "$lastRadarFoundCombined" -ge "$lastCCFoundCombined" ]; then
        lastEventTime=$lastRadarFoundCombined
    elif [ "$lastRadarFoundCombined" -lt "$lastCCFoundCombined" ]; then
        lastEventTime=$lastCCFoundCombined          
    fi
   
    if [ ! -z "$lastEventTime" ]; then      
        #Restart wireless if greater than 30 minutes from last radar detection or channel change event
        currentTime30M=$(date +%s -d@"$(( `date +%s`-30*60))")
        if [ "$lastEventTime" -ge "$currentTime30M" ]; then
            logger -st ChannelHog "[*] Channel (${currentChan}) can't switch back yet as still in Non-Occupancy Period."
        else
            logger -st ChannelHog "[*] Channel has changed from ${targetChan} to ${currentChan}. Restarting WiFi."
            service restart_wireless
        fi
    fi          
fi
 
Last edited:
Being able to modify, configure 160Mhz and DFS on my AIMesh nodes AX86) has me seriously considering starting from scratch and making them AP’s instead (Ethernet backhaul)

But haven’t found anything on the pro/cons of both modes or if the AP’s use the same SSID, channel’s will roaming between the three (router, node 1 and node 2) will be as transparent as it is under the AiMesh setup.

Any thoughts/opinions?
 
I modified the code to check for both 'Radar detected' and 'wl_chanspec_changed_action' and use the timestamp of the most current. I haven't run this through extensive testing yet but so far haven't seen any issues.

Bash:
#Check log for 'Radar detected' and 'wl_chanspec_changed_action' before wifi is taken Up/Down.
lastRadarFoundLine="$(grep "Radar detected" /tmp/syslog.log | tail -1)"
lastChanChangeLine="$(grep "wl_chanspec_changed_action" /tmp/syslog.log | tail -1)"

if [ "$restart5ghz1" = "true" ]; then  
    logger -st ChannelHog "[*] $currentbandwidth Channel Width Detected - Restarting ${restartradio} Radio"
    wl -i "$port5ghz1" down
    wl -i "$port5ghz1" up
fi
if [ "$restart5ghz2" = "true" ]; then
    logger -st ChannelHog "[*] $currentbandwidth Channel Width Detected - Restarting ${restartradio} Radio"
    wl -i "$port5ghz2" down
    wl -i "$port5ghz2" up
fi

#After down/up event
#Get targeted and current WIFI channel
#Currently only checks $port5ghz1.

targetChanSpec="$(nvram get wl1_chanspec)"
targetChan=${targetChanSpec%/*}
currentChanSpec="$(wl -i $port5ghz1 chanspec | awk '{print $1}')"
currentChan=${currentChanSpec%/*}

#Nested Function to get event time from log file
Get_ChanChange_Time () {
    local lastEventFoundLine="$1"
    if [ ! -z "$lastEventFoundLine" ]; then
        #Parse date from last event detected log line
        local lastEventFoundY="$(date +"%Y")"
        local lastEventFoundM="$(echo $lastEventFoundLine | awk '{print $1}')"              
        case $lastEventFoundM in
            Jan) MON="01" ;;
            Feb) MON="02" ;;
            Mar) MON="03" ;;
            Apr) MON="04" ;;
            May) MON="05" ;;
            Jun) MON="06" ;;
            Jul) MON="07" ;;
            Aug) MON="08" ;;
            Sep) MON="09" ;;
            Oct) MON="10" ;;
            Nov) MON="11" ;;
            Dec) MON="12" ;;
        esac  
        local lastEventFoundM=$MON
        local lastEventFoundD="$(echo $lastEventFoundLine | awk '{print $2}')"
        local lastEventFoundT="$(echo $lastEventFoundLine | awk '{print $3}')"  
        local lastEventFoundCombined="$(date +%s -d "$(echo $lastEventFoundY"."$lastEventFoundM"."$lastEventFoundD"-"$lastEventFoundT)")"

        #No year is listed in log so apply current year as a work-around. If combined found date is greater than current date then change year to previous year.
        local currentTime=$(date +%s)          
        if [ "$lastEventFoundCombined" -gt "$currentTime" ]; then
            local lastEventFoundPY=$((lastEventFoundY-1))
            local lastEventFoundCombinedPY="$(date +%s -d "$(echo $lastEventFoundPY"."$lastEventFoundM"."$lastEventFoundD"-"$lastEventFoundT)")"
            local lastEventFoundCombined=$lastEventFoundCombinedPY
        fi
        echo "$lastEventFoundCombined"
    fi              
}

#Compare if current channel differs from target channel
if [ "$targetChan" != "0" ] && [ "$currentChan" != "$targetChan" ]; then  
   
    #Select most current event  
    if [ ! -z "$lastRadarFoundLine" ]; then
        lastRadarFoundCombined=$(Get_ChanChange_Time "$lastRadarFoundLine")
    else
        lastRadarFoundCombined="0"
    fi
    if [ ! -z "$lastChanChangeLine" ]; then
        lastCCFoundCombined=$(Get_ChanChange_Time "$lastChanChangeLine")
    else
        lastCCFoundCombined="0"
    fi

    if [ "$lastRadarFoundCombined" -eq "0" ] && [ "$lastCCFoundCombined" -eq "0" ]; then
        lastEventTime=""
    elif [ "$lastRadarFoundCombined" -ge "$lastCCFoundCombined" ]; then
        lastEventTime=$lastRadarFoundCombined
    elif [ "$lastRadarFoundCombined" -lt "$lastCCFoundCombined" ]; then
        lastEventTime=$lastCCFoundCombined          
    fi
   
    if [ ! -z "$lastEventTime" ]; then      
        #Restart wireless if greater than 30 minutes from last radar detection or channel change event
        currentTime30M=$(date +%s -d@"$(( `date +%s`-30*60))")
        if [ "$lastEventTime" -ge "$currentTime30M" ]; then
            logger -st ChannelHog "[*] Channel (${currentChan}) can't switch back yet as still in Non-Occupancy Period."
        else
            logger -st ChannelHog "[*] Channel has changed from ${targetChan} to ${currentChan}. Restarting WiFi."
            service restart_wireless
        fi
    fi          
fi
It is nice to see community work at play here! I see it has gotten @Adamm attention. Awesome work!
 
  • Like
Reactions: ika
I modified the code to check for both 'Radar detected' and 'wl_chanspec_changed_action' and use the timestamp of the most current. I haven't run this through extensive testing yet but so far haven't seen any issues.

Bash:
#Check log for 'Radar detected' and 'wl_chanspec_changed_action' before wifi is taken Up/Down.
lastRadarFoundLine="$(grep "Radar detected" /tmp/syslog.log | tail -1)"
lastChanChangeLine="$(grep "wl_chanspec_changed_action" /tmp/syslog.log | tail -1)"

if [ "$restart5ghz1" = "true" ]; then 
    logger -st ChannelHog "[*] $currentbandwidth Channel Width Detected - Restarting ${restartradio} Radio"
    wl -i "$port5ghz1" down
    wl -i "$port5ghz1" up
fi
if [ "$restart5ghz2" = "true" ]; then
    logger -st ChannelHog "[*] $currentbandwidth Channel Width Detected - Restarting ${restartradio} Radio"
    wl -i "$port5ghz2" down
    wl -i "$port5ghz2" up
fi

#After down/up event
#Get targeted and current WIFI channel
#Currently only checks $port5ghz1.

targetChanSpec="$(nvram get wl1_chanspec)"
targetChan=${targetChanSpec%/*}
currentChanSpec="$(wl -i $port5ghz1 chanspec | awk '{print $1}')"
currentChan=${currentChanSpec%/*}

#Nested Function to get event time from log file
Get_ChanChange_Time () {
    local lastEventFoundLine="$1"
    if [ ! -z "$lastEventFoundLine" ]; then
        #Parse date from last event detected log line
        local lastEventFoundY="$(date +"%Y")"
        local lastEventFoundM="$(echo $lastEventFoundLine | awk '{print $1}')"             
        case $lastEventFoundM in
            Jan) MON="01" ;;
            Feb) MON="02" ;;
            Mar) MON="03" ;;
            Apr) MON="04" ;;
            May) MON="05" ;;
            Jun) MON="06" ;;
            Jul) MON="07" ;;
            Aug) MON="08" ;;
            Sep) MON="09" ;;
            Oct) MON="10" ;;
            Nov) MON="11" ;;
            Dec) MON="12" ;;
        esac 
        local lastEventFoundM=$MON
        local lastEventFoundD="$(echo $lastEventFoundLine | awk '{print $2}')"
        local lastEventFoundT="$(echo $lastEventFoundLine | awk '{print $3}')" 
        local lastEventFoundCombined="$(date +%s -d "$(echo $lastEventFoundY"."$lastEventFoundM"."$lastEventFoundD"-"$lastEventFoundT)")"

        #No year is listed in log so apply current year as a work-around. If combined found date is greater than current date then change year to previous year.
        local currentTime=$(date +%s)         
        if [ "$lastEventFoundCombined" -gt "$currentTime" ]; then
            local lastEventFoundPY=$((lastEventFoundY-1))
            local lastEventFoundCombinedPY="$(date +%s -d "$(echo $lastEventFoundPY"."$lastEventFoundM"."$lastEventFoundD"-"$lastEventFoundT)")"
            local lastEventFoundCombined=$lastEventFoundCombinedPY
        fi
        echo "$lastEventFoundCombined"
    fi             
}

#Compare if current channel differs from target channel
if [ "$targetChan" != "0" ] && [ "$currentChan" != "$targetChan" ]; then 
  
    #Select most current event 
    if [ ! -z "$lastRadarFoundLine" ]; then
        lastRadarFoundCombined=$(Get_ChanChange_Time "$lastRadarFoundLine")
    else
        lastRadarFoundCombined="0"
    fi
    if [ ! -z "$lastChanChangeLine" ]; then
        lastCCFoundCombined=$(Get_ChanChange_Time "$lastChanChangeLine")
    else
        lastCCFoundCombined="0"
    fi

    if [ "$lastRadarFoundCombined" -eq "0" ] && [ "$lastCCFoundCombined" -eq "0" ]; then
        lastEventTime=""
    elif [ "$lastRadarFoundCombined" -ge "$lastCCFoundCombined" ]; then
        lastEventTime=$lastRadarFoundCombined
    elif [ "$lastRadarFoundCombined" -lt "$lastCCFoundCombined" ]; then
        lastEventTime=$lastCCFoundCombined         
    fi
  
    if [ ! -z "$lastEventTime" ]; then     
        #Restart wireless if greater than 30 minutes from last radar detection or channel change event
        currentTime30M=$(date +%s -d@"$(( `date +%s`-30*60))")
        if [ "$lastEventTime" -ge "$currentTime30M" ]; then
            logger -st ChannelHog "[*] Channel (${currentChan}) can't switch back yet as still in Non-Occupancy Period."
        else
            logger -st ChannelHog "[*] Channel has changed from ${targetChan} to ${currentChan}. Restarting WiFi."
            service restart_wireless
        fi
    fi         
fi
You might want to look at this script that I posted. It also parses the syslog and calculates the time ($uptime) since the most recent of two events. You might be able to use the guts of that script to reduce your script's line count.
 
It is nice to see community work at play here! I see it has gotten @Adamm attention. Awesome work!

I’m very open to these kinds of collaborations and happy to see them. If it’s all polished by the time I get back home and the features make sense, I’d be happy to merge them.
 
Was this ever merge?
 
No one ever made a pull request and looks like @jb1187 hasn’t logged in for some time
I appreciate the response...I'm still using this nifty script. Wish I was smart enough to pull a request for this.
 
You say your script does a daily check to stabilize at 160mhz. But the AX86U downclocks more aggressively, once there is no 160mhz connection it will downclock quickly, so the script doesn't seem to solve the problem.
 
The same problem. AX86U
On the firmware Merlin 388.2_2 160mhz lasted ~ 3-4 days
On the firmware Merlin 3004.388.4 ~ 1-2 days.
I set up disabling wifi once a day for 15 minutes, it does not help.
Does it make sense to try this script?
 
Yes, try this script. I don't see how disabling WiFi for 15 minutes a day would help.

This has been working on my RT-AX86U since the script was released.
 
I don't think that is all this script does.
 
Tell me how to delete this script.
It is enough to delete /jffs/addons/channelhog/channelhog.sh ?
This script is completely useless for ax86u on Merlin 3004.388.4 firmware.
At 7:30 in the morning, the frequency was 80, although in the evening after installing the script, it rebooted and the frequency was 160.
 
Tell me how to delete this script.
It is enough to delete /jffs/addons/channelhog/channelhog.sh ?
This script is completely useless for ax86u on Merlin 3004.388.4 firmware.
At 7:30 in the morning, the frequency was 80, although in the evening after installing the script, it rebooted and the frequency was 160.

I think you misunderstand how ChannelHog works and what issue it was designed to solve rather than blindly disabling wifi every day.

Asus routers had a design flaw where if the channel width was downgraded to 80MHz it would never bump back to 160MHz on its own. ChannelHog solves this issue by running a daily cronjob that scans the current 5GHz channel, if the channel width is below 160Mhz the specific wireless radio will be restarted. I'm not sure how present this issue is on the latest generation of hardware as I no longer have issues with channel width to verify, but I can assure you from personal experience (hence the reason I made it) that the script does indeed solve the problem it was designed to.
 
You say your script does a daily check to stabilize at 160mhz. But the AX86U downclocks more aggressively, once there is no 160mhz connection it will downclock quickly, so the script doesn't seem to solve the problem.

For public release, I opted for a safer 24-hour cronjob. I can see the value in making this customizable for those who don't mind the disruption of wifi momentarily going down more frequently at home
 
after installing this script, the frequency 160 did not last even 3 hours, and does not rise.
It's better to tell me how to remove it :)
The best result was on the Merlin 388.2_2 firmware, where the frequency was stable for 3 days, without any scripts.

PS. Found the menu :)
 
Last edited:
I believe a better way to say this is:

”Even with the script installed, 160MHz dropped in under 3 hours - before the script could detect this. Trying the latest 388.2_2 firmware seems to have cured the non-resume 160MHz issue”
As @Adamm pointed out, it will only detect this drop once per day (in the middle of the night).
One could make it more aggressive - just change the cru a line for hourly or so.

I did use this successfully a while ago. I had an AX58U running as a Media Server. I did notice that every so often it would drop to 80MHz and stay there forever. With this script, it would bounce the wifi (it turns it off then on fairly quickly) and get me back to 160Mhz. BTW, I did modify the cru a line to have it check every 4 hours ;-)

From what I have been reading - firmware 388.2_2 seems to have fixed this usue. So, ChannelHog might not be needed in the future.
But, it is good insurance in case this “bug” in Asus firmware creeps in again…
 
For Asus AX86U, this does not work. I've been waiting for several days.
On other forums, they wrote that this problem was solved by switching to GT-AX6000, so most likely this is an Asus AX86U bug.
 
  • Like
Reactions: fsb
For Asus AX86U, this does not work. I've been waiting for several days.
On other forums, they wrote that this problem was solved by switching to GT-AX6000, so most likely this is an Asus AX86U bug.

How does it not work, please elaborate
 

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top