mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-21 19:47:20 -06:00
First stab at power utilization tracking
This commit is contained in:
parent
3d5f85c0ca
commit
ac3e899f5e
@ -9,7 +9,7 @@ from django.contrib.postgres.fields import ArrayField, JSONField
|
||||
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
from django.db import models
|
||||
from django.db.models import Count, Q
|
||||
from django.db.models import Count, Q, Sum
|
||||
from django.urls import reverse
|
||||
from mptt.models import MPTTModel, TreeForeignKey
|
||||
from taggit.managers import TaggableManager
|
||||
@ -1938,6 +1938,41 @@ class PowerPort(CableTermination, ComponentModel):
|
||||
"Connected endpoint must be a PowerOutlet or PowerFeed, not {}.".format(type(value))
|
||||
)
|
||||
|
||||
def get_power_stats(self):
|
||||
"""
|
||||
Return power utilization statistics
|
||||
"""
|
||||
feed = self._connected_powerfeed
|
||||
if not feed or not self.poweroutlets.count():
|
||||
return None
|
||||
|
||||
stats = []
|
||||
powerfeed_available = self._connected_powerfeed.available_power
|
||||
|
||||
outlet_ids = PowerOutlet.objects.filter(power_port=self).values_list('pk', flat=True)
|
||||
utilization = PowerPort.objects.filter(_connected_poweroutlet_id__in=outlet_ids).aggregate(
|
||||
maximum_draw=Sum('maximum_draw'),
|
||||
allocated_draw=Sum('allocated_draw'),
|
||||
)
|
||||
utilization['outlets'] = len(outlet_ids)
|
||||
utilization['available_power'] = powerfeed_available
|
||||
stats.append(utilization)
|
||||
|
||||
# Per-leg stats for three-phase feeds
|
||||
if feed.phase == POWERFEED_PHASE_3PHASE:
|
||||
for leg, leg_name in POWERFEED_LEG_CHOICES:
|
||||
outlet_ids = PowerOutlet.objects.filter(power_port=self, feed_leg=leg).values_list('pk', flat=True)
|
||||
utilization = PowerPort.objects.filter(_connected_poweroutlet_id__in=outlet_ids).aggregate(
|
||||
maximum_draw=Sum('maximum_draw'),
|
||||
allocated_draw=Sum('allocated_draw'),
|
||||
)
|
||||
utilization['name'] = 'Leg {}'.format(leg_name)
|
||||
utilization['outlets'] = len(outlet_ids)
|
||||
utilization['available_power'] = powerfeed_available / 3
|
||||
stats.append(utilization)
|
||||
|
||||
return stats
|
||||
|
||||
|
||||
#
|
||||
# Power outlets
|
||||
@ -2923,3 +2958,10 @@ class PowerFeed(ChangeLoggedModel, CableTermination, CustomFieldModel):
|
||||
|
||||
def get_status_class(self):
|
||||
return STATUS_CLASSES[self.status]
|
||||
|
||||
@property
|
||||
def available_power(self):
|
||||
kva = self.voltage * self.amperage * self.max_utilization
|
||||
if self.phase == POWERFEED_PHASE_3PHASE:
|
||||
return kva * 1.732
|
||||
return kva
|
||||
|
@ -332,6 +332,49 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if power_ports and poweroutlets %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Power Utilization</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body">
|
||||
<tr>
|
||||
<th>Input</th>
|
||||
<th>Outlets</th>
|
||||
<th>Allocated/Max (W)</th>
|
||||
<th>Available (VA)</th>
|
||||
</tr>
|
||||
{% for pp in power_ports %}
|
||||
{% for leg in pp.get_power_stats %}
|
||||
<tr>
|
||||
{% if leg.name %}
|
||||
<td style="padding-left: 20px">{{ leg.name }}</td>
|
||||
{% else %}
|
||||
<td>{{ pp }}</td>
|
||||
{% endif %}
|
||||
<td>{{ leg.outlets|placeholder }}</td>
|
||||
<td>{{ leg.allocated_draw }} / {{ leg.maximum_draw }}</td>
|
||||
<td>{{ leg.available_power }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% if perms.dcim.add_interface or perms.dcim.add_consoleport or perms.dcim.add_powerport %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
{% if perms.dcim.add_consoleport %}
|
||||
<a href="{% url 'dcim:consoleport_add' pk=device.pk %}" class="btn btn-xs btn-primary">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add console port
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_powerport %}
|
||||
<a href="{% url 'dcim:powerport_add' pk=device.pk %}" class="btn btn-xs btn-primary">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add power port
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if request.user.is_authenticated %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
|
Loading…
Reference in New Issue
Block a user