Skip to content

Raw JSON API cannot express a write-only command and expect_cmd: null waits for an arbitrary notification #25

Description

@Bjorkan

TL;DR

Some mower commands do not send a notification back. The raw API has no way to say “write this packet and finish.” Setting expect_cmd to null instead means “wait for the first notification of any kind,” so the call either times out or returns an unrelated packet.

Problem

The low-level request method supports write_only=True, but async_send_raw_json() never exposes or enables it.

Relevant code:

The reverse-engineering material records commands, including schedule writes, where no immediate application-level acknowledgement was observed.

Why it happens

Two separate concepts are represented by one nullable field:

  • no command filter: accept any response;
  • no response expected: finish after the GATT write.

The current implementation uses None only for the first meaning. A user reasonably trying "expect_cmd": null for a no-ACK command gets the opposite behavior: pyGrouw waits for traffic.

Current behavior

For a raw command that sends no notification:

  1. the GATT write succeeds;
  2. pyGrouw waits up to the notification timeout;
  3. the mower may already have applied the command;
  4. the API raises GrouwBleTimeout.

If an unrelated notification arrives first, it is returned as the command response because expected_cmd is None accepts any parsed message.

The caller cannot distinguish “write succeeded, no response expected” from “write outcome unknown.”

Expected behavior

The raw schema should represent response policy explicitly, for example:

{
  "hex": "...",
  "response_mode": "write_only"
}

Supported modes could be:

  • write_only: return after a successful GATT write;
  • any: return the first valid parsed notification;
  • command: wait for a specified response command;
  • status_follow_up: write the payload, issue a status query, then wait for status.

expect_cmd: null should not ambiguously mean both “anything” and “nothing.”

Impact

Protocol validation becomes misleading: an applied command is reported as failed, encouraging users to resend it. On a mower moving near a Bluetooth range boundary, the timeout also holds the request lock and delays normal commands while waiting for a response that will never exist.

Suggested direction

Expose the existing write_only capability through a validated raw-request model and return structured transport information, such as write_completed=True and response=None.

Keep raw/debug behavior explicit and avoid guessing response policy from protocol prefix alone.

Acceptance criteria

  • A raw write-only request completes after the GATT write without waiting for a notification.
  • any response remains available as a separate explicit mode.
  • A write-only failure before completion raises a GATT/connection error.
  • A cancelled or disconnected post-write operation reports an indeterminate outcome rather than claiming the command was not sent.
  • Tests cover no notification, an unrelated notification, a specified command response, and follow-up status mode.
  • Home Assistant's raw service can select the response policy explicitly.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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