Sign inSign up

dougeubanks/gmc-exporter

By dougeubanks

Updated 7 days ago

GQ Electronics GMC Geiger counter exporter: Prometheus, InfluxDB, MQTT, radmon, Safecast

Image
0

1.7K

dougeubanks/gmc-exporter repository overview

gmc-exporter

Reads a GQ Electronics GMC-series Geiger counter over USB serial and publishes its readings to whichever telemetry backends you enable.

Built to run unattended for months. A partial serial read, an unplugged adapter, an unreachable backend or a panic inside a client library all degrade to a logged, skipped reading rather than a dead container.

Quick start

docker run -d --name gmc-exporter \
  --device=/dev/ttyUSB0 \
  --group-add="$(stat -c '%g' /dev/ttyUSB0)" \
  -p 9101:9101 \
  -e GOGMC_PROMETHEUS_ENABLED=true \
  dougeubanks/gmc-exporter:latest

Then:

curl localhost:9101/metrics
curl localhost:9101/readyz

Device access — read this first

This is the one thing that catches people out. The container runs as a non-root user, and reading /dev/ttyUSB0 needs two separate permissions: the kernel's device cgroup must allow the container the device, and the process must be able to open a node owned by root:dialout.

Measured against a real device node:

Device passed as--privileged--group-addWorks
--devicenoyesyes — recommended
volume mount (-v)yesyesyes
volume mountyesnono
volume mountnoyesno

A volume mount makes the node visible but grants no device permission, which is why that route still needs --privileged. Use --device and you can leave privileged mode off entirely.

If it cannot open the device, the container says exactly what to add — naming the group the node actually belongs to — and keeps retrying rather than exiting.

Sinks

Every sink is disabled by default and independently toggleable. Each is individually timed out, published to concurrently, and unable to stop the poll loop or affect another sink.

SinkEnable withCredentials
PrometheusGOGMC_PROMETHEUS_ENABLEDnone
InfluxDB 1.xGOGMC_INFLUX1_ENABLEDoptional user/password
InfluxDB 2.xGOGMC_INFLUX2_ENABLEDtoken, org, bucket
OpenTelemetry (OTLP)GOGMC_OTLP_ENABLEDoptional headers
MQTT + Home Assistant discoveryGOGMC_MQTT_ENABLEDoptional user/password
radmon.orgGOGMC_RADMON_ENABLEDuser + data-sending password
GMCMAP.comGOGMC_GMCMAP_ENABLEDaccount ID + counter ID
SafecastGOGMC_SAFECAST_ENABLEDAPI key

Start with Prometheus. It needs no credentials at all, cannot fail in a way that stalls the poll loop, and keeps working if you change every other backend.

Endpoints

PathPurpose
/metricsPrometheus scrape
/healthzLiveness. Never fails because a backend is down
/readyzReadiness. 503 if the device is disconnected or readings are stale
/healthPer-dependency detail. Carries no URLs, hostnames or tokens

Configuration

Everything is set by environment variable, prefixed GOGMC_. Every secret also accepts a _FILE variant, so it can be delivered as a Docker or Kubernetes secret rather than as a plain variable visible to docker inspect:

GOGMC_RADMON_PASSWORD_FILE=/run/secrets/radmon_password

A config file is optional and picked up automatically from /etc/gmc-exporter/config.ini or /config.ini. Precedence is flags, then environment, then file, then defaults.

Full reference: docs/ENV_VARS.md

Tags

TagMeaning
latestNewest release
1Newest 1.x
1.0Newest 1.0.x
1.0.0Exactly that version

Pin to 1.0.0 for reproducibility, or 1 to get fixes without breaking changes. Rolling back is just running an older tag: the exporter holds no state and never writes to the device.

Supported hardware

The protocol is GQ Electronics' own, documented in GQ-RFC1201, covering the GMC-280, GMC-300, GMC-320 and later.

Developed and verified against a GMC-320Re 4.62 on a CH340 USB-serial bridge. Every response length was confirmed against real hardware before being relied on, and the calibration table — which the vendor does not document — was derived by measurement. The evidence is in docs/protocol-measurements.md.

Thanks to GQ Electronics for publishing the protocol specification.

More documentation

DocumentUse it for
READMEOverview and deployment
RUNBOOKIt broke and you are on call
ENV_VARSEvery setting
SECURITYCredential handling, reporting a vulnerability
IssuesBugs and questions

Tag summary

Content type

Image

Digest

sha256:ffcb8c1bc

Size

6.7 MB

Last updated

7 days ago

docker pull dougeubanks/gmc-exporter