# DuoPump

## `DuoPump` (FB)

FUNCTION\_BLOCK DuoPump

### Short description

> Redundant control of two identical circulation pumps with anti-blocking function\
> Additional functions: request for heat generation, manual overrides, pump run-on, operating hours counter, operational monitoring\
> Typical application: redundant control of a twin pump in a heating circuit

### Representation

<figure><img src="/files/eb3108bd4fed1ea86a96634a49f125ff1b54eb53" alt=""><figcaption></figcaption></figure>

### Interfaces

#### Inputs

| Name        | Data type         | Value range                                                               | Initial value          | Function                                                        |
| ----------- | ----------------- | ------------------------------------------------------------------------- | ---------------------- | --------------------------------------------------------------- |
| *xEnOne*    | BOOL              |                                                                           |                        | Request for lead pump                                           |
| *xEnTwo*    | BOOL              |                                                                           |                        | Request for lead and follower pump                              |
| *xFb1*      | BOOL              |                                                                           |                        | Operating feedback of circulation pump 1                        |
| *xFb2*      | BOOL              |                                                                           |                        | Operating feedback of circulation pump 2                        |
| *xAlarmIn1* | BOOL              |                                                                           |                        | Fault indication of circulation pump 1                          |
| *xAlarmIn2* | BOOL              |                                                                           |                        | Fault indication of circulation pump 2                          |
| *eAOO1*     | HVACTYPES.eManBin | HVACTYPES.eManBin.Auto, HVACTYPES.eManBin.ManOff, HVACTYPES.eManBin.ManOn | HVACTYPES.eManBin.Auto | Operating mode of manual override - hardware circulation pump 1 |
| *eAOO2*     | HVACTYPES.eManBin | HVACTYPES.eManBin.Auto, HVACTYPES.eManBin.ManOff, HVACTYPES.eManBin.ManOn | HVACTYPES.eManBin.Auto | Operating mode of manual override - hardware circulation pump 2 |
| *xQuit*     | BOOL              |                                                                           | FALSE                  | Reset of fault indication of operational monitoring             |

#### Outputs

| Name                 | Data type       | Value range | Initial value | Function                                                        |
| -------------------- | --------------- | ----------- | ------------- | --------------------------------------------------------------- |
| *xHB1*               | BOOL            |             |               | Enable - circulation pump 1 after manual override               |
| *xHB2*               | BOOL            |             |               | Enable - circulation pump 2 after manual override               |
| *xAB1*               | BOOL            |             |               | Enable - circulation pump 1 before manual override              |
| *xAB2*               | BOOL            |             |               | Enable - circulation pump 2 before manual override              |
| *xEnergyRequest*     | BOOL            |             |               | Request for heat generation                                     |
| *xAlarmFb1*          | BOOL            |             |               | Fault indication - operational monitoring - circulation pump 1  |
| *xAlarmFb2*          | BOOL            |             |               | Fault indication - operational monitoring - circulation pump 2  |
| *tOffDelay*          | TIME            |             |               | Remaining time of the circulation pump off-delay                |
| *dtLastFb1*          | DATE\_AND\_TIME |             |               | Date/time of last operation of circulation pump 1               |
| *dtLastFb2*          | DATE\_AND\_TIME |             |               | Date/time of last operation of circulation pump 2               |
| *dtAbsLastOn1*       | DATE\_AND\_TIME |             |               | Date/time of last anti-blocking operation of circulation pump 1 |
| *dtAbsLastOn2*       | DATE\_AND\_TIME |             |               | Date/time of last anti-blocking operation of circulation pump 2 |
| *udiOperatingHours1* | UDINT           |             |               | Operating hours of circulation pump 1                           |
| *udiOperatingHours2* | UDINT           |             |               | Operating hours of circulation pump 2                           |
| *udiCountFb1*        | UDINT           |             |               | Number of starts of circulation pump 1                          |
| *udiCountFb2*        | UDINT           |             |               | Number of starts of circulation pump 2                          |
| *xAlarm1*            | BOOL            |             |               | Collective fault - circulation pump 1                           |
| *xAlarm2*            | BOOL            |             |               | Collective fault - circulation pump 2                           |
| *xAlarm*             | BOOL            |             |               | Aggregate fault                                                 |
| *xAuto*              | BOOL            |             |               | Collective automatic-mode message                               |

#### Setpoints / parameters

