Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d6db296
[wifi-info] Add IP address text sensor
bharvey88 Feb 25, 2026
d50e4b9
[version] Add ESPHome and Apollo firmware version sensors
bharvey88 Feb 25, 2026
d000ca3
[esphome] Modernise board spec, web server version, remove legacy opt…
bharvey88 Feb 25, 2026
8c2a09e
fix: add entity_category diagnostic to ESPHome Version sensor
bharvey88 Feb 26, 2026
02ff25c
fix: add update_interval: never to static Apollo Firmware Version sensor
bharvey88 Feb 26, 2026
d547a43
fix: remove duplicate entity_category key on ESPHome Version sensor
bharvey88 Feb 26, 2026
64c94a4
Merge pull request #27 from ApolloAutomation/esphome-modernisation
TrevorSchirmer Feb 27, 2026
6d2d9a6
Merge pull request #26 from ApolloAutomation/version-sensors
TrevorSchirmer Feb 27, 2026
80c1945
fix: remove unused id, add entity_category diagnostic to IP address s…
bharvey88 Feb 25, 2026
d73a082
Merge pull request #25 from ApolloAutomation/wifi-info-ip-address
bharvey88 Feb 27, 2026
4783838
[cpap] Add invert water logic and auto refill for CPAP filling use case
bharvey88 Mar 1, 2026
2b6250e
Fix auto refill triggering on boot by using on_release instead of on_…
bharvey88 Mar 1, 2026
0519e65
Fix premature pump stop in inverted mode when using two sensors
bharvey88 Mar 1, 2026
f7af815
Bump version to 26.3.2.1
bharvey88 Mar 2, 2026
e637d23
Bump version to 26.3.2.1
bharvey88 Mar 2, 2026
1d3fc49
Merge pull request #28 from ApolloAutomation/cpap-invert-water-logic
Bunton33 Mar 3, 2026
817818c
fix: remove update_interval: never from Apollo Firmware Version sensor
bharvey88 Mar 6, 2026
09d3d60
Fix Apollo Firmware Version sensor showing unknown
bharvey88 Mar 6, 2026
abfb0e8
fix: publish firmware version once on boot instead of polling
bharvey88 Mar 6, 2026
f0f2a12
fix: add firmware version publish to PUMP-1_Minimal
bharvey88 Mar 7, 2026
bb2c678
Fix: publish firmware version once on boot instead of polling
bharvey88 Mar 7, 2026
23a8b4c
fix: add logbook entry when auto refill triggers via invert water logic
bharvey88 Mar 9, 2026
bd58d14
[cpap] Add logbook entry for auto refill trigger
bharvey88 Mar 9, 2026
ab51496
feat: add Pump Activity event entity for HA logbook
bharvey88 Mar 10, 2026
dd9cb47
fix: guard pump_stopped event and log against rejected starts
bharvey88 Mar 10, 2026
9a9644a
fix: replace event entity with text sensor for readable HA logbook en…
bharvey88 Mar 10, 2026
0cabc9c
[cpap] Add Last Pump Action text sensor for HA logbook
bharvey88 Mar 11, 2026
0ec11e9
feat: rename Invert Water Logic to Tank Refill Mode + auto-configure …
bharvey88 Mar 11, 2026
712e264
fix: sync dependent switches on boot to match restored tank_refill_mo…
bharvey88 Mar 11, 2026
894a316
feat: auto-toggle Auto Refill with Tank Refill Mode
bharvey88 Mar 17, 2026
623f8cb
[ux] Rename Invert Water Logic to Tank Refill Mode + auto-configure s…
bharvey88 Mar 26, 2026
bb25a90
Run label-check and auto-assign via pull_request_target
bharvey88 Jun 10, 2026
d51b0d9
Check for updates when the network connects
bharvey88 Jun 11, 2026
f07d04b
Release notes: compact formatting for the HA update dialog
bharvey88 Jun 11, 2026
640f627
Merge pull request #41 from ApolloAutomation/fix-update-first-check
TrevorSchirmer Jun 11, 2026
1cf2bfa
Merge pull request #40 from ApolloAutomation/fix-fork-pr-workflows
TrevorSchirmer Jun 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name-template: 'Release v$NEXT_PATCH_VERSION'
tag-template: "$RESOLVED_VERSION"
change-template: "- #$NUMBER $TITLE @$AUTHOR"
sort-direction: ascending
category-template: '**$TITLE**'

