Python interface for GQ GMC geiger counters using the GQ-RFC1201 protocol
Project description
GQ Terminal
A Python library and command-line interface for GQ GMC geiger counters, implementing the GQ-RFC1201 protocol.
⚠️ Not a certified instrument. GQ GMC counters are hobbyist devices and this library is unaffiliated with GQ Electronics. Do not use values from this software for safety-, regulatory-, or medical-decision-making. Counts and rates depend on calibration, geometry, isotope, and instrument health — verifying any of that is the user's responsibility. The MIT license disclaims all warranty; the same applies to readings.
🔬 Hardware coverage. The only configuration verified end-to-end against a physical device is GMC-600+ firmware Re.2.22. The GMC-280, GMC-300, GMC-320, GMC-500 series, and other GMC-600 firmware revisions should work — the library auto-detects the family and adjusts the protocol accordingly — but those code paths are exercised only by the test suite, not against real hardware. If you have one of these and it works (or doesn't), please open an issue with the output of
python tools/diagnose.py.
📡 Protocol is a moving target. GQ Electronics ships firmware revisions that diverge from the GQ-RFC1201 spec without updating the document (we know of at least: 15-byte GETVER on Re.2.22, 512-byte GETCFG on 500/600/800-series, 4-byte CPM on the same). If your device returns unexpected data, run
python tools/diagnose.py --port <port>and attach the output to a bug report.
Installation
pip install gq-terminal
Quick start
Python API
from gq_terminal import GMCInterface
with GMCInterface('/dev/ttyUSB0', baudrate=115200) as gmc:
print(gmc.get_version()) # e.g. "GMC-600 2.42"
print(gmc.get_serial_number()) # 7-byte serial as hex
print(f"{gmc.get_battery_voltage():.2f} V")
print(f"CPM: {gmc.get_cpm()}")
gmc.start_heartbeat()
for _ in range(10):
cps = gmc.read_heartbeat()
if cps is not None:
print(f"CPS: {cps}")
gmc.stop_heartbeat()
The context manager raises GMCError on connection failure. Outside a
with block, call gmc.connect() and check the boolean return.
Command line
gq-terminal info --port /dev/ttyUSB0
gq-terminal info --port /dev/ttyUSB0 --verbose
gq-terminal monitor --port /dev/ttyUSB0 --duration 60
gq-terminal log --port /dev/ttyUSB0 --interval 60 --output radiation.csv
gq-terminal config read --port /dev/ttyUSB0
gq-terminal history --port /dev/ttyUSB0 --address 0 --length 1024
gq-terminal --help
gq-terminal monitor --help
You can also invoke the CLI as a module: python -m gq_terminal info ....
Supported commands
Implements all 26 commands defined by GQ-RFC1201:
| Category | Methods |
|---|---|
| Basic | get_version, get_cpm, get_battery_voltage, get_serial_number |
| Real-time | start_heartbeat, stop_heartbeat, read_heartbeat |
| Environment | get_temperature, get_gyroscope (GMC-320 Re.3.01+) |
| Real-time clock | get_datetime, set_datetime (GMC-280/300 Re.3.00+) |
| Memory | get_history_data, get_config, write_config, erase_config, update_config |
| Device control | send_key, power_off, power_on, reboot, factory_reset |
Serial configuration
| Setting | Default |
|---|---|
| Baud rate | 115200 (use 57600 for GMC-300 V3.xx and earlier) |
| Data bits | 8 |
| Parity | None |
| Stop bits | 1 |
| Flow control | None |
Troubleshooting
Linux: Permission denied: /dev/ttyUSB0 — your user needs access to the
serial device. The portable fix is to add yourself to the dialout group
(sudo usermod -a -G dialout $USER) and log out / back in.
Short read: expected N bytes, got 0 — usually wrong baud rate (try 57600
for older firmware), wrong port, or the device is off. With heartbeat mode
running, do not interleave heartbeat reads with normal commands without first
calling stop_heartbeat().
Windows: which COM port? — open Device Manager → Ports (COM & LPT) with the device plugged in.
Development
This project uses uv for dependency management
and a Makefile for common tasks.
git clone https://github.com/jmcmeen/gq-terminal
cd gq-terminal
make dev # uv sync --extra dev
make test # run the pytest suite
make check # lint + typecheck + test (everything CI runs)
make build # build sdist + wheel into dist/
make help # list all targets
The test suite uses a fake serial backend, so no hardware is required.
If you don't have uv and don't want it, plain pip works too:
pip install -e ".[dev]"
pytest
Citing
If you use this software in research, please cite it. A CITATION.cff is
included in the repository, and tagged releases are archived on Zenodo with
DOIs — see the badge on the GitHub repository.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gq_terminal-0.1.0.tar.gz.
File metadata
- Download URL: gq_terminal-0.1.0.tar.gz
- Upload date:
- Size: 19.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd4720510ced6cf7f91676f36f9f3ebd7abb6b8e0b3a35c01df818f9921e0af1
|
|
| MD5 |
5a8e56c123b1efb9b57d284089370de8
|
|
| BLAKE2b-256 |
ba3552e96be665cc2388c8e34f774aa1fa511f8f98bdd7f812eaeb3c8d3ad999
|
Provenance
The following attestation bundles were made for gq_terminal-0.1.0.tar.gz:
Publisher:
publish.yml on jmcmeen/gq-terminal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gq_terminal-0.1.0.tar.gz -
Subject digest:
bd4720510ced6cf7f91676f36f9f3ebd7abb6b8e0b3a35c01df818f9921e0af1 - Sigstore transparency entry: 1513751077
- Sigstore integration time:
-
Permalink:
jmcmeen/gq-terminal@2344b8f48af76c18b27643242e6ea9d3256c32ae -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jmcmeen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2344b8f48af76c18b27643242e6ea9d3256c32ae -
Trigger Event:
release
-
Statement type:
File details
Details for the file gq_terminal-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gq_terminal-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
afd1399fb6751b05cf3e8b53b46420254f89a84cfc9adca353e925cebb86554e
|
|
| MD5 |
a9f7e461aa03b19cda6949688fffd1a6
|
|
| BLAKE2b-256 |
22dc6642ff6ceeffe66f0cea4aad0960a8967aa4469b0e1210e1e65d8d0ca889
|
Provenance
The following attestation bundles were made for gq_terminal-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on jmcmeen/gq-terminal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gq_terminal-0.1.0-py3-none-any.whl -
Subject digest:
afd1399fb6751b05cf3e8b53b46420254f89a84cfc9adca353e925cebb86554e - Sigstore transparency entry: 1513751248
- Sigstore integration time:
-
Permalink:
jmcmeen/gq-terminal@2344b8f48af76c18b27643242e6ea9d3256c32ae -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jmcmeen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2344b8f48af76c18b27643242e6ea9d3256c32ae -
Trigger Event:
release
-
Statement type: