Add support for Yeedi Floor 3 Station (kd0una)#1472
Conversation
Add hardware capability definition for the Yeedi Floor 3 Station (model ID kd0una, product K960_ACS_INT). Device uses eco-ng protocol (JSON over MQTT) and connects via MQTT over TLS on port 443. Capabilities include: battery, charge, clean (with area), fan speed (quiet/normal/max/max_plus), life span (brush/filter/side brush), map (full map support with trace and position), network, play sound, stats, water (4 levels + mop attached), station (auto empty, actions, state), settings (true detect, volume, carpet boost, child lock, mop wash freq), continuous cleaning, clean count, clean preference, error, custom command. Verified working via Bumper self-hosted server with a real device. Companion Bumper PR: DeebotUniverse/bumper#3 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Can you also control your Yeedi using the official servers? |
Yes, and I used those MQTT packets from official Yeedi server to modify the code. |
|
So you can control your vacuum also without using bumper? |
Yes. |
There was a problem hiding this comment.
Pull request overview
Adds a new hardware capability module for the Yeedi Floor 3 Station (kd0una) so the client can construct the correct StaticDeviceInfo/Capabilities set for this eco-ng (JSON/MQTT) device.
Changes:
- Introduces
deebot_client/hardware/kd0una.pydefining supported capabilities (cleaning, map, station actions, settings, stats, water, etc.). - Wires up station-related features (actions, auto-empty config, station state) using existing JSON command/event types.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| auto_empty.Frequency.SMART, | ||
| auto_empty.Frequency.MIN_10, | ||
| auto_empty.Frequency.MIN_15, | ||
| auto_empty.Frequency.MIN_25, |
There was a problem hiding this comment.
Enabling GetAutoEmpty() for this model can crash message handling if the device reports an unknown frequency (e.g. the captured "30"). OnAutoEmpty currently does Frequency(frequency_str) without guarding, which raises ValueError for values not in the enum. Either extend auto_empty.Frequency to include the device’s value(s) (e.g. MIN_30 = "30") and include it in types, or update the auto-empty message parsing to tolerate unknown values (map to None) before shipping this capability for kd0una.
| auto_empty.Frequency.MIN_25, | |
| auto_empty.Frequency.MIN_25, | |
| auto_empty.Frequency.MIN_30, |
| from deebot_client import commands | ||
| from deebot_client.capabilities import ( |
There was a problem hiding this comment.
Import style is inconsistent with the other hardware capability modules: they typically import StationAction directly (from deebot_client.commands import StationAction) instead of importing the commands package and using commands.StationAction.*. Aligning with the existing pattern improves readability and keeps imports uniform across hardware definitions.
| from deebot_client.commands.json.auto_empty import GetAutoEmpty, SetAutoEmpty | ||
| from deebot_client.commands.json.battery import GetBattery | ||
| from deebot_client.commands.json.carpet import GetCarpetAutoFanBoost, SetCarpetAutoFanBoost | ||
| from deebot_client.commands.json.charge import Charge |
There was a problem hiding this comment.
This import line exceeds the formatting used in similar hardware modules (most split these into a parenthesized multi-line import). Please reformat to match the project’s style (and avoid line-length/formatter churn).
| from deebot_client.commands.json.charge import Charge | |
| from deebot_client.commands.json.charge import ( | |
| Charge, | |
| ) |
- Add `Capabilities` to correct alphabetical position in import block - Remove duplicate `Capabilities` import - Split `GetCarpetAutoFanBoost, SetCarpetAutoFanBoost` into multi-line - Alphabetize `station_state`/`stats` and `StationEvent`/`StatsEvent` Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #1472 +/- ##
==========================================
+ Coverage 94.79% 94.82% +0.03%
==========================================
Files 152 153 +1
Lines 5974 6010 +36
Branches 350 350
==========================================
+ Hits 5663 5699 +36
Misses 249 249
Partials 62 62 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Thank you so much for accepting my idea, it means a lot to me since this is my first PR. |
Pull Request: Add Yeedi Floor 3 Station (kd0una) Hardware Support
Summary
Adds hardware capability definition for the Yeedi Floor 3 Station (model ID
kd0una, productK960_ACS_INT). This device uses the eco-ng protocol (JSON over MQTT) and connects to a self-hosted Bumper server (with companion Bumper PR for port 443 MQTT support).Type of Change
Changes
New file:
deebot_client/hardware/kd0una.pyComplete capability definition based on:
zwkcqc.py(Deebot T20 Omni) as the closest known similar deviceCapabilities included:
availabilityGetBatteryavailability checkbatteryGetBatterychargeChargeclean.actionClean,CleanAreaclean.continuousGetContinuousCleaning/SetContinuousCleaning(=getBreakPoint)clean.countGetCleanCount/SetCleanCountclean.preferenceGetCleanPreference/SetCleanPreferenceerrorGetErrorfan_speedlife_spanmapnetworkGetNetInfoplay_soundPlaySoundsettings.carpet_auto_fan_boostGetCarpetAutoFanBoost/SetCarpetAutoFanBoostsettings.child_lockGetChildLock/SetChildLocksettings.mop_auto_wash_frequencyGetMopAutoWashFrequency/SetMopAutoWashFrequency(0–60 min)settings.true_detectGetTrueDetect/SetTrueDetectsettings.volumeGetVolume/SetVolumestateGetChargeState,GetCleanInfostatsGetStats,GetTotalStatsstation.actionstation.auto_emptystation.stateGetStationStatewater.amountwater.mop_attachedGetWaterInfocustomCustomCommandpass-throughDevice Details
DNS domains (TW region):
jmq-ngiot-tw.area.ww.ecouser.net(MQTT broker)iotin-ww.ecouser.net(IoT initialization)portal-ww.ecouser.net(REST portal)Testing
Confirmed Working (via Bumper self-hosted server)
Not Yet Verified
CleanArea)"30"which is outside theFrequencyenum (10/15/25/AUTO/SMART); may need adjustmentKnown Limitations
auto_emptyfrequency mismatch: The MQTT capture showed"frequency":"30"in thegetAutoEmptyresponse. Theauto_empty.Frequencyenum defines 10, 15, 25, AUTO, SMART. The robot may return a value not in the enum, causing the entity to show an unknown state. This may need a follow-up fix once the exact supported values are confirmed.getDryingDuration/setDryingDuration: Confirmed in MQTT capture ({"duration":120}), but no corresponding command class exists in deebot_client yet. Not included in this PR.getBlock/setBlock(DND schedule): Confirmed in capture, but noGetDnd/SetDndcommand class found in the current codebase. Not included.Checklist
Related Work
kd0unadevice registration, and post-connect handshake — required for local operation without cloudgetDryingDurationandgetBlocksupport would require new command classes in this repo