Kohler Decision-Maker MPAC V2 (Kohler)
The Kohler MPAC driver monitors and controls a Kohler Decision-Maker MPAC V2 automatic transfer switch (ATS) controller — MPAC 1200 V2 or MPAC 1500 V2 — over Modbus/TCP. It polls the controller's system overview, source metering, setup, I/O, active events, and run-history registers and publishes them as device attributes with history enabled for graphing. It also exposes a small set of control commands: force-transfer-to-off, resume, loaded/unloaded test, preferred-source selection, transition-mode change, and service disconnect.
This is a single controller device — all values surface as device attributes, so you do not have to create zones for it. Register addressing follows Kohler TP-6113 §15 (the Decision-Maker MPAC V2 Modbus map), using Kohler's extended convention where register 400001 is holding register 0.
Status
Built against Kohler TP-6113 Section 15. Tested against the MPAC 1200/1500 V2 register map. Serial Modbus/RTU is supported by the underlying Modbus transport but most MPAC V2 controllers are commissioned over Ethernet (Modbus/TCP), which this page assumes.
Prerequisites
- An MPAC V2 controller (1200 or 1500) reachable on the LAN with its Modbus/TCP option enabled in the controller menus.
- The controller's Modbus TCP Unit ID — Kohler's default is 2 (not 1).
- Outbound TCP/502 from the GEM controller to the MPAC IP address.
- Know whether your unit is in legacy or non-legacy device-ID mode if you intend to confirm the model from the
device_idattribute (see Identifying the model).
An ATS switches a building between utility and generator power. The force transfer, test, service disconnect, and preferred source commands change how that switch behaves and can drop or transfer load. Only issue them when you understand the on-site consequences, and confirm the controller's front-panel switch is in Auto — many MPAC configurations reject Modbus writes while the front panel is in Manual or Off.
Setup
- Enable Modbus/TCP on the MPAC controller and note its IP address and Unit ID (default
2). - Create the device — open Devices (System → Devices → Add Device), give it a
name, and pick the Kohler Decision-Maker MPAC V2 driver. The form's View integration guide button opens this page inline. - Fill in the connection fields in the Device Attributes section:
- Unit ID — match the controller (default
2). - Controller IP — the MPAC's LAN address (under Show optional attributes, in the Connection group).
- TCP Port —
502(default).
- Unit ID — match the controller (default
- (Optional) Choose the register groups to poll — the Monitored Register Groups field controls how much is read each cycle (see Register groups below). Leave it at the default to poll live metering, setup, status, and history.
- Pick a subsystem for the device. Of the driver's suggested subsystems (Power, Generator, Building Automation), only Power ships by default — create Generator or Building Automation under Subsystems first if you want a dedicated one.
- Save (the button reads Create Device) and watch the device's attributes populate after the first poll completes.
Use the Load sample: MPAC 1500 V2 on the LAN button on the Device Attributes header to pre-fill a typical configuration (ip, port 502, unit_id 2, a trimmed register-group list), then adjust the IP.
Device attributes
These are the configuration fields you set on the device. Everything else on this page is read from the controller automatically.
| Attribute | Required | Type | Default | Notes |
|---|---|---|---|---|
unit_id | yes | int | 2 | Modbus slave address. Kohler default is 2. Range 1–247. |
ip | no | string | — | LAN IP of the MPAC controller (for Modbus/TCP). |
port | no | int | 502 | Modbus/TCP port. |
comm_port | no | string | — | Serial device path for Modbus/RTU wiring (e.g. /dev/ttyUSB0). See Serial wiring. |
baud_rate | no | int | 9600 | Modbus/RTU baud rate. |
timeout | no | int | 10000 | Modbus request timeout in ms. |
polling_rate | no | int | 30000 | How often (ms) the selected register groups are swept. |
reconnect_timeout | no | int | 3000 | Delay (ms) between reconnect attempts after a transport error. |
monitor_registers | no | string | monitoring,setup,status,history | Comma-separated list of register groups to poll. See below. |
Register groups
monitor_registers decides which blocks of the register map are read each cycle. The field renders as a dropdown offering each single group plus all; the default polls four groups at once. To poll a custom combination of several groups, set the monitor_registers value to a comma-separated list in the device's Attributes editor (e.g. monitoring,status,history).
| Group | What it reads | In the default? |
|---|---|---|
monitoring | System overview, source A/B voltages, line voltages, frequencies, currents, closed-transition phase delta. | yes |
setup | Nominal voltages/frequencies, phase counts, rated amperage, transition/operation mode, preferred-source selection, service-disconnect type. | yes |
status | Active time delay, MLB input/output state and hardware-output bits, accessory status, and active events. | yes |
history | Last outage, switch-transfer counts, failures-to-transfer, loss-of-preferred counts, transfer times, run/standby minutes. | yes |
ats | ATS designation, load/branch descriptions, location, serial number (text fields). | no |
network | MPAC + FPGA firmware, controller IP, configured unit ID, present date/time, model device_id. | no |
all | Everything above. | — |
ats and network are not in the default set, so the controller's nameplate strings, firmware versions, and device_id only appear if you add those groups (or choose all). They change rarely, so polling them every cycle is wasteful — add them once to confirm, then drop back to the runtime groups.
Values are deduplicated: an attribute is only written when its value actually changes, and every published attribute has history enabled so you can graph it under History.
Telemetry attributes (auto-populated)
Read live from the controller by the poll loop. Bitmap registers are decoded into individual named attributes — e.g. the System Overview register becomes system_overview_contactor_position, system_overview_preferred_source, and so on. Enumerated values resolve to the exact strings below; use them verbatim when writing triggers or macro conditions on plant state.
System overview & events (monitoring + status)
| Attribute | Values / unit |
|---|---|
system_overview_contactor_position | off · source1 · source2 · source1_source2 |
system_overview_preferred_source | source1 · source2 |
system_overview_preferred_source_available | true · false |
system_overview_standby_source_available | true · false |
active_events | Comma-separated list of active event descriptions, or none. |
active_event_codes | Comma-separated numeric event codes. |
active_event_count | Number of active events. |
active_events is a human-readable roll-up of every active alarm/state bit. Common entries include: not in auto, exerciser active, test mode active, peak shave mode active, load control active, source 1 under voltage / source 1 over voltage, source 2 under voltage / source 2 over voltage, loss of phase, fail to transfer, fail to acquire preferred, common alarm active, service disconnect, critical service required. A code with no friendly name shows as event <n>.
Source metering (monitoring)
| Attribute | Unit |
|---|---|
source_a_voltage_l1 / _l2 / _l3 | V (line-to-neutral) |
source_b_voltage_l1 / _l2 / _l3 | V (line-to-neutral) |
source_a_line_voltage_l1_l2 / _l2_l3 / _l3_l1 | V (line-to-line) |
source_b_line_voltage_l1_l2 / _l2_l3 / _l3_l1 | V (line-to-line) |
source_a_frequency / source_b_frequency | Hz |
current_l1 / current_l2 / current_l3 | A |
phase_degree_delta | ° (closed-transition phase difference) |
Source A is typically the utility/normal source and Source B the generator/emergency source, but confirm against the controller's wiring.
Setup & mode (setup)
| Attribute | Values / unit |
|---|---|
service_disconnect_type | off · emergency · hold_current |
nominal_normal_voltage / nominal_emergency_voltage | V |
nominal_normal_frequency / nominal_emergency_frequency | Hz |
normal_number_of_phases / emergency_number_of_phases | count |
rated_amperage | A |
preferred_source_selection | source1 · source2 |
transition_operation_modes_transition_mode | open · programmed · closed |
transition_operation_modes_operation_mode | genset · genset_to_utility · utility_to_genset_genset · utility_to_utility |
transition_operation_modes_transfer_switch_position | auto · manual |
transition_operation_modes_transfer_switch_position is the one to watch before sending control commands: manual means the front panel is in control and Modbus writes will likely be rejected.
Status & I/O (status)
| Attribute | Notes |
|---|---|
time_delay_number | Which active time-delay timer is running. |
time_delay_remaining / time_delay_preset | Seconds. |
mlb_input_state / mlb_output_state | Raw MLB I/O state words. |
mlb_hardware_output_engine_start_control | Engine start contact. |
mlb_hardware_output_relay_k1 … _relay_k4 | Programmable relay outputs K1–K4. |
mlb_hardware_output_source_1_available / _source_2_available | Source-available contacts. |
mlb_hardware_output_contactor_source_1 / _contactor_source_2 | Contactor position contacts. |
mlb_hardware_output_not_in_auto / _warning | Not-in-auto and warning flags. |
accessory_status_exercise_in_progress | Exerciser running. |
accessory_status_loaded_test_occurring / _unloaded_test_occurring | Test state. |
accessory_status_peak_shave_in_progress / _load_control_in_progress | Demand-management state. |
accessory_status_user_forcing_to_off | A force-transfer-to-off is active. |
Run history (history)
| Attribute | Unit |
|---|---|
last_outage_time / last_outage_date | clock / calendar |
last_outage_duration | min |
switch_transfers_total / switch_transfers_reset | count |
failures_to_transfer_total / failures_to_transfer_reset | count |
loss_of_preferred_total / loss_of_preferred_reset | count |
transfer_time_src1_to_src2 / transfer_time_src2_to_src1 | ms |
minutes_operation_total / minutes_standby_total / minutes_not_preferred_total | min |
The _total counters are lifetime; the _reset counters are since the last controller reset.
Nameplate & network (ats + network)
Only polled when you add the ats and/or network groups.
| Attribute | Notes |
|---|---|
ats_designation / ats_load_description / ats_branch_description / ats_location | Free-text labels configured on the controller. |
ats_serial_number | ATS serial number. |
mpac_firmware_version / fpga_firmware_version | Firmware (major.minor). |
ip_address / modbus_tcp_unit_id | As reported by the controller. |
present_date / present_time | Controller clock. |
device_id | Resolved model name — see below. |
Identifying the model
When the network group is polled, device_id resolves the controller's model code to a label:
| Code | Model |
|---|---|
78 | MPAC 1500 V2 |
77 | MPAC 1200 V2 |
23 | MPAC 1500 V2 (legacy addressing) |
27 | MPAC 1200 V2 (legacy addressing) |
A code the driver doesn't recognize is reported as unknown (<n>).
Commands
Issue these from a macro, a trigger, or the device's command surface. The read-only commands are always safe; the rest write to the controller and should be used with the warning above in mind.
| Command | Args | What it does |
|---|---|---|
get_status | — | Returns the last cached register values (no controller write). |
poll | — | Forces an immediate poll of the selected register groups. |
force_transfer_off | — | Forces the transfer switch to the off position. |
resume_operation | — | Clears a force-transfer and resumes normal operation. |
start_test | loaded | Starts a generator test. loaded = true for a loaded test, false for an unloaded test. |
stop_test | — | Ends an in-progress remote test. |
set_preferred_source | value | Sets the preferred source. 0 = source 2, 1 = source 1. |
set_transition_mode | value | Sets the transition mode. 0 = open, 1 = programmed, 2 = closed. |
service_disconnect | value | Sets the service-disconnect type. 0 = off, 1 = emergency, 2 = hold current. |
start_test takes its argument as a string — pass loaded as true or false. Out-of-range values on set_preferred_source / set_transition_mode / service_disconnect are rejected with an error rather than written, so a mistyped value can't put the controller in an undefined state.
Serial (Modbus/RTU)
If the MPAC is wired to GEM over RS-485 instead of Ethernet, the underlying Modbus transport opens a serial device at the configured baud rate. Set the Baud Rate to match the controller and wire A/B per the controller's terminal markings. For serial commissioning detail — adapters, wiring, and the unit-ID scanner — see the Modbus integration page. Ethernet (Modbus/TCP) is the recommended and most common path for MPAC V2.
Troubleshooting
| Symptom | Check |
|---|---|
| No attributes populate | Wrong Unit ID (Kohler default is 2, not 1), Modbus/TCP not enabled on the controller, or TCP/502 blocked. Confirm the IP and that Modbus is on in the controller menus. |
connection refused / timeouts on 502 | Modbus/TCP option is disabled, or another Modbus master already owns the connection. The MPAC serves one master. |
| Control commands have no effect | The front panel is in Manual or Off — check transition_operation_modes_transfer_switch_position; it must read auto. Many configurations reject Modbus writes otherwise. |
| Nameplate / firmware / IP attributes are missing | The ats and network groups aren't in the default poll set. Add them to Monitored Register Groups (or choose all) for one cycle to capture them. |
| Values feel slow to update | Lower Poll Interval (ms) from the 30000 default — but keep it reasonable; the driver only writes attributes that actually changed, so frequent polling is cheap but still loads the bus. |
device_id reads unknown (<n>) | Your controller reports a model code outside the known set; the rest of the register map still reads correctly. |
Related Documentation
- Modbus — generic Modbus transport, unit-ID scanner, and register browser this driver builds on
- Devices — adding and managing devices (the MPAC is a single device with telemetry as device attributes; it creates no zones)
- Subsystems — where to place the controller (Power by default)
- Attributes — viewing and editing the device's attributes, including
monitor_registers - History — graphing the controller's metered and history attributes over time
- Triggers — react to active events, source loss, or transfer state changes
- Power Management — the energy dashboard where power devices surface