@apocaliss92/nodepetkit

中文文档
0.1.0发布于 2026/07/04MITTypeScriptESM + CJS零依赖近 30 天下载 2023

Node.js/TypeScript client for PetKit smart pet devices over the PetKit cloud (REST)

原始使用文档
文档目录16 节
  1. Install
  2. Quick start
  3. Token-based authentication
  4. Supported devices
  5. How it works
  6. API reference
  7. Nodepetkit
  8. BaseDevice
  9. FeederDevice
  10. LitterDevice
  11. PurifierDevice
  12. FountainDevice
  13. Diagnostics dumper
  14. Error types
  15. Credits & scope
  16. License

nodepetkit

Node.js / TypeScript client for PetKit smart pet devices over the PetKit cloud (REST).

Spiritual successor to pypetkitapi — same wire protocol, same cloud endpoints, TypeScript-native. If you can control your device in the PetKit mobile app, you can control it with this library.

Node only. Uses crypto and fetch primitives available in Node ≥ 20. It does not run in browsers.


Install

npm i @apocaliss92/nodepetkit

Requires Node 20 or later.


Quick start

import { Nodepetkit, FeederDevice } from '@apocaliss92/nodepetkit';

const petkit = new Nodepetkit(
  { email: '[email protected]', password: 'secret' },
  { region: 'us' }, // region name or ISO id — resolved to a gateway at login
);

// 1. Authenticate (resolves your region gateway, then logs in)
await petkit.login();

// 2. Discover devices registered to your account
const devices = await petkit.discoverDevices();

// 3. Create a typed device handle (fetches its initial state)
const feeder = (await petkit.createDevice(devices[0])) as FeederDevice;

// 4. React to polled state changes
feeder.on('stateChanged', ({ changed }) => console.log('changed:', changed));

// 5. Send commands
await feeder.feed(20); // dispense 20g now
await feeder.setChildLock(true);

// 6. Poll again whenever you like (PetKit has no realtime push)
await feeder.refresh();

Token-based authentication

If you already have a session token:

const petkit = new Nodepetkit({ token: 'your-session-id', region: 'us' });
await petkit.login(); // resolves the gateway; pass `gateway` too to skip that call

⚠️ PetKit only allows one active session per account. Logging in here can log out your phone app (and vice-versa). Consider a dedicated shared "family member" account, as recommended by the Home Assistant PetKit community.


Supported devices

Device classSeriesStatus
FeederDeviceFresh Element / Mini / D3 / D4 / D4S (Gemini) / D4H / D4SHCore commands
LitterDevicePura X (T3), Pura MAX (T4), T5 / T6 / T7Core commands
PurifierDeviceK2 / K3 deodorizersCore commands
FountainDeviceEversweet W4 / W5 / CTW2 / CTW3State + settings; BLE control @experimental
UnknownDeviceAny unrecognised typeFallback (raw state + passthrough commands)

State field names and command payloads are transcribed from pypetkitapi. They are not yet hardware-verified in this port — open an issue if a field or command is wrong.


How it works

  1. Region — login() calls GET v1/regionservers on passport.petkt.com to map your region to a gateway (api.eu-pet.com, api.petkt.com, api.petktasia.com, …).
  2. Auth — it POSTs user/login with an MD5-hashed password; the returned session id is sent as X-Session / F-Session on every later call.
  3. Discovery — discoverDevices() reads group/family/list (plus the shared-device roster).
  4. State — createDevice() POSTs {deviceType}/device_detail (or deviceData) and stores it.
  5. Commands — updateSettings for persistent options, controlDevice for transient actions, and per-device endpoints (saveDailyFeed, deodorantReset, …) for the rest.

PetKit's classic REST API has no realtime push channel, so state is refreshed by polling (device.refresh()); there is no WebSocket to keep open.

All internals (PetkitHttp, CloudDeviceGateway, login, crypto helpers) are kept out of the public surface to preserve API stability.


API reference

Nodepetkit

new Nodepetkit(
  creds: { email: string; password: string } | { token: string; region: string; gateway?: string },
  opts?: { region?: string; timezone?: string },
)
MethodReturnsDescription
login()Promise<void>Resolve the region gateway and authenticate
discoverDevices()Promise<PetkitDeviceInfo[]>List devices on the account
createDevice(info)Promise<BaseDevice>Build a typed handle and fetch its state
getSession()PetkitSession | nullThe active token + resolved gateway

