diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 1f7603241..d03d3f5a9 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -703,8 +703,8 @@ class PowerFeedSerializer(TaggitSerializer, CustomFieldModelSerializer): default=PowerFeedSupplyChoices.SUPPLY_AC ) phase = ChoiceField( - choices=POWERFEED_PHASE_CHOICES, - default=POWERFEED_PHASE_SINGLE + choices=PowerFeedPhaseChoices, + default=PowerFeedPhaseChoices.PHASE_SINGLE ) tags = TagListSerializerField( required=False diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 5d44f1cf4..cd4124518 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -900,11 +900,27 @@ class PowerFeedSupplyChoices(ChoiceSet): SUPPLY_DC = 'dc' CHOICES = ( - (SUPPLY_AC, 'Primary'), - (SUPPLY_DC, 'Redundant'), + (SUPPLY_AC, 'AC'), + (SUPPLY_DC, 'DC'), ) LEGACY_MAP = { SUPPLY_AC: 1, SUPPLY_DC: 2, } + + +class PowerFeedPhaseChoices(ChoiceSet): + + PHASE_SINGLE = 'single-phase' + PHASE_3PHASE = 'three-phase' + + CHOICES = ( + (PHASE_SINGLE, 'Single phase'), + (PHASE_3PHASE, 'Three-phase'), + ) + + LEGACY_MAP = { + PHASE_SINGLE: 1, + PHASE_3PHASE: 3, + } diff --git a/netbox/dcim/constants.py b/netbox/dcim/constants.py index 13335de3f..79ad5229d 100644 --- a/netbox/dcim/constants.py +++ b/netbox/dcim/constants.py @@ -68,12 +68,6 @@ COMPATIBLE_TERMINATION_TYPES = { } # Power feeds -POWERFEED_PHASE_SINGLE = 1 -POWERFEED_PHASE_3PHASE = 3 -POWERFEED_PHASE_CHOICES = ( - (POWERFEED_PHASE_SINGLE, 'Single phase'), - (POWERFEED_PHASE_3PHASE, 'Three-phase'), -) POWERFEED_STATUS_OFFLINE = 0 POWERFEED_STATUS_ACTIVE = 1 POWERFEED_STATUS_PLANNED = 2 diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index f767d0903..fb9467397 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -3870,7 +3870,7 @@ class PowerFeedCSVForm(forms.ModelForm): help_text='AC/DC' ) phase = CSVChoiceField( - choices=POWERFEED_PHASE_CHOICES, + choices=PowerFeedPhaseChoices, required=False, help_text='Single or three-phase' ) @@ -3948,7 +3948,7 @@ class PowerFeedBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEd widget=StaticSelect2() ) phase = forms.ChoiceField( - choices=add_blank_choice(POWERFEED_PHASE_CHOICES), + choices=add_blank_choice(PowerFeedPhaseChoices), required=False, initial='', widget=StaticSelect2() @@ -4024,7 +4024,7 @@ class PowerFeedFilterForm(BootstrapMixin, CustomFieldFilterForm): widget=StaticSelect2() ) phase = forms.ChoiceField( - choices=add_blank_choice(POWERFEED_PHASE_CHOICES), + choices=add_blank_choice(PowerFeedPhaseChoices), required=False, widget=StaticSelect2() ) diff --git a/netbox/dcim/migrations/0084_3569_powerfeed_fields.py b/netbox/dcim/migrations/0084_3569_powerfeed_fields.py index 5004258bd..5dafa4f3a 100644 --- a/netbox/dcim/migrations/0084_3569_powerfeed_fields.py +++ b/netbox/dcim/migrations/0084_3569_powerfeed_fields.py @@ -11,6 +11,11 @@ POWERFEED_SUPPLY_CHOICES = ( (2, 'dc'), ) +POWERFEED_PHASE_CHOICES = ( + (1, 'single-phase'), + (3, 'three-phase'), +) + def powerfeed_type_to_slug(apps, schema_editor): PowerFeed = apps.get_model('dcim', 'PowerFeed') @@ -24,6 +29,12 @@ def powerfeed_supply_to_slug(apps, schema_editor): PowerFeed.objects.filter(supply=id).update(supply=slug) +def powerfeed_phase_to_slug(apps, schema_editor): + PowerFeed = apps.get_model('dcim', 'PowerFeed') + for id, slug in POWERFEED_PHASE_CHOICES: + PowerFeed.objects.filter(phase=id).update(phase=slug) + + class Migration(migrations.Migration): atomic = False @@ -53,4 +64,14 @@ class Migration(migrations.Migration): code=powerfeed_supply_to_slug ), + # PowerFeed.phase + migrations.AlterField( + model_name='powerfeed', + name='phase', + field=models.CharField(blank=True, max_length=50), + ), + migrations.RunPython( + code=powerfeed_phase_to_slug + ), + ] diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 3b9ee069e..1510c7bea 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -2108,7 +2108,7 @@ class PowerPort(CableTermination, ComponentModel): } # Calculate per-leg aggregates for three-phase feeds - if self._connected_powerfeed and self._connected_powerfeed.phase == POWERFEED_PHASE_3PHASE: + if self._connected_powerfeed and self._connected_powerfeed.phase == PowerFeedPhaseChoices.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( @@ -3121,9 +3121,10 @@ class PowerFeed(ChangeLoggedModel, CableTermination, CustomFieldModel): choices=PowerFeedSupplyChoices, default=PowerFeedSupplyChoices.SUPPLY_AC ) - phase = models.PositiveSmallIntegerField( - choices=POWERFEED_PHASE_CHOICES, - default=POWERFEED_PHASE_SINGLE + phase = models.CharField( + max_length=50, + choices=PowerFeedPhaseChoices, + default=PowerFeedPhaseChoices.PHASE_SINGLE ) voltage = models.PositiveSmallIntegerField( validators=[MinValueValidator(1)], @@ -3197,7 +3198,7 @@ class PowerFeed(ChangeLoggedModel, CableTermination, CustomFieldModel): # Cache the available_power property on the instance kva = self.voltage * self.amperage * (self.max_utilization / 100) - if self.phase == POWERFEED_PHASE_3PHASE: + if self.phase == PowerFeedPhaseChoices.PHASE_3PHASE: self.available_power = round(kva * 1.732) else: self.available_power = round(kva)