- id: '1745383146738' alias: Demand Following description: '' triggers: - trigger: state entity_id: - sensor.power_demand_mw - trigger: state entity_id: - sensor.total_power_output_mw conditions: - condition: numeric_state entity_id: sensor.power_demand_mw above: 0 - condition: numeric_state entity_id: sensor.total_power_output_mw above: 0 actions: - variables: loop: '{{ states(''input_select.loop'')|string }}' flow_ratio: '{{ (states(''sensor.COOLANT_SEC_CIRCULATION_PUMP''+loop+''SPEED'') | int / 100 * states(''sensor.coolant_sec_circulation_pump''+loop+''capacity'') | int) / (states(''sensor.COOLANT_CORE_CIRCULATION_PUMP''+loop+''SPEED'') | int / 100 * states(''sensor.coolant_core_circulation_pump''+loop+''capacity'') | int) }}' - if: - condition: or conditions: - condition: numeric_state entity_id: sensor.total_power_output_mw below: sensor.demand_lowerlimit - condition: numeric_state entity_id: sensor.total_power_output_mw above: sensor.demand_upperlimit alias: Power Output not within Demand Limits then: - alias: Adjust Primary-only or Steam Valve and all pumps if: - condition: numeric_state entity_id: sensor.demand_delta above: -6 below: 6 - alias: Sec/Pri Flow Ratio is within bounds condition: template value_template: "{{ (states('sensor.demand_delta') | int > 0 and flow_ratio\ \ >= 3.0) or \n(states('sensor.demand_delta') | int < 0 and flow_ratio <=\ \ 4.0) }}" enabled: true then: - action: rest_command.nucleares_webserver_set data: var: COOLANT_CORE_CIRCULATION_PUMP{{loop}}ORDERED_SPEED val: '{{ states(''sensor.coolant_core_circulation_pump''+loop+''speed'') | int + (states(''sensor.demand_delta'') | int | abs) / (states(''sensor.demand_delta'') | int) }}' alias: Adjust Primary Pump Speed +/- 1 - delay: hours: 0 minutes: 0 seconds: '{{ 3 / states(''sensor.game_sim_speed'') | int }}' milliseconds: 0 alias: Wait for (3 / simspeed) seconds - alias: NOTIFICATION action: persistent_notification.create data: message: 'Demand: {{ states(''sensor.power_demand_mw'') }}
Output: {{ states(''sensor.total_power_output_mw'') | float }}
Delta = {{ states(''sensor.demand_delta'') | round(2) }}

Loop: {{loop}} ==> PRIMARY PUMP speed adjustment
Primary = {{ states(''sensor.COOLANT_CORE_CIRCULATION_PUMP''+loop+''SPEED'') | int }}% -> {{ states(''sensor.COOLANT_CORE_CIRCULATION_PUMP''+loop+''SPEED'') | int / 100 * states(''sensor.coolant_core_circulation_pump''+loop+''capacity'') | int }} L/m of {{ states(''sensor.coolant_core_circulation_pump''+loop+''capacity'') | int }} L/m
Secondary = {{ states(''sensor.COOLANT_SEC_CIRCULATION_PUMP''+loop+''SPEED'') | int }}% -> {{ states(''sensor.COOLANT_SEC_CIRCULATION_PUMP''+loop+''SPEED'') | int / 100 * states(''sensor.coolant_sec_circulation_pump''+loop+''capacity'') | int }} L/m of {{ states(''sensor.coolant_sec_circulation_pump''+loop+''capacity'') | int }} L/m
MSCV = {{ states(''sensor.mscv''+loop+''opening_actual'') }}% {{ states(''sensor.mscv''+loop+''opening_actual'') | int * 100 }} L/m
Flow Ratio = {{ flow_ratio | round(3) }}
New Primary Pump speed: {{ max(states(''sensor.coolant_core_circulation_pump''+loop+''speed'') | int + states(''sensor.demand_delta'') | int,6) }}%' notification_id: PrimaryPump enabled: true else: - variables: target_mscv: '{{ max(min(states(''sensor.mscv''+loop+''opening_actual'') | int + (states(''sensor.demand_delta'') | int / 6) | int,40),2) }}' alias: target MSCV = current mscv + (demand_delta / 6) - alias: Match Secondary Pump Speed to Target MSCV action: rest_command.nucleares_webserver_set data: var: COOLANT_SEC_CIRCULATION_PUMP{{loop}}ORDERED_SPEED val: '{{ (target_mscv | int * 1000 / states(''sensor.coolant_sec_circulation_pump''+loop+''capacity'') | int) | round(1) }}' - alias: Match Primary Pump Speed to Target MSCV action: rest_command.nucleares_webserver_set data: var: COOLANT_CORE_CIRCULATION_PUMP{{loop}}ORDERED_SPEED val: '{{ (target_mscv | int * 300 / states(''sensor.coolant_core_circulation_pump''+loop+''capacity'') | int) | round(1) }}' - alias: If MSCV not at Target, adjust MSCV +/- 1 if: - condition: template value_template: '{{ states(''sensor.mscv''+loop+''opening_actual'') | int != target_mscv }}' alias: Is MSCV not at Target? then: - action: rest_command.nucleares_webserver_set data: var: MSCV{{loop}}OPENING_ORDERED val: '{{ states(''sensor.mscv''+loop+''opening_actual'') | int + (states(''sensor.demand_delta'') | int | abs) / (states(''sensor.demand_delta'') | int) }}' alias: Adjust Main Steam Control Valve +/- 1 - alias: NOTIFICATION action: persistent_notification.create data: message: "Demand: {{ states('sensor.power_demand_mw') }}
Output: {{\ \ states('sensor.total_power_output_mw') }}
Delta = {{ states('sensor.demand_delta')\ \ | round(2) }}

