当n I heard that they're gonna make LEDs non-programmable I was like HELL NO. And decided to do what MikroTik probably should do from very beginning - simulate faster LEDs in software to keep best of both worlds - programmable LEDs AND fast blinking LEDs. I'm aware it's not really "correct" solution because it kinda... makes up data basing on 1s interval read but I hope many people will still find it useful. Current implementation of LEDs in CRS3xx switches blinks like once every 2 seconds so sometimes it's really hard to tell whether there's actually any traffic since it's easy to miss that 1 blink every 2 seconds lol...
So here's code. LED blinker for sfp ports (CRS317, CRS326)
Code:Select all
add name=ledblinkersfp source="/interface ethernet\ \n\ \n:local cycletime 1000\ \n:local cyclenum 2\ \n:local blinkpercycle 8\ \n:local blinkparts 3\ \n:local ifmatch \"sfp-sfpplus\"\ \n:local instance \"ledblinkersfp\"\ \n:local ledsuffix \"-led1\"\ \n\ \n######\ \n\ \n\ \n:local pstat ({})\ \n\ \n:while ([:len [/system script job find script=\$instance]] = 1) do={\ \n\ \n :local iflst [find name~(\$ifmatch) running=yes]\ \n :local ledlst ({})\ \n\ \n :local blinkshort (\$cycletime / \$blinkpercycle)\ \n :local blinkshortoff (\$blinkshort / \$blinkparts)\ \n :local blinkshorton (\$blinkshortoff * (\$blinkparts -1))\ \n\ \n :local realblinkshorton (\$blinkshorton - 50)\ \n :if (\$realblinkshorton < 0) do={\ \n :set realblinkshorton 0\ \n }\ \n\ \n /system leds set [find name~(\$ifmatch) running=no] type=interface-activity\ \n :if ([:len \$iflst] != [:len \$pstat]) do={\ \n :set pstat ({})\ \n :foreach counter=i in=\$iflst do={\ \n :set pstat (\$pstat,\"0/0\")\ \n }\ \n }\ \n\ \n :foreach counter=k,i in=\$iflst do={\ \n :local iname [get \$i name] \ \n :local iled [/system leds find leds=(\$iname.\$ledsuffix)]\ \n :set ledlst (\$ledlst, \$iled)\ \n }\ \n\ \n\ \n :for counter=loop from=1 to=\$cyclenum do={ \ \n :local cstat ({})\ \n :local blinklst ({})\ \n\ \n :foreach counter=k,i in=\$iflst do={\ \n :local istat ([get \$i rx-bytes].\"/\".[get \$i tx-bytes])\ \n :local iled (\$ledlst->\$k)\ \n :set cstat (\$cstat, \$istat)\ \n :if (\$istat != (\$pstat->\$k)) do={\ \n :set blinklst (\$blinklst, (\$iled))\ \n }\ \n }\ \n :for counter=i from=0 to=(\$cycletime / \$blinkshort - 1) do={\ \n :if (\$i = 0) do={\ \n :delay delay-time=((\$realblinkshorton).\"ms\")\ \n } else={\ \n :delay delay-time=((\$blinkshorton).\"ms\")\ \n }\ \n\ \n :foreach counter=j in=\$blinklst do={\ \n /system leds set \$j type=off\ \n }\ \n :delay delay-time=((\$blinkshortoff).\"ms\")\ \n :foreach counter=j in=\$blinklst do={\ \n /system leds set \$j type=on\ \n }\ \n }\ \n :set pstat \$cstat\ \n }\ \n}"
For LED blinker for ether ports (CRS326 only) you only need to change script name to "ledblinkereth" and change variables on top of script to:
Code:Select all
\n:local ifmatch \"ether\"\ \n:local instance \"ledblinkereth\"\ \n:local ledsuffix \"-led\"\
Here's script to reset all LEDs back to "interface-activity" type if someone doesn't want to use script anymore:
Code:Select all
add name=ledreset source="/interface ethernet\ \n\ \n:local ledsuffix \"-led1\"\ \n:local iflst [find name~\"sfp-sfpplus\"]\ \n\ \n:foreach counter=k,i in=\$iflst do={\ \n :local iname [get \$i name]\ \n :local iled [/system leds find leds=(\$iname.\$ledsuffix)]\ \n :put (\"Reset: \".[/system leds get \$iled leds])\ \n /system leds set \$iled type=interface-activity\ \n}\ \n"
Script comes with some defaults I found reasonable but if you want, blinking speed and behavior is configurable. How to configure it:
- :local cycletime 1000 <- time between interface stats probing. By default 1000ms since CRS3xx chip reports rx and tx bytes only once every second
- :local cyclenum 2 <- how many probe cycles will be performed before interface details will be refreshed (number of cycles before eg. interface down will be noticed. By default 2 seconds)
- :local blinkpercycle 8 <- how many times LED will blink during single cycle (during 1 second by default)
- :local blinkparts 3 <- ratio of LED on / LED off for each blink. By default 1/3 time LED is off and 2/3 time it's on
- :local ifmatch "sfp-sfpplus" <- pattern for interface match
- :local instance "ledblinkersfp" <- name of script as you added it in /system script (script uses it to determine whether script is already running as job. Each instance of blinker has to use unique name eg. ledblinkersfp and ledblinkereth for CRS326)
- :local ledsuffix "-led1" <- suffix that has to be added to interface name to find matching LED.