diff --git a/README.md b/README.md index 43f08b455acd3492872ec3d039a9390fcd317b2c..0c8de42e0b02e7e454badc5b36eed5e3bff734b4 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,28 @@ Note this is not yet complete. go get -u gitlab.com/lyda/gqgmc/cmd/gqgmcd ``` +## Configuring + +Command line: + +``` +Usage of gqgmcd: + --config string Config file (default "gqgmc.conf") + --device string Device for Geiger Counter (default "/dev/gqgmc") + --listen-address string Address for HTTP requests (default ":8080") + --model string Model of Geiger Counter (default "gqgmc") + --sleep-cycle int Seconds to sleep per cycle. (default 5) + --static-dir string Static files directory (default "static") + --template-dir string Template directory (default "templates") +``` + +The config file uses the same variables (not `config` obviously) +but with any dashes replaced with underscores. So +`static_dir = /var/lib/gqgmcd/static` for instance. + ## Prometheus variables -There is a sample `prometheus.yml` configuration in the `docs/` +There is a sample `prometheus.yml` configuration in the `docs/prometheus/` directory. See the Prometheus [getting started](https://prometheus.io/docs/introduction/getting_started/) docs for more information. @@ -20,9 +39,29 @@ docs for more information. * `gqgmc_geiger_cpm` (histogram) CPM readings. * `gqgmc_geiger_cps` (histogram) CPS readings. * `gqgmc_power_volts` (histogram) Voltage readings. -* `gqgmc_sys_errors` (histogram) Error counts. Records problems +* `gqgmc_sys_errors` (gauge) Error counts. Records problems communicating with the device. +There are also sample consoles in the `docs/prometheus/` directory. Add this +to the left hand side menu in `menu.lib` your prometheus install: + +``` +{{ if query "up{job='gqgmc'}" }} +{{ template "_menuItem" (args . "gqgmc.html" "GQGMC") }} +{{ if match "^gqgmc" .Path }} + {{ if .Params.instance }} + <ul> + <li {{ if eq .Path "gqgmc-overview.html" }}class="prom_lhs_menu_selected"{{ end }}> + <a href="gqgmc-overview.html?instance={{ .Params.instance }}">{{.Params.instance }}</a> + </li> + </ul> + {{ end }} +{{ end }} +{{ end }} +``` + + + ## Configuring udev Copy the `linux/51-gqgmc.rules` file to the `/etc/udev/rules.d` @@ -40,3 +79,20 @@ with read/write permission for all users. ```bash ls -la /dev/gqgmc ``` + +## Development Resources + +There's a GQ Electronics [forum](https://www.gqelectronicsllc.com/forum/) which +isn't hugely active, but some really good info and helpful people +there. If you follow the git log on this project you'll see this +is based off a C++ implementation which is +[over on sourceforge](https://sourceforge.net/projects/gqgmc/) + +## TODO + +There's still a fair bit to do. This works good enough for my purposes so +I'm not likely to do much more. I've seeded the +[issue tracker](https://gitlab.com/lyda/gqgmc/issues) with the obvious +issues. +[Merge Requests](https://docs.gitlab.com/ee/gitlab-basics/add-merge-request.html) +welcome! diff --git a/TODO b/TODO deleted file mode 100644 index 561ed5cd38974c797c5a80d01395970f1b03ef64..0000000000000000000000000000000000000000 --- a/TODO +++ /dev/null @@ -1,86 +0,0 @@ -Package - https://github.com/Debian/dh-make-golang - -Logging. - -Review gq-rfc1201-1.40.txt - * Implement missing commands - -Sample prometheus console page. - -Pull configuration in from a config file. Allow for multiple devices? - -Turn command line tool into something that takes flags and so on. - -List of the various bytes of the config block based off this post - https://www.gqelectronicsllc.com/forum/topic.asp?TOPIC_ID=4447 : - - PowerOnOff, //to check if the power is turned on/off intended - AlarmOnOff, //1 - SpeakerOnOff, - GraphicModeOnOff, - BackLightTimeoutSeconds, - IdleTitleDisplayMode, - AlarmCPMValueHiByte, //6 - AlarmCPMValueLoByte, - CalibrationCPMHiByte_0, - CalibrationCPMLoByte_0, - CalibrationuSvUcByte3_0, - CalibrationuSvUcByte2_0, //11 - CalibrationuSvUcByte1_0, - CalibrationuSvUcByte0_0, - CalibrationCPMHiByte_1, - CalibrationCPMLoByte_1, //15 - CalibrationuSvUcByte3_1, - CalibrationuSvUcByte2_1, - CalibrationuSvUcByte1_1, - CalibrationuSvUcByte0_1, - CalibrationCPMHiByte_2, //20 - CalibrationCPMLoByte_2, - CalibrationuSvUcByte3_2, - CalibrationuSvUcByte2_2, - CalibrationuSvUcByte1_2, - CalibrationuSvUcByte0_2, //25 - IdleDisplayMode, - AlarmValueuSvByte3, - AlarmValueuSvByte2, - AlarmValueuSvByte1, - AlarmValueuSvByte0, //30 - AlarmType, - SaveDataType, - SwivelDisplay, - ZoomByte3, - ZoomByte2, //35 - ZoomByte1, - ZoomByte0, - SPI_DataSaveAddress2, - SPI_DataSaveAddress1, - SPI_DataSaveAddress0, //40 - SPI_DataReadAddress2, - SPI_DataReadAddress1, - SPI_DataReadAddress0, - PowerSavingMode, - Reserved, //45 - Reserved, - Reserved, - DisplayContrast, - MAX_CPM_HIBYTE, - MAX_CPM_LOBYTE, //50 - Reserved, - LargeFontMode, - LCDBackLightLevel, - ReverseDisplayMode, - MotionDetect, //55 - bBatteryType, - BaudRate, - Reserved, - GraphicDrawingMode, - LEDOnOff, - Reserved, - SaveThresholdValueuSv_m_nCPM_HIBYTE, - SaveThresholdValueuSv_m_nCPM_LOBYTE, - SaveThresholdMode, - SaveThresholdValue3, - SaveThresholdValue2, - SaveThresholdValue1, - SaveThresholdValue0, - Save_DateTimeStamp, //this one uses 6 byte space diff --git a/docs/GQ-GMC-ICD.docx b/docs/GQ-GMC-ICD.docx deleted file mode 100644 index c31072b97b45b7f2be1bac6ac131e2db22ac00be..0000000000000000000000000000000000000000 Binary files a/docs/GQ-GMC-ICD.docx and /dev/null differ diff --git a/docs/gqgmc.png b/docs/gqgmc.png new file mode 100644 index 0000000000000000000000000000000000000000..3bc8b6e6ffde328923151b8426a3f10356e06265 Binary files /dev/null and b/docs/gqgmc.png differ diff --git a/docs/prometheus/gqgmc-overview.html b/docs/prometheus/gqgmc-overview.html new file mode 100644 index 0000000000000000000000000000000000000000..c08fe52838b328d9f6ef0e9dfdee542cfe415fd3 --- /dev/null +++ b/docs/prometheus/gqgmc-overview.html @@ -0,0 +1,80 @@ +{{ template "head" . }} + +{{ template "prom_right_table_head" }} + <tr> + <th colspan="2">Counts</th> + </tr> + <tr> + <td>CPS</td> + <td>{{ template "prom_query_drilldown" (args (printf "gqgmc_geiger_cps_sum{job='gqgmc',instance='%s'}/gqgmc_geiger_cps_count{job='gqgmc',instance='%s'}" .Params.instance .Params.instance) "c/s" "humanizeNoSmallPrefix") }}</td> + </tr> + <tr> + <td>CPM</td> + <td>{{ template "prom_query_drilldown" (args (printf "gqgmc_geiger_cpm_sum{job='gqgmc',instance='%s'}/gqgmc_geiger_cpm_count{job='gqgmc',instance='%s'}" .Params.instance .Params.instance) "c/m" "humanizeNoSmallPrefix") }}</td> + </tr> + + <tr> + <th colspan="2">Power</th> + </tr> + <tr> + <td>Volts</td> + <td>{{ template "prom_query_drilldown" (args (printf "gqgmc_power_volts_sum{job='gqgmc',instance='%s'}/gqgmc_power_volts_count{job='gqgmc',instance='%s'}/10" .Params.instance .Params.instance) "v" "humanizeNoSmallPrefix") }}</td> + </tr> + + <tr> + <th colspan="2">Errors</th> + </tr> + <tr> + <td>Errors</td> + <td>{{ template "prom_query_drilldown" (args (printf "irate(gqgmc_sys_errors{job='gqgmc',instance='%s'}[5m])" .Params.instance) "err/cycle" "humanizeNoSmallPrefix") }}</td> + </tr> + +{{ template "prom_right_table_tail" }} + +{{ template "prom_content_head" . }} + <h1>GQGMC Overview - {{ .Params.instance }}</h1> + + <h3>CPM</h3> + <div id="cpmGraph"></div> + <script> + new PromConsole.Graph({ + node: document.querySelector("#cpmGraph"), + expr: "gqgmc_geiger_cpm_sum{job='gqgmc',instance='{{ .Params.instance }}'}/gqgmc_geiger_cpm_count{job='gqgmc',instance='{{ .Params.instance }}'}", + name: 'CPM Counts', + yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix, + yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix, + yTitle: "Clicks", + yUnits: "/m", + }) + </script> + + <h3>Power</h3> + <div id="powerGraph"></div> + <script> + new PromConsole.Graph({ + node: document.querySelector("#powerGraph"), + expr: "gqgmc_power_volts_sum{job='gqgmc',instance='{{ .Params.instance }}'}/gqgmc_power_volts_count{job='gqgmc',instance='{{ .Params.instance }}'}/10", + name: 'Power', + yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix, + yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix, + yTitle: "Volts", + }) + </script> + + <h3>Errors per cycle</h3> + <div id="errorGraph"></div> + <script> + new PromConsole.Graph({ + node: document.querySelector("#errorGraph"), + expr: "irate(gqgmc_sys_errors{job='gqgmc',instance='{{ .Params.instance }}'}[5m])", + name: 'Errors', + yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix, + yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix, + yTitle: "Errors", + yUnits: "/cycle", + }) + </script> + +{{ template "prom_content_tail" . }} + +{{ template "tail" }} diff --git a/docs/prometheus/gqgmc.html b/docs/prometheus/gqgmc.html new file mode 100644 index 0000000000000000000000000000000000000000..ad4c6089bbec3cd1694bf651543e65e54826ba5e --- /dev/null +++ b/docs/prometheus/gqgmc.html @@ -0,0 +1,29 @@ +{{ template "head" . }} + +{{ template "prom_right_table_head" }} +<tr> + <th>Prometheus</th> + <th>{{ template "prom_query_drilldown" (args "sum(up{job='gqgmc'})") }} / {{ template "prom_query_drilldown" (args "count(up{job='gqgmc'})") }}</th> +</tr> +{{ template "prom_right_table_tail" }} + +{{ template "prom_content_head" . }} +<h1>GQGMC</h1> + +<table class="table table-condensed table-striped table-bordered" style="width: 0%"> +<tr> + <th>GQGMC</th> + <th>Up</th> +</tr> +{{ range query "up{job='gqgmc'}" | sortByLabel "instance" }} +<tr> + <td><a href="gqgmc-overview.html?instance={{ .Labels.instance }}">{{ .Labels.instance }}</a></td> + <td {{ if eq (. | value) 1.0 }}>Yes{{ else }} class="alert-danger">No{{ end }}</td> +</tr> +{{ else }} +<tr><td colspan=4>No devices found.</td></tr> +{{ end }} + +{{ template "prom_content_tail" . }} + +{{ template "tail" }} diff --git a/docs/prometheus.yml b/docs/prometheus/prometheus.yml similarity index 100% rename from docs/prometheus.yml rename to docs/prometheus/prometheus.yml