Loop: {{loop}} ==> STEAM VALVE adjustment
MSCV\ \ = {{ target_mscv }}
New Primary = {{\n (target_mscv | int * 300\ \ / states('sensor.coolant_core_circulation_pump'+loop+'capacity') |\n\ int) | int }}
New Secondary = {{ (target_mscv | int * 1000 / states('sensor.coolant_sec_circulation_pump'+loop+'capacity')\ \ | int) | int }}
Ratio:{{flow_ratio | round(4)}}" notification_id: SteamValve enabled: true - delay: hours: 0 minutes: 0 seconds: '{{ 10 / states(''sensor.game_sim_speed'') | int }}' milliseconds: 0 alias: Wait for (10 / simspeed) seconds - delay: hours: 0 minutes: 0 seconds: 1 milliseconds: 0 mode: single - id: '1746027130216' alias: Core Target Temp description: '' triggers: - trigger: state entity_id: - sensor.core_state_criticality - sensor.core_temp - sensor.rods_pos_actual for: hours: 0 minutes: 0 seconds: 5 conditions: - condition: numeric_state entity_id: sensor.core_state_criticality above: -5 below: 5 actions: - variables: tgt_reactivity: '{{ min(((states(''input_number.target_core_temp'') | float - states(''sensor.core_temp'') | float) / states(''input_number.target_core_temp'') | float) | round(3) * 10 | float,2) }}' - alias: Target ROD Position different than Actual Position if: - condition: template value_template: "{{ (states('sensor.rods_pos_actual') | float + max(states('sensor.core_state_criticality')\ \ | float - tgt_reactivity,-2)) \n | float | round(1) != states('sensor.rods_pos_actual')\ \ | float | round(1) }}\n" then: - action: notify.persistent_notification metadata: {} data: message: "SET RODS to {{(states('sensor.rods_pos_actual') | float + max(states('sensor.core_state_criticality')\ \ | float - tgt_reactivity,-2)) \n | float | round(2) }}" data: notification_id: rods - action: rest_command.nucleares_webserver_set data: var: RODS_ALL_POS_ORDERED val: '{{ states(''sensor.rods_pos_actual'') | float + max(states(''sensor.core_state_criticality'') | float - tgt_reactivity,-2) }}' alias: Adjust Control Rods - delay: hours: 0 minutes: 0 seconds: '{{ (states(''sensor.core_temp'') | int - states(''input_number.target_core_temp'') | int) | abs / 10 / states(''sensor.game_sim_speed'') | int + 1 }}' milliseconds: 0 mode: single - id: '1746249037975' alias: Hourly Timestamp description: '' triggers: - trigger: template value_template: '{{ states(''sensor.time'').split(":")[1] | int == 0 }}' enabled: true conditions: [] actions: - action: input_number.set_value metadata: {} data: value: 10000 target: entity_id: - input_number.timestamp - action: input_number.set_value metadata: {} data: value: 0 target: entity_id: - input_number.timestamp mode: single