categories:
- title: "🚨 Breaking changes"
Expand All @@ -26,11 +27,9 @@ include-labels:

no-changes-template: '- No changes'

# The shared build workflow appends a Full Changelog compare link to the
# release body (release-drafter cannot render 4-part version tags).
template: |
## What's Changed
**What's Changed**

$CHANGES

**Full Changelog**: https://github.com/ApolloAutomation/PUMP-1/compare/$PREVIOUS_TAG...$RESOLVED_VERSION.1

Be sure to 🌟 this repository for updates!
5 changes: 4 additions & 1 deletion .github/workflows/autoassign.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
name: Auto Assign
# pull_request_target (not pull_request) so assignment works on
# fork-submitted PRs; fork pull_request runs get a read-only token.
# Safe because this workflow never checks out or executes PR code.
on:
issues:
types: [opened]
pull_request:
pull_request_target:
types: [opened]
jobs:
run:
Expand Down
7 changes: 0 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@ on:
pull_request:

permissions:
# Allow GITHUB_TOKEN to add labels to pull requests
pull-requests: write
issues: write
contents: read
id-token: write

jobs:
label-check:
name: Label Check
uses: ApolloAutomation/Workflows/.github/workflows/label-check.yml@main

ci:
name: Building ${{ matrix.file }} / ESPHome ${{ matrix.esphome-version }}
runs-on: ubuntu-latest
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/label-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Label Check

# pull_request_target (not pull_request) so the job gets a write token on
# fork-submitted PRs too; plain pull_request runs from forks are read-only
# and cannot add labels. Safe because the called workflow only reads the PR
# body and never checks out or executes PR code. The "edited" type re-runs
# the check when the template checkboxes are changed.
on:
pull_request_target:
types: [opened, edited, reopened, synchronize]

permissions:
pull-requests: write
issues: write
contents: read

jobs:
label-check:
name: Label Check
uses: ApolloAutomation/Workflows/.github/workflows/label-check.yml@main
109 changes: 104 additions & 5 deletions Integrations/ESPHome/Core.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
substitutions:
name: apollo-pump-1
version: "25.12.18.1"
version: "26.3.2.1"
device_description: ${name} made by Apollo Automation - version ${version}.

esp32:
board: esp32-c6-devkitm-1
variant: esp32c6
flash_size: 8MB
framework:
Expand All @@ -18,9 +17,22 @@ esphome:
id(pump_start_time) = 0;
id(safety_alert_active) = false;
- script.execute: pump_safety_check
- priority: -20
then:
- if:
condition:
switch.is_on: tank_refill_mode
then:
- switch.turn_on: stop_pump_when_full
- switch.turn_off: stop_pump_when_dry
- switch.turn_on: auto_refill
else:
- switch.turn_off: stop_pump_when_full
- switch.turn_on: stop_pump_when_dry
Comment on lines +26 to +31

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="Integrations/ESPHome/Core.yaml"

# Show the exact snippet around the initially referenced lines (26-31)
echo "=== $FILE lines 1-80 ==="
nl -ba "$FILE" | sed -n '1,80p'

# Show the section around the other referenced range (152-200)
echo
echo "=== $FILE lines 120-200 ==="
nl -ba "$FILE" | sed -n '120,210p'

# Show the section around the referenced branch near 458-520
echo
echo "=== $FILE lines 430-520 ==="
nl -ba "$FILE" | sed -n '430,520p'

# Find all occurrences of stop_pump_when_full and show small context
echo
echo "=== Occurrences of stop_pump_when_full ==="
rg -n "stop_pump_when_full" "$FILE" || true

# For each is_off/is_on condition involving stop_pump_when_full, show a bit more context
echo
echo "=== Lines with switch.is_off/on: stop_pump_when_full ==="
rg -n "switch\.(is_off|is_on):\s*stop_pump_when_full" "$FILE" -n || true

# Show definition/booleans for stop_pump_when_full if present
echo
echo "=== Potential stop_pump_when_full entity definition (context) ==="
rg -n "(id:\s*stop_pump_when_full|name:\s*stop_pump_when_full|platform:|binary_sensor:|switch:)" "$FILE" || true

Repository: ApolloAutomation/PUMP-1

Length of output: 178


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="Integrations/ESPHome/Core.yaml"
if [ ! -f "$FILE" ]; then
  echo "Missing file: $FILE"
  exit 1
fi

show_range () {
  local start="$1" end="$2"
  echo "=== $FILE lines $start-$end ==="
  awk -v s="$start" -v e="$end" 'NR>=s && NR<=e {printf "%6d %s\n", NR, $0}' "$FILE"
  echo
}

show_range 1 80
show_range 120 210
show_range 430 520

echo "=== Occurrences of stop_pump_when_full ==="
rg -n "stop_pump_when_full" "$FILE" || true
echo
echo "=== Lines with switch.is_off/is_on: stop_pump_when_full ==="
rg -n "switch\.(is_off|is_on):\s*stop_pump_when_full" "$FILE" || true
echo
echo "=== Potential stop_pump_when_full entity definition (context) ==="
rg -n "(id:\s*stop_pump_when_full|name:\s*stop_pump_when_full)" "$FILE" || true

Repository: ApolloAutomation/PUMP-1

Length of output: 9824


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="Integrations/ESPHome/Core.yaml"

for term in "fluid_input_sensor" "fulid_output_sensor" "inverted" "destination full" "refill" "auto_refill" "pumpUntilFull" "pump_control" "fulid_output_sensor"; do
  echo "=== rg $term ==="
  rg -n "$term" "$FILE" || true
done

echo
echo "=== Show sensor-related sections (small ranges) ==="
# show a few nearby ranges around likely sensor ids
rg -n "binary_sensor:" "$FILE"
# print around first few matches of fluid_input_sensor
for l in $(rg -n "fluid_input_sensor" "$FILE" | cut -d: -f1 | head -n 5); do
  start=$((l-15)); end=$((l+40));
  echo "--- around line $l ($start-$end) ---"
  awk -v s="$start" -v e="$end" 'NR>=s && NR<=e {printf "%6d %s\n", NR, $0}' "$FILE"
  echo
done

# print around fulid_output_sensor occurrences
for l in $(rg -n "fulid_output_sensor" "$FILE" | cut -d: -f1 | head -n 5); do
  start=$((l-15)); end=$((l+40));
  echo "--- around line $l ($start-$end) ---"
  awk -v s="$start" -v e="$end" 'NR>=s && NR<=e {printf "%6d %s\n", NR, $0}' "$FILE"
  echo
done

Repository: ApolloAutomation/PUMP-1

Length of output: 17605


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="Integrations/ESPHome/Core.yaml"

echo "=== Context around additional stop_pump_when_full usage (~370-420) ==="
awk 'NR>=350 && NR<=430 {printf "%6d %s\n", NR, $0}' "$FILE"

echo
echo "=== Exact tank_full vs destination_full conditions in pump_safety_check (~430-475) ==="
awk 'NR>=430 && NR<=477 {printf "%6d %s\n", NR, $0}' "$FILE"

Repository: ApolloAutomation/PUMP-1

Length of output: 5355


Inverted-mode “destination full” stop is gated on stop_pump_when_full: off, but refill mode turns stop_pump_when_full on by default—making that stop path unreachable unless the switch is manually disabled.

  • tank_refill_mode enables stop_pump_when_full (on_boot: lines 26-31; on_turn_on: lines 150-154; pumpUntilFull: lines 388-393).
  • In pump_safety_check, the inverted-mode “destination full” block requires tank_refill_mode and switch.is_off: stop_pump_when_full (lines 458-466), so it won’t run in default refill mode; only the separate “tank full” check (output sensor, gated on stop_pump_when_full: on) can stop the pump.
One possible alignment
-                      - switch.is_off: stop_pump_when_full
+                      - switch.is_on: stop_pump_when_full

- switch.turn_off: auto_refill
- priority: -100
then:
- delay: 1000ms
- delay: 1000ms
- script.execute: statusCheck
- priority: -10
then:
Expand Down Expand Up @@ -69,6 +81,7 @@ captive_portal:

web_server:
port: 80
version: 3

