Skip to content

feat: add water fountain controls - working mode, LED brightness, DND (closes #94)#202

Open
aavdberg wants to merge 6 commits intoJezza34000:mainfrom
aavdberg:feat/fountain-controls-issue-94
Open

feat: add water fountain controls - working mode, LED brightness, DND (closes #94)#202
aavdberg wants to merge 6 commits intoJezza34000:mainfrom
aavdberg:feat/fountain-controls-issue-94

Conversation

@aavdberg
Copy link
Copy Markdown
Contributor

@aavdberg aavdberg commented Mar 31, 2026

Summary

Implements missing controls for water fountain devices requested in #94.

New entities

Entity Type Device How
Working mode Select W4/W5/CTW2 (Normal/Smart) BLE CMD 220
Working mode Select CTW3 (Standard/Intermittent) BLE CMD 220
Led brightness Select All fountains (Low/Normal/High) REST API
Indicator light Switch All fountains REST API
Do not disturb Switch All fountains REST API

Technical notes

Working mode via BLE

pypetkitapi's FOUNTAIN_COMMAND dict was missing byte sequences for MODE_NORMAL, MODE_SMART, MODE_STANDARD, and MODE_INTERMITTENT. The sequences follow the same CMD 220 frame format as the existing POWER_ON/POWER_OFF entries and are derived from the W5BLEMQTT project:

cmd=220, type=1, data=[state=1, mode_byte, op_type=1]

These are patched into FOUNTAIN_COMMAND at integration startup in init.py until they can be upstreamed to pypetkitapi.

LED brightness / DND / Indicator light

These settings use UPDATE_SETTING with the correct camelCase field names (lampRingBrightness, lampRingSwitch, noDisturbingSwitch). The fountain-specific noDisturbingSwitch replaces the generic disturbMode key used by other device types.

Translations

State labels for the new select entities added to en, nl, and uk.

Follow-up fixes (addressing review feedback)

  • Battery mode restored (const.py): FOUNTAIN_WORKING_MODE_CTW3 now includes 3: 'battery' again. Battery mode is displayed as current state when device reports it, but excluded from selectable options (hardware-managed state, not user-settable). Selecting it logs a warning instead of silently failing.
  • 404 on CTW3 for updateSettings (switch.py, select.py): Indicator light, Do not disturb, and LED brightness now have ignore_types=[CTW3] - these REST API endpoints return 404 on CTW3. CTW3 controls LED and DND via BLE (future work).
  • Translations: Added 'battery' state to working_mode in en.json, nl.json, uk.json.

Implements issue Jezza34000#94 - adds missing controls for water fountain devices:

- Working mode select (Normal/Smart for W4/W5/CTW2, Standard/Intermittent
  for CTW3) via BLE command using CMD 220
- LED brightness select (Low/Normal/High) via REST API UPDATE_SETTING
- Indicator light (LED on/off) switch via REST API UPDATE_SETTING
- Do Not Disturb switch using fountain-specific API key (noDisturbingSwitch)

The working mode BLE byte sequences are patched into pypetkitapi's
FOUNTAIN_COMMAND at integration startup to avoid requiring a pypetkitapi
release. CMD 220 data format: [state, mode, op_type=1].

Translations updated in en, nl, and uk with state labels for select entities.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aavdberg aavdberg requested a review from Jezza34000 as a code owner March 31, 2026 07:15
Copilot AI review requested due to automatic review settings March 31, 2026 07:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds missing control entities for Petkit water fountain devices, enabling users to manage fountain working mode (via BLE) and LED/DND/indicator settings (via REST) from Home Assistant.

Changes:

  • Added water-fountain switches for Indicator light and Do not disturb using UPDATE_SETTING REST calls.
  • Added water-fountain selects for Working mode (BLE CMD 220 via FountainAction) and LED brightness (REST lampRingBrightness).
  • Extended translations (en/nl/uk) with state labels for the new select options.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
custom_components/petkit/__init__.py Patches pypetkitapi’s FOUNTAIN_COMMAND at startup to add missing working-mode BLE command frames.
custom_components/petkit/select.py Introduces fountain Working mode + LED brightness select entities and BLE mode handler.
custom_components/petkit/switch.py Adds fountain Indicator light + Do not disturb switch entities using REST settings updates.
custom_components/petkit/translations/en.json Adds translated state labels for working mode and LED brightness options.
custom_components/petkit/translations/nl.json Adds translated state labels for working mode and LED brightness options.
custom_components/petkit/translations/uk.json Adds translated state labels for working mode and LED brightness options.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread custom_components/petkit/select.py
Hassfest validation requires translation keys to be lowercase [a-z0-9-_]+.
Changed FOUNTAIN_WORKING_MODE, FOUNTAIN_WORKING_MODE_CTW3 and LED_BRIGHTNESS
const values to lowercase. Updated translation state keys in en/nl/uk.json
to match.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Jezza34000
Copy link
Copy Markdown
Owner

Hi @aavdberg
Thanks for your contribution!

However, this PR doesn’t follow the current library architecture. It extends a class that should instead be defined and maintained within the library itself, not directly in the integration code.

To keep the structure consistent and maintainable, please update your code to align with the library’s architecture. Any new functionality should first be implemented in pyperkitapi before being integrated into Home Assistant.
Once that’s adjusted, I’ll be happy to review the updated version.

… mode

- Remove FOUNTAIN_COMMAND.update() patch from __init__.py. The working
  mode commands (MODE_NORMAL, MODE_SMART, MODE_STANDARD, MODE_INTERMITTENT)
  are now part of pypetkitapi directly (see Jezza34000/py-petkit-api#56).

- Remove 'battery' (mode 3) from FOUNTAIN_WORKING_MODE_CTW3 and all
  translations. Battery mode is a hardware/power-source state entered
  automatically when running on battery; it cannot be set by the user via
  BLE. Selecting it would silently do nothing. Removed from const.py and
  en/nl/uk translation files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aavdberg
Copy link
Copy Markdown
Contributor Author

Hi @Jezza34000,

Thanks for the feedback! You're absolutely right — the \FOUNTAIN_COMMAND.update()\ patch in _init_.py\ is not the right place for this.

I've made the following adjustments:

  1. Created a PR to pypetkitapi adding the missing mode commands directly to \FOUNTAIN_COMMAND\ in \command.py: feat: add fountain working mode commands to FOUNTAIN_COMMAND py-petkit-api#56

  2. Removed the \FOUNTAIN_COMMAND.update()\ patch from _init_.py\ — the HA integration now relies on the commands being present in the library itself.

  3. Removed 'Battery' from CTW3 working mode options (as flagged by the code reviewer): Battery mode is a hardware state entered automatically when running on battery power — it can't be set by the user via BLE. Removed from \FOUNTAIN_WORKING_MODE_CTW3\ and all translation files.

Note: this PR depends on pypetkitapi PR #56 being merged and a new version released before it can be fully reviewed/merged.

aavdberg and others added 2 commits March 31, 2026 10:34
…192)

Define INDICATOR_LIGHT constant to avoid duplicating the literal string
three times in switch.py (lines 51, 77, 837).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Jezza34000
Copy link
Copy Markdown
Owner

Hi @aavdberg
Which fountain model did you use for your tests?
It's not working for me with my CTW3
I'm getting a 404 error on the updateSettings endpoint for the light and DND parameters.

Copy link
Copy Markdown
Owner

@Jezza34000 Jezza34000 left a comment

Choose a reason for hiding this comment

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

For now this PR does not work properly.
With CTW3 new entity in switch and select are not working.
Light cause 404
Working mode did not throw any error but it's not applied on foutain

Comment thread custom_components/petkit/const.py
Comment thread custom_components/petkit/select.py
- Restore battery mode (3) to FOUNTAIN_WORKING_MODE_CTW3 in const.py:
  Battery mode is a valid CTW3 state reported by the device and must
  not be removed from the dict.

- CTW3 working mode select: battery is shown as current option when
  the device reports mode 3, but excluded from selectable options
  (it is a hardware state entered automatically, not user-settable).
  _handle_fountain_mode now logs a warning if a read-only mode is
  somehow selected.

- Add ignore_types=[CTW3] to WaterFountain Indicator light and
  Do not disturb switches: lampRingSwitch and noDisturbingSwitch
  use the updateSettings REST endpoint which returns 404 on CTW3.

- Add ignore_types=[CTW3] to LED brightness select: same reason.

- Add CTW3 import to switch.py.

- Add 'battery' translation to working_mode states in en/nl/uk.json.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Apr 4, 2026

@irfanhakim-as
Copy link
Copy Markdown

irfanhakim-as commented Apr 27, 2026

I was about to create an issue to report/ask why the Pause and Resume (button) entities were flagged as Unavailable on my Eversweet Solo 2 water fountain (which I've learned from this PR is referred to as CTW2), but I assume this PR - once it's ready, should already address that?

Being able to switch between Smart and Normal mode (and Pause too hopefully) for my fountain from HA would be soo great, looking fwd to the release that would include this :))

edit: Regardless, thanks so much to all of you for this amazing integration <3

@Jezza34000
Copy link
Copy Markdown
Owner

Hi @aavdberg,
On my side, it’s still not working. The CTW3 does not accept the “Intermittent” mode when I set it, it switches to “Pause” instead.
I think this needs a fix in the library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants