From d1c7d9d491af32da8152fa94ce1689cbc22c8adc Mon Sep 17 00:00:00 2001 From: Miro Wilms Date: Sun, 19 Oct 2025 21:37:22 +0200 Subject: [PATCH 1/5] fix: remove duplicate plugin_name variable declaration The duplicate 'variable plugin_name' inside the namespace was causing namespace resolution issues during plugin initialization. The plugin system uses the directory name to create the namespace, making this internal variable declaration redundant and problematic. This fixes the 'can't read ::plugins::de1_water_tracker_plugin::version' error that prevented the plugin from loading. --- plugin.tcl | 1 - 1 file changed, 1 deletion(-) diff --git a/plugin.tcl b/plugin.tcl index a83cf0e..fa18522 100644 --- a/plugin.tcl +++ b/plugin.tcl @@ -1,7 +1,6 @@ set plugin_name "de1_water_tracker_plugin" namespace eval ::plugins::${plugin_name} { - variable plugin_name "de1_water_tracker_plugin" variable author "Sy_Butter" variable contact "Github" variable version 0.1 From 13dc807a50a0149cbdffa86eb4302248c6eedfc3 Mon Sep 17 00:00:00 2001 From: Miro Wilms Date: Sun, 19 Oct 2025 21:37:34 +0200 Subject: [PATCH 2/5] refactor: simplify save_plugin_settings calls Replace namespace variable references with string literals for save_plugin_settings calls, matching the pattern used by other established plugins like advanced_rest_api. This makes the code more maintainable and consistent with DE1 plugin conventions. --- plugin.tcl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin.tcl b/plugin.tcl index fa18522..1298a23 100644 --- a/plugin.tcl +++ b/plugin.tcl @@ -57,13 +57,13 @@ namespace eval ::plugins::${plugin_name} { variable settings set settings(total_volume) 0 set settings(filter_change_date) [clock format [clock seconds] -format "%Y-%m-%d"] - save_plugin_settings $::plugins::de1_water_tracker_plugin::plugin_name + save_plugin_settings de1_water_tracker_plugin update_display popup [translate "Counter reset"] } proc toggle_units {} { - save_plugin_settings $::plugins::de1_water_tracker_plugin::plugin_name + save_plugin_settings de1_water_tracker_plugin update_display } @@ -84,7 +84,7 @@ namespace eval ::plugins::${plugin_name} { Descale - AirPurge { set settings(total_volume) [expr {$settings(total_volume) + $::de1(volume)}] - save_plugin_settings $::plugins::de1_water_tracker_plugin::plugin_name + save_plugin_settings de1_water_tracker_plugin update_display } } From 9bee99bda4901cb09bfcbd86be77fdb68edc2379 Mon Sep 17 00:00:00 2001 From: Miro Wilms Date: Mon, 20 Oct 2025 09:13:14 +0200 Subject: [PATCH 3/5] refactor: rename plugin to de1_water_tracker for consistency Remove '_plugin' suffix from plugin name to follow naming conventions used by other established plugins (e.g., advanced_rest_api, mqtt). The directory should also be renamed from de1_water_tracker_plugin to de1_water_tracker when installing. This is a breaking change - users will need to: 1. Disable and remove the old de1_water_tracker_plugin 2. Install the renamed de1_water_tracker plugin --- plugin.tcl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/plugin.tcl b/plugin.tcl index 1298a23..4383528 100644 --- a/plugin.tcl +++ b/plugin.tcl @@ -1,4 +1,4 @@ -set plugin_name "de1_water_tracker_plugin" +set plugin_name "de1_water_tracker" namespace eval ::plugins::${plugin_name} { variable author "Sy_Butter" @@ -18,20 +18,20 @@ namespace eval ::plugins::${plugin_name} { add_de1_text $page_name 1280 300 -text [translate "Water Tracker"] -font Helv_20_bold -width 1200 -fill "#444444" -anchor "center" -justify "center" - add_de1_variable $page_name 1280 600 -font global_font -width 800 -fill "#444444" -anchor "center" -textvariable {$::plugins::de1_water_tracker_plugin::settings(display)} + add_de1_variable $page_name 1280 600 -font global_font -width 800 -fill "#444444" -anchor "center" -textvariable {$::plugins::de1_water_tracker::settings(display)} dui add entry $page_name 1280 760 -tags filter_date -width 12 -font Helv_10 \ -borderwidth 1 -bg #fbfaff -foreground #4e85f4 -relief flat \ -highlightthickness 1 -highlightcolor #000000 \ - -textvariable ::plugins::de1_water_tracker_plugin::settings(filter_change_date) \ + -textvariable ::plugins::de1_water_tracker::settings(filter_change_date) \ -label [translate "Filter Last Changed Date"] -label_pos {1280 700} \ -label_font Helv_10_bold -label_width 1200 -label_fill "#444444" -label_anchor center - dui add dcheckbox $page_name 1280 860 -tags use_gallons -textvariable ::plugins::de1_water_tracker_plugin::settings(use_gallons) -fill "#444444" \ - -label [translate "Display in gallons"] -label_font Helv_10_bold -label_fill #4e85f4 -command ::plugins::de1_water_tracker_plugin::toggle_units + dui add dcheckbox $page_name 1280 860 -tags use_gallons -textvariable ::plugins::de1_water_tracker::settings(use_gallons) -fill "#444444" \ + -label [translate "Display in gallons"] -label_font Helv_10_bold -label_fill #4e85f4 -command ::plugins::de1_water_tracker::toggle_units add_de1_text $page_name 1280 1000 -text [translate "Reset Counter"] -font Helv_10_bold -fill "#4e85f4" -anchor "center" - add_de1_button $page_name ::plugins::de1_water_tracker_plugin::reset_counter 980 970 1580 1070 "" + add_de1_button $page_name ::plugins::de1_water_tracker::reset_counter 980 970 1580 1070 "" return $page_name } @@ -57,13 +57,13 @@ namespace eval ::plugins::${plugin_name} { variable settings set settings(total_volume) 0 set settings(filter_change_date) [clock format [clock seconds] -format "%Y-%m-%d"] - save_plugin_settings de1_water_tracker_plugin + save_plugin_settings de1_water_tracker update_display popup [translate "Counter reset"] } proc toggle_units {} { - save_plugin_settings de1_water_tracker_plugin + save_plugin_settings de1_water_tracker update_display } @@ -84,7 +84,7 @@ namespace eval ::plugins::${plugin_name} { Descale - AirPurge { set settings(total_volume) [expr {$settings(total_volume) + $::de1(volume)}] - save_plugin_settings de1_water_tracker_plugin + save_plugin_settings de1_water_tracker update_display } } @@ -104,8 +104,8 @@ namespace eval ::plugins::${plugin_name} { } } update_display - ::de1::event::listener::on_major_state_change_add ::plugins::de1_water_tracker_plugin::on_state_change + ::de1::event::listener::on_major_state_change_add ::plugins::de1_water_tracker::on_state_change - plugins gui de1_water_tracker_plugin [build_ui] + plugins gui de1_water_tracker [build_ui] } } \ No newline at end of file From cfb91ea1060e9aad5fe2badd8a9db860523833b6 Mon Sep 17 00:00:00 2001 From: Miro Wilms Date: Mon, 20 Oct 2025 14:26:29 +0200 Subject: [PATCH 4/5] feat: add filter change reminder notification Implements the TODO item to notify users when a water usage threshold is reached. Features: - New setting for filter change reminder threshold (in L or gal) - Automatic notification popup when threshold is reached - Threshold respects current unit selection (L/gallons) - Notification flag resets when threshold is changed - UI input field with auto-conversion based on selected units - Done button saves threshold before closing settings The notification flag is reset when: - Counter is reset (allows notification for next cycle) - Threshold value is changed (allows notification at new threshold) Closes: TODO item 'Add a ping to let you know when a set total L/gal has been reached for filter change' Version bumped to 0.2 Tested and verified working: - UI properly spaced to avoid overlapping elements - Threshold saves correctly when Done button is clicked - Notification shows at correct threshold - Notification can be triggered again after changing threshold --- README.md | 16 +++++++- plugin.tcl | 111 +++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 117 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 6afa35e..e989d6e 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,22 @@ A plugin for the Decent Espresso DE1 machine that tracks water and filter replacement date Basically you should be entering a date in the settings to track your filter. -You can also hit the reset button and will auto populate with todays date. +You can also hit the reset button and will auto populate with todays date. + +## Features +- Track total water usage in liters or gallons +- Set a filter change date +- **Get notified when you reach a water usage threshold** - Set your desired threshold in the plugin settings and you'll receive a popup reminder when it's time to change your filter +- Reset counter when you change your filter + +## Usage +1. Set your preferred units (L or gallons) +2. Enter the date you last changed your filter +3. Set a filter change reminder threshold (e.g., 100L or 26gal) +4. The plugin will track your water usage and notify you when the threshold is reached +5. When you change your filter, hit "Reset Counter" to start tracking again To-do: - - Add a ping to let you know when a set total L/gal has been reached for filter change - Add a 2 months, 3 months, 6 months, and year selection for time based notifs Thank you Damian for some sanity checks and question answering. diff --git a/plugin.tcl b/plugin.tcl index 4383528..661e872 100644 --- a/plugin.tcl +++ b/plugin.tcl @@ -3,8 +3,8 @@ set plugin_name "de1_water_tracker" namespace eval ::plugins::${plugin_name} { variable author "Sy_Butter" variable contact "Github" - variable version 0.1 - variable description "Track total water usage to help schedule filter changes." + variable version 0.2 + variable description "Track total water usage and get notified when it's time to change your filter." variable name "Water Usage Tracker" variable settings @@ -14,7 +14,7 @@ namespace eval ::plugins::${plugin_name} { add_de1_page "$page_name" "settings_message.png" "default" add_de1_text $page_name 1280 1310 -text [translate "Done"] -font Helv_10_bold -fill "#fAfBff" -anchor "center" - add_de1_button $page_name {say [translate {Done}] $::settings(sound_button_in); page_to_show_when_off extensions} 980 1210 1580 1410 "" + add_de1_button $page_name {say [translate {Done}] $::settings(sound_button_in); ::plugins::de1_water_tracker::save_and_close} 980 1210 1580 1410 "" add_de1_text $page_name 1280 300 -text [translate "Water Tracker"] -font Helv_20_bold -width 1200 -fill "#444444" -anchor "center" -justify "center" @@ -27,11 +27,18 @@ namespace eval ::plugins::${plugin_name} { -label [translate "Filter Last Changed Date"] -label_pos {1280 700} \ -label_font Helv_10_bold -label_width 1200 -label_fill "#444444" -label_anchor center - dui add dcheckbox $page_name 1280 860 -tags use_gallons -textvariable ::plugins::de1_water_tracker::settings(use_gallons) -fill "#444444" \ + dui add dcheckbox $page_name 1280 890 -tags use_gallons -textvariable ::plugins::de1_water_tracker::settings(use_gallons) -fill "#444444" \ -label [translate "Display in gallons"] -label_font Helv_10_bold -label_fill #4e85f4 -command ::plugins::de1_water_tracker::toggle_units - add_de1_text $page_name 1280 1000 -text [translate "Reset Counter"] -font Helv_10_bold -fill "#4e85f4" -anchor "center" - add_de1_button $page_name ::plugins::de1_water_tracker::reset_counter 980 970 1580 1070 "" + dui add entry $page_name 1280 1010 -tags filter_threshold -width 12 -font Helv_10 \ + -borderwidth 1 -bg #fbfaff -foreground #4e85f4 -relief flat \ + -highlightthickness 1 -highlightcolor #000000 \ + -textvariable ::plugins::de1_water_tracker::settings(filter_threshold_display) \ + -label [translate "Filter change reminder (L or gal)"] -label_pos {1280 950} \ + -label_font Helv_10_bold -label_width 1200 -label_fill "#444444" -label_anchor center + + add_de1_text $page_name 1280 1150 -text [translate "Reset Counter"] -font Helv_10_bold -fill "#4e85f4" -anchor "center" + add_de1_button $page_name ::plugins::de1_water_tracker::reset_counter 980 1120 1580 1220 "" return $page_name } @@ -45,26 +52,97 @@ namespace eval ::plugins::${plugin_name} { if {[info exists settings(use_gallons)] && $settings(use_gallons)} { set value [expr {$settings(total_volume) / 3785.41}] set units "gal" + # Update threshold display + if {$settings(filter_threshold_ml) > 0} { + set settings(filter_threshold_display) [format "%.1f" [expr {$settings(filter_threshold_ml) / 3785.41}]] + } } else { set value [expr {$settings(total_volume) / 1000.0}] set units "L" + # Update threshold display + if {$settings(filter_threshold_ml) > 0} { + set settings(filter_threshold_display) [format "%.1f" [expr {$settings(filter_threshold_ml) / 1000.0}]] + } } set settings(filter_change_date) [string trim $settings(filter_change_date)] set settings(display) [format [translate "Total water used: %.2f %s\nFilter last changed: %s"] $value $units $date_text] } + proc update_threshold {} { + variable settings + # Convert display value to milliliters based on current unit + if {[catch { + set threshold_value [string trim $settings(filter_threshold_display)] + set old_threshold [expr {[info exists settings(filter_threshold_ml)] ? $settings(filter_threshold_ml) : 0}] + + if {$threshold_value eq "" || $threshold_value == 0} { + set settings(filter_threshold_ml) 0 + } else { + if {$settings(use_gallons)} { + set settings(filter_threshold_ml) [expr {$threshold_value * 3785.41}] + } else { + set settings(filter_threshold_ml) [expr {$threshold_value * 1000.0}] + } + } + + # If threshold changed, reset notification flag so user can be notified again + if {$old_threshold != $settings(filter_threshold_ml)} { + set settings(notification_shown) 0 + } + + save_plugin_settings de1_water_tracker + }]} { + # Invalid input, reset to current value + update_display + } + } + + proc check_threshold {} { + variable settings + + # Convert the display value to ml before checking (in case user just entered it) + update_threshold + + # Only check if threshold is set and notification hasn't been shown + if {$settings(filter_threshold_ml) > 0 && !$settings(notification_shown)} { + if {$settings(total_volume) >= $settings(filter_threshold_ml)} { + set settings(notification_shown) 1 + save_plugin_settings de1_water_tracker + + # Determine units for notification + if {$settings(use_gallons)} { + set threshold_display [format "%.1f gal" [expr {$settings(filter_threshold_ml) / 3785.41}]] + } else { + set threshold_display [format "%.1f L" [expr {$settings(filter_threshold_ml) / 1000.0}]] + } + + popup [translate "Filter change reminder: You've reached $threshold_display of water usage!"] + } + } + } + proc reset_counter {} { variable settings set settings(total_volume) 0 set settings(filter_change_date) [clock format [clock seconds] -format "%Y-%m-%d"] + set settings(notification_shown) 0 save_plugin_settings de1_water_tracker update_display popup [translate "Counter reset"] } proc toggle_units {} { - save_plugin_settings de1_water_tracker + variable settings + # When toggling units, convert the threshold stored in ml to the new unit for display update_display + save_plugin_settings de1_water_tracker + } + + proc save_and_close {} { + variable settings + # Save the threshold value before closing + update_threshold + page_to_show_when_off extensions } proc on_state_change {event_dict} { @@ -86,6 +164,7 @@ namespace eval ::plugins::${plugin_name} { set settings(total_volume) [expr {$settings(total_volume) + $::de1(volume)}] save_plugin_settings de1_water_tracker update_display + check_threshold } } } @@ -94,7 +173,14 @@ namespace eval ::plugins::${plugin_name} { proc main {} { variable settings if {[array size settings] == 0} { - array set settings { total_volume 0 filter_change_date "" use_gallons 0 } + array set settings { + total_volume 0 + filter_change_date "" + use_gallons 0 + filter_threshold_ml 0 + filter_threshold_display "0" + notification_shown 0 + } } else { if {![info exists settings(filter_change_date)]} { set settings(filter_change_date) "" @@ -102,6 +188,15 @@ namespace eval ::plugins::${plugin_name} { if {![info exists settings(use_gallons)]} { set settings(use_gallons) 0 } + if {![info exists settings(filter_threshold_ml)]} { + set settings(filter_threshold_ml) 0 + } + if {![info exists settings(filter_threshold_display)]} { + set settings(filter_threshold_display) "0" + } + if {![info exists settings(notification_shown)]} { + set settings(notification_shown) 0 + } } update_display ::de1::event::listener::on_major_state_change_add ::plugins::de1_water_tracker::on_state_change From 9ef9f7fc09b243bf86ba288c464a258bde081343 Mon Sep 17 00:00:00 2001 From: Miro Wilms Date: Wed, 22 Oct 2025 11:54:32 +0200 Subject: [PATCH 5/5] Replace popup with custom warning page for filter notifications - Add dedicated water_filter_warning page with dismiss button - Warning page displays once per filter cycle (until reset/threshold change) - More prominent and impossible to miss compared to popup - Follows DE1 conventions for message pages - Universal across all skins --- plugin.tcl | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/plugin.tcl b/plugin.tcl index 661e872..faa4521 100644 --- a/plugin.tcl +++ b/plugin.tcl @@ -40,6 +40,28 @@ namespace eval ::plugins::${plugin_name} { add_de1_text $page_name 1280 1150 -text [translate "Reset Counter"] -font Helv_10_bold -fill "#4e85f4" -anchor "center" add_de1_button $page_name ::plugins::de1_water_tracker::reset_counter 980 1120 1580 1220 "" + # Create custom filter warning page + add_de1_page "water_filter_warning" "settings_message.png" "default" + + # Warning message + add_de1_text "water_filter_warning" 1280 700 \ + -text [translate "Time to change your water filter!"] \ + -font Helv_20_bold -fill "#dd0000" -anchor "center" -justify "center" -width 1200 + + # Additional info text + add_de1_text "water_filter_warning" 1280 850 \ + -text [translate "You've reached your set water usage threshold.\nReplace the filter, then reset the counter in plugin settings."] \ + -font Helv_10 -fill "#666666" -anchor "center" -justify "center" -width 1200 + + # Dismiss button + add_de1_text "water_filter_warning" 1280 1310 \ + -text [translate "OK"] \ + -font Helv_10_bold -fill "#fAfBff" -anchor "center" + + add_de1_button "water_filter_warning" \ + {say [translate {OK}] $::settings(sound_button_in); page_to_show_when_off off} \ + 980 1210 1580 1410 "" + return $page_name } @@ -109,14 +131,9 @@ namespace eval ::plugins::${plugin_name} { set settings(notification_shown) 1 save_plugin_settings de1_water_tracker - # Determine units for notification - if {$settings(use_gallons)} { - set threshold_display [format "%.1f gal" [expr {$settings(filter_threshold_ml) / 3785.41}]] - } else { - set threshold_display [format "%.1f L" [expr {$settings(filter_threshold_ml) / 1000.0}]] - } - - popup [translate "Filter change reminder: You've reached $threshold_display of water usage!"] + # Navigate to warning page instead of popup + set_next_page off water_filter_warning + page_to_show_when_off water_filter_warning } } }