Yet Another wireless alignment script with LEDs and beeps

My company is testing the RB433/411 boards to see if we can’t use them as wireless CPE, and as part of that testing I wrote a script to monitor signal level and provide LED and audio feedback, without having to put the wireless interface into alignment mode. I plan on using it so that it launches on startup of the AP, to assist the installer during initial installation and alignment of the CPE.


Basic features are:

  • customizeable runtime (caveat: it’s fairly inaccurate, but still effective)
  • recognizes 9 different signal levels, each with it’s own LED patter and beep duration
  • recognizes 3 different association states (associated, searching, disabled/other), each
    association state also has its own unique LEDs and beeps
  • uses 4 of the 5 LED lights on RB411/433 boards for signal quality display
  • uses the “user-LED” (green LED above blue power LED) for signal association display.
  • plays startup/shutdown tones (mostly for fun I guess, heh)

I hope that someone out there would appreciate my efforts as well, so I’m posting it here for free use/criticism/whatever! It’s shown in “code” format below. Enjoy!

-= Mark Shumate
-= InfoWest

#
# Mikrotik RB411/433 "Lights and Sound" alignment script
# written by Mark Shumate Feb 2009
#
# NOTE: This script may work on other platforms, I
# don't have anything but RB411/433 here in front of
# me. The beeps will probably work on practically any
# wireless AP type Routerboard, but maybe the script
# would have to be edited? Dunno if it complains when
# you reference LEDs that don't exist...
#
# This script recognizes 9 different "signal levels"
# and 3 assoc. statuses (connected, searching, other)
# Currently, "signal levels" indicate the SNR/margin
# measurement. Higher signal-to-noise measurements
# correspond to higher levels. So level 8 would be
# the best, below 1 would be the worst. The better
# the signal-to-noise, the more LEDs you get, and
# the faster the beeps get. Only 4 LEDs are used,
# (the 5th being left alone, for NAND access ind.)
# with intermediate signal levels resulting in a
# combination of solid and flashing LEDs, shown
# here:
#
# >= Level 8 : 4 solid (100ms beeps)
# >= Level 7 : 3 solid, 4th flashing (300ms beeps)
# >= Level 6 : 3 solid (500ms beep cycle)
# >= Level 5 : 2 solid, 3rd flashing (700ms beeps)
# >= Level 4 : 2 solid (900ms beeps)
# >= Level 3 : 1 solid, 2nd flashing (1100ms beeps)
# >= Level 2 : 1 solid (1300ms beeps)
# >= Level 1 : 1 flashing (1500ms beeps)
# <  Level 1 : no LEDs, beeps only (1700ms beeps)
#
# The user-LED (green LED above the blue power LED)
# is used to display the association status. If the
# wireless interface is associated, the user-LED is
# solid. If the wireless interface is actively
# searching, but not yet associated, the user-LED is
# blinking twice a second, with a pause while a
# rising trill of 3 beeps is played. If the wireless
# interface is neither associated, nor searching
# (like disabled, or something weird) then the light
# will flicker rapidly every 2 seconds, and a
# falling trill of 2 beeps is played.

# Finally, the script plays startup (rising) and
# shutdown (falling) tones.

# For reference, the delay times associated with the
# different signal levels are shown here:
#:local lnsdelaytime 100ms;  <---signals at/above lvl 8
#:local lnsdelaytime 300ms;  <---signals between 7 and 8
#:local lnsdelaytime 500ms;  <---signals between 6 and 7
#:local lnsdelaytime 700ms;  <---signals between 5 and 6
#:local lnsdelaytime 900ms:  <---signals between 4 and 5
#:local lnsdelaytime 1100ms; <---signals between 3 and 4
#:local lnsdelaytime 1300ms; <---signals between 2 and 3
#:local lnsdelaytime 1500ms; <---signals between 1 and 2
#:local lnsdelaytime 1750ms; <---signals below lvl 1
#:local lnsdelaytime 2000ms; <---signal not available

# default delaytime
:local lnsdelaytime "2000ms";

# name of wireless interface to monitor (default wlan1)
:local lnsintname "wlan1";

# frequency (as in pitch) of beep (recommend 700 - 1000)
:local lnsbeepfreq 800;

# Here, the different signal levels are assigned to
# signal-to-noise measurements. I haven't really tweaked
# these yet to be in line with field testing, so they
# may need quite a bit of adjusting.
:local lnslevel8 70;
:local lnslevel7 65;
:local lnslevel6 60;
:local lnslevel5 55;
:local lnslevel4 50;
:local lnslevel3 45;
:local lnslevel2 40;
:local lnslevel1 35;

