I want to make a function to get the traffic on an interface and convert the unit correctly to B, KiB, MiB or GiB depending on the size. Just like Winbox does automatically:
I have tried this script but it doesn’t work, any help please?
What have you tried till now to get the script running?
There are several things wrong in the script.
The first one is that $1 is used and that is a special variable in a function and contains the first value transferred by the call function. So using it here invalids the :local 1. Use sound variable names.
Then the else { have to be on the same line as the :if
Then calling the function responds with the Eval code used by Mikrotik and is translation of your code to ‘directly executable’ code in ROS. If you put around the name of the function caller then it will return the calculated value instead of the Eval code
I don’t know, what you want to archive, but perhaps the 'monitor ’ command could be something for you,
but I have no idea if you can isolate one of the parameters.
It works fine but it is built to get values >1 GBs (/1073741824) but when the traffic is <1 GB the value I get = 0.
I have seen this sequence in this forum to convert values of the variables “tx-total” and “rx-total” so that they can be displayed correctly by a person regardless of the value obtained. (Bytes or KiB or MiB or GiB).
the following function is what i could find to adapt it to my script:
Actually was curious the “:local 1 …” usage – I would have thought be the error here. But instead it overrides any argument that would have been in $1. Guess that make sense but variables starting with a number is something I avoid. But for reassignment of the positional arguments, unintentionally cleaver.
I think the script problem is it’s not really a function any more. So if you change “human” from :local to :global, then use the $human function whatever you want. I added some protection around invalid types being provided, but assuming the rest of the B,K,M logic is right…
:global human do={
:if ([:typeof $1]="nothing") do={
:error "must provide a byte value to humanize";
};
:local input [:tonum $1];
:if ([:typeof $input]!="num") do={
:error "cannot convert $1 to number";
};
:local q;
:local r;
:local output;
:if ($input<1024) do={
:set $output "$input B";
} else={
:if ($input<1048576) do={
:set q ($input/1024);
:set r ($input-$q*1024);
:set r ($r/102);
:set output "$q.$r KiB";
} else={
:if ($input<1073741824) do={
:set q ($input/1048576);
:set r ($input-$q*1048576);
:set r ($r/104858);
:set output "$q.$r MiB"
} else={
:set q ($input/1073741824);
:set r ($input-$q*1073741824);
:set r ($r/107374182);
:set output "$q.$r GiB"
}
}
}
:return $output
};
So to use this you “call” $human with the results of a “/interface/get” command that returns with bytes. If you want to print it to the console (instead of using $human in a script), you can add a put like below to see the returned value from $human:
:put [$human [/interface get lte2 tx-byte]]
# 1.4 GiB
or assign it to variable to use and/or use string interpolation:
{
# in a script, block, you can assign it to variable to then use in email script
:local ltetx [$human [/interface get lte2 tx-byte]]
:put $ltetx
# alternatively in a string using interpolation
:local strtxrx "TX is $([$human [/interface get lte2 tx-byte]] and RX is $([$human [/interface get lte2 rx-byte]]))
}
I am not an expert nor a programmer but, tried often enough to find out how scripting works in ROS. Eval code is the translation of the script code we humans write. You see that strange script appear if you don’t put square brackets around this calling this function.
If you had put a parameter after it then the $1 would have transferred parameter into the function. The $1 is a reserved variable in a function.
The strange code called Eval, is coming from the word evaluate I assume:
Why does it display the Eval code?
By using :put $human you ask ROS to print the code of the function and it then displays then the code already converted to Eval.
By using :put [$human] you ask ROS to give you the result from the function.
By using :put :human 13 you ask ROS to give you the result from the function and the parameter 13 will be stored in $1 (special variable) inside the function.
When you store a function in Global then it is also stored converted to Eval code. As you can see underneath.