This repository contains a python CLI script as well as a Home Assistant integration that can be used to control Chihiros LEDs for aquariums via bluetooth without the vendor app. It also includes first Home Assistant support for Chihiros dosing pumps. For this purpose, the protocol to control the devices has been reversed engineered with the help of decompiling the old Magic App as well as sniffing and analyzing of bluetooth packages that are sent by the new My Chihiros App. The new app is based on flutter and only contains a binary that can not easily be analyzed.
Warning
This is an independent, unofficial, community-developed project. It is not affiliated with, endorsed by, sponsored by, or otherwise associated with Chihiros Aquatic Studio.
“Chihiros” and any other product names or trademarks referenced by this project belong to their respective owners.
This software is provided “as is” and without warranties of any kind, whether express or implied. You use it entirely at your own risk. The authors and contributors are not responsible for any damage, loss, injury, equipment malfunction, data loss, or other consequences resulting from the use of this project, including damage to aquarium equipment, livestock, or other property.
- Chihiros LED A2
- Chihiros WRGB II (Regular, Pro, Slim; Pro is true WRGB)
- Chihiros WRGB VIVID III (true WRGB, including fan speed control and fan RPM/temperature sensors)
- Chihiros Tiny Terrarium Egg
- Chihiros C II (RGB, White)
- Chihiros Universal WRGB
- Chihiros Z Light TINY
- Chihiros Commander 1
- Chihiros Commander 4
- Chihiros dosing pump (
DYDOSE*) with first Home Assistant support for manual dosing, daily dose totals, and lifetime pump cycle/ml counters - other LED models might work as well but are not tested
- Inside HACS add this repository as a custom repository:
HACS -> Integrations -> 3 dots on the top right-> Custom repositories - Search for
Chihirosin the repositories and download it - Restart Home Assistant
- Go to the integrations user interface and add the Chihiros integration
- Supported devices should be discovered at this point
- Copy the directory
custom_components/chihirosto your<config dir>/custom_componentsdirectory - Restart Home-Assistant
- Add the Chihiros integration to your Home Assistant instance via the integrations user interface
The integration provides services for changing the auto mode schedule from Developer Tools -> Actions or from automations:
chihiros.add_schedule: add one schedule period.chihiros.remove_schedule: remove one schedule period.chihiros.reset_schedule: remove all schedule periods.chihiros.set_schedule: replace the complete schedule.
If only one Chihiros device is configured, entry_id and address can be
omitted. If multiple devices are configured, include either the config entry ID
or Bluetooth address.
Replace the complete schedule:
service: chihiros.set_schedule
data:
address: "AA:BB:CC:DD:EE:FF"
periods:
- start: "08:00"
end: "12:00"
brightness: 40
ramp_up_minutes: 30
weekdays:
- monday
- tuesday
- start: "09:00"
end: "17:00"
brightness: 55
weekdays:
- wednesday
- thursdayAdd one white or shared-brightness period:
service: chihiros.add_schedule
data:
start: "08:00"
end: "18:30"
brightness: 70
ramp_up_minutes: 30
weekdays:
- monday
- tuesdayRemove a matching period:
service: chihiros.remove_schedule
data:
start: "08:00"
end: "18:30"
ramp_up_minutes: 30
weekdays:
- monday
- tuesdayReset all schedule periods:
service: chihiros.reset_schedule
data:
address: "AA:BB:CC:DD:EE:FF"Schedule writes are validated before sending commands to the device. Unsupported
channels, invalid brightness values, invalid weekdays, empty replacement
schedules, and multiple replacement periods for the same weekday are rejected.
Known devices replace the previous period for a weekday when another one is
written, so set_schedule accepts at most one period per weekday. After writing
a schedule, enable the Auto Mode switch to run it.
Dosing pumps expose one manual dose button, one dose-volume number control, and the following locally tracked sensors per pump channel:
dosed today(volume in mL, reset at local midnight)total ml(cumulative lifetime volume,total_increasing)total cycles(cumulative lifetime dose count,total_increasing)
The lifetime total ml and total cycles sensors are total_increasing, so they
can be fed directly into the Home Assistant utility_meter to derive daily,
weekly, monthly, or yearly consumption sensors. The first setup asks
whether the pump has two or four channels. Manual doses can also be triggered
from automations with chihiros.dose_ml:
service: chihiros.dose_ml
data:
address: "AA:BB:CC:DD:EE:FF"
pump: 1
ml: 2.5- a device with bluetooth LE support for sending the commands to the LED
- uv for Python environment and dependency management
# setup the environment
uv sync --extra cli
# show help
uv run chihirosctl --help
# discover devices and their address
uv run chihirosctl list-devices
# turn on the device
uv run chihirosctl turn-on <device-address>
# turn off the device
uv run chihirosctl turn-off <device-address>
# manually set the brightness to 100
uv run chihirosctl set-brightness <device-address> 100
# create an automatic timed setting that turns on the light from 8:00 to 18:00 at brightness 100
uv run chihirosctl add-setting <device-address> 8:00 18:00 100
# create a setting for specific weekdays with maximum brightness of 75 and ramp up time of 30 minutes
uv run chihirosctl add-setting <device-address> 9:00 18:00 75 --weekdays monday --weekdays tuesday --ramp-up-in-minutes 30
# manually set the brightness to 60 red, 80 green, 100 blue on RGB models
uv run chihirosctl set-brightness <device-address> 60 80 100
# create an automatic timed setting that turns on the light from 8:00 to 18:00
uv run chihirosctl add-setting <device-address> 8:00 18:00 100 100 100
# create a setting for specific weekdays with maximum brightness of 35, 55, 75 and ramp up time of 30 minutes
uv run chihirosctl add-setting <device-address> 9:00 18:00 35 55 75 --weekdays monday --weekdays tuesday --ramp-up-in-minutes 30
# on true WRGB models, set red, green, blue, and white levels
uv run chihirosctl add-setting <device-address> 9:00 18:00 35 55 75 40
# enable auto mode to activate the created timed settings
uv run chihirosctl enable-auto-mode <device-address>
# delete a created setting
uv run chihirosctl remove-setting <device-address> 8:00 18:00
# reset all created settings
uv run chihirosctl reset-settings <device-address>
# trigger a manual dose on a dosing pump: pump 1, 2.5 mL
uv run chihirosctl dose-ml <device-address> 1 2.5
The Bluetooth command format and known modes are documented in docs/protocol.md.
Reusable library and CLI code lives in src/chihiros_led_control/. The Home
Assistant integration lives in custom_components/chihiros/ and imports the
vendored runtime copy from custom_components/chihiros/vendor/ so HACS installs
do not require the top-level package.
Want to help add support for a device that is not listed yet? See docs/capturing-ble-traffic.md for step-by-step instructions on recording the Bluetooth traffic between the official My Chihiros app and the device. Captures like these are how new device protocols get reverse-engineered.
Set up the development environment with uv:
uv --cache-dir .uv-cache sync --group dev
uv --cache-dir .uv-cache run --group dev pytest
uv --cache-dir .uv-cache run --group dev pre-commit run --all-filesHome Assistant integration tests use the separate ha-test dependency group
because they install Home Assistant and its test-time runtime dependencies. Run
them explicitly when changing files under custom_components/chihiros/:
uv --cache-dir .uv-cache run --group ha-test pytest tests/test_home_assistant_integration.py tests/test_manifest_requirements.pyThe integration test creates a temporary Home Assistant config directory,
symlinks this repository's custom_components/ directory into it, and patches
storage writes so the test does not need a running Home Assistant instance or
real Bluetooth hardware. The manifest requirements test keeps the integration's
runtime requirement pins aligned with pyproject.toml.
After changing library code, refresh the vendored copy:
uv --cache-dir .uv-cache run python scripts/sync_vendor.py
uv --cache-dir .uv-cache run python scripts/sync_vendor.py --checkFor local Home Assistant testing with Docker Compose, see docs/home-assistant-docker.md.
Successful pushes to main create an automatic GitHub release after the HA Validation workflow passes. The release workflow reads custom_components/chihiros/manifest.json, creates a tag named v<version>, and uses GitHub generated release notes. If that tag already exists, the release is skipped.
See docs/architecture.md for the package layout.