# Buzzer
output:
Expand Down Expand Up @@ -127,6 +140,30 @@ switch:
restore_mode: RESTORE_DEFAULT_OFF
icon: mdi:water-sync
entity_category: config
- platform: template
name: "Tank Refill Mode"
id: tank_refill_mode
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
icon: mdi:water-sync
entity_category: config
on_turn_on:
then:
- switch.turn_on: stop_pump_when_full
- switch.turn_off: stop_pump_when_dry
- switch.turn_on: auto_refill
on_turn_off:
then:
- switch.turn_off: stop_pump_when_full
- switch.turn_on: stop_pump_when_dry
- switch.turn_off: auto_refill
- platform: template
name: "Auto Refill"
id: auto_refill
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
icon: mdi:autorenew
entity_category: config
- platform: template
name: "Pump Safety Override"
id: pump_safety_override
Expand All @@ -147,10 +184,21 @@ switch:
- if:
condition:
or:
- binary_sensor.is_on: fluid_input_sensor
# Normal mode: input has water
- and:
- switch.is_off: tank_refill_mode
- binary_sensor.is_on: fluid_input_sensor
# Inverted mode: input is dry (destination is low, needs filling)
- and:
- switch.is_on: tank_refill_mode
- binary_sensor.is_off: fluid_input_sensor
# Bypass: dry protection not enabled
- switch.is_off: stop_pump_when_dry
then:
Comment on lines 186 to 197

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="Integrations/ESPHome/Core.yaml"

echo "== Target file existence =="
ls -la "$FILE" || true

echo
echo "== Lines 150-230 =="
nl -ba "$FILE" | sed -n '140,240p'

echo
echo "== Find tank_refill_mode usages/definitions =="
rg -n "tank_refill_mode" "$FILE" || true

echo
echo "== Find stop_pump_when_dry usages/definitions =="
rg -n "stop_pump_when_dry" "$FILE" || true

echo
echo "== Show relevant start gating context (look for 'start'/'pump' 'dry' logic blocks) =="
rg -n -C 2 "(start|pump).*dry|dry.*(start|pump)|(tank_refill_mode|stop_pump_when_dry).*then:|on_press|on_boot|lambda|id:|condition:|or:|switch\.is_off|switch\.is_on" "$FILE" || true

Repository: ApolloAutomation/PUMP-1

Length of output: 259


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="Integrations/ESPHome/Core.yaml"

echo "== Lines 150-230 =="
awk 'NR>=150 && NR<=230 {printf "%d\t%s\n", NR, $0}' "$FILE"

echo
echo "== Find tank_refill_mode usages/definitions =="
rg -n "tank_refill_mode" "$FILE" || true

echo
echo "== Find stop_pump_when_dry usages/definitions =="
rg -n "stop_pump_when_dry" "$FILE" || true

echo
echo "== Context around OR branch near lines ~180-200 =="
awk 'NR>=170 && NR<=210 {printf "%d\t%s\n", NR, $0}' "$FILE"

echo
echo "== Find the 'pump start' gating logic block (best-effort search) =="
rg -n -C 3 "(pump|start).*condition:|condition:|or:|binary_sensor\.is_(on|off)|switch\.is_(on|off)" "$FILE" | head -n 200

Repository: ApolloAutomation/PUMP-1

Length of output: 10325


Tank Refill Mode should not satisfy the “dry protection bypass” branch for pump start

In pump_controlon_turn_on, pump start is allowed when any or: branch is true, including - switch.is_off: stop_pump_when_dry. But when tank_refill_mode is enabled, stop_pump_when_dry is forced OFF, so this bypass branch becomes true and lets the pump start even when fluid_input_sensor indicates wet.

