Vacuums & mowers
The eufy Clean line covers robot vacuums (RoboVac / X-series, e.g. the Clean X10 Pro Omni) and robot mowers. Vacuums are driven through the vacuumClean and fanSpeed capabilities. Like every capability they resolve dynamically, so any robot on the Clean line exposes the same fluent API; nothing is hardcoded per model.
Mowers are part of the same Clean family but a distinct device type, so their control surface is a later addition — the sections below cover vacuums today.
const dev = await eufy.getDevice(sn);
const robo = dev.vacuumClean(); // present only on a Clean-line deviceThe accessor returns undefined on a device without the capability, so guard it (dev.vacuumClean()?.…) or assert once up front. Each individual getter is present only when the device reports that value, so read them defensively.
Reads need the realtime feed — not wired yet
On the modern robovac (verified on a Clean X10 Pro Omni) the cloud device record does not carry the robot's live state — its reported parameters hold none of the vacuum/suction/battery values. Those arrive only over the robot's realtime feed, which the SDK does not yet route into device state. Because each getter is evidence-gated, that means vacuumClean() / fanSpeed() currently expose no state getters on a cloud-only bind — the object resolves, but activity, battery, power, volume and fanSpeed are absent until that feed is wired. The controls and the state reads both land with that work; today treat the Clean surface as capability-detected but not yet readable.
State
dev.vacuumClean()?.activity; // what the robot is doing (see below)
dev.vacuumClean()?.battery; // 0–100
dev.vacuumClean()?.power; // boolean — powered on
dev.vacuumClean()?.volume; // speaker volume, 0–100activity is the robot's high-level state:
activity | meaning |
|---|---|
cleaning | actively cleaning (see caveat) |
returning | heading back to the dock |
docked | on the dock (idle or charging) |
paused | a task is paused (see caveat) |
idle | standby / asleep |
error | a fault is active |
unknown | a state the SDK can't classify yet |
Caveat:
cleaningis currently broader than "actively vacuuming" — a robot that is paused mid-clean, or parked on the dock running a wash/dry cycle, also reportscleaningtoday. As a result the standalonepausedstate may not appear in practice. Treatcleaningas "a job is in progress" rather than "the brushes are spinning right now". This narrows as more states are decoded.
Suction
import { suctionLevelName } from "eufy-mega";
const level = dev.fanSpeed()?.fanSpeed; // raw integer
suctionLevelName(level); // "Quiet" | "Standard" | "Turbo" | "Max" | "BoostIQ" | "MaxPro" | undefined
dev.fanSpeed()?.boostIq; // boolean — BoostIQ auto-suctionfanSpeed is the raw level the device reports. The level → name mapping is fixed across models (0 Quiet · 1 Standard · 2 Turbo · 3 Max · 4 BoostIQ · 5 MaxPro) — name it with suctionLevelName(). What differs per model is only which levels a device supports (some expose a narrower range), which is why the SDK returns the integer rather than constraining it. BoostIQ is a level here; the separate boostIq boolean is the independent auto-suction toggle, and a device can report both.
Refreshing state + controls
As noted above, the robot's state doesn't come down on the cloud device record — it arrives on a realtime feed the SDK doesn't route into device state yet, so today activity, battery and the rest don't populate from a cloud bind. Wiring that feed is what turns the reads on (and keeps them fresh mid-clean). Controls — start / pause / return-to-dock, suction, volume — land alongside it; today the robot surface is read-only and, pending the feed, effectively empty.
See Devices & capabilities for how capability resolution works, and the device gallery for the Clean line.