Community discussions

MikroTik App
 
excession
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 95
Joined: Mon May 11, 2015 8:16 pm

POE Power Script

Wed May 04, 2022 12:06 am

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.
#poe-status
:local poeOutStatus ""
:local interfaceName ""
:local poeOutPower 0
:local poeOutPowerRemainder 0
:local poeOutCurrent 0
:local poeOutVoltage 0
:local poeTotalPower 0
:local poeResult [interface ethernet poe monitor [find] as-value once]

:put ("POE Status:")
:foreach line in=$poeResult do={
    :set poeOutStatus ($line->"poe-out-status")
    :if ($poeOutStatus="powered-on") do={
        :set interfaceName ($line->"name")
        :set poeOutPower (($line->"poe-out-power")/10)
        :set poeOutPowerRemainder (($line->"poe-out-power")-($poeOutPower*10))
        :set poeOutCurrent ($line->"poe-out-current")
        :set poeOutVoltage (($line->"poe-out-voltage")/10)
        :set poeTotalPower ($poeTotalPower+($line->"poe-out-power"))

        :put ("Interface: ".$interfaceName."\t | Power: ".$poeOutPower.".".$poeOutPowerRemainder."W\t | Current: ".$poeOutCurrent."mA\t | Voltage: ".$poeOutVoltage."V")
        
        }

    }
:put ("Total Power: ".($poeTotalPower/10).".".(($poeTotalPower)-((($poeTotalPower/10))*10))."W")

sys script run poe-status 

POE Status:
Interface: ether4 | Power: 2.0W | Current: 79mA | Voltage: 26V
Interface: ether6 | Power: 2.6W | Current: 100mA | Voltage: 26V
Interface: ether8 | Power: 3.7W | Current: 72mA | Voltage: 52V
Interface: ether10 | Power: 2.8W | Current: 55mA | Voltage: 52V
Interface: ether14 | Power: 5.1W | Current: 99mA | Voltage: 52V
Interface: ether16 | Power: 4.4W | Current: 85mA | Voltage: 52V
Total Power: 20.6W
 
tangent
Forum Guru
Forum Guru
Posts: 1329
Joined: Thu Jul 01, 2021 3:15 pm
Contact:

Re: POE Power Script

Wed May 04, 2022 2:05 am

Nice! Thanks for sharing.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: POE Power Script

Wed May 04, 2022 2:41 am

A revised version, inside are present some hints and semplifications...
{
: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 sysTens ""
:local sysPSUl ""
:local sysPSUh ""
/system health
:if ([:typeof [get psu1-voltage]] != "nil") do={
    :set sysPSUl "PSU low $[$div [get psu1-voltage] "V"]"
    :set sysPSUh " | PSU high $[$div [get psu2-voltage] "V"]"
} else={
    :set sysTens [$div [get voltage] "V"]
}
:put ("Total: $[$form $pTotalCurr "mA"] | $[$div $pTotalPowr "W"]")
:put ("Routerboard: $sysTens$sysPSUl$sysPSUh")
}

Units with more than one PSU (CRS112-8P-4S or 16P or 24P or 48P devices)
on example ifWanted="auto-on|forced-on|off", ifAlsoIdle=true and ifMode=true

terminal code

POE Status:
Interface: ether1       | Mode: low      auto-on         powered-on     | 23.8V |   98mA | 2.3W
Interface: ether2       | Mode: low      forced-on       powered-on     | 23.7V |  120mA | 2.8W
Interface: ether3       | Mode: low      auto-on         short-circuit
Interface: ether4       | Mode: high     auto-on         waiting-for-load
Interface: ether5       | Mode: low      off     disabled
Interface: ether6       | Mode: low      auto-on         powered-on     | 23.7V |  196mA | 4.6W
Interface: ether7       | Mode: low      auto-on         powered-on     | 23.8V |  113mA | 2.6W
Interface: ether8       | Mode: low      auto-on         powered-on     | 23.8V |  109mA | 2.5W
Total:  636mA | 14.8W
Routerboard: PSU low 24.2V | PSU high 48.6V

Units with single PSU (hEX PoE / PowerBOX models)
on example ifWanted="auto-on|forced-on", ifAlsoIdle=false and ifMode=false

terminal code

POE Status:
Interface: ether2       | 27.4V |  145mA | 3.9W
Interface: ether3       | 27.4V |  113mA | 3.0W
Total:  258mA | 6.9W
Routerboard: 27.4V
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: POE Power Script

Wed May 04, 2022 2:59 am

I notice just now than my revision can be improved:
Total separate values for each PSU1 and PSU2 on 8P/16P/24P/48P devices.
 
excession
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 95
Joined: Mon May 11, 2015 8:16 pm

Re: POE Power Script

Wed May 04, 2022 11:57 am

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?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: POE Power Script

Wed May 04, 2022 12:16 pm

Yes, every device with mult-poe-voltage has the same single 8 port identical blocks inside.
 
tangent
Forum Guru
Forum Guru
Posts: 1329
Joined: Thu Jul 01, 2021 3:15 pm
Contact:

Re: POE Power Script

Thu Jul 21, 2022 12:50 pm

A revised version…

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.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: POE Power Script

Fri Jul 22, 2022 12:12 am

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...
 
User avatar
sadjoe
just joined
Posts: 22
Joined: Fri Jan 05, 2024 10:15 pm

Re: POE Power Script

Tue Jan 16, 2024 10:48 pm

Hello,

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
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: POE Power Script

