Skip to content

Commit 8a77d98

Browse files
committed
feat: Add ocr-incr-only flag
1 parent cf58250 commit 8a77d98

3 files changed

Lines changed: 44 additions & 10 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ All options can be set via CLI flags or environment variables. Flags take preced
131131
| `--mqtt-device-manufacturer` | `MQTT_DEVICE_MANUFACTURER` | `Generic` | Manufacturer shown in Home Assistant |
132132
| `--mqtt-device-model` | `MQTT_DEVICE_MODEL` | `Generic` | Model shown in Home Assistant |
133133
| `--meter-divisor` | `METER_DIVISOR` | `1000` | Divisor to convert raw reading to m³ (e.g. `000354225` / `1000` = `354.225`) |
134+
| `--ocr-incr-only` | `OCR_INCR_ONLY` | `false` | Only publish readings that are ≥ the previous value (after dividing by `meter-divisor`), discarding likely OCR errors |
134135
135136
### MQTT / Home Assistant
136137

http.go

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,20 @@ package main
33
import (
44
"io"
55
"log"
6+
"math"
67
"net/http"
78
"os"
89
"path/filepath"
910
"strconv"
11+
"sync"
1012
"time"
1113
)
1214

15+
var (
16+
lastReadingMu sync.Mutex
17+
lastReading = math.NaN()
18+
)
19+
1320
func handleOCR(w http.ResponseWriter, r *http.Request) {
1421
if r.Method != http.MethodPost {
1522
http.Error(w, "POST only", http.StatusMethodNotAllowed)
@@ -96,22 +103,41 @@ func processOCR(imageData []byte, batLevel, batVoltage int) {
96103

97104
reading := extractReading(ocrOut.Texts, ocrMatchRe, ocrFixRules)
98105

99-
if reading != "" {
100-
if val, err := strconv.ParseFloat(reading, 64); err == nil {
101-
metricMeterReading.Set(val)
102-
}
106+
// Append reading to CSV unconditionally so discarded values are still on disk.
107+
storeReading(imagePath, reading)
108+
109+
if reading == "" {
110+
log.Printf("OCR completed in %s: no reading found, texts=%v", elapsed, ocrOut.Texts)
111+
return
103112
}
104113

105-
// Append reading to CSV now that we have a result.
106-
storeReading(imagePath, reading)
114+
val, err := strconv.ParseFloat(reading, 64)
115+
if err != nil {
116+
log.Printf("OCR completed in %s: invalid reading %q, texts=%v", elapsed, reading, ocrOut.Texts)
117+
return
118+
}
119+
120+
divided := val / meterDivisor
107121

108-
if mqttBroker != "" && reading != "" {
109-
if val, err := strconv.ParseFloat(reading, 64); err == nil {
110-
publishReading(val/meterDivisor, batLevel, batVoltage)
122+
if ocrIncrOnly {
123+
lastReadingMu.Lock()
124+
prev := lastReading
125+
if !math.IsNaN(prev) && divided < prev {
126+
lastReadingMu.Unlock()
127+
log.Printf("OCR incr-only: discarding reading %.3f < previous %.3f", divided, prev)
128+
return
111129
}
130+
lastReading = divided
131+
lastReadingMu.Unlock()
132+
}
133+
134+
metricMeterReading.Set(val)
135+
136+
if mqttBroker != "" {
137+
publishReading(divided, batLevel, batVoltage)
112138
}
113139

114-
log.Printf("OCR completed in %s: reading=%s texts=%v", elapsed, reading, ocrOut.Texts)
140+
log.Printf("OCR completed in %s: reading=%s (%.3f m³) texts=%v", elapsed, reading, divided, ocrOut.Texts)
115141
}
116142

117143
func handleHealth(w http.ResponseWriter, r *http.Request) {

main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ var (
2929
mqttDeviceManufacturer string
3030
mqttDeviceModel string
3131
meterDivisor float64
32+
ocrIncrOnly bool
3233
)
3334

3435
func main() {
@@ -120,6 +121,11 @@ func main() {
120121
Usage: "Divisor to convert the raw OCR reading to m³ (e.g. 000354225 / 1000 = 354.225)",
121122
Sources: cli.EnvVars("METER_DIVISOR"),
122123
},
124+
&cli.BoolFlag{
125+
Name: "ocr-incr-only",
126+
Usage: "Only publish readings that are >= the previous reading (after dividing by meter-divisor), discarding likely OCR errors",
127+
Sources: cli.EnvVars("OCR_INCR_ONLY"),
128+
},
123129
},
124130
Action: run,
125131
}
@@ -146,6 +152,7 @@ func run(_ context.Context, cmd *cli.Command) error {
146152
mqttDeviceManufacturer = cmd.String("mqtt-device-manufacturer")
147153
mqttDeviceModel = cmd.String("mqtt-device-model")
148154
meterDivisor = cmd.Float("meter-divisor")
155+
ocrIncrOnly = cmd.Bool("ocr-incr-only")
149156

150157
if mqttBroker != "" {
151158
initMQTT()

0 commit comments

Comments
 (0)