From 44ea19863fc40d84fb9a62e68c1633b6e031a1ca Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Sat, 20 Dec 2025 20:41:23 -0500 Subject: [PATCH] Update x,y and add db writes back in --- main.go | 102 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 39 deletions(-) diff --git a/main.go b/main.go index 91036d4..870afc9 100644 --- a/main.go +++ b/main.go @@ -49,39 +49,39 @@ type Light struct { MinOnDurationMS int64 `json:"min_on_duration_ms"` } - var defaultLights = map[string]Light{ - "furnace_power": {"Furnace Power", 1146, 785, "urgent", 100}, - "living_room_stat": {"Living Room Thermostat", 885, 230, "low", 100}, - "living_room_heat": {"Living Room Heating", 1395, 240, "low", 100}, - "dining_room_stat": {"Dining Room Thermostat", 885, 272, "low", 100}, - "dining_room_heat": {"Dining Room Heating", 1400, 275, "low", 100}, - "hot_water_stat": {"Hot Water Thermostat", 880, 445, "low", 100}, - "hot_water_heat": {"Hot Water Heating", 1405, 445, "low", 100}, - "first_bed_stat": {"First Bedroom Thermostat", 880, 480, "low", 100}, - "first_bed_heat": {"First Bedroom Heating", 1407, 488, "low", 100}, - "master_bed_stat": {"Master Bedroom Thermostat", 880, 530, "low", 100}, - "master_bed_heat": {"Master Bedroom Heating", 1407, 538, "low", 100}, - "basement_stat": {"Basement Thermostat", 879, 564, "low", 100}, - "basement_heat": {"Basement Heating", 1413, 578, "low", 100}, - "second_bed_stat": {"Second Bedroom Thermostat", 875, 613, "low", 100}, - "second_bed_heat": {"Second Bedroom Heating", 1413, 618, "low", 100}, - "inducer": {"Inducer", 1415, 662, "low", 100}, - "burner": {"Burner", 1415, 699, "low", 100}, - "circulator": {"Circulator", 1418, 749, "low", 100}, + "living_room_stat": {"Living Room Thermostat", 775, 251, "low", 100}, + "living_room_heat": {"Living Room Heating", 1320, 263, "low", 100}, + "dining_room_stat": {"Dining Room Thermostat", 779, 290, "low", 100}, + "dining_room_heat": {"Dining Room Heating", 1317, 305, "low", 100}, + "hot_water_stat": {"Hot Water Thermostat", 773, 488, "low", 100}, + "hot_water_heat": {"Hot Water Heating", 1313, 501, "low", 100}, + "first_bed_stat": {"First Bedroom Thermostat", 769, 526, "low", 100}, + "first_bed_heat": {"First Bedroom Heating", 1309, 540, "low", 100}, + "master_bed_stat": {"Master Bedroom Thermostat", 773, 570, "low", 100}, + "master_bed_heat": {"Master Bedroom Heating", 1309, 588, "low", 100}, + "basement_stat": {"Basement Thermostat", 769, 614, "low", 100}, + "basement_heat": {"Basement Heating", 1309, 630, "low", 100}, + "second_bed_stat": {"Second Bedroom Thermostat", 764, 657, "low", 100}, + "second_bed_heat": {"Second Bedroom Heating", 1307, 672, "low", 100}, + "inducer": {"Inducer", 1307, 711, "low", 100}, + "burner": {"Burner", 1307, 760, "low", 100}, + "circulator": {"Circulator", 1307, 799, "low", 100}, + "furnace_power": {"Furnace Power", 1038, 837, "urgent", 100}, } + func main() { fmt.Println("Starting multi-light monitor") dbPath := getEnv("LIGHT_DB_PATH", "lightlog.db") - webcamURL := getEnv("WEBCAM_URL", "http://furnace.service:8082/stream") - minBrightness := getEnvInt("MIN_BRIGHTNESS", 160) + webcamURL := getEnv("WEBCAM_URL", "http://furnace.service:8081/stream") + minBrightness := getEnvInt("MIN_BRIGHTNESS", 170) checkInterval := getEnvDuration("CHECK_INTERVAL", 2*time.Second) webPort := getEnv("FURNACE_WEB_PORT", "8090") - lights, err := loadLightsFromEnv() - if err != nil { - log.Fatal(err) - } + lights, err := loadLightsFromEnv() + if err != nil { + log.Fatal(err) + } fmt.Println("Using DB:", dbPath) fmt.Println("Using webcam:", webcamURL) @@ -104,6 +104,10 @@ func main() { state TEXT, timestamp DATETIME )`) + _, err = db.Exec(`CREATE INDEX IF NOT EXISTS idx_light_checks_name_ts + ON light_checks(name, timestamp DESC + );`) + if err != nil { log.Fatal(err) } @@ -111,12 +115,14 @@ func main() { prevStates := make(map[string]bool) for { - img, err := grabFrame(webcamURL) - if err != nil { - log.Println("Error grabbing frame:", err) - time.Sleep(time.Second) - continue - } + img, err := grabFrame(webcamURL) + if err != nil { + log.Println("Error grabbing frame:", err) + time.Sleep(time.Second) + continue + } + + now := time.Now() for key, light := range lights { on := isLightOn(img, light, minBrightness) @@ -125,11 +131,12 @@ func main() { if on != prevStates[key] { stateStr := onOff(on) - // Notify fmt.Printf("%s: %s\n", light.Name, stateStr) + + insertLightEvent(db, key, on, now) + sendNtfyNotification(light, on) - // Update previous state prevStates[key] = on } } @@ -141,7 +148,7 @@ func main() { func loadLightsFromEnv() (map[string]Light, error) { raw := os.Getenv("LIGHTS_JSON") if raw == "" { - return defaultLights, nil + return defaultLights, nil } var lights map[string]Light @@ -156,7 +163,6 @@ func loadLightsFromEnv() (map[string]Light, error) { return lights, nil } - func grabFrame(url string) (image.Image, error) { resp, err := http.Get(url) if err != nil { @@ -268,10 +274,10 @@ func sendNtfyNotification(light Light, on bool) { } func startWebServer(db *sql.DB, port string) { - lights, err := loadLightsFromEnv() - if err != nil { - log.Fatal(err) - } + lights, err := loadLightsFromEnv() + if err != nil { + log.Fatal(err) + } http.HandleFunc("/lights", func(w http.ResponseWriter, r *http.Request) { rows, err := db.Query(` @@ -303,3 +309,21 @@ func startWebServer(db *sql.DB, port string) { log.Println("HTTP server listening on", port) log.Fatal(http.ListenAndServe(":"+port, nil)) } + +func insertLightEvent(db *sql.DB, name string, on bool, ts time.Time) { + state := "off" + if on { + state = "on" + } + + _, err := db.Exec( + `INSERT INTO light_checks (name, state, timestamp) + VALUES (?, ?, ?)`, + name, + state, + ts, + ) + if err != nil { + log.Println("DB insert failed:", err) + } +}