## Estates *** ```plantuml @startuml BlenderOperationalStates skinparam state { BackgroundColor<> LightGreen BackgroundColor<> LightBlue BackgroundColor<> LightYellow BackgroundColor<> LightPink } [*] --> Idle state Idle state "Production Mode" as Production <> { state "First Production" as FirstProd state "Normal Production" as NormalProd state "Production Runout" as RunOut FirstProd --> NormalProd : First production\ncompleted NormalProd --> RunOut : End production\nrequested RunOut --> FirstProd : New recipe } state "CIP Mode" as CIP <> { state "Tank Cleaning" as TankCIP state "Line Cleaning" as LineCIP TankCIP --> LineCIP } state "Rinse Mode" as Rinse <> { state "Cold Rinse" as ColdRinse state "Hot Rinse" as HotRinse ColdRinse --> HotRinse } state "Startup Sequence" as Startup <> { state "Deaerator Startup" as DeaerStartup state "Syrup Startup" as SyrupStartup state "Blend/Fill Startup" as BlendStartup DeaerStartup --> SyrupStartup SyrupStartup --> BlendStartup } Idle --> Startup : Start system Startup --> FirstProd : Startup complete Production --> Rinse : Production complete Rinse --> CIP : Rinse complete CIP --> Idle : CIP complete Production --> CIP : Emergency CIP Rinse --> Idle : Emergency stop @enduml ``` ## Calculations *** ```plantuml @startuml BlenderPIDCalculationFlow skinparam activity { BackgroundColor<> PaleGreen BackgroundColor<> LightBlue BackgroundColor<> LightYellow BackgroundColor<> Pink BorderColor Black } start :Initialize variables; partition "Recipe Parameters" { :Determine beverage type; if (Sugar beverage?) then (yes) :Calculate syrup percentage based on Brix; note right: gActualSyrupPerc = (ProductBrix + ProdBrixOffset) / gActualSyrupBrix else (no) :Calculate syrup percentage based on ratio; note right: gActualSyrupPerc = 1 / (Ratio + 1) endif :Calculate water percentage; note right: gActualWaterPerc = 1 - gActualSyrupPerc :Calculate mixing ratio; note right: gActualRatioM = gActualWaterPerc / gActualSyrupPerc } partition "Flow Setpoint Calculations" { if (Production mode?) then (yes) :Calculate CO2 equilibrium pressure; :Set tank pressure setpoint based on mode; :Calculate target production rate; :Apply slew rate limiting; :Calculate water flow setpoint; note right: gSP_H2O = gActual_Prod_SP / (gActualSP_RatioVol + 1.0) * gActualSP_RatioVol :Check for critical blending conditions; :Calculate syrup flow setpoint; note right: gSP_SYR = (gSyrSPRef + gSyrSPTemp) * gActualSyrupDens :Calculate CO2 setpoint; if (Second gas injection enabled?) then (yes) :Calculate second gas setpoint; else (no) :Set second gas setpoint to zero; endif else (no) :Set all flow setpoints to zero; endif } partition "Tank Level Controls" { :Calculate syrup tank level setpoint; :Calculate deaeration tank level setpoint; :Calculate storage tank level setpoint; } partition "Temperature Controls" { :Calculate water and product temperature setpoints; } stop @enduml ``` ## Components *** ```plantuml @startuml BlenderSystemComponents skinparam component { BackgroundColor LightCyan BorderColor Black } package "Blender System" { [Syrup Flow Control] as SyrupControl [Water Flow Control] as WaterControl [CO2 Injection] as CO2Control [Second Gas Injection] as Gas2Control [Deaeration System] as DeaerSystem [Temperature Control] as TempControl [Tank Level Control] as LevelControl [Pressure Control] as PressControl } package "BlenderPID_PIDSPCalc" as PIDCalc { [Ratio Calculator] as RatioCalc [Water SP Calculator] as WaterSPCalc [Syrup SP Calculator] as SyrupSPCalc [CO2 SP Calculator] as CO2SPCalc [Level SP Calculator] as LevelSPCalc [Temperature SP Calculator] as TempSPCalc [Critical Condition Detection] as CritDetect } package "Input Parameters" { [Recipe Parameters] as Recipe [Production Settings] as ProdSettings [System Constants] as Constants } package "PID Controllers" { [RMM301 PID] as WaterPID [RMP302 PID] as SyrupPID [RVM301 PID] as PressurePID [RVN304 PID] as DeaerPID } Recipe --> RatioCalc ProdSettings --> WaterSPCalc Constants --> RatioCalc RatioCalc --> WaterSPCalc RatioCalc --> SyrupSPCalc RatioCalc --> CO2SPCalc WaterSPCalc --> WaterPID SyrupSPCalc --> SyrupPID CO2SPCalc --> CO2Control LevelSPCalc --> LevelControl TempSPCalc --> TempControl WaterPID --> WaterControl SyrupPID --> SyrupControl PressurePID --> PressControl DeaerPID --> DeaerSystem WaterControl --> CritDetect SyrupControl --> CritDetect CritDetect --> SyrupSPCalc : Correction feedback @enduml ``` ### Sequence *** ```plantuml @startuml BlenderSequence skinparam sequence { LifeLineBackgroundColor LightYellow ParticipantBackgroundColor LightCyan } participant "BlenderPID_PIDSPCalc" as Calc participant "Water Flow Controller" as Water participant "Syrup Flow Controller" as Syrup participant "CO2 Controller" as CO2 participant "Tank Level Controller" as Level participant "Temperature Controller" as Temp activate Calc == Startup Phase == Calc -> Level : Set deaerator tank level setpoint activate Level Level -> Calc : Level feedback deactivate Level Calc -> Temp : Set target water temperature activate Temp Temp -> Calc : Temperature feedback deactivate Temp == First Production Phase == Calc -> Water : Set initial water flow activate Water Water -> Calc : Flow measurement deactivate Water Calc -> Syrup : Set initial syrup flow (with extra syrup) activate Syrup Syrup -> Calc : Flow measurement deactivate Syrup Calc -> CO2 : Set CO2 injection (with extra CO2) activate CO2 CO2 -> Calc : CO2 measurement deactivate CO2 == Normal Production Phase == loop While in production mode Calc -> Water : Adjust water flow setpoint activate Water Water -> Calc : Flow measurement deactivate Water Calc -> Syrup : Adjust syrup flow setpoint activate Syrup Syrup -> Calc : Flow measurement alt Critical blending detected Calc -> Syrup : Apply correction factor end deactivate Syrup Calc -> CO2 : Adjust CO2 setpoint activate CO2 CO2 -> Calc : CO2 measurement deactivate CO2 Calc -> Level : Monitor and maintain target levels activate Level Level -> Calc : Level feedback deactivate Level end == Runout Phase == Calc -> Water : Ramp down water flow Calc -> Syrup : Ramp down syrup flow Calc -> CO2 : Reduce CO2 injection Calc -> Level : Adjust tank levels for end of production deactivate Calc @enduml ``` ## Clases *** ```plantuml @startuml BlenderClassDiagram skinparam class { BackgroundColor LightCyan BorderColor Black } class BlenderPID_PIDSPCalc { +Execute() } class RecipeParameters { +ProductBrix: REAL +ProdBrixOffset: REAL +SyrupBrix: REAL +Ratio: REAL +CO2Vols: REAL +CO2Fact: REAL +GAS2Vols: REAL +SP_ProdTemp: REAL +ProdTankPress: REAL } class SystemVariables { +gActualSyrupPerc: REAL +gActualWaterPerc: REAL +gActual_RatioM: REAL +gActual_Prod_SP: REAL +gActual_Prod_Flow: REAL +gSP_H2O: REAL +gSP_SYR: REAL +gSP_CO2: REAL +gSP_GAS2: REAL +gCriticalBlending: BOOL } class PIDControllers { +RMM301: PID +RMP302: PID +RVM301: PID +RVN304: PID } class OperationModes { +gBlenderProdMode: BOOL +gBlenderRinseMode: BOOL +gBlenderCIPMode: BOOL +gBlenderStableFlow: BOOL +First_Production: BOOL } class TankSetpoints { +gSP_SYR_Level: REAL +gSP_DEAIR_Level: REAL +gSP_STORAGE_Level: REAL +gSP_H2O_Temperature: REAL +gSP_Prod_Temperature: REAL } BlenderPID_PIDSPCalc -- RecipeParameters BlenderPID_PIDSPCalc -- SystemVariables BlenderPID_PIDSPCalc -- PIDControllers BlenderPID_PIDSPCalc -- OperationModes BlenderPID_PIDSPCalc -- TankSetpoints @enduml ```