Suggested fix
-                # Bypass: dry protection not enabled
-                - switch.is_off: stop_pump_when_dry
+                # Bypass only in normal mode when dry protection is intentionally disabled
+                - and:
+                    - switch.is_off: tank_refill_mode
+                    - switch.is_off: stop_pump_when_dry
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
or:
- binary_sensor.is_on: fluid_input_sensor
# Normal mode: input has water
- and:
- switch.is_off: tank_refill_mode
- binary_sensor.is_on: fluid_input_sensor
# Inverted mode: input is dry (destination is low, needs filling)
- and:
- switch.is_on: tank_refill_mode
- binary_sensor.is_off: fluid_input_sensor
# Bypass: dry protection not enabled
- switch.is_off: stop_pump_when_dry
then:
or:
# Normal mode: input has water
- and:
- switch.is_off: tank_refill_mode
- binary_sensor.is_on: fluid_input_sensor
# Inverted mode: input is dry (destination is low, needs filling)
- and:
- switch.is_on: tank_refill_mode
- binary_sensor.is_off: fluid_input_sensor
# Bypass only in normal mode when dry protection is intentionally disabled
- and:
- switch.is_off: tank_refill_mode
- switch.is_off: stop_pump_when_dry
then:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Integrations/ESPHome/Core.yaml` around lines 186 - 197, The bypass branch in
pump_control → on_turn_on currently allows pump start solely when
switch.stop_pump_when_dry is off, which becomes true whenever tank_refill_mode
is enabled; modify that branch so the bypass requires both stop_pump_when_dry to
be off AND tank_refill_mode to be off (i.e., only allow the dry-protection
bypass when tank_refill_mode is not active), updating the or: branch that
contains "- switch.is_off: stop_pump_when_dry" to include an additional
condition referencing "switch.is_off: tank_refill_mode".

- logger.log: "Pump turning on - conditions met"
- text_sensor.template.publish:
id: last_pump_action
state: "Pump Started"
- lambda: |-
id(pump_start_time) = millis();
id(safety_alert_active) = false;
Expand All @@ -160,10 +208,17 @@ switch:
- switch.turn_off: pump_control
on_turn_off:
then:
- if:
condition:
lambda: 'return id(pump_start_time) != 0;'
then:
- logger.log: "Pump turned off"
- text_sensor.template.publish:
id: last_pump_action
state: "Pump Stopped"
- lambda: |-
id(pump_start_time) = 0;
id(safety_alert_active) = false;
- logger.log: "Pump turned off"

binary_sensor:
- platform: status
Expand Down Expand Up @@ -213,6 +268,20 @@ binary_sensor:
input: true
pullup: true
inverted: true
on_release:
then:
- if:
condition:
and:
- switch.is_on: auto_refill
- switch.is_on: tank_refill_mode
- switch.is_off: pump_control
then:
- logger.log: "Auto refill triggered - tank level low"
- text_sensor.template.publish:
id: last_pump_action
state: "Auto Refill Triggered"
- script.execute: pumpUntilFull

- platform: gpio
name: Fluid Output
Expand Down Expand Up @@ -295,6 +364,26 @@ light:
min_brightness: 50%
max_brightness: 100%

text_sensor:
- platform: template
name: "Last Pump Action"
id: last_pump_action
icon: mdi:pump
- platform: wifi_info
ip_address:
name: "IP Address"
id: wifi_ip
entity_category: "diagnostic"
- platform: version
name: "ESPHome Version"
hide_timestamp: true
entity_category: "diagnostic"
- platform: template
name: "Apollo Firmware Version"
id: apollo_firmware_version
update_interval: never
entity_category: "diagnostic"

script:
- id: pumpUntilFull
then:
Expand Down Expand Up @@ -366,10 +455,20 @@ script:
then:
- logger.log: "Pump stopping - safety"
- switch.turn_off: pump_control
- if:
condition:
- and:
- switch.is_on: tank_refill_mode
- switch.is_off: stop_pump_when_full
- binary_sensor.is_on: fluid_input_sensor
then:
- logger.log: "Pump stopping - destination full (inverted mode)"
- switch.turn_off: pump_control
- if:
condition:
- and:
- switch.is_on: stop_pump_when_dry
- switch.is_off: tank_refill_mode
- binary_sensor.is_off: fluid_input_sensor
then:
- logger.log: "Pump stopping - input dry"
Expand Down
13 changes: 6 additions & 7 deletions Integrations/ESPHome/PUMP-1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ esphome:
friendly_name: Apollo PUMP-1
comment: Apollo PUMP-1
name_add_mac_suffix: true
platformio_options:
board_build.flash_mode: dio

on_boot:
- priority: 500
then:
- text_sensor.template.publish:
id: apollo_firmware_version
state: "${version}"
- priority: -10
then:
- if:
Expand Down Expand Up @@ -49,10 +51,7 @@ update:

wifi:
on_connect:
- delay: 5s
- ble.disable:
on_disconnect:
- ble.enable:
- component.update: firmware_update
ap:
ssid: "Apollo PUMP-1 Hotspot"

Expand Down
9 changes: 6 additions & 3 deletions Integrations/ESPHome/PUMP-1_Minimal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ esphome:
friendly_name: Apollo PUMP-1
comment: Apollo PUMP-1
name_add_mac_suffix: true
platformio_options:
board_build.flash_mode: dio

project:
name: "ApolloAutomation.PUMP-1"
version: "${version}"

min_version: 2023.11.1
on_boot:
priority: 500
then:
- text_sensor.template.publish:
id: apollo_firmware_version
state: "${version}"

dashboard_import:
package_import_url: github://ApolloAutomation/PUMP-1/Integrations/ESPHome/PUMP-1_Minimal.yaml
Expand Down