Pentair ScreenLogic (IntelliTouch / EasyTouch)
The pentair_screenlogic driver integrates GEM with Pentair pool/spa controllers through the ScreenLogic2 Protocol Adapter (Pentair P/N 522104). It covers the IntelliTouch family (i5, i7, i9, i10+) and EasyTouch (4 / 8) controllers that pre-date IntelliCenter. For the newer IntelliCenter controller, pick the pentair_ip driver instead — it speaks a different protocol on a different port.
The ScreenLogic adapter exposes a binary message protocol on local TCP port 80. Despite the port, this is Pentair's own protocol — it is NOT HTTP. Pointing a browser at the adapter returns garbage.
What this driver supports
- Automatic zone creation — on connect (and via the
sync_zonescommand) the driver discovers every controller circuit and creates one GEM zone per circuit, routing lights to the lighting subsystem and everything else to the pool/water subsystem. The sync is additive and idempotent — existing zones are never touched. - Circuit control — turn any controller-defined circuit on or off. Pool, Spa, Pool Light, Spa Light, AUX 1–4 (or however your installer labeled them) are all driven by the same
set_circuit_statemessage under the hood. - Pool/spa body zones with on/off + setpoint — the Pool and Spa body circuits are auto-created with the
water_onoff_setpointcontrol, which renders the body's live water temperature, the heat setpoint with up/down adjustment, and the on/off buttons in a single tile. Setpoint changes from that control are routed to the correct body automatically (no manual body-index wrangling). - Heat setpoint — adjust pool or spa heater setpoint within the controller's configured min/max range.
- Heat mode — set body heat mode to
off,solar,solar_preferred,heater, ordont_change. - Status polling — air temperature, pool/spa water temperature and pool/spa setpoints land on the device as live read-only values; the on/off state of every controller circuit lands on whichever zone you mapped to that circuit. Pool/spa body zones additionally mirror their live
temperature,setpoint,heat_modeand a derivedsystem_modeso triggers, widgets and the setpoint control can read them directly. Polled every 15 s by default.
Prerequisites
- A Pentair ScreenLogic2 Protocol Adapter (P/N 522104) on the same LAN as GEM, with a reserved DHCP lease or static IP.
- A Pentair IntelliTouch or EasyTouch controller wired to the ScreenLogic adapter's RS-485 port.
- The ScreenLogic password (set in the Pentair ScreenLogic mobile app, under Settings → Network). If no password is configured on the adapter, leave the field blank.
Setup steps
- Reserve an IP for the ScreenLogic2 adapter in your router so GEM can find it after a reboot.
- On the Devices page choose System → Devices → Add Device and pick the driver
pentair_screenlogic. Set:- ScreenLogic Adapter IP (
ip) — the adapter's local IP. - TCP Port (
port) — leave at 80 unless you are tunneling through another box. - ScreenLogic Password (
password) — the password from the mobile app, or blank if none.
- ScreenLogic Adapter IP (
- Save and reload the device. Within a few seconds the device's status attributes (Air Temperature, Pool/Spa Water Temperature, Pool/Spa Heat Setpoint) populate, confirming the adapter logged in.
- The driver auto-creates one GEM zone per discovered circuit on connect — no manual zone setup is required. Light circuits (Pool Light, Spa Light, IntelliBrite, MagicStream, etc.) land in the lighting subsystem as
light_switchzones; the Pool and Spa body circuits land in the pool/water subsystem aswater_onoff_setpointzones (on/off plus the heat setpoint tile); every other non-light circuit (Cleaner, Spillway, Valve, generic AUX) lands in the pool/water subsystem as a plainwater_onoffzone. Each zone's address is the ScreenLogic circuit id (e.g.,500) and its label is the circuit name from the controller. The circuit's ScreenLogic function code is stored on the zone asscreenlogic_circuit_functionfor reference, and body zones additionally carrybody_type(0= pool,1= spa).- Subsystem resolution is forgiving: the driver looks for a subsystem named pool, then water, then spa for non-light circuits, and light for light circuits. If the matching subsystem does not exist, that circuit is skipped with a log warning — add the subsystem on the Subsystems page and re-run
sync_zones.
- Subsystem resolution is forgiving: the driver looks for a subsystem named pool, then water, then spa for non-light circuits, and light for light circuits. If the matching subsystem does not exist, that circuit is skipped with a log warning — add the subsystem on the Subsystems page and re-run
- Auto-create is additive and idempotent: it only ever creates zones for circuit ids that don't already have one on this device. It never modifies, re-subsystems, renames, or removes an existing zone. Disable any auto-created zones you don't want, and freely change the subsystem/control/label of the ones you keep — a later
sync_zonesleaves them untouched. Run thesync_zonescommand any time (Script Console or a macro) to pick up circuits added to the controller after the initial sync. - Trigger an
on/offcommand on a zone from the Zones page to verify the round-trip before subscribing UI widgets.
Attribute reference
Device attributes
| Attribute | Type | Required | Description |
|---|---|---|---|
ip | string | yes | Local IP of the ScreenLogic2 adapter. |
port | int | no (default 80) | TCP port the adapter listens on. |
password | secure string | no | Adapter password from the Pentair ScreenLogic mobile app. Leave blank if none set. |
status_interval | int | no (default 15000) | How often the driver polls pool/spa status, in milliseconds. |
request_timeout | int | no (default 5000) | Fallback wait before treating a message as lost. Each built-in command already applies its own fixed timeout (3–5 s), so this value only takes effect for requests that don't specify one — in practice it rarely changes behavior. |
The driver also writes these read-only status attributes onto the device after each poll: air_temp, pool_temp, spa_temp, pool_setpoint, spa_setpoint. They are the device's reported values — set them on the device only if you want a starting value before the first poll; the driver overwrites them on every status tick.
Zone attributes
| Attribute | Type | Description |
|---|---|---|
screenlogic_circuit_function | int | The ScreenLogic circuit function code captured at auto-create time (e.g., 2 = Pool, 1 = Spa, 7/16 = light variants). Informational — useful for spotting how the driver classified a circuit. |
body_type | int | Set on pool/spa body zones only: 0 = pool, 1 = spa. Targets heat-setpoint writes from the setpoint verb / water_onoff_setpoint control. Absent on non-body circuits. |
The driver also writes the standard state (on / off) onto each zone as circuit states change. On body zones (pool/spa) it additionally mirrors, every poll: temperature (live water temp), setpoint (current heat setpoint), heat_mode (the body's heat-source string), and system_mode (heat when a heat source is selected, otherwise off — this is what lights the heat indicator on the setpoint control).
Zone address format
A plain integer matching the ScreenLogic circuit id. Ids start at 500 but the map is not fixed — body and AUX ids differ per install, so don't assume them. The driver auto-creates a zone per circuit (labeled with the controller's own circuit name), and you can run get_circuits to confirm the ids on a given controller. A typical IntelliTouch install looks like this (yours will differ):
| Address | Typical meaning |
|---|---|
500 | Spa body circuit |
505 | Pool body circuit |
501–504, 506+ | Pumps, lights, fountains, jets and other AUX outputs |
Commands
| Command | Args | Description |
|---|---|---|
on | address | Turn the addressed circuit on. |
off | address | Turn the addressed circuit off. |
set_circuit_state | address, state | Generic on/off — state accepts on/off/1/0. |
set_heat_setpoint | address, setpoint | Body setpoint in the controller's configured units (°F on US installs, °C on EMEA). address is the body index — 0 for pool, 1 for spa. The low-level command; for zone-driven control use setpoint instead. |
setpoint | setpoint | Set the heat setpoint for a pool/spa body zone. The body is derived from the zone (its body_type attribute / circuit address), so this fires directly off a body zone — it's the verb the water_onoff_setpoint control emits. |
set_heat_mode | address, mode | Body heat mode: off, solar, solar_preferred, heater, dont_change. address is the body index — 0 for pool, 1 for spa. |
get_circuits | — | List circuit ids and names from the controller. Use this during onboarding. |
sync_zones | — | Discover circuits and auto-create one GEM zone per circuit. Additive and idempotent — existing zone addresses are skipped, none are modified or removed. Runs automatically on connect; re-run it to pick up circuits added later. |
get_status | — | Refresh pool/spa/air temperatures and circuit states immediately. |
get_version | — | Read the firmware version string from the ScreenLogic adapter. |
There are two ways to set a heat setpoint. From a pool/spa body zone (or its water_onoff_setpoint tile) use the generic setpoint verb — the driver derives the body from the zone, so you don't pass a body index. The low-level set_heat_setpoint / set_heat_mode commands instead take address = the body index (0 pool, 1 spa), not a circuit id; run those as device-level commands (Script Console or a macro with explicit address/setpoint/mode). The on/off/set_circuit_state commands use address = the circuit id and work directly from a zone.
Known limitations
- One client at a time. The ScreenLogic2 adapter only accepts a single active session. Close the Pentair ScreenLogic mobile app and any other integrations (Home Assistant, screenlogicpy scripts) before relying on GEM, otherwise the adapter aggressively drops the older socket.
- Pump speed / chemistry telemetry is not parsed. The status response carries IntelliFlo pump speeds and Chem Controller chlorine/pH/ORP readings, but the driver currently reads only air/water temperatures, setpoints, and circuit states. Pump and chemistry values are not surfaced.
- Light themes / IntelliBrite colors are not exposed as commands. The controller can drive them, but the driver does not currently send color/theme commands.
- Schedule and macro editing are not exposed. Edit schedules from the ScreenLogic mobile app; GEM only reads and writes runtime state.
- The driver polls on a fixed interval rather than listening for unsolicited pushes. If a circuit changes from the Pentair app or a wall control, GEM reflects it on the next status tick (15 s by default) rather than instantly. Lower
status_intervalif you need tighter latency. - The setpoint tile assumes °F-range values. The shared
water_onoff_setpoint/ climate-setpoint control only adjusts setpoints that read between 50 and 140, which matches °F pool/spa setpoints. On a °C-configured controller the displayed temperature and setpoint are still correct, but the up/down arrows will refuse to act because a ~28 °C value falls outside that window. Use theset_heat_setpointdevice command on °C installs until the control's range is unit-aware.
Troubleshooting
| Symptom | What to check |
|---|---|
connect succeeds but login fails immediately | Wrong password. Open the Pentair ScreenLogic mobile app on the same LAN and copy the password from Settings → Network. If the adapter is unprotected, leave the field blank. |
| Socket connects then drops within seconds | Another client (mobile app, Home Assistant, etc.) is holding the adapter. ScreenLogic only accepts one session at a time. |
| Pool / spa state never updates | Confirm the circuit id you used as the zone address with get_circuits. IntelliTouch sometimes renumbers AUX ids after a configuration reset. |
| Circuit on/off times out | The circuit command already waits up to 5 s for an acknowledgement, so a timeout almost always means something else: another client is holding the adapter's single session, the device dropped its login (reload it and watch for the status attributes to repopulate), or the circuit id used as the zone address no longer matches the controller — re-run get_circuits to confirm. (Raising request_timeout does not extend the circuit-command wait, which is fixed.) |
| Heat setpoint silently ignored | The controller enforces a min/max range that the driver does not pre-validate. Open the IntelliTouch on-screen menu and confirm the heat limit configuration covers the value you sent. |
| Temperatures are in the wrong unit | The controller reports in the unit it is configured for. Change the unit on the IntelliTouch itself (or in the ScreenLogic mobile app) — the driver does not transform the value. |
Choosing between pentair_screenlogic and pentair_ip
| Your controller | Driver |
|---|---|
| IntelliTouch (i5 / i7 / i9 / i10+) with ScreenLogic adapter | pentair_screenlogic |
| EasyTouch (4 / 8) with ScreenLogic adapter | pentair_screenlogic |
| IntelliCenter (any model) | pentair_ip |
The IntelliCenter controller talks directly on TCP 6681 in its own newline-delimited JSON protocol — there is no ScreenLogic adapter in front of it. The two drivers cannot be used interchangeably.
Related Documentation
- Devices — adding and managing the ScreenLogic device
- Zones — mapping circuits to controllable zones
- Subsystems — where pool/spa zones live (add a Pool subsystem if you want one)