Coverage for backend/core/auxiliary/models/PropertySet.py: 88%

63 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-11-06 23:27 +0000

1from typing import Tuple 

2from django.db import models 

3 

4from flowsheetInternals.unitops.config import PropertySetType 

5from core.auxiliary.enums.uiEnums import CompoundMode 

6 

7from .PropertyInfo import PropertyInfo 

8from .PropertyValue import PropertyValue 

9from .ControlValue import ControlValue 

10from flowsheetInternals.unitops.config import * 

11from core.managers import AccessControlManager 

12class PropertySet(models.Model): 

13 """ 

14 Base class for property sets 

15 This class implements no special methods for updating properties 

16 """ 

17 flowsheet = models.ForeignKey("Flowsheet", on_delete=models.CASCADE, related_name="propertySets") 

18 compoundMode = models.CharField(choices=CompoundMode.choices, default="") 

19 simulationObject = models.OneToOneField("flowsheetInternals_unitops.SimulationObject", on_delete=models.CASCADE, related_name="properties", null=True) 

20 

21 

22 created_at = models.DateTimeField(auto_now_add=True) 

23 

24 objects = AccessControlManager() 

25 

26 class Meta: 

27 ordering = ['created_at'] 

28 

29 @property 

30 def containedProperties(self) -> models.QuerySet[PropertyInfo]: 

31 return self.ContainedProperties.all() 

32 

33 @property 

34 def schema(self) -> PropertySetType: 

35 return get_object_schema(self.simulationObject).properties 

36 

37 @property 

38 def disable_all(self) -> bool: 

39 simulationObject = self.simulationObject 

40 if not simulationObject.is_stream(): 

41 return False 

42 if simulationObject.has_recycle_connection: 42 ↛ 43line 42 didn't jump to line 43 because the condition on line 42 was never true

43 return False # don't disable properties if connected to a recycle block 

44 ports = simulationObject.connectedPorts 

45 if ports.count() == 0: 45 ↛ 46line 45 didn't jump to line 46 because the condition on line 45 was never true

46 return False # floating stream 

47 elif ports.count() == 1: 

48 if ports.get().direction == "inlet": 

49 return False # inlet stream 

50 return True 

51 

52 @property 

53 def has_simulation_object(self) -> bool: 

54 # eg. pinch analysis property set has no simulation object 

55 return bool(self.simulationObject) 

56 

57 

58 def get_property(self, key: str, index: int = 0) -> PropertyInfo: 

59 """ 

60 Utility method for getting a property within this set by key. 

61 """ 

62 try: 

63 prop: PropertyInfo = self.ContainedProperties.get(key=key, index=index) 

64 return prop 

65 except PropertyInfo.DoesNotExist: 

66 raise ValueError(f"Property with key `{key}` not found in PropertySet, options: {[prop.key for prop in self.containedProperties]}") 

67 

68 

69 def update_property(self, key: str, value: float | None = None, unit: str | None = None, index: int = 0) -> None: 

70 """ 

71 Utility method for updating the value and/or unit of a property, referenced by the key. 

72 """ 

73 prop = self.get_property(key, index) 

74 if value is not None: 

75 prop.set_value(value) 

76 if unit is not None: 

77 prop.unit = unit 

78 prop.save() 

79 

80 

81 def add_control(self, prop1: str | PropertyInfo, prop2: str | PropertyInfo) -> ControlValue: 

82 """ 

83 Add a control relationship between two properties. 

84 """ 

85 if isinstance(prop1, str): 85 ↛ 87line 85 didn't jump to line 87 because the condition on line 85 was always true

86 prop1 = self.get_property(prop1) 

87 if isinstance(prop2, str): 

88 prop2 = self.get_property(prop2) 

89 return prop1.add_control(prop2) 

90 

91 def get_unspecified_properties(self) -> list[str]: 

92 # For some reason, Pinch analysis is using property sets. They don't have simulation objects attached, 

93 # so getting unspecified properties is not possible. 

94 # Thus we have to return an empty list. 

95 if not self.simulationObject: 95 ↛ 96line 95 didn't jump to line 96 because the condition on line 95 was never true

96 return [] 

97 return self.simulationObject.get_unspecified_properties()