| Name                  | Data type         | Value range                                                                                  | Initial value          | Function                                                 |
| --------------------- | ----------------- | -------------------------------------------------------------------------------------------- | ---------------------- | -------------------------------------------------------- |
| **eManModeB1**        | eMANBIN           | eMANBIN.Auto, eMANBIN.ManOff, eMANBIN.ManOn                                                  | eMANBIN.Auto           | Operating mode of manual override for circulation pump 1 |
| **eManModeB2**        | eMANBIN           | eMANBIN.Auto, eMANBIN.ManOff, eMANBIN.ManOn                                                  | eMANBIN.Auto           | Operating mode of manual override for circulation pump 2 |
| **udiOffDelay**       | UDINT             | 0 to 600s                                                                                    | 60s                    | Run-on duration of the circulation pumps                 |
| **eOffDelayTimeBase** | eTime             | eTime.Second, eTime.Minute, eTime.Hour                                                       | eTime.Second           | Scaling of the off-delay (seconds / minutes / hours)     |
| **eAbsDay**           | eDoW              | eDoW\.Monday to eDoW\.Sunday                                                                 | eDoW\.Monday           | Weekday of the anti-blocking operation                   |
| **todAbsStartTime**   | TOD               | 00:00:00 - 23:59:59                                                                          | 08:00:00               | Time of the anti-blocking operation                      |
| **tAbsTime**          | UDINT             | 0 to 3600s                                                                                   | 120s                   | Duration of the anti-blocking operation                  |
| **xFbControl**        | BOOL              |                                                                                              | TRUE                   | Enable operational monitoring                            |
| **udiFbControlTime**  | UDINT             | 0 to 300s                                                                                    | 60s                    | Duration of the operating monitoring                     |
| **eModeRedundance**   | eOpModeRedundance | eOpModeRedundance.Auto, eOpModeRedundance.ForceComponent1, eOpModeRedundance.ForceComponent2 | eOpModeRedundance.Auto | Redundancy mode                                          |

### Function description

#### General

This function block controls two identical circulation pumps in redundant operation.\
The selection of the number of required circulation pumps is made via the inputs *xEnOne* and *xEnTwo*\
The enables of circulation pumps 1 and 2 are made via the outputs *xHB1* and *xHB2* or *xAB1* and *xAB2*.\
\
The following function blocks are essentially used:

* Redundance2
* AbsB
* OperatingHours
* ManBin

> **Prerequisite for using the DuoPump function block**
>
> The use of the TimeRead2 function block is required for correct operation.

#### Redundant control

It is used for redundant control of the two circulation pumps depending on the influencing variables requests (*xEnOne* and *xEnTwo*), operating hours (*uxiOperatingHours1* and *uxiOperatingHours2*), operating states (*xFb1* and *xFb2*), fault conditions (*xAlarm1* and *xAlarm2*) and the operating mode for sequence determination (**eModeRedundance**).\
The enable of the lead and, if necessary, the follower pump is determined internally and transferred to the internal outputs *xCmd1* or *xCmd2* transferred.\
\
The lead pump is requested when it is requested by the input *xEnOne* and/or while the pump run-on time is active.\
The lead and the follower pump are requested when they are requested by the input *xEnTwo* requested.\
Requests at input *xEnTwo* take precedence over requests at input *xEnOne*.\
\
The selection of lead or follower pump is given high priority by the states of the fault indications of the circulation pumps *xAlarm1* or *xAlarm2* (Fault = TRUE).\
\
The selection of lead or follower pump is given low priority by the parameter *eModeRedundance*.\
With *eModeRedundance* = Auto the selection is made based on the current number of operating hours of the circulation pumps.\
The time difference for switching based on operating hours is 100 hours. Switching occurs according to different criteria which are described in detail in the FB Redundance2.\
The options **xConOperatingHours** as well as **xEnFb** are activated (= TRUE).\
In the case *eModeRedundance* = ForceComponent1 or *eModeRedundance* = ForceComponent2 the lead pump is accordingly circulation pump 1 or circulation pump 2.

#### Enable - circulation pump 1 before manual override *xAB1*

The output *xAB1* is set by the redundant control, the output *xAlarm1*, the off-delay module and the anti-blocking module.