# The (veery approximate, heh) running time of the script
# is set here. I am too lazy right now to do this a
# better way...besides, who cares if the thing beeps or 
# flashes a couple extra minutes right?!? :)
:local lnsrunningtime 60m;

# Here, we set how long the script will beep. NOTE that
# startup/shutdown tones will still be played. 
# I like this feature when using an access point where
# the LEDs are clearly visible. If you don't want this
# feature, set it to the same as $lnsrunningtime
# (above).
:local lnsbeeptime 10m;

# figure out beep cutoff time
:local lnsrunbeepdiff;
:set lnsrunbeepdiff ($lnsrunningtime - $lnsbeeptime);


# initialize LEDs, play starting tones
:delay 50ms;
:led user-led=no led4=no led3=no led2=no led1=no;
:delay 50ms;
:beep frequency=($lnsbeepfreq - 300) length=50ms;
:delay 50ms;
:beep frequency=($lnsbeepfreq - 200) length=50ms;
:delay 50ms;

# main monitoring cycle
:while ($lnsrunningtime > 0s) do={
  /interface wireless monitor "$lnsintname" once do={
    :if ($"status" = "connected-to-ess") do={
      :if ($"signal-to-noise" >= $lnslevel8) do={
        :set lnsdelaytime 100ms;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=$lnsbeepfreq length=($lnsdelaytime / 2);
        }
        :led user-led=yes led4=yes led3=yes led2=yes led1=yes;
        :delay $lnsdelaytime;
      }
      :if ($"signal-to-noise" >= $lnslevel7 && $"signal-to-noise" < $lnslevel8) do={
        :set lnsdelaytime 300ms;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=$lnsbeepfreq length=($lnsdelaytime / 2);
        }
        :for i from=1 to=3 do={
          :led user-led=yes led4=no led3=yes led2=yes led1=yes;
          :delay ($lnsdelaytime / 6);
          :led user-led=yes led4=yes led3=yes led2=yes led1=yes;
          :delay ($lnsdelaytime / 6);
        }
      }
      :if ($"signal-to-noise" >= $lnslevel6 && $"signal-to-noise" < $lnslevel7) do={
        :set lnsdelaytime 500ms;
        :led user-led=yes led4=no led3=yes led2=yes led1=yes;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=$lnsbeepfreq length=($lnsdelaytime / 2);
        }
        :delay $lnsdelaytime;
      }
      :if ($"signal-to-noise" >= $lnslevel5 && $"signal-to-noise" < $lnslevel6) do={
        :set lnsdelaytime 700ms;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=$lnsbeepfreq length=($lnsdelaytime / 2);
        }
        :for i from=1 to=3 do={
          :led user-led=yes led4=no led3=no led2=yes led1=yes;
          :delay ($lnsdelaytime / 6);
          :led user-led=yes led4=no led3=yes led2=yes led1=yes;
          :delay ($lnsdelaytime / 6);
        }
      }
      :if ($"signal-to-noise" >= $lnslevel4 && $"signal-to-noise" < $lnslevel5) do={
        :set lnsdelaytime 900ms;
        :led user-led=yes led4=no led3=no led2=yes led1=yes;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=$lnsbeepfreq length=($lnsdelaytime / 2);
        }
        :delay $lnsdelaytime;
      }
      :if ($"signal-to-noise" >= $lnslevel3 && $"signal-to-noise" < $lnslevel4) do={
        :set lnsdelaytime 1100ms;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=$lnsbeepfreq length=($lnsdelaytime / 2);
        }
        :for i from=1 to=3 do={
          :led user-led=yes led4=no led3=no led2=no led1=yes;
          :delay ($lnsdelaytime / 6);
          :led user-led=yes led4=no led3=no led2=yes led1=yes;
          :delay ($lnsdelaytime / 6);
        }
      }
      :if ($"signal-to-noise" >= $lnslevel2 && $"signal-to-noise" < $lnslevel3) do={
        :set lnsdelaytime 1300ms;
        :led user-led=yes led4=no led3=no led2=no led1=yes;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=$lnsbeepfreq length=($lnsdelaytime / 2);
        }
        :delay $lnsdelaytime;
      }
      :if ($"signal-to-noise" >= $lnslevel1 && $"signal-to-noise" < $lnslevel2) do={
        :set lnsdelaytime 1500ms;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=$lnsbeepfreq length=($lnsdelaytime / 2);
        }
        :for i from=1 to=3 do={
          :led user-led=yes led4=no led3=no led2=no led1=no;
          :delay ($lnsdelaytime / 6);
          :led user-led=yes led4=no led3=no led2=no led1=yes;
          :delay ($lnsdelaytime / 6);
        }
      }
      :if ($"signal-to-noise" < $lnslevel1) do={
        :set lnsdelaytime 1700ms;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=$lnsbeepfreq length=($lnsdelaytime / 2);
        }
        :led user-led=yes led4=no led3=no led2=no led1=no;
        :delay $lnsdelaytime;
      }
    } else={
      :if ($"status" = "searching-for-network") do={
        :set lnsdelaytime 2000ms;
        :led user-led=no led4=no led3=no led2=no led1=no;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=$lnsbeepfreq length=100ms;
        }
        :delay 100ms;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=($lnsbeepfreq + 100) length=75ms;
        }
        :delay 75ms;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=($lnsbeepfreq + 200) length=50ms;
        }
        :delay 50ms;
        :for i from=1 to=4 do={
          :led user-led=no;
          :delay ($lnsdelaytime / 8)
          :led user-led=yes;
          :delay ($lnsdelaytime / 8)
        }
        :set lnsdelaytime ($lnsdelaytime + (50ms + 75ms + 100ms));
      } else={
        :set lnsdelaytime 2000ms;
        :led user-led=no led4=no led3=no led2=no led1=no;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=($lnsbeepfreq - 150) length=150ms;
        }
        :delay 150ms;
        :if ($lnsrunningtime > $lnsrunbeepdiff) do={
          :beep frequency=($lnsbeepfreq - 350) length=100ms;
        }
        :delay 100ms;
        :for i from=1 to=4 do={
          :led user-led=yes;
          :delay 50ms;
          :led user-led=no;
          :delay 50ms;
        }
        :delay 1550ms;
      }
    }
  }
:set lnsrunningtime ("$lnsrunningtime" - "$lnsdelaytime");
}

# shut off LEDs, play shutdown tones
:delay 50ms;
:led user-led=no led4=no led3=no led2=no led1=no;
:delay 50ms;
:beep frequency=($lnsbeepfreq - 200) length=50ms;
:delay 50ms;
:beep frequency=($lnsbeepfreq - 300) length=50ms;
:delay 50ms;

absolutely brilliant!! Well done!

The only change I’ve made is to change all references to user-led to led5, because in our enclosures user-led is hidden, but since you kept led5 free, it was just a matter of doing a find/replace.

Once again, well done, this is a great script and will stay on my memory stick for a very long time! Thanks!

Wow, I just found this. Its going in my toolbox for sure! I tested it on v4.0 beta and it works there too. Thanks!

Can you explain how to run this script through Winbox or via telnet or something? I’ve never run scripts before on these. I use RB433 boards and would like to be able to do an alignment with this.

Thanks

  • In WinBox, go to System / Scripts
  • Click + to add a new script
  • give it a name as you wish
  • Copy the script and paste it into the big ‘Source’ box
  • click OK
  • select it and click ‘Run Script’ in the Script List window.

I haven’t figured out how to stop the script once it starts running, but I just reboot the router.

Thanks! that wasw very helpful!

I did find out that if you run a script, then go to the Jobs tab, you can cancel the script from running without having to reboot.

yes you’re right! Completely forgot about that!

btw.. I really like how easy it is to adjust how to adjust this section:
:local lnslevel8 70;
:local lnslevel7 65;
:local lnslevel6 60;
:local lnslevel5 55;
:local lnslevel4 50;
:local lnslevel3 45;
:local lnslevel2 40;
:local lnslevel1 35;

If i want to make minor tweaks to my alignment I can go from level 1 at around 50dB to level 8 around 64dB, using 2dB increments. That’s pretty cool. Can’t wait to try this for real.

How can I make this script automatically come on everytime the router reboots???

add /system scheduler with start-time=startup

Could you please give me the steps. I have tried in system scheduler with no luck.

Thank you

will this script give different beeps for the bridge and station mode?

i am using Level3 (Ver 4.11) Board= RB711 (32MB RAM)

the bridge is giving a constant beep and the station changes its beeps when trying to adjust.