Skip to content

start()/set_mode() ignore setpoint, forcing hardcoded ~3671 RPM default suffix #27

Description

@eman

Origin

Companion issue to eman/esphome-alpha-hwr#43, filed against this repo because the same bug exists here — the ESPHome component is a line-for-line port of this client's ControlService (its source comments cite this file's line numbers directly), so it inherited the bug rather than introducing it.

Problem

start() and set_mode() never send the pump's actual/desired setpoint. They call _send_control_request(mode_val, start=True) with no setpoint, which falls back to _MODE_SUFFIX_MAP's default suffix bytes. Every mode's default suffix except DHW and Temperature Range is the same 4 bytes, bytes([0x45, 0x65, 0x70, 0x00]), which decodes as a big-endian IEEE‑754 float to exactly 3671.0:

>>> import struct
>>> struct.unpack(">f", bytes([0x45, 0x65, 0x70, 0x00]))[0]
3671.0

So calling start() (or set_mode(), which also calls _send_control_request(mode_val, start=True) with no setpoint) always commands the pump to run at 3671 RPM/3671 Pa-equivalent/etc, regardless of any setpoint previously written via set_constant_speed()/set_constant_pressure()/set_constant_flow().

Evidence

  • src/alpha_hwr/services/control.py:185-208start() calls self._send_control_request(mode_val, start=True), no setpoint arg.
  • src/alpha_hwr/services/control.py:347-368set_mode() likewise calls self._send_control_request(mode_val, start=True) with no setpoint.
  • src/alpha_hwr/services/control.py:235-286_send_control_request(): when setpoint is None, uses self._MODE_SUFFIX_MAP.get(mode_byte, bytes([0x45, 0x65, 0x70, 0x00])) (line 267-269).
  • src/alpha_hwr/services/control.py:146-165_MODE_BYTE_MAP/_MODE_SUFFIX_MAP: every mode except DHW (0x19) and Temperature Range (0x1B) shares the identical default suffix bytes([0x45, 0x65, 0x70, 0x00]) = 3671.0.
  • Cross-repo bench confirmation: esphome-alpha-hwr#23 reports the pump running at ~3671 RPM whenever "Pump Enabled" is turned on, which is this exact code path (ported verbatim into control_service.cpp's CLASS10_CONTROL_MAP).
  • The same issue report also independently confirms a working alternative: GENIbus Class 3 START/STOP commands ([0x03, 0x81, 0x06] / [0x03, 0x81, 0x05]) turn the pump on/off without touching the setpoint at all, respecting whatever setpoint is already stored on the pump. This repo's own Register enum already has the relevant GENIbus command IDs defined but unused: src/alpha_hwr/constants.py:88-94 (STOP = 0x0305, AUTO = 0x0306, REMOTE = 0x0307), annotated # Class 3 Commands (not used in BLE captures).

Suggested fix

Either:

  1. Have start() look up/track the current setpoint for the active mode and pass it explicitly to _send_control_request() instead of relying on the default suffix, or
  2. Switch start()/stop() to the Class 3 START/STOP commands (command IDs 0x06/0x05), which don't require a setpoint at all and let the pump use whatever is already stored — this also avoids the enable-forces-a-value problem tracked in the companion force-enable issue.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions