From abb57a7ae91d39be67cd8285d22bc19116aa6b56 Mon Sep 17 00:00:00 2001 From: David Ashby Date: Mon, 18 Apr 2022 20:18:00 -0400 Subject: [PATCH] add more metrics that only appear when a print job is running --- main.go | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-- main_test.go | 24 +++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 main_test.go diff --git a/main.go b/main.go index 16276ab..7ac6c3f 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,8 @@ import ( "io" "log" "net/http" + "strconv" + "strings" "time" "github.com/prometheus/client_golang/prometheus" @@ -20,6 +22,11 @@ type Metrics struct { ZPosition float64 `json:"pos_z_mm"` PrintingSpeed int `json:"printing_speed"` FlowFactor int `json:"flow_factor"` + Progress int `json:"progress"` + PrintDur string `json:"print_dur"` + TimeEst string `json:"time_est"` + TimeZone string `json:"time_zone"` + ProjectName string `json:"project_name"` } type Config struct { @@ -33,7 +40,7 @@ var ( opsFlowFactor = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "prusa_connect", Name: "flow_factor", - Help: "Current flow factor, as a percentage", + Help: "Current flow factor, as a unitless number", }) opsPrintSpeed = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "prusa_connect", @@ -43,7 +50,7 @@ var ( opsZPosition = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "prusa_connect", Name: "z_position", - Help: "Depth, in MM, of the Z head", + Help: "Vertical depth, in mm, of the Z head", }) opsBed = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "prusa_connect", @@ -55,6 +62,21 @@ var ( Name: "temp_nozzle", Help: "Temperature, in celsius, of the print nozzle", }) + opsProgress = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "prusa_connect", + Name: "progress", + Help: "Current print completeness, as a percentage", + }) + opsDuration = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "prusa_connect", + Name: "duration", + Help: "Duration of current print job, as seconds since start", + }) + opsRemaining = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "prusa_connect", + Name: "remaining", + Help: "Estimated remaining time of current print job, as seconds", + }) errCount = 0 ) @@ -109,11 +131,50 @@ func recordMetrics(ctx context.Context, config Config) { opsZPosition.Set(t.ZPosition) opsBed.Set(float64(t.TempBed)) opsNozzle.Set(float64(t.TempNozzle)) + opsProgress.Set(float64(t.Progress)) + opsDuration.Set(float64(parseDuration(t.PrintDur) / time.Second)) + estimatedTimeRemaining, err := strconv.ParseFloat(t.TimeEst, 64) + if err == nil { + opsRemaining.Set(float64(estimatedTimeRemaining)) + } } } }() } +// taking a guess on proper parsing here... +func parseDuration(d string) time.Duration { + dur := 0 + d = strings.TrimSpace(d) + number := []rune{} + for _, t := range d { + switch t { + case ' ': + continue + case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0': + number = append(number, t) + case 's': + i, _ := strconv.Atoi(string(number)) + dur += i * int(time.Second) + number = []rune{} + case 'm': + i, _ := strconv.Atoi(string(number)) + dur += (i * int(time.Minute)) + number = []rune{} + case 'h': + i, _ := strconv.Atoi(string(number)) + dur += (i * int(time.Hour)) + number = []rune{} + case 'd': + i, _ := strconv.Atoi(string(number)) + dur += (i * int(time.Hour) * 24) + number = []rune{} + } + + } + return time.Duration(dur) +} + func main() { var hostname string flag.StringVar(&hostname, "hostname", "localhost", "Hostname the Prusa Connect API is available at (assumes http)") @@ -142,6 +203,9 @@ func main() { r.MustRegister(opsZPosition) r.MustRegister(opsPrintSpeed) r.MustRegister(opsFlowFactor) + r.MustRegister(opsProgress) + r.MustRegister(opsDuration) + r.MustRegister(opsRemaining) recordMetrics(context.Background(), config) diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..065978c --- /dev/null +++ b/main_test.go @@ -0,0 +1,24 @@ +package main + +import ( + "testing" + "time" +) + +func TestParseDuration(t *testing.T) { + d := parseDuration(" 45s") + if d != (45 * time.Second) { + t.Log(d) + t.Fail() + } + d = parseDuration(" 10m 45s") + if d != (45*time.Second)+(10*time.Minute) { + t.Log(d) + t.Fail() + } + d = parseDuration(" 12h 10m 45s") + if d != (12*time.Hour)+(45*time.Second)+(10*time.Minute) { + t.Log(d) + t.Fail() + } +}