I am testing this on a hap lite running Ros 6.49.17.
The idea is to have something that can flip/toggle the status of the user led (the ONLY programmable led on hap lite) at each run.
For the moment I am using it as the script connected to Mode button, so at each press of the mode button the user led is triggered at the opposite state it is:
/system routerboard mode-button
set enabled=yes hold-time=0s..2s on-event=LEDtoggle
The script in human readable format:
/system leds
:if ([:len [find where (leds="user-led" and type=on)]] > 0) do={
set [find where leds="user-led"] type=off
} else={
set [find where leds="user-led"] type=on}
and in the export format:
/system script
add dont-require-permissions=no name=LEDtoggle owner=admin policy=read,write \
source="/system leds\r\
\n:if ([:len [find where (leds=\"user-led\" and type=on)]] > 0) do={\r\
\nset [find where leds=\"user-led\"] type=off\r\
\n} else={\r\
\nset [find where leds=\"user-led\"] type=on}\r\
\n"
It works just fine .
Questions:
is it “correct”? (as is it works, but to be picky the else condition should probably be “narrowed” to another conditional check, and I am also not too sure about the various brackets)
can it be simplified? (the detection method with len of the find with two conditions seems to me a bit over-complicated)
is there a way in Ros command to “flip” a value 0/1 (or yes/no or in this case on/off)?
The essence is the same , bummer , I hoped there was a clever way to invert the status of a boolean somehow without needing to check the current one with if, something loosely like (pseudocode):
set [find where leds=“user-led”] type= NOT $currtype
The add leds would work on hardware that support it and do nothing on hardware that doesn’t, right?
Is the check for <1 “better” than the check for >0 I originally had?
Is the :toarray conversion actually needed or it is just good practice?
Why " " ? It’s better than… I don’t want to argue with the AI as usual
I hoped there was a clever way to invert the status of a boolean somehow without needing to check the current one
Exact, can be done, but is not a boolean, is on or off. Why MikroTik choose that??? Mah…
with if, something loosely like (pseudocode): set [find where leds=“user-led”] type= NOT $currtype
yes like hypotetical if is true/false “set $uledid ![get $uledid type]”
The add leds would work on hardware that support it and do nothing on hardware that doesn’t, right?
Not tested, as wroted, but I do not know a way to test (except for compare RB model against know list or use on-error-resume-next)
Is the check for <1 “better” than the check for >0 I originally had?
In my case it means “if there isn’t (at least) one add it on”
In your case it means “if you find (at least) one turned on”
The difference is that I do only one search, so I need to know if there is at least one ID inside the returned value,
in your case you do 3 separate searches.
It’s a code optimization.
Is the :toarray conversion actually needed
It is absolutely useless, but… there is always a but…
I prefer to always provide correct types to functions.
Often with the change of versions “strange” things happen (remember???..).
So since leds= expects an array, I provide it with an array, without RouterOS converting the string into an array.
Basically I do NOT increase the number of operations that must be doed, but I explicitly make a conversion that should happen inside.
or it is just good practice?
I usually write scripts that make people… think… (at least I hope).
It’s not a bad thing to make sure that the right variable types are used, without blindly relying on the internal conversion (which as seen, often fails).
[pratical example: in RouterOS 7.18 if the quotation marks were not put in the file name (which is a string) it gave an error]
In fact, even “on” and “off” being two strings, I enclosed them in quotation marks.
Bear in mind that often when I review my very old scripts, I’m not satisfied with them…
Over time I’ve learned to make them better…
To be picky, 2 as there is the else, but I get the point, generally speaking is better to limit the number of searches and use a variable as reference.
In the specific case of the hap lite, there is seemingly no other led accessible but user-led, so I could even remove the "user-led" reference and just look for type on or off or even (horror! ) use set 0=on/set 0=off.
While playing with the thingy, there is also the disabled state, the user-led set to on BUT disabled is actually off, and as soon as I enable it, it lights up.
At least on 6.49.17, the status change is in the log as system, info, but always with the same message (not useful) "led trigger changed by admin" , no mention of which led it is, not which change was made.
I think you misunderstood me, it was a compliment for you…
I know you didn’t have the idea, but you were fundamental in intuiting the right point of view…
[What can be easy flipped as true/false? Whether it is disabled or not!]
I need some time to digest this new approach, it may become useful also for something else, no idea what yet.
If we limit the type to either on or off, we have four possible setting combos leading to the two possible states, but with ratio 1:3:
(disabled=no)+(type=on)=LED ON
(disabled=yes)+(type=on)=LED OFF
(disabled=yes)+(type=off)=LED OFF
(disabled=no)+(type=off)=LED OFF
A hypothetical “isLEDon?” script only checking whether the led is on or off needs to check for just one set of conditions, #1 above.
Then one could make the script do nothing if condition #1 is found else set the whole stuff as condition #2.
This would not alter the actual status of the led (if the led is on, it remains on, if the led is off it remains off[1]) but the settings will surely be the “right” ones for the disabled= boolean flip.
[1] if it is set to something else like -say - wireless-status too bad, I need the led to be either on or off to toggle it, so for me !on=off
That makes sense -- a quick glance at an AP to see whether wifi is enabled.
I was hoping for something more interesting: Maybe the bathroom being available, or dinner being ready, or an important message waiting, or the room temp outside of a range....
I know, but with one set per line it seems to me more readable.
I am always thinking about the future me finding an old script and struggling to understand what (the heck) it was intended to do.
Yes , you are right of course, this would be the definitive (as simple as possible, but not simpler ) version, but I needed to do the intermediate step to understand/test a couple of things, now that you condensed everything in a one-liner it is perfect for this simple use.
When/If I will add other commands to the mode button press (i.e. - and this is a partial reply to Josephny's question[1]) it will make sense (to me) to re-split the commands one per line.
[1] the complete answer is not yet ready, it will do such things... What they are, yet I know not, but they shall be... The terrors of the network!