Coverage for backend/django/core/auxiliary/models/PropertySet.py: 93%
65 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
1from typing import TYPE_CHECKING, Tuple
2from django.db import models
4from flowsheetInternals.unitops.config import PropertySetType
5from core.auxiliary.enums.uiEnums import CompoundMode
7from .PropertyInfo import PropertyInfo
8from .PropertyValue import PropertyValue
9from .ControlValue import ControlValue
10from flowsheetInternals.unitops.config import *
11from core.managers import AccessControlManager, AllFlowsheetStatesManager
12from .FlowsheetHistoryModel import FlowsheetHistoryModel
14if TYPE_CHECKING:
15 from flowsheetInternals.unitops.models.SimulationObject import SimulationObject
18class PropertySet(FlowsheetHistoryModel, models.Model):
19 """
20 Base class for property sets
21 This class implements no special methods for updating properties
22 """
24 flowsheet_state = models.ForeignKey(
25 "FlowsheetState", on_delete=models.CASCADE, related_name="propertySets"
26 )
27 compoundMode = models.CharField(choices=CompoundMode.choices, default="")
28 simulationObject: models.OneToOneField["SimulationObject"] = models.OneToOneField(
29 "flowsheetInternals_unitops.SimulationObject",
30 on_delete=models.CASCADE,
31 related_name="properties",
32 null=True,
33 )
35 created_at = models.DateTimeField(auto_now_add=True)
37 objects = AccessControlManager()
38 all_states = AllFlowsheetStatesManager()
40 class Meta:
41 ordering = ["created_at"]
43 @property
44 def containedProperties(self) -> models.QuerySet[PropertyInfo]:
45 return self.ContainedProperties.all()
47 @property
48 def schema(self) -> PropertySetType:
49 return get_object_schema(self.simulationObject).properties
51 @property
52 def disable_all(self) -> bool:
53 simulationObject = self.simulationObject
54 if not simulationObject.is_stream():
55 return False
56 if simulationObject.has_recycle_connection:
57 return False # don't disable properties if connected to a recycle block
58 ports = simulationObject.connectedPorts
59 if ports.count() == 0: 59 ↛ 60line 59 didn't jump to line 60 because the condition on line 59 was never true
60 return False # floating stream
61 elif ports.count() == 1:
62 if ports.get().direction == "inlet":
63 return False # inlet stream
64 return True
66 @property
67 def has_simulation_object(self) -> bool:
68 # eg. pinch analysis property set has no simulation object
69 return bool(self.simulationObject)
71 def get_property(self, key: str, index: int = 0) -> PropertyInfo:
72 """
73 Utility method for getting a property within this set by key.
74 """
75 try:
76 prop: PropertyInfo = self.ContainedProperties.get(key=key, index=index)
77 return prop
78 except PropertyInfo.DoesNotExist:
79 raise ValueError(
80 f"Property with key `{key}` not found in PropertySet, options: {[prop.key for prop in self.containedProperties]}"
81 )
83 def update_property(
84 self,
85 key: str,
86 value: float | None = None,
87 unit: str | None = None,
88 index: int = 0,
89 ) -> None:
90 """
91 Utility method for updating the value and/or unit of a property, referenced by the key.
92 """
93 prop = self.get_property(key, index)
94 if value is not None:
95 prop.set_value(value)
96 if unit is not None:
97 prop.unit = unit
98 prop.save()
100 def add_control(
101 self, prop1: str | PropertyInfo, prop2: str | PropertyInfo
102 ) -> ControlValue:
103 """
104 Add a control relationship between two properties.
105 """
106 if isinstance(prop1, str): 106 ↛ 108line 106 didn't jump to line 108 because the condition on line 106 was always true
107 prop1 = self.get_property(prop1)
108 if isinstance(prop2, str):
109 prop2 = self.get_property(prop2)
110 return prop1.add_control(prop2)
112 def get_unspecified_properties(self) -> list[str]:
113 # For some reason, Pinch analysis is using property sets. They don't have simulation objects attached,
114 # so getting unspecified properties is not possible.
115 # Thus we have to return an empty list.
116 if not self.simulationObject:
117 return []
118 return self.simulationObject.get_unspecified_properties()