Silverline / Poolex Pool Heat Pump custom integration for Home Assistant

If you own a Poolex Silverline FI pool heat pump — or one of its OEM siblings (Brustec, Steinbach Silent Mini, Phalén Calidi XP, and other Poolstar-platform units with a Tuya WBR3 module) — you've probably hit the wall that made me write this: the official Tuya integration shows the pump as off / heat only, and LocalTuya can't cleanly reach Boost or the cooling modes either. The hardware speaks seven modes; the existing tooling exposes maybe two of them.

So I built a small, local-only integration that models the device properly.

:backhand_index_pointing_right: Repo: GitHub - christianreiss/ha-silverline: Local Home Assistant custom integration for Poolex Silverline FI pool heat pumps (Tuya v3.3): climate control, diagnostics, presets, LAN auto-discovery, no cloud dependency, HACS-installable. · GitHub
License: MIT.


What it does

It talks the Tuya local protocol v3.3 directly over your LAN — no Smart Life cloud at runtime — and presents the pump as a single, clean climate entity:

  • HVAC modes: off / heat / cool / heat_cool (Auto)
  • Presets: inverter / boost / silent, which together cover all seven device modes — including Boost-Cool and Silent-Cool, the ones the official HA Tuya integration cannot reach (core#117566).
  • Per-mode setpoint handling: the slider's min/max adapts to the active mode (Heat 15–40 °C, Cool 8–28 °C, Auto 8–40 °C), because the device clamps differently per mode and keeps a separate stored setpoint for each.

On top of that:

  • Diagnostic sensors (firmware-dependent — see below): compressor exhaust/return temps, evaporator + ambient temps, water inlet/outlet, target/actual compressor frequency, EEV step count, fan rpm, and a decoded fault code.
  • Binary sensors for the water-pump relay and the common fault bits (water flow, antifreeze, high/low pressure, comms).
  • Fault codes as self-clearing Repair issues — a fault opens an issue under Settings → Repairs and closes itself the moment the device clears the bit.
  • Reauth flow when the local key rotates, Reconfigure flow for IP changes, plus LAN auto-discovery of the device.
  • Diagnostics download with secrets redacted, and German + English translations.

The protocol layer is a standalone async library (pysilverline) — a hand-rolled Tuya v3.3 client, usable outside Home Assistant if you want it.


Honest caveat: diagnostic sensors are firmware-dependent

This is the one thing I want to be upfront about. The rich diagnostic DPs (101–111) only exist on some firmware variants. The Poolex PC-SLP090N I verified live exposes exactly five datapoints — power, target temp, current temp, mode, fault — and none of the 101–111 diagnostics. The Brustec / Steinbach firmware ships the full set.

The integration handles this gracefully: it only registers entities for the DPs your firmware actually emits, so you never get a dashboard full of permanently-unavailable sensors. But it means: if you're on a minimal Poolex firmware, you get the climate entity + fault handling and not much telemetry. That's the device's limit, not the integration's.

Other known limits, all documented in the README: °F mode isn't supported (lock the remote to °C), Auto mode has no Boost/Silent variant (device limitation — selecting a preset in Auto raises a clear error), and switching HVAC mode restores that mode's last stored setpoint after ~½ second.


Install

Via HACS → Custom repositories → add https://github.com/christianreiss/ha-silverline as type Integration → install Poolex Silverline → restart → add it from Settings → Devices & Services.

You'll need the device's IP, Device ID, and local key (the usual tinytuya wizard / Tuya IoT Platform route — instructions in the README). The setup form validates the credentials against the live device before it creates the entry, so a wrong key surfaces as invalid_auth right there instead of silently failing later.

One gotcha worth repeating: the WBR3 module accepts one local TCP client at a time. If Smart Life is still talking to it on the same network, HA gets kicked. Cleanest fix is to firewall the pump off outbound 443/8886 so it stays genuinely LAN-only — which is the whole point anyway.


What I'd love help with :folded_hands:

I've only been able to verify against my own PC-SLP090N. The Tuya schema is shared across the whole Poolstar/WBR3 family, so the integration should work on the siblings — but "should" isn't "does."

If you have a Poolex JetLine Selection FI, a Steinbach Silent Mini, a Brustec BR, a Phalén Calidi XP, or any other Silverline FI size (120/180/200): please install it, and grab the diagnostics download from the device page (Settings → Devices → your pump → ⋮ → Download diagnostics — it's secret-redacted). Drop it here or open an issue. That tells me exactly which DPs your firmware exposes and lets me confirm the 101–111 diagnostic mapping on real hardware instead of inference.

Bug reports, mode-enum mismatches, and "this DP means something different on my unit" reports are all very welcome.

Repo, README, and full known-limitations list: GitHub - christianreiss/ha-silverline: Local Home Assistant custom integration for Poolex Silverline FI pool heat pumps (Tuya v3.3): climate control, diagnostics, presets, LAN auto-discovery, no cloud dependency, HACS-installable. · GitHub

Happy to answer anything below. :person_swimming:

Hello,
I own a Poolex Silverline Full Inverter 70 heat pump, which communicates using the local Tuya protocol v3.5.

After some effort, I was only able to establish communication using the Tuya Heat Pump (Local) integration, although not without difficulties.

I tested your modification/update, but unfortunately it did not resolve the issue and I was unable to achieve a successful connection.

Please let me know if you need any additional logs, diagnostics, or configuration details from my side.

Thanks a lot for testing this and for reporting back — really appreciated :folded_hands:

From what you described, your main issue seems to be the initial local connection itself (not just missing entities afterward), and the key detail is that your FI 70 appears to speak Tuya local protocol v3.5.

This integration is currently built for the v3.3 Poolstar/WBR3 family, so if your unit is truly v3.5, a failed handshake/auth is unfortunately expected right now.

If you’re willing, I’d love to collect a bit of data so I can verify this properly and see what’s needed for v3.5 support.

Please share: exact model + firmware version of the heat pump; Home Assistant version + integration version/commit you tested; debug logs from a failed setup attempt; diagnostics download from the config entry (redacted is fine); and whether tinytuya can connect locally with the same IP/device ID/local key (including what protocol version it reports).

For debug logs in HA, you can temporarily add:

logger:
  default: warning
  logs:
    custom_components.silverline: debug
    pysilverline: debug

Then restart HA, retry setup once, and share the relevant log excerpt.

:warning: Please do not post secrets publicly (local key, full device ID, tokens, etc.).

If you share those details, I can confirm whether this is a strict v3.5 protocol mismatch and map out the next step.

I released 0.8.3 with improved 3.5 Support; upgrade and give it a try!

Hi Christian,

after testing the new version, the device can now be added successfully, and there is no need for the heat pump to be without internet connection.

I selected the integration as “Other / Unknown” during setup (not a specific model).

Updated diagnostics from Poolex Silverline FI 70.

Key information:

  • Tuya protocol: 3.5 (detected + configured)
  • Connection: successful (local)
  • DP range: 1, 2, 3, 4, 13, 101–145

The behavior confirms a working v3.5 handshake, but DP-to-entity mapping needs adjustment (incorrect sensor/temperature values).

Diagnostics attached (redacted).

If needed, I can provide HA debug logs or a tinytuya comparison.

Thanks!
Michal

Glad 3.5 connects now! :tada:

The wrong readings are expected. Your Full Inverter 70 exposes DPs 101–145, but the integration's 101–111 map currently comes from a different model (the JetLine Selection FI). So those diagnostic sensors read the right DP numbers but the wrong meaning for your firmware — e.g. it labels whatever your DP 101 is as "exhaust temperature."

The core climate values (power/mode/set/current temp on DPs 1–4) should be correct. Could you confirm whether the set and current water temperature in HA match the OEM app? If they read ~10× too high (e.g. 280 instead of 28), there's also a scaling difference to handle.

To map your model properly I need to see what each DP actually is. Two things would let me do it:

(a) A raw tinytuya snapshot of the full dps dict (values, ideally with types):slight_smile:

python -m tinytuya scan to find it, then in Python:

import tinytuya
d = tinytuya.Device('DEVICE_ID', 'IP', 'LOCAL_KEY', version=3.5)
print(d.status())

(b) The OEM app readings at the same moment — water in/out, ambient/air temp, set temp, and any compressor frequency / fan values it shows — so each DP number can be matched to its meaning.

:warning: Please redact your device ID and local key before posting; the dps values themselves are fine to share.

With that I'll add a proper Full Inverter 70 profile (correct DP map + any scaling) in the next release.

Hi Christian,

I’m sending the DP values from the TinyTuya output:

{'dps': {'1': True, '2': 32, '3': 27, '4': 'Heat', '13': 0, '101': 28, '102': 22, '103': 27, '104': 67, '105': 8, '106': 6, '108': 35, '109': 85, '110': 85, '111': 267, '114': 781, '115': 0, '120': 230, '121': 4, '124': 45, '125': 12, '126': 12, '127': 0, '128': 2, '130': 0, '131': 2, '132': -1, '133': -8, '137': 10, '138': 0, '140': 80, '141': 0, '142': 40, '145': 8}}

Preliminary DP mapping:

  • DP 2 → 32 °C (set water temperature)
  • DP 103 → 27 °C (inlet water temperature)
  • DP 101 → 28 °C (outlet water temperature)
  • DP 102 → 22 °C (ambient air temperature)

I’m not able to reliably identify the meaning of the remaining DPs yet.

Thanks,
Michal

This is very helpful, thank you!

What's already clear from the dump:

DP Value Meaning
1 true power on
2 32 set temp (°C)
3 27 current water temp (°C)
4 Heat mode
13 0 fault bitmap (no faults)
101 28 outlet water temp (°C)
102 22 ambient air temp (°C)
103 27 inlet water temp (°C)

Note: DP 107 is absent from your firmware entirely — the JetLine FI has it as target frequency, your device doesn't use it.

My best guesses for the rest — please cross-check with the OEM app:

  • DP 108 = 35 → actual compressor frequency (Hz)?
    • DP 142 = 40 → target compressor frequency (Hz)?
    • DP 104 = 67 → outdoor humidity (%)?
    • DP 114 = 781 → power consumption (W)?
    • DP 120 = 230 → AC voltage (V) — looks very much like mains voltage
    • DP 121 = 4 → current draw (A)?
    • DP 124 = 45 → discharge gas temperature (°C)?
    • DP 110 = 85 → fan speed (% or RPM)?
    • DP 111 = 267 → water pump speed (RPM)?
      Could you check the OEM app while the pump is running and tell me what values it shows for frequency, humidity, power, and anything else — so I can pin down the unknowns?

Once confirmed I'll add a proper Full Inverter 70 profile so those diagnostic sensors all read correctly.

Hi,

That’s exactly the problem — in the Tuya app, the device appears only as a basic heater controller. I can adjust the temperature and switch modes (heating, cooling, etc.). I can also see the inlet temperature, outlet temperature, outdoor temperature, and the timer, but that’s about all it can do :frowning:

Well, what else do you expect it to report? :slight_smile:

Hi Christian,

I did some more testing with my Poolex Silverline Full Inverter 70, and I’d like to clarify my previous report.

Current behavior

The integration does connect successfully and the device is created in Home Assistant.
I can see entities, temperature sensors, and other status values, and those values are updating correctly.

Where the problem occurs

The issue appears when I try to send a control command to the heat pump, for example:

  • changing the operating mode
  • changing the target temperature

At that moment, Home Assistant logs show the following error:

Failed to update the heat pump: timeout waiting for cmd 0x07

What this suggests

So at the moment it looks like:

  • reading data works
  • entities and sensors are created correctly
  • status / temperature values are updated
  • but write / control commands fail

So the problem does not seem to be the initial connection itself, but rather the write/control operations.

Additional test

I also tried blocking the heat pump’s IP from internet access, to rule out any interference between local communication and the cloud / official app, but it did not help. The behavior remained exactly the same.

Thanks,
Michal

Thanks for the detailed report — timeout waiting for cmd 0x07 was the exact clue I needed. :slightly_smiling_face:

What was wrong: on v3.5 the integration was sending control writes (mode / target-temp changes) with the old v3.3 control opcode 0x07. v3.5 firmware ignores that opcode — it expects the newer CONTROL_NEW (0x0d) command, the same one v3.4 uses. Reads use a different command and were already correct, which is why connecting and the entities updating worked fine while every write timed out.

Fixed in 0.9.2 (bundling pysilverline 0.4.2), just released. Please update via HACS (redownload the integration if the update doesn't show up straight away), restart Home Assistant, and try changing the mode or the target temperature.

Tracking issue: v3.5 control writes time out — set_multiple sends CONTROL (0x07) instead of CONTROL_NEW (0x0d) · Issue #4 · christianreiss/ha-silverline · GitHub

Since I don't have v3.5 hardware here, could you report back whether writes work now? If it still fails, the exact error matters — in particular whether the message now says cmd 0x0d instead of 0x07. That one detail tells me the command itself is now correct and only the acknowledgement handling needs a final tweak.

Thanks again for the legwork on this one!

Hi Christian,
First of all thank you for the wonderfull integration.

I also have a Poolex Silverline Full Inverter 70. I tested it with version 0.9.2 of your Integration, and it seems that making changes still have a little trouble. The command seems to reach the device and now failes with this error:

CONTROL failed retcode=0x01000000

Thank you for your work,
Lennart

Hey!

I had a similar Bug Report on Github (Issues · christianreiss/ha-silverline · GitHub) already. Your issue might have been solved already. Upgrade to v0.9.3 or beyond and retest!

Hi,

I have the same problem with version 0.9.6 also on my jetline FI series. Read values are ok but write/actions values seems KO.

I see also this in my logs :
2026-06-23 21:46:22.685 INFO (MainThread) [homeassistant.components.climate] Setting up poolex_silverline.climate

2026-06-23 21:46:22.686 INFO (MainThread) [homeassistant.components.sensor] Setting up poolex_silverline.sensor

2026-06-23 21:46:22.689 INFO (MainThread) [homeassistant.components.binary_sensor] Setting up poolex_silverline.binary_sensor

2026-06-23 21:46:22.690 INFO (MainThread) [homeassistant.components.switch] Setting up poolex_silverline.switch

2026-06-23 21:46:22.690 INFO (MainThread) [homeassistant.components.number] Setting up poolex_silverline.number

2026-06-23 21:46:22.690 INFO (MainThread) [homeassistant.components.select] Setting up poolex_silverline.select

2026-06-23 22:03:05.708 ERROR (MainThread) [custom_components.poolex_silverline.coordinator] Error fetching poolex_silverline data: poll failed: timeout waiting for cmd 0x0a

Many thanks for your wonderful work.
Cheers
DM

Some details here
2026-06-24 11:15:08.756 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Finished fetching poolex_silverline data in 0.014 seconds (success: True)

2026-06-24 11:15:09.897 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:15:30.900 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:15:38.110 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:15:38.756 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Finished fetching poolex_silverline data in 0.014 seconds (success: True)

2026-06-24 11:15:47.907 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:15:51.910 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:15:55.911 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:16:04.916 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:16:06.656 DEBUG (MainThread) [pysilverline.client] v3.5 CONTROL_NEW ack carried retcode=0x01000000; accepting (write-ack retcode is not a reliable failure signal)

2026-06-24 11:16:06.656 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Manually updated poolex_silverline data

2026-06-24 11:16:08.129 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:16:08.918 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:16:21.923 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame 2026-06-24 11:15:08.756 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Finished fetching poolex_silverline data in 0.014 seconds (success: True)

2026-06-24 11:15:09.897 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:15:30.900 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:15:38.110 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:15:38.756 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Finished fetching poolex_silverline data in 0.014 seconds (success: True)

2026-06-24 11:15:47.907 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:15:51.910 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:15:55.911 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:16:04.916 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:16:06.656 DEBUG (MainThread) [pysilverline.client] v3.5 CONTROL_NEW ack carried retcode=0x01000000; accepting (write-ack retcode is not a reliable failure signal)

2026-06-24 11:16:06.656 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Manually updated poolex_silverline data

2026-06-24 11:16:08.129 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:16:08.918 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame

2026-06-24 11:16:21.923 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame
--------------- JSON ----------------
{
"home_assistant": {
"arch": "x86_64",
"dev": false,
"docker": true,
"hassio": true,
"installation_type": "Home Assistant OS",
"os_name": "Linux",
"os_version": "6.18.35-haos",
"python_version": "3.14.5",
"timezone": "Europe/Zurich",
"version": "2026.6.4",
"virtualenv": false,
"container_arch": "amd64",
"supervisor": "2026.06.2",
"host_os": "Home Assistant OS 18.0",
"docker_version": "29.5.3",
"chassis": "vm",
"run_as_root": true
},
"custom_components": {
"sun2": {
"documentation": "",
"version": "3.4.3",
"requirements":
},
"ecowitt_local": {
"documentation": "",
"version": "1.7.5",
"requirements": [
"aiohttp>=3.8.0"
]
},
"auto_backup": {
"documentation": "",
"version": "1.5.3",
"requirements":
},
"solar_energy_management": {
"documentation": "",
"version": "1.7.2",
"requirements":
},
"email_notifier": {
"documentation": "",
"version": "0.1.2",
"requirements":
},
"blitzortung": {
"documentation": "",
"version": "1.5.0",
"requirements": [
"paho-mqtt>=2.1.0"
]
},
"wiim": {
"documentation": "",
"version": "1.0.92",
"requirements": [
"pywiim==2.2.16"
]
},
"ajax": {
"documentation": "",
"version": "0.32.2",
"requirements": [
"aiobotocore>=2.22.0",
"onvif-zeep-async>=3.1.12"
]
},
"aegis_ajax": {
"documentation": "",
"version": "1.12.1",
"requirements": [
"grpcio>=1.60.0",
"protobuf>=4.25.0",
"firebase-messaging>=0.4.5",
"pycryptodome>=3.20"
]
},
"solaredge_forecast": {
"documentation": "",
"version": "1.0.2",
"requirements": [
"solaredge==0.0.4"
]
},
"flightradar24": {
"documentation": ""
"version": "v1.34.2",
"requirements": [
"FlightRadarAPI==1.5.1",
"pycountry==24.6.1"
]
},
"poolex_silverline": {
"documentation": "",
"version": "0.9.6",
"requirements": [
"pysilverline==0.4.4"
]
},
"samsungtv_smart": {
"documentation": "",
"version": "0.14.5",
"requirements": [
"websocket-client!=1.4.0,>=0.58.0",
"wakeonlan>=2.0.0",
"aiofiles>=0.8.0",
"casttube>=0.2.1"
]
},
"hacs": {
"documentation": "",
"version": "2.0.5",
"requirements": [
"aiogithubapi>=22.10.1"
]
},
"localtuya": {
"documentation": "",
"version": "5.2.3",
"requirements":
},
"swissweather": {
"documentation": "",
"version": "1.2.5",
"requirements": [
"requests"
]
},
"frigate": {
"documentation": "",
"version": "5.15.4",
"requirements": [
"hass-web-proxy-lib==0.0.8",
"titlecase==2.4.1"
]
},
"presence_simulation": {
"documentation": "",
"version": "4.11",
"requirements":
},
"solaredge_modbus_multi": {
"documentation": "",
"version": "3.2.5",
"requirements": [
"pymodbus>=3.8.3",
"awesomeversion>=25.5.0"
]
}
},
"integration_manifest": {
"domain": "poolex_silverline",
"name": "Poolex Silverline",
"codeowners": [
"christianreiss"
],
"config_flow": true,
"documentation": "",
"integration_type": "device",
"iot_class": "local_push",
"issue_tracker": "",
"loggers": [
"pysilverline",
"custom_components.poolex_silverline"
],
"quality_scale": "platinum",
"requirements": [
"pysilverline==0.4.4"
],
"version": "0.9.6",
"is_built_in": false,
"overwrites_built_in": false
},
"setup_times": {
"null": {
"setup": 0.00028439698508009315
},
"01KVTYXDAH0QHYVBN98JFVEGA4": {
"wait_import_platforms": -1.0728572999942116,
"config_entry_setup": 1.981609396985732
}
},
"data": {
"versions": {
"integration": "0.9.6",
"pysilverline": "0.4.4"
},
"entry": {
"created_at": "2026-06-23T19:22:02.449831+00:00",
"data": {
"device_id": "REDACTED",
"host": "REDACTED",
"local_key": "REDACTED",
"model": "jetline_fi",
"port": 6668,
"protocol_version": "3.5"
},
"discovery_keys": {},
"disabled_by": null,
"domain": "poolex_silverline",
"entry_id": "REDACTED",
"minor_version": 3,
"modified_at": "2026-06-23T19:22:02.449833+00:00",
"options": {},
"pref_disable_new_entities": false,
"pref_disable_polling": false,
"source": "user",
"subentries": ,
"title": "REDACTED",
"unique_id": "REDACTED",
"version": 1
},
"device_info": {
"device_id": "REDACTED",
"model": "jetline_fi"
},
"connection": {
"host": "REDACTED",
"port": 6668,
"detected_version": "3.5",
"connected": true
},
"coordinator": {
"supported_dps": [
"1",
"101",
"102",
"103",
"104",
"105",
"106",
"108",
"109",
"110",
"111",
"114",
"115",
"120",
"121",
"124",
"125",
"126",
"127",
"128",
"13",
"130",
"131",
"132",
"133",
"137",
"138",
"140",
"141",
"142",
"145",
"2",
"3",
"4"
],
"runtime_today_seconds": 4966.467291000003,
"last_update_success": true,
"last_exception": null,
"active_fault_codes":
},
"state": {
"power": true,
"temp_set": 29,
"temp_current": 30,
"mode": "Auto",
"fault": 0,
"suction_temp": 30,
"ambient_temp": 29,
"pool_temp": 30,
"discharge_temp": 63,
"inlet_temp": 16,
"outlet_temp": 18,
"outdoor_coil_temp": null,
"indoor_coil_temp": null,
"target_frequency": null,
"actual_frequency": 40,
"eev_steps": 35,
"fan_speed": 35,
"aux_valve_opening": null,
"water_pump": true,
"water_pump_rpm": 140,
"condensing_temp": 45,
"evaporating_temp": -8,
"superheat": -1,
"compressor_load": 80,
"total_hours": 237,
"target_superheat": 10,
"target_condensing": 40,
"raw": {
"1": true,
"2": 29,
"3": 30,
"4": "Auto",
"13": 0,
"101": 30,
"102": 29,
"103": 30,
"104": 63,
"105": 16,
"106": 18,
"108": 40,
"109": 35,
"110": 35,
"111": 140,
"114": 551,
"115": 0,
"120": 237,
"121": 2,
"124": 45,
"125": 12,
"126": 12,
"127": 0,
"128": 2,
"130": 0,
"131": 2,
"132": -1,
"133": -8,
"137": 10,
"138": 0,
"140": 80,
"141": 0,
"142": 40,
"145": 8
}
}
},
"issues":
}

Hey @darkm00nch — thanks for the detailed logs and the diagnostics dump, that's exactly what I needed to narrow this down. :folded_hands:

I dug into your case. Two separate things are going on, and importantly, neither is the retcode you saw.

1. The "ignoring undecryptable push frame" spam. These frames actually decrypt cleanly with your session key (if the key were wrong the connection would drop instead) — but the plaintext your JetLine FI firmware sends in its STATUS pushes isn't JSON in the shape the parser expects. So every push update is silently thrown away, and the integration falls back to polling. That's why reads look fine but the live state feels sluggish/off.

2. Writes acked-but-not-applied. The retcode=0x01000000 is a red herring — real Tuya v3.5 firmware (confirmed on another unit) acks writes with exactly those bytes even when the write succeeds, so the integration correctly treats it as "accepted" and tinytuya does the same. Flipping that back to "error" wouldn't make your writes apply — it'd just hide the problem behind a scary message again. The real cause is almost certainly that your firmware speaks a slightly different control dialect, and I need to see the bytes to be sure.

Here's the honest bit: I don't have a v3.5 JetLine FI on my bench, so I can't reproduce this directly. Rather than ship a blind guess, I just released v0.9.10 (with pysilverline 0.4.6) which adds one diagnostic-only change (no behaviour change): when a push can't be parsed, it now logs the raw decrypted bytes. That lets me see exactly what your pump is actually sending.

Could you help me capture it? Update to v0.9.10 via HACS, then add this to configuration.yaml and restart:

logger:
  default: warning
  logs:
    pysilverline: debug
    custom_components.poolex_silverline: debug

Then please grab:

(1) A few of the new push lines — they'll look like ignoring undecryptable push frame (cmd=0x08, NN bytes): a1b2c3… — paste 3–4 of them.

(2) A write test — set the target temperature to something clearly different (e.g. +3 °C), wait ~60 s for a full poll, and tell me whether it held or snapped back. That confirms whether the write truly fails on the device vs. just a display glitch.

(3) Does the official Tuya / Smart Life app change settings on this unit reliably? (Confirms the hardware accepts writes at all.)

With those three I can build a real, testable fix for the JetLine FI v3.5 family (which should also help @lenbu98's Full Inverter 70). The push bytes are just DP state — no credentials in them, safe to paste.


Note for everyone else reading: for new bug reports please open a GitHub issue (Issues · christianreiss/ha-silverline · GitHub) rather than replying here — it keeps device-specific logs, versions and back-and-forth in one trackable place. Thanks! :slightly_smiling_face:

Hi Christian,

(1) here are some of the new push lines:

2026-06-27 10:37:14.867 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Finished fetching poolex_silverline data in 0.012 seconds (success: True)
2026-06-27 10:37:25.792 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame (cmd=0x08, 269 bytes): 00000000332e35000000000000f930000000017b2270726f746f636f6c223a342c2274223a313738323534393434342c2264617461223a7b22647073223a7b22313034223a37342c22313036223a32312c22313033223a32372c22313031223a32392c22313035223a31372c22313032223a33322c22313038223a34332c22313039223a37352c22313130223a37352c22313131223a3234322c22313134223a3738312c22313135223a302c22313230223a3231352c22313231223a342c22313234223a34352c22313235223a31322c22313236223a31322c22313237223a302c22313238223a322c22313330223a302c22313331223a322c22313337223a31
2026-06-27 10:37:44.868 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Finished fetching poolex_silverline data in 0.012 seconds (success: True)
2026-06-27 10:37:56.803 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame (cmd=0x08, 269 bytes): 00000000332e35000000000000f931000000017b2270726f746f636f6c223a342c2274223a313738323534393437352c2264617461223a7b22647073223a7b22313034223a37342c22313036223a32312c22313033223a32372c22313031223a32392c22313035223a31372c22313032223a33322c22313038223a34322c22313039223a37352c22313130223a37352c22313131223a3234332c22313134223a3738312c22313135223a302c22313230223a3231342c22313231223a342c22313234223a34352c22313235223a31322c22313236223a31322c22313237223a302c22313238223a322c22313330223a302c22313331223a322c22313337223a31
2026-06-27 10:38:14.868 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Finished fetching poolex_silverline data in 0.013 seconds (success: True)
2026-06-27 10:38:26.815 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame (cmd=0x08, 269 bytes): 00000000332e35000000000000f932000000017b2270726f746f636f6c223a342c2274223a313738323534393530352c2264617461223a7b22647073223a7b22313034223a37342c22313036223a32312c22313033223a32372c22313031223a32392c22313035223a31372c22313032223a33312c22313038223a34332c22313039223a37352c22313130223a37352c22313131223a3234332c22313134223a3738302c22313135223a302c22313230223a3231372c22313231223a342c22313234223a34352c22313235223a31322c22313236223a31322c22313237223a302c22313238223a322c22313330223a302c22313331223a322c22313337223a31
2026-06-27 10:38:44.867 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Finished fetching poolex_silverline data in 0.012 seconds (success: True)
2026-06-27 10:38:56.824 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame (cmd=0x08, 269 bytes): 00000000332e35000000000000f933000000017b2270726f746f636f6c223a342c2274223a313738323534393533352c2264617461223a7b22647073223a7b22313034223a37342c22313036223a32312c22313033223a32372c22313031223a32392c22313035223a31372c22313032223a33312c22313038223a34332c22313039223a37352c22313130223a37352c22313131223a3234342c22313134223a3738312c22313135223a302c22313230223a3231352c22313231223a342c22313234223a34352c22313235223a31322c22313236223a31322c22313237223a302c22313238223a322c22313330223a302c22313331223a322c22313337223a31
2026-06-27 10:39:14.870 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Finished fetching poolex_silverline data in 0.015 seconds (success: True)
2026-06-27 10:39:27.836 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame (cmd=0x08, 269 bytes): 00000000332e35000000000000f934000000017b2270726f746f636f6c223a342c2274223a313738323534393536362c2264617461223a7b22647073223a7b22313034223a37342c22313036223a32312c22313033223a32372c22313031223a32392c22313035223a31372c22313032223a33302c22313038223a34332c22313039223a37352c22313130223a37352c22313131223a3234342c22313134223a3738312c22313135223a302c22313230223a3231342c22313231223a342c22313234223a34352c22313235223a31322c22313236223a31322c22313237223a302c22313238223a322c22313330223a302c22313331223a322c22313337223a31
2026-06-27 10:39:37.657 DEBUG (MainThread) [pysilverline.client] v3.5 CONTROL_NEW ack carried retcode=0x01000000; accepting (write-ack retcode is not a reliable failure signal)
2026-06-27 10:39:37.658 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Manually updated poolex_silverline data
2026-06-27 10:39:57.854 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame (cmd=0x08, 269 bytes): 00000000332e35000000000000f935000000017b2270726f746f636f6c223a342c2274223a313738323534393539362c2264617461223a7b22647073223a7b22313034223a37332c22313036223a32302c22313033223a32372c22313031223a32392c22313035223a31372c22313032223a33302c22313038223a34322c22313039223a37352c22313130223a37352c22313131223a3234342c22313134223a3738312c22313135223a302c22313230223a3231352c22313231223a342c22313234223a34352c22313235223a31322c22313236223a31322c22313237223a302c22313238223a322c22313330223a302c22313331223a322c22313337223a31
2026-06-27 10:40:06.869 DEBUG (MainThread) [custom_components.poolex_silverline.coordinator] Finished fetching poolex_silverline data in 0.014 seconds (success: True)
2026-06-27 10:40:28.858 DEBUG (MainThread) [pysilverline.client] ignoring undecryptable push frame (cmd=0x08, 269 bytes): 00000000332e35000000000000f936000000017b2270726f746f636f6c223a342c2274223a313738323534393632372c2264617461223a7b22647073223a7b22313034223a37332c22313036223a32312c22313033223a32372c22313031223a32392c22313035223a31372c22313032223a33302c22313038223a34332c22313039223a37352c22313130223a37352c22313131223a3234342c22313134223a3738302c22313135223a302c22313230223a3231352c22313231223a342c22313234223a34352c22313235223a31322c22313236223a31322c22313237223a302c22313238223a322c22313330223a302c22313331223a322c22313337223a31

(2) Changes in the UI snap back after a few seconds, back to to values set in the Tuya app.

(3) Changes made via the Tuya app work without any problems

Thanks @lenbu98 — that capture was exactly what I needed. :folded_hands:

Those push lines decode cleanly now. Your firmware wraps its status pushes in a layer the parser didn't expect (a 15-byte version header in front of a {"protocol":4,…,"data":{"dps":…}} envelope), so every push was being dropped as "undecryptable". Fixed in v0.9.12 (pysilverline 0.4.8) — once you update, the diagnostic/telemetry sensors (water/coil temps, frequencies, runtime, etc.) update live via push instead of only on the 30-second poll, and the log spam stops.

Two honest caveats:

(1) This release fixes the reading side. It does not by itself fix the thing you actually care about — the setpoint/mode changes snapping back. Those status pushes only ever carry telemetry DPs, never the control DPs, so I can't tell from them whether HA is writing to the wrong DP for your variant or the device is rejecting the local write outright.

(2) To pin that down I need a before/after diagnostics diff:

  • Settings → Devices & Services → Poolex → the device → Download diagnostics
  • change the setpoint in the Tuya app (so we know it took)
  • Download diagnostics again
  • attach both (or just diff the stateraw section)

That tells me which DP your unit actually uses for the setpoint, and whether HA already reads it back correctly. With that I can build the write fix properly instead of guessing and breaking it for the v3.5 units where writes already work.

(Everyone else following along: please open a GitHub issue for new reports — Issues · christianreiss/ha-silverline · GitHub — it's much easier to track than the forum thread. :slightly_smiling_face:)

Many thanks Christian, I'll switch over to github issues for following tracking. I'll post my informations as per your request there.
Cheers