Tue Jan 16, 2024 11:43 pm

Hello,

I am getting this one below. Is this normal ? I am using Mikrotik hex S
That model do not have standard "4 PoE port" block, but "i" PoE out on ether5 that act differently.
 
guipoletto
Member Candidate
Member Candidate
Posts: 195
Joined: Mon Sep 19, 2011 5:31 am

Re: POE Power Script

Wed Jan 17, 2024 1:59 am

A bit of a hack, to allow for properly formatted output when interface names length's differ by more than 1 tab length (8 characters)

the "11" being added to the calculation is the length of the first prefix, "Interface: "
{
#poe-status
:local poeOutStatus ""
:local interfaceName ""
:local poeOutPower 0
:local poeOutPowerRemainder 0
:local poeOutCurrent 0
:local poeOutVoltage 0
:local poeTotalPower 0
:local poeResult [interface ethernet poe monitor [find] as-value once]
:local nameLen 0
:local maxLen 0
:local tabTo 0
:local numTabs 0
:local tab ""

:foreach line in=$poeResult do={
	:set interfaceName ($line->"name")
	:if ([:len $interfaceName] > $maxLen) do={:set maxLen [:len $interfaceName]}
}
:set tabTo ((((($maxLen+11)/8)+1)*8)-1)

:put ("POE Status:")
:foreach line in=$poeResult do={
    :set poeOutStatus ($line->"poe-out-status")
    :if ($poeOutStatus="powered-on") do={
        :set interfaceName ($line->"name")
        :set poeOutPower (($line->"poe-out-power")/10)
        :set poeOutPowerRemainder (($line->"poe-out-power")-($poeOutPower*10))
        :set poeOutCurrent ($line->"poe-out-current")
        :set poeOutVoltage (($line->"poe-out-voltage")/10)
        :set poeTotalPower ($poeTotalPower+($line->"poe-out-power"))
	:set nameLen ([:len $interfaceName] + 11)
        :set numTabs ((($tabTo-$nameLen)/8))
	:for i from=0 to=($numTabs) do={:set tab ($tab."\t")}

        :put ("Interface: ".$interfaceName.$tab." | Power: ".$poeOutPower.".".$poeOutPowerRemainder."W\t | Current: ".$poeOutCurrent."mA\t | Voltage: ".$poeOutVoltage."V")
        
	:set tab ""
        }

    }
:put ("Total Power: ".($poeTotalPower/10).".".(($poeTotalPower)-((($poeTotalPower/10))*10))."W")
}
 
User avatar
sadjoe
just joined
Posts: 22
Joined: Fri Jan 05, 2024 10:15 pm

Re: POE Power Script

Wed Jan 17, 2024 11:00 am

A bit of a hack, to allow for properly formatted output when interface names length's differ by more than 1 tab length (8 characters)

the "11" being added to the calculation is the length of the first prefix, "Interface: "
{
#poe-status
:local poeOutStatus ""
:local interfaceName ""
:local poeOutPower 0
:local poeOutPowerRemainder 0
:local poeOutCurrent 0
:local poeOutVoltage 0
:local poeTotalPower 0
:local poeResult [interface ethernet poe monitor [find] as-value once]
:local nameLen 0
:local maxLen 0
:local tabTo 0
:local numTabs 0
:local tab ""

:foreach line in=$poeResult do={
	:set interfaceName ($line->"name")
	:if ([:len $interfaceName] > $maxLen) do={:set maxLen [:len $interfaceName]}
}
:set tabTo ((((($maxLen+11)/8)+1)*8)-1)

:put ("POE Status:")
:foreach line in=$poeResult do={
    :set poeOutStatus ($line->"poe-out-status")
    :if ($poeOutStatus="powered-on") do={
        :set interfaceName ($line->"name")
        :set poeOutPower (($line->"poe-out-power")/10)
        :set poeOutPowerRemainder (($line->"poe-out-power")-($poeOutPower*10))
        :set poeOutCurrent ($line->"poe-out-current")
        :set poeOutVoltage (($line->"poe-out-voltage")/10)
        :set poeTotalPower ($poeTotalPower+($line->"poe-out-power"))
	:set nameLen ([:len $interfaceName] + 11)
        :set numTabs ((($tabTo-$nameLen)/8))
	:for i from=0 to=($numTabs) do={:set tab ($tab."\t")}

        :put ("Interface: ".$interfaceName.$tab." | Power: ".$poeOutPower.".".$poeOutPowerRemainder."W\t | Current: ".$poeOutCurrent."mA\t | Voltage: ".$poeOutVoltage."V")
        
	:set tab ""
        }

    }
:put ("Total Power: ".($poeTotalPower/10).".".(($poeTotalPower)-((($poeTotalPower/10))*10))."W")
}
That's the output for me.
 > sys script run poe-status1
POE Status:
Total Power: 0.0W
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: POE Power Script

Wed Jan 17, 2024 6:23 pm

Is it so difficult to understand that it doesn't work on your model?
What did I write wrong or rude in my previous answer?
 
guipoletto
Member Candidate
Member Candidate
Posts: 195
Joined: Mon Sep 19, 2011 5:31 am

Re: POE Power Script

Wed Jan 17, 2024 8:47 pm

That's the output for me.
 > sys script run poe-status1
POE Status:
Total Power: 0.0W
Hi, i tested with two,CRS318's (NetPower), running 7.13:
output-tabformatted.png
You do not have the required permissions to view the files attached to this post.

Who is online

Users browsing this forum: ko00000000001 and 25 guests