Behavioral wrapper around a registry Device for first-generation (V1) products, which only expose the heating mode. Subclasses layer the richer generations on top. Obtain instances through FacadeManager.get — facades are cached per entity.
Facade for Glow products (incl. Onyx and Shine): split high/low temperature registers, a dedicated on/off switch, and a temperature compensation offset.
Facade for Pro products: single-register temperatures, humidity and reported-mode measures, open-window detection, and the presence derogation.
Facade for V2/V4 products: named-attribute control, derogations (boost, vacation), timer and lock switches.
Lazily creates and caches facade instances using a WeakMap keyed by entity reference. Ensures each registry entity maps to exactly one facade throughout its lifetime.
Union of every facade generation FacadeManager.get can return. Narrow with supportsV2, supportsGlow and supportsPro before reading generation-specific members.
Whether the facade's product generation carries the Glow surface (split temperature registers, on/off switch, compensation).
Whether the facade's product generation carries the Pro surface (measures, open-window detection, presence).
Whether the facade's product generation carries the V2 surface (named-attribute control, derogations, timer, lock).
In-memory model of one bound Heatzy device: wire identity, the last-synced attribute payload, and the derived state the wire does not carry (previous mode, derogation end date). Instances are created and updated exclusively by DeviceRegistry.syncDevices, which preserves object identity across syncs.
Central in-memory registry of all bound Heatzy devices. Synced from
the /bindings + /devdata responses and queryable by id.
The last non-stop heating mode — what "back on" restores to.
Refresh a registry model in place from a fresh /bindings entry and
its live attributes; preserves the instance so facade references
stay valid.
Base class for all errors thrown by this SDK.
Thrown when a facade reads an attribute its device's last-synced
payload does not carry — either the product generation does not
support it (narrow with supportsV2 / supportsGlow / supportsPro
before reading) or the wire dropped a field the SDK consumes.
The server rejected the credentials (Gizwits answers HTTP 400 or 401 on the login path).
Thrown when a runtime validator (Zod, in this SDK) rejects an
upstream response. The context field surfaces which boundary the
payload came from (e.g. 'login', 'GET /bindings') so consumer
dashboards can group drift alerts without parsing the message string.
User-defined type guard for APIError and its subclasses.
The API surface facades depend on — a structural slice of HeatzyAPI that keeps the facade layer decoupled from the client's lifecycle machinery (and trivially mockable in tests).
Configuration accepted by HeatzyAPI.create. Every property —
including the inherited LoginCredentials pair — may be
absent or explicitly undefined, interchangeably: the runtime
applies the same default either way (credentials can also arrive
later via authenticate or the SettingManager).
Persisted-settings surface the SDK reads and writes through the SettingManager. Hosts that render or migrate stored values can type their storage against this shape.
Callback bundle invoked around SDK lifecycle moments. All callbacks are optional and non-throwing — the SDK ignores any exceptions they raise so a buggy observer cannot break the request flow.
Logger interface for API call tracing.
Emitted when a request (possibly after retries) completes successfully.
Emitted when a request ultimately fails after exhausting its retries.
Identifies a single logical request across its lifecycle events.
Generated client-side via crypto.randomUUID() when each request
starts, so consumers can correlate a onRequestStart with its
eventual onRequestComplete or onRequestError — including across
retry attempts, which share the same correlationId.
Emitted each time a retry attempt is scheduled.
External storage adapter for persisting API session settings.
Emitted at the start of a request, before any retry attempts.
Callback invoked after sync operations, with optional device ids.
Transport configuration. Discriminated by presence of an
HttpClient instance — the SDK either reuses your wired client
(with its own dispatcher, headers, timeout) or builds a fetch-backed
default whose timeout you can tweak via timeoutMs.
Method decorator that invokes a sync notification after the
decorated method resolves. The host implements notifySync
structurally — facades enrich the payload with their id before
delegating, HeatzyAPI emits straight through the lifecycle
emitter.
Method decorator that merges the decorated method's resolved payload
into the host's in-memory model before returning it — so a
mutation echo (setValues) or a fresh read (values) immediately
refreshes the registry entity without waiting for the next sync.
Thin fetch-based HTTP client used internally by the SDK.
Thrown by HttpClient whenever an upstream response has a non-2xx
status. The shape mirrors what downstream code needs: response.status,
response.headers, and response.data.
Construction options for HttpClient.
Snapshot of the request that triggered an HttpError.
Configuration accepted by HttpClient.request: body (data),
query (params), per-request headers, method, abort signal and URL.
Minimal response shape surfaced to callers.
HTTP status codes used across the SDK. Single source so callers don't redefine them per file.
Type guard for HTTP errors thrown by the internal HTTP client.
Live attribute payload returned by /devdata/{did}/latest. Extends
the writable set with the read-only measures; field names mirror the
Gizwits wire verbatim (cur_tempH, cft_temp…) — do not rename
them to satisfy style rules.
/bindings response envelope: every device bound to the account.
One /bindings entry — the wire identity of a bound device.
/devdata/{did}/latest response envelope.
/control/{did} body for every product generation but V1.
/control/{did} body for V1 products, which speak a positional
raw triplet instead of named attributes: two constant fillers,
then the positional mode.
Heatzy (Gizwits) user credentials — also the verbatim /login body.
/login response: the user token and its expiry (epoch seconds).
Writable attribute set accepted by /control/{did}. Availability is
product-dependent — the comments group fields by the generations
that support them.
Union of both /control/{did} body dialects.
Optional form of T whose properties may also be explicitly
undefined — the input-side counterpart of Partial<T> under
exactOptionalPropertyTypes (whose mapped ? does not admit a
present-undefined key). For inputs whose runtime treats a
present-undefined key exactly like an absent one.
Build the control attributes that set a target temperature, in the
register layout the product generation expects: Glow clamps the
value into the mode's accepted range — symmetric with the read
side — and splits it across tempH/tempL (hundreds bit +
remainder in tenths); every other generation takes a single temp
register in tenths, unclamped.
Derogation (temporary override) modes.
Heating modes. cft1/cft2 do not exist on V1 and V2 products.
Product generations, ordered so >= reads as capability support.
Numeric boolean the wire uses for every switch attribute.
com_temp values: an offset encoded around 50 (= no change).
Derogation (temporary override) modes.
Heating modes. cft1/cft2 do not exist on V1 and V2 products.
Product generations, ordered so >= reads as capability support.
Numeric boolean the wire uses for every switch attribute.
com_temp values: an offset encoded around 50 (= no change).
Resolve a device's product generation from its product_key.
Heatzy (Gizwits) API client. Handles authentication, session persistence and restore, device syncing, and the
/bindings,/devdataand/controlendpoint calls. Uses a private constructor — create instances via HeatzyAPI.create.