BaseDevice

All device classes extend BaseDevice, a typed event emitter.

MemberTypeDescription
idstringPetKit device id
deviceTypestringRaw type (d4s, t4, w5, …)
typeDeviceTypeFamily: feeder / litter / fountain / purifier / unknown
namestringFriendly name
onlinebooleanBest-effort online flag
stateReadonly<DeviceState>Latest polled detail
refresh()Promise<void>Poll the cloud and merge state
event stateChanged{ changed }Emitted when polled state changes

FeederDevice

food · food1 · food2 · batteryPower · desiccantLeftDays · feeding · errorCode · feed(grams | { hopper1, hopper2 }) · cancelFeed() · resetDesiccant() · markFoodReplenished() · callPet() (D3) · playSound(id) (D3/D4H/D4SH) · setChildLock() · setIndicatorLight() · setFeedSound() · setVolume() · setSetting(kv)

LitterDevice

boxFull · sandPercent · sandLack · liquidLack · deodorantLeftDays · errorCode · battery · usedTimes · startCleaning() · dumpLitter() · removeOdor() · levelLitter() · resetN60Deodorizer() · resetN50Deodorant() · setLight() · setMaintenance() · setPower() · stop(code) · setAutoClean() · setChildLock() · setSandType(1|2|3) · setAutoInterval(seconds) · setSetting(kv)

PurifierDevice

mode · power · liquid · liquidLack · humidity · temperature · setPower() · setMode(PUR_MODE) · setAutoWork() · setChildLock() · setSetting(kv)

FountainDevice

mode · powered · running · filterPercent · filterWarning · lackWarning · batteryPercent · cloud: setLightRing() · setLightBrightness() · setDoNotDisturb() · setSetting(kv) · BLE (@experimental): powerOn() · powerOff() · pause() · resume() · setNormalMode() · setSmartMode() · resetFilter()

Fountains have no direct cloud control — commands are relayed over BLE through a nearby PetKit device, so BLE methods only work when such a relay is on your account/network.


Diagnostics dumper

import { createDumper } from '@apocaliss92/nodepetkit';

const snapshot = createDumper(feeder, { redact: true }).dump();
// { id: '******1234', deviceType: 'd4', type: 'feeder', name: '***chen', state: {…} }

redact: true (default) masks the device id and name so dumps can be shared safely.


Error types

ClassThrown when
PetkitErrorBase class for all library errors
PetkitAuthErrorLogin / region-resolution / token failure
PetkitApiErrorPetKit application error (.code) or non-2xx HTTP
PetkitTransportErrorNetwork error reaching the REST API
PetkitDeviceOfflineErrorReserved — not yet thrown

Credits & scope

Reverse-engineered from pypetkitapi (the library behind the Jezza34000 Home Assistant PetKit integration). See docs/petkit-cloud-api-spec.md for the full protocol notes this port is built from. Not affiliated with or endorsed by PetKit.

License

MIT — see LICENSE.

版本与发布记录

@apocaliss92/nodepetkit 共发布 1 个版本,首次发布于 2026/07/04;过去 12 个月发布了 1 个版本。

版本发布日期距今
0.1.0latest2026/07/044 个月前

关于 @apocaliss92/nodepetkit 的常见问题

@apocaliss92/nodepetkit 是什么?

Node.js/TypeScript client for PetKit smart pet devices over the PetKit cloud (REST)

如何安装 @apocaliss92/nodepetkit?

在项目目录运行 npm install @apocaliss92/nodepetkit,或使用 pnpm add / yarn add / bun add。

@apocaliss92/nodepetkit 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@apocaliss92/nodepetkit 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@apocaliss92/nodepetkit 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@apocaliss92/nodepetkit 可以商用吗?

@apocaliss92/nodepetkit 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@apocaliss92/nodepetkit 的下载量有多少?

根据 npm 官方下载统计,@apocaliss92/nodepetkit 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,023 次,日均约 67 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@apocaliss92/nodepetkit 还在维护吗?

最新版本 0.1.0 发布于 2026/07/04(4 个月前);至今共发布 1 个版本,其中过去 12 个月发布了 1 个;首次发布于 2026/07/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。