Skip to content

enable_remote_mode()/disable_remote_mode() use wrong GENIbus opcode (INFO 0xC1 instead of SET 0x81) #30

Description

@eman

Origin

Companion issue to eman/esphome-alpha-hwr#46, filed against this repo because the ESPHome component's identical opcode bug is a direct port of this client's enable_remote_mode()/disable_remote_mode().

Problem

enable_remote_mode() and disable_remote_mode() build their Class 3 GENIbus frame with the INFO operation specifier (0xC1) instead of SET (0x81) in the second APDU byte, so they likely never actually execute on the pump — INFO only asks the pump to describe a data item, it doesn't perform the command.

Note: unlike the ESPHome port, this client does not have the companion "switch reflects a local intent flag instead of pump state" bug — get_mode() already derives SetpointInfo.is_remote from the pump's own control_source readback (services/control.py:465-467, is_remote = (control_source == 2)), not from a locally-latched flag. So the fix needed here is narrower: just the opcode in the two methods below, plus verifying the control_source == 2 mapping is actually correct once the opcode is fixed.

Evidence

  • services/control.py:312-316enable_remote_mode(): apdu = bytes([0x03, 0xC1, 0x07])
  • services/control.py:341-345disable_remote_mode(): apdu = bytes([0x03, 0xC1, 0x06])
  • Per GENIbus's APDU encoding (operation in bits 7-6, length in bits 5-0 of the second byte): 0xC1 = operation 3 (INFO) + length 1; the SET operation for a 1-byte command is 0x81 (operation 2 + length 1).
  • Cross-repo bench confirmation: esphome-alpha-hwr#23 tested both against a real pump — [0x03, 0xC1, 0x07] returns an 8-byte ack [03 01 AC] (class 3, ack OK, one data byte — an INFO descriptor, i.e. no execution), while [0x03, 0x81, 0x07] returns [03 00] (class 3, ack OK, zero data bytes — a clean execution ack), and only the latter actually starts/stops the pump when tested with the analogous START/STOP command IDs.
  • Countervailing evidence worth checking before changing this: resources/GRUNDFOS_APP_BLE_DATA_MAPPING.md (decompiled Grundfos GO app analysis) documents the real app's Class 3 commands as using OS_INFO (section 9, item 6, and the example frame at line 556-570), but sent from source address 0x0A ("Remote Master") rather than 0xF8, which this client always uses (_build_geni_packet(0xF8, 0xE7, apdu), e.g. services/control.py:314, 343). It's unconfirmed whether the real fix is the opcode, the source address, or both — see the discussion in esphome-alpha-hwr#46 for the full reasoning.

Suggested fix

Bench-verify against real hardware which change actually causes the pump's control_source (as read by get_mode()) to move between values, then apply it here: either changing the opcode to 0x81 (keeping source 0xF8), changing the source address to 0x0A (keeping opcode 0xC1), or both. Once fixed, confirm whether is_remote = (control_source == 2) (services/control.py:465-467) is actually the correct mapping — the ESPHome-side testing found control_source reading 0 in every sample taken so far, consistent with REMOTE/LOCAL never having actually executed.

References

  • eman/esphome-alpha-hwr#23 (original report, Control Problem #5)
  • eman/esphome-alpha-hwr#46 (companion issue in the ESPHome component, includes the source-address counter-evidence discussion)
  • resources/GRUNDFOS_APP_BLE_DATA_MAPPING.md:216-224, 556-620

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