Просмотр исходного кода

Clean up power utilization logic

Jeremy Stretch 5 лет назад
Родитель
Сommit
eaf8d95ce5
3 измененных файлов с 34 добавлено и 19 удалено
  1. 10 3
      netbox/dcim/models/device_components.py
  2. 16 12
      netbox/dcim/models/racks.py
  3. 8 4
      netbox/templates/dcim/rack.html

+ 10 - 3
netbox/dcim/models/device_components.py

@@ -320,8 +320,12 @@ class PowerPort(CableTermination, PathEndpoint, ComponentModel):
         """
         """
         # Calculate aggregate draw of all child power outlets if no numbers have been defined manually
         # Calculate aggregate draw of all child power outlets if no numbers have been defined manually
         if self.allocated_draw is None and self.maximum_draw is None:
         if self.allocated_draw is None and self.maximum_draw is None:
+            poweroutlet_ct = ContentType.objects.get_for_model(PowerOutlet)
             outlet_ids = PowerOutlet.objects.filter(power_port=self).values_list('pk', flat=True)
             outlet_ids = PowerOutlet.objects.filter(power_port=self).values_list('pk', flat=True)
-            utilization = PowerPort.objects.filter(_connected_poweroutlet_id__in=outlet_ids).aggregate(
+            utilization = PowerPort.objects.filter(
+                _cable_peer_type=poweroutlet_ct,
+                _cable_peer_id__in=outlet_ids
+            ).aggregate(
                 maximum_draw_total=Sum('maximum_draw'),
                 maximum_draw_total=Sum('maximum_draw'),
                 allocated_draw_total=Sum('allocated_draw'),
                 allocated_draw_total=Sum('allocated_draw'),
             )
             )
@@ -333,10 +337,13 @@ class PowerPort(CableTermination, PathEndpoint, ComponentModel):
             }
             }
 
 
             # Calculate per-leg aggregates for three-phase feeds
             # Calculate per-leg aggregates for three-phase feeds
-            if self._connected_powerfeed and self._connected_powerfeed.phase == PowerFeedPhaseChoices.PHASE_3PHASE:
+            if getattr(self._cable_peer, 'phase', None) == PowerFeedPhaseChoices.PHASE_3PHASE:
                 for leg, leg_name in PowerOutletFeedLegChoices:
                 for leg, leg_name in PowerOutletFeedLegChoices:
                     outlet_ids = PowerOutlet.objects.filter(power_port=self, feed_leg=leg).values_list('pk', flat=True)
                     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(
+                    utilization = PowerPort.objects.filter(
+                        _cable_peer_type=poweroutlet_ct,
+                        _cable_peer_id__in=outlet_ids
+                    ).aggregate(
                         maximum_draw_total=Sum('maximum_draw'),
                         maximum_draw_total=Sum('maximum_draw'),
                         allocated_draw_total=Sum('allocated_draw'),
                         allocated_draw_total=Sum('allocated_draw'),
                     )
                     )

+ 16 - 12
netbox/dcim/models/racks.py

@@ -3,6 +3,7 @@ from collections import OrderedDict
 from django.conf import settings
 from django.conf import settings
 from django.contrib.auth.models import User
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.fields import GenericRelation
 from django.contrib.contenttypes.fields import GenericRelation
+from django.contrib.contenttypes.models import ContentType
 from django.contrib.postgres.fields import ArrayField
 from django.contrib.postgres.fields import ArrayField
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.core.validators import MaxValueValidator, MinValueValidator
 from django.core.validators import MaxValueValidator, MinValueValidator
@@ -22,6 +23,7 @@ from utilities.fields import ColorField, NaturalOrderingField
 from utilities.querysets import RestrictedQuerySet
 from utilities.querysets import RestrictedQuerySet
 from utilities.mptt import TreeManager
 from utilities.mptt import TreeManager
 from utilities.utils import array_to_string, serialize_object
 from utilities.utils import array_to_string, serialize_object
+from .device_components import PowerOutlet, PowerPort
 from .devices import Device
 from .devices import Device
 from .power import PowerFeed
 from .power import PowerFeed
 
 
@@ -536,20 +538,22 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
         """
         """
         Determine the utilization rate of power in the rack and return it as a percentage.
         Determine the utilization rate of power in the rack and return it as a percentage.
         """
         """
-        power_stats = PowerFeed.objects.filter(
-            rack=self
-        ).annotate(
-            allocated_draw_total=Sum('connected_endpoint__poweroutlets__connected_endpoint__allocated_draw'),
-        ).values(
-            'allocated_draw_total',
-            'available_power'
+        powerfeeds = PowerFeed.objects.filter(rack=self)
+        available_power_total = sum(pf.available_power for pf in powerfeeds)
+        if not available_power_total:
+            return 0
+
+        pf_powerports = PowerPort.objects.filter(
+            _cable_peer_type=ContentType.objects.get_for_model(PowerFeed),
+            _cable_peer_id__in=powerfeeds.values_list('id', flat=True)
         )
         )
+        poweroutlets = PowerOutlet.objects.filter(power_port_id__in=pf_powerports)
+        allocated_draw_total = PowerPort.objects.filter(
+            _cable_peer_type=ContentType.objects.get_for_model(PowerOutlet),
+            _cable_peer_id__in=poweroutlets.values_list('id', flat=True)
+        ).aggregate(Sum('allocated_draw'))['allocated_draw__sum'] or 0
 
 
-        if power_stats:
-            allocated_draw_total = sum(x['allocated_draw_total'] or 0 for x in power_stats)
-            available_power_total = sum(x['available_power'] for x in power_stats)
-            return int(allocated_draw_total / available_power_total * 100) or 0
-        return 0
+        return int(allocated_draw_total / available_power_total * 100)
 
 
 
 
 @extras_features('custom_fields', 'custom_links', 'export_templates', 'webhooks')
 @extras_features('custom_fields', 'custom_links', 'export_templates', 'webhooks')

+ 8 - 4
netbox/templates/dcim/rack.html

@@ -150,10 +150,14 @@
                         <a href="{% url 'dcim:device_list' %}?rack_id={{ rack.id }}">{{ device_count }}</a>
                         <a href="{% url 'dcim:device_list' %}?rack_id={{ rack.id }}">{{ device_count }}</a>
                     </td>
                     </td>
                 </tr>
                 </tr>
-                    <tr>
-                        <td>Utilization</td>
-                        <td>{% utilization_graph rack.get_utilization %}</td>
-                    </tr>
+                <tr>
+                    <td>Space Utilization</td>
+                    <td>{% utilization_graph rack.get_utilization %}</td>
+                </tr>
+                <tr>
+                    <td>Power Utilization</td>
+                    <td>{% utilization_graph rack.get_power_utilization %}</td>
+                </tr>
             </table>
             </table>
         </div>
         </div>
         <div class="panel panel-default">
         <div class="panel panel-default">