| Redundant control | *xAlarm1* | Off-delay module | Anti-blocking module | *xAB1* | Notes                                |
| ----------------- | --------- | ---------------- | -------------------- | ------ | ------------------------------------ |
| X                 | TRUE      | X                | X                    | FALSE  | Shutdown allowed by collective fault |
| FALSE             | X         | FALSE            | FALSE                | FALSE  | Lock via redundant control           |
| TRUE              | X         | FALSE            | FALSE                | TRUE   | Enable via redundant control         |
| X                 | X         | TRUE             | X                    | TRUE   | Off-delay operation                  |
| X                 | X         | X                | TRUE                 | TRUE   | Anti-blocking operation              |

Legend: X = any

#### Enable - circulation pump 2 before manual override *xAB2*

The output *xAB2* by the redundant control, the output *xAlarm2*, the off-delay module and the anti-blocking module.

| Redundant control | *xAlarm2* | Off-delay module | Anti-blocking module | *xAB2* | Notes                                |
| ----------------- | --------- | ---------------- | -------------------- | ------ | ------------------------------------ |
| X                 | TRUE      | X                | X                    | FALSE  | Shutdown allowed by collective fault |
| FALSE             | X         | FALSE            | FALSE                | FALSE  | Lock via redundant control           |
| TRUE              | X         | FALSE            | FALSE                | TRUE   | Enable via redundant control         |
| X                 | X         | TRUE             | X                    | TRUE   | Off-delay operation                  |
| X                 | X         | X                | TRUE                 | TRUE   | Anti-blocking operation              |

Legend: X = any

#### Enable - circulation pump 1 after manual override *xHB1*

Enable - circulation pump 1 after manual override *xHB1* corresponds to Enable - circulation pump 1 before manual override *xAB1*, additionally extended by a manual override module.

| *xAB1* | eMANBIN        | *xHB1* | Notes                                          |
| ------ | -------------- | ------ | ---------------------------------------------- |
| FALSE  | eMANBIN.Auto   | FALSE  | Manual override module in automatic            |
| TRUE   | eMANBIN.Auto   | TRUE   | Manual override module in automatic            |
| X      | eMANBIN.ManOn  | TRUE   | Manual override module in manual operation On  |
| X      | eMANBIN.ManOff | FALSE  | Manual override module in manual operation Off |

Legend: X = any

#### Enable - circulation pump 2 after manual override *xHB2*

Enable - circulation pump 2 after manual override *xHB2* corresponds to Enable - circulation pump 2 before manual override *xAB2*, additionally extended by a manual override module.

| *xAB2* | eMANBIN        | *xHB2* | Notes                                          |
| ------ | -------------- | ------ | ---------------------------------------------- |
| FALSE  | eMANBIN.Auto   | FALSE  | Manual override module in automatic            |
| TRUE   | eMANBIN.Auto   | TRUE   | Manual override module in automatic            |
| X      | eMANBIN.ManOn  | TRUE   | Manual override module in manual operation On  |
| X      | eMANBIN.ManOff | FALSE  | Manual override module in manual operation Off |

Legend: X = any

#### Operating feedbacks *xFb1* and *xFb2*

Circulation pump 1 in operation: *xFb1* = TRUE\
Circulation pump 1 not in operation: *xFb1* = FALSE\
\
Circulation pump 2 in operation: *xFb2* = TRUE\
Circulation pump 2 not in operation: *xFb2* = FALSE

#### Fault indications *xAlarmIn1* and *xAlarmIn2*

Circulation pump 1 faulty: *xAlarmIn1* = TRUE\
Circulation pump 1 not faulty: *xAlarmIn1* = FALSE\
\
Circulation pump 2 faulty: *xAlarmIn2* = TRUE\
Circulation pump 2 not faulty: *xAlarmIn2* = FALSE

#### Reset of fault indication of operational monitoring *xQuit*

The reset of the fault indication of the operational monitoring *xAlarmFb1* and *xAlarmFb2* occurs as long as the reset of the fault indication of the operational monitoring *xQuit* is active (= TRUE).

#### Request - energy generation *xEnergyRequest*

The request - energy generation *xEnergyRequest* is influenced by the anti-blocking modules, the run-on modules and the operating feedbacks of circulation pumps 1 and 2 *xFb1* and *xFb2* .\
\
The request - heat generation *xEnergyRequest* is active when\
\
the operating feedback from circulation pump 1 *xFb1* is present and at the same time the anti-blocking module 1 is not active\
and/or\
the operating feedback from circulation pump 2 *xFb2* is present and at the same time the anti-blocking module 2 is not active\
and\
the run-on module is not active

#### Off-delay module

The run-on module is realized by a turn-off delay with an adjustable duration **udiOffDelay** . The run-on module is activated if no request is present via the inputs *xEnOne* or *xEnTwo* anymore.\
The pump run-on occurs only on the lead pump.

#### Anti-blocking modules

The anti-blocking modules are realized by the binary anti-blocking module with adjustable duration.\
The duration **tAbsTime**, the time **tAbsStartTime** and the weekday **eAbsDay** is adjustable for the first pump.\
The timing for the second pump is offset from the timing of the first pump by twice the duration of the first pump **tAbsTime**.\
The timestamp (date/time) of the last anti-blocking operation is available, separated for each circulation pump, at the outputs *dtAbsLastOn1* or *dtAbsLastOn2* available.

#### Collective fault - circulation pump 1 *xAlarm1*

The collective fault - circulation pump 1 *xAlarm1* is active (= TRUE) if the fault indication of circulation pump 1 *xAlarmIn1* is active (= TRUE) and/or a fault indication - operational monitoring - circulation pump 1 *xAlarmFb1* (= TRUE) is present.\
In all other situations the collective fault - circulation pump 1 is *xAlarm1* not active (= FALSE).

#### Collective fault - circulation pump 2 *xAlarm2*

The collective fault - circulation pump 2 *xAlarm2* is active (= TRUE) if the fault indication of circulation pump 2 *xAlarmIn2* is active (= TRUE) and/or a fault indication - operational monitoring - circulation pump 2 *xAlarmFb2* (= TRUE) is present.\
In all other situations the collective fault - circulation pump 2 is *xAlarm2* not active (= FALSE).

#### Aggregate fault *xAlarm*

The aggregate fault *xAlarm* is active (= TRUE) if the collective fault - circulation pump 1 *xAlarm1* is active or the collective fault - circulation pump 2 *xAlarm2* is active.\
In all other situations the collective fault is *xAlarm* not active (= FALSE).

#### Operating hours counter - circulation pump 1

The operating hours counter for circulation pump 1 is active when the operating feedback *xFb1* = TRUE and at the same time the collective fault *xAlarm1* = FALSE is.

#### Operating hours counter - circulation pump 2

The operating hours counter for circulation pump 2 is active when the operating feedback *xFb2* = TRUE and at the same time the collective fault *xAlarm2* = FALSE is.

> **Write access to the counter values**
>
> Via the path ‘InstanceName.\_OperatingHours\[1].udiOperatingHours’ or ‘InstanceName.\_OperatingHours\[1].udiCountFb’ a write access to both counter values is possible.\
> Via the path ‘InstanceName.\_OperatingHours\[2].udiOperatingHours’ or ‘InstanceName.\_OperatingHours\[2].udiCountFb’ a write access to both counter values is possible.

#### Operational monitoring - circulation pump 1

The operational monitoring monitors the correct function of circulation pump 1.\
The monitoring can generally be enabled (**xFbControl** = TRUE) or disabled (**xFbControl** = FALSE).\
The operating mode of the manual override - hardware circulation pump 1 must be in automatic mode (*eAOO1* = HVACTYPES.eManBin.Auto).\
\
The fault indication - operational monitoring - circulation pump 1 *xAlarmFb1* is activated (= TRUE) if during the duration of the operational monitoring **udiFbControlTime** the states of the input *xFb1* and the output *xHb1* are unequal.\
\
The fault indication - operational monitoring - circulation pump 1 *xAlarmFb1* is deactivated (= FALSE) if at least one of the following conditions is active:\
\
\&#xNAN;*eAOO1* = HVACTYPES.eManBin.Auto (switching to automatic mode of the manual override - hardware).\
Reset of the fault indication of the operational monitoring *xQuit* = TRUE\
Enable operational monitoring **xFbControl** = FALSE

#### Operational monitoring - circulation pump 2

The operational monitoring monitors the correct function of circulation pump 2.\
The monitoring can generally be enabled (**xFbControl** = TRUE) or disabled (**xFbControl** = FALSE).\
The operating mode of the manual override - hardware circulation pump 2 must be in automatic mode (*eAOO2* = HVACTYPES.eManBin.Auto).\
\
The fault indication - operational monitoring - circulation pump 2 *xAlarmFb2* is activated (= TRUE) if during the duration of the operational monitoring **udiFbControlTime** the states of the input *xFb2* and the output *xHb2* are unequal.\
\
The fault indication - operational monitoring - circulation pump 2 *xAlarmFb2* is deactivated (= FALSE) if at least one of the following conditions is active:\
\
\&#xNAN;*eAOO2* = HVACTYPES.eManBin.Auto (switching to automatic mode of the manual override - hardware).\
Reset of the fault indication of the operational monitoring *xQuit* = TRUE\
Enable operational monitoring **xFbControl** = FALSE

#### Collective automatic-mode message *xAuto*

The collective automatic-mode message *xAuto* is activated (= TRUE) if the following conditions are met simultaneously:

* Input *eAOO1* = HVACTYPES.eManBin.Auto
* Input *eAOO2* = HVACTYPES.eManBin.Auto
* Setpoint / parameters **eManModeB1** = eMANBIN.Auto
* Setpoint / parameters **eManModeB2** = eMANBIN.Auto

### CODESYS

InOut:

| Scope       | Name                 | Type              | Initial                |
| ----------- | -------------------- | ----------------- | ---------------------- |
| Input       | `xEnOne`             | `BOOL`            |                        |
| Input       | `xEnTwo`             | `BOOL`            |                        |
| Input       | `xFb1`               | `BOOL`            |                        |
| Input       | `xFb2`               | `BOOL`            |                        |
| Input       | `xAlarmIn1`          | `BOOL`            |                        |
| Input       | `xAlarmIn2`          | `BOOL`            |                        |
| Input       | `eAOO1`              | eManBin           | eManBin.Auto           |
| Input       | `eAOO2`              | eManBin           | eManBin.Auto           |
| Input       | `xQuit`              | `BOOL`            | FALSE                  |
| Output      | `xHB1`               | `BOOL`            |                        |
| Output      | `xHB2`               | `BOOL`            |                        |
| Output      | `xAB1`               | `BOOL`            |                        |
| Output      | `xAB2`               | `BOOL`            |                        |
| Output      | `xEnergyRequest`     | `BOOL`            |                        |
| Output      | `xAlarmFb1`          | `BOOL`            |                        |
| Output      | `xAlarmFb2`          | `BOOL`            |                        |
| Output      | `tOffDelay`          | `TIME`            |                        |
| Output      | `dtLastFb1`          | `DT`              |                        |
| Output      | `dtLastFb2`          | `DT`              |                        |
| Output      | `dtAbsLastOn1`       | `DT`              |                        |
| Output      | `dtAbsLastOn2`       | `DT`              |                        |
| Output      | `udiOperatingHours1` | `UDINT`           |                        |
| Output      | `udiOperatingHours2` | `UDINT`           |                        |
| Output      | `udiCountFb1`        | `UDINT`           |                        |
| Output      | `udiCountFb2`        | `UDINT`           |                        |
| Output      | `xAlarm1`            | `BOOL`            |                        |
| Output      | `xAlarm2`            | `BOOL`            |                        |
| Output      | `xAlarm`             | `BOOL`            |                        |
| Output      | `xAuto`              | `BOOL`            |                        |
| Input Const | `eModeRedundance`    | eOpModeRedundance | eOpModeRedundance.Auto |
| Input Const | `udiFbControlTime`   | `UDINT`           | 60                     |
| Input Const | `xFbControl`         | `BOOL`            | TRUE                   |
| Input Const | `udiAbsTime`         | `UDINT`           | 120                    |
| Input Const | `todAbsStartTime`    | `TOD`             | TIME\_OF\_DAY#9:0      |
| Input Const | `eAbsDay`            | eDoW              | eDow\.Monday           |
| Input Const | `eOffDelayTimeBase`  | eTime             | eTime.Second           |
| Input Const | `udiOffDelay`        | `UDINT`           | 60                     |
| Input Const | `eManModeB2`         | eMANBIN           | eMANBIN.Auto           |
| Input Const | `eManModeB1`         | eMANBIN           | eMANBIN.Auto           |

Methods:

> mQuit

> mResetOperatingHours

Structure:

* mQuit (Method)
* mResetOperatingHours (Method)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://support.powerio.com/hub/codesys-hvac/en/hvac-library/functionblocks/components/duopump.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
