Got a little annoyed trying to work with the standard POE monitor function, so wrote this little script to only show POE values for interfaces with POE demand and to calculate the total power draw.
Ooh, I like the $div function and the $ifWanted. Some useful stuff for me here on ROS syntax, thanks.
I noticed on my CRS328 that total useable power capacity is actually dictated by which port block you’re on. So each block of 8 ports has a separate 150w capacity.
Was thinking about adding an option to split the total calculation on x number of ports. Couldn’t think of a way to programmatically determine the split without a user set variable, ROS doesn’t seem to expose/store this info.
Unless POE power capacity is always dependant on an 8 port block on Mikrotik devices, anyone know?
I've updated it for 7.4, particularly the /system/health stuff at the end, to track the intentional changes in the way health reporting works in ROS 7. I tested it on a CRS328-24P and a hEX PoE to handle the dual-power vs single-power case:
{
:local ifWanted "auto-on|forced-on|off"; # it can be one or more, with | as a separator, between auto-on, forced-on and off
:local ifAlsoIdle true; # Can be true or false. If true displays also the poe capable interface on idle status
:local ifMode true; # Can be true or false. If true displays also how the interface mode is set
:local pTotalCurr 0
:local pTotalPowr 0
:local div do={
:local in [:tostr $1]
:local sym [:tostr $2]
:local int [:pick $in 0 ([:len $in] - 1)]
:local dec [:pick $in ([:len $in] - 1) [:len $in]]
:local ret "$int.$dec$sym"
:if ($ret = ".0$sym") do={:set ret "0.0$sym"}
:return $ret
}
:local form do={
:local in [:tostr $1]
:local sym [:tostr $2]
:local temp " $in"
:return "$[:pick $temp ([:len $temp] - 4) [:len $temp]]$sym"
}
:put ("POE Status:")
/interface ethernet poe
:foreach line in=[monitor [find where poe-out~$ifWanted] once as-value] do={
:local ifName ($line->"name")
:local ifPOut ($line->"poe-out")
:local ifPVol ($line->"poe-voltage")
:local ifStatus ($line->"poe-out-status")
:local pOutTens [$div ($line->"poe-out-voltage") "V"]
:local pOutCurr [$form ($line->"poe-out-current") "mA"]
:local pOutPowr [$div ($line->"poe-out-power") "W"]
:set pTotalCurr ($pTotalCurr + ($line->"poe-out-current"))
:set pTotalPowr ($pTotalPowr + ($line->"poe-out-power"))
:local ifStrMod ""
:if ($ifStatus = "powered-on") do={
:if ($ifMode) do={:set ifStrMod " Mode: $ifPVol\t $ifPOut\t $ifStatus\t|"}
:put ("Interface: $ifName\t|$ifStrMod $pOutTens | $pOutCurr | $pOutPowr")
} else={
:if ($ifAlsoIdle) do={
:set ifStrMod $ifStatus
:if ($ifMode) do={:set ifStrMod "| Mode: $ifPVol\t $ifPOut\t $ifStatus"}
:put ("Interface: $ifName\t$ifStrMod")
}
}
}
:local sysPSU ""
/system health
:do {
:local p1v [get [find name="psu1-voltage"] value]
:set sysPSU "PSU low $p1v V"
:do {
:local p2v [get [find name="psu2-voltage"] value]
:set sysPSU "$sysPSU | PSU high $p2v V"
} on-error={}
} on-error={
:set sysPSU ([get [find name="voltage"] value] . "V")
}
:put ("Total: $[$form $pTotalCurr "mA"] | $[$div $pTotalPowr "W"]")
:put ("Routerboard: $sysPSU")
}
Note also the use of on-error traps instead of typeof testing for nil. As a RouterOS scripting newbie, I don't know how kosher this is, but it seems cleaner than type-testing.
Thanks for the change.
Honestly, I think it is clearer to specify which “error” you expect, rather than generically skipping a piece because “it gives” / “can give” an error…
I’ve always hated «On Error Resume Next» way of programming.
But obviously sometime you are forced to use on-error because the scripting language do not give to you any alternative…
I am getting this one below. Is this normal ? I am using Mikrotik hex S
> system/routerboard/export
# 2024-01-16 22:49:56 by RouterOS 7.13.1
# software id = 6H10-A1GS
#
# model = RB760iGS
/system health print
Columns: NAME, VALUE, TYPE
# NAME VALUE TYPE
0 voltage 48.6 V
1 temperature 69 C
> sys script run poe-status
POE Status:
Interface: | Mode:
Interface: | Mode:
Interface: | Mode:
Interface: | Mode:
Interface: | Mode:
Total: 0mA | 0.0W
Routerboard: 48.6V