Skip to main content

gmg-local

Local UDP client for Green Mountain Grills Wi-Fi pellet grills.

No cloud account, no vendor API, no internet. It talks to the grill on your LAN and nothing else.

Not on PyPI yet - built and tested, awaiting a decision to publish. Origin and attribution: NOTICE.md.

from gmg_local import discover

for grill in discover():
    state = grill.status()
    print(grill.serial_number, state["temp"], "F")

Why this exists

Every public Python implementation of this protocol froze on 2023-01-28. The most-installed Home Assistant integration for these grills reads grill temperature from a single byte, so a 350 °F grill reports as 94 °F - the one number the device exists to tell you.

u16(94, 1) == 350   # not 94

Install

pip install -e .          # from a clone; not on PyPI yet

Requires Python 3.11+. No dependencies.

API

discover(timeout=1, ip_bind_address="0.0.0.0", target=None) Broadcast for grills. Pass target to unicast across VLANs, where broadcast dies at the L2 edge.
Grill.status(retries=5) One poll, decoded. Retries on silence and on junk.
Grill.firmware(retries=5) The firmware string (UN!), verbatim - e.g. UNJB02SUF0_2.3. Same retry contract as status().
model_for(firmware) Pure. "Jim Bowie" for a JB firmware prefix, None for anything unrecognised.
Grill.set_temp(f) / set_temp_probe(f, n) Targets, in Fahrenheit.
Grill.power_on() / power_on_cool() / power_off() Cold smoke is power_on_cool.
parse_status(frame) Pure. No sockets, no clock - testable without a grill.
poll_interval_for(state) 10s while cooking, 60s while off.

What the status frame contains

A healthy grill answers UR001! with 52 bytes; this library decodes through byte 33.

offset field notes
2, 4, 6 grill temp, probe 1, setpoint 16-bit LE pairs
8 API version
16, 18 probe 2 temp and setpoint
24-27 warn state 32-bit LE
28 probe 1 setpoint
30 power state 0 Off, 1 On, 2 Fan, 3 Cold Smoke
32 fire state 0 Default, 1 Off, 2 Startup, 3 Running, 4 Cool Down, 5 Fail, 198 Cold Smoke
33 fire state progress see below
34-51 undecoded gmg 0.0.4 labels 48 and 50 as pellet alarms - unverified

Byte 33

Emitted as fireStatePercentage. GMG's own cloud API names this field fireStateProgress, paired with fireState.

It is a four-step progress marker through whatever fire state the grill is currently in. Across a full instrumented cycle it ran 25 → 50 → 75 → 100 during Startup, hitting 100 at the exact second the grill switched to Running, then 75 → 50 → 0 through Cool Down, hitting 0 as the fan stopped.

Two readings are ruled out by that data:

  • Not a startup-stage index. A stage counter does not run backwards.
  • Not a pellet-hopper level. A hopper does not fill during ignition and empty when the fan stops. One public implementation labels it hopper_pct and ships it as a pellet gauge; it reads 100% on a hot grill and 0% on a cold one.

What each 25% step physically means is unknown, and is not in the packet. Display the step number; do not invent labels.

Things the hardware does that will surprise you

  • Probe writes are silently discarded while the grill is off. Write 203, read back 0. No error, no acknowledgement.
  • The grill serves one client at a time. Concurrent conversations lose messages, so all I/O here is serialised behind a lock.
  • Short datagrams happen. They are a transport artifact, not data. Parsing one either raises or invents fields; this library retries instead.
  • Temperature keeps rising after the fire is cut - roughly 18 °F over a minute in one observed shutdown.

Tests

pip install -e ".[dev]" && pytest

The fixtures are reconstructed - real decoded observations re-encoded at the documented offsets - not captured frames. They prove the parser is self-consistent with observed behaviour, not that the offsets are correct. Offsets are corroborated across four independent implementations.

Preserving a genuine 52-byte capture is the prerequisite for decoding bytes 34-51, and should replace these fixtures when one exists.

Credits

See NOTICE.md. Original integration by jwhitby91; protocol cross-checked against brandenc40/green-mountain-grill and Christopher McKay's gmg.

Release files for gmg-local 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gmg-local 0.3.0
File Size Uploaded
gmg_local-0.3.0.tar.gz 21.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gmg-local 0.3.0
File Interpreter ABI Platform
gmg_local-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.9 kB

Release files / gmg_local-0.3.0.tar.gz

Download URL gmg_local-0.3.0.tar.gz
Size 21.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6c366fa6bcceffebc6a405a89c085c8ec169122079c953bd3b863798d8728dee
BLAKE2b-256 checksum
How to use checksums
5f2bc0dc24cbc9b4ff2bd7143990d69eed7250cb2c575bf77f384167e29d86f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.

Transparency log

Release files / gmg_local-0.3.0-py3-none-any.whl

Download URL gmg_local-0.3.0-py3-none-any.whl
Size 13.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c6e06d24c6c3b4a1b5234b025e85d4636acefa91a9d73bb9d97b58987869e2a0
BLAKE2b-256 checksum
How to use checksums
e8a9eab60dc5419b5416367d057c7c8135045935739fe7bcdac76314839df970
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page