/**
 * Helper functions for MatterServer.registerAccessory()
 * Extracted from the monolithic 521-line function for better maintainability
 */
import type { EndpointType } from '@matter/main';
import type { LevelControl } from '@matter/main/clusters/level-control';
import type { Behavior } from '@matter/node';
import type { MatterAccessory } from './types.js';
/**
 * Type representing a behavior class (constructor)
 */
type BehaviorType = Behavior.Type;
/**
 * Cluster IDs from Matter specification
 * Using Matter.js Cluster references instead of magic numbers
 */
export declare const CLUSTER_IDS: {
    readonly AIR_QUALITY: import("@matter/main").Brand<"ClusterId"> & 91;
    readonly CARBON_MONOXIDE_CONCENTRATION: import("@matter/main").Brand<"ClusterId"> & 1036;
    readonly CLOSURE_CONTROL: import("@matter/main").Brand<"ClusterId"> & 260;
    readonly COLOR_CONTROL: import("@matter/main").Brand<"ClusterId"> & 768;
    readonly DOOR_LOCK: import("@matter/main").Brand<"ClusterId"> & 257;
    readonly KEYPAD_INPUT: import("@matter/main").Brand<"ClusterId"> & 1289;
    readonly LEVEL_CONTROL: import("@matter/main").Brand<"ClusterId"> & 8;
    readonly MEDIA_PLAYBACK: import("@matter/main").Brand<"ClusterId"> & 1286;
    readonly NITROGEN_DIOXIDE_CONCENTRATION: import("@matter/main").Brand<"ClusterId"> & 1043;
    readonly ON_OFF: import("@matter/main").Brand<"ClusterId"> & 6;
    readonly OZONE_CONCENTRATION: import("@matter/main").Brand<"ClusterId"> & 1045;
    readonly PM10_CONCENTRATION: import("@matter/main").Brand<"ClusterId"> & 1069;
    readonly PM25_CONCENTRATION: import("@matter/main").Brand<"ClusterId"> & 1066;
    readonly THERMOSTAT: import("@matter/main").Brand<"ClusterId"> & 513;
    readonly WINDOW_COVERING: import("@matter/main").Brand<"ClusterId"> & 258;
};
/**
 * Validates required fields on a Matter accessory
 * @throws MatterDeviceError if validation fails
 */
export declare function validateAccessoryRequiredFields(accessory: MatterAccessory): void;
/**
 * Generic feature detection from device type behaviors
 * Extracts supported features from a device type's cluster definition
 *
 * @param deviceType - The Matter device type
 * @param clusterIdOrName - Cluster ID (number) or name (string)
 * @param featureExtractor - Function to extract feature names from supportedFeatures
 * @returns Array of detected features or null if cluster not found
 */
export declare function detectBehaviorFeatures(deviceType: EndpointType, clusterIdOrName: number | string, featureExtractor: (supportedFeatures: Record<string, boolean>) => string[]): string[] | null;
/**
 * Extract whatever features a behavior already declares, whatever the cluster.
 *
 * matter.js records a composed behavior's features as camelCase booleans and
 * `.with(...)` takes the PascalCase names, so carrying a feature set across is
 * just a capitalise - the same mapping the per-cluster extractors below do by
 * hand (`hueSaturation` to `HueSaturation`, `xy` to `Xy`).
 *
 * Used for clusters whose features we have no reason to reason about. We only
 * need them preserved when a Homebridge behavior replaces the base one, and a
 * hand-written list would silently drop any feature matter.js adds later.
 */
export declare function extractDeclaredFeatures(supportedFeatures: Record<string, boolean>): string[];
/**
 * Extract ColorControl features from supportedFeatures
 */
export declare function extractColorControlFeatures(supportedFeatures: Record<string, boolean>): string[];
/**
 * Extract Thermostat features from supportedFeatures
 */
export declare function extractThermostatFeatures(supportedFeatures: Record<string, boolean>): string[];
/**
 * Extract LevelControl features from supportedFeatures.
 *
 * Used to read features off a device type's declared LevelControl requirement
 * (e.g. DimmableLightDevice's `LevelControlServer.with("Lighting","OnOff")`).
 * When the device type doesn't declare LevelControl at all (e.g. PumpDevice,
 * which has LevelControl only in its `optional` requirements and not in
 * `SupportedBehaviors`), the caller should apply an empty feature set via
 * `.with()` so the Lighting feature inherited from matter.js's internal
 * `LevelControlBase = LevelControlBehavior.with(OnOff, Lighting)` is stripped
 * — otherwise the Pump endpoint inherits the `[LT]` branch of the spec
 * (minLevel constraint 1-254, initializeLighting warnings) that only applies
 * to lighting devices.
 */
export declare function extractLevelControlFeatures(supportedFeatures: Record<string, boolean>): LevelControl.Features[];
/**
 * Determine ColorControl features based on handlers
 * Only includes features that have corresponding handler methods
 */
export declare function determineColorControlFeaturesFromHandlers(handlers: Record<string, unknown>): string[];
/**
 * Determine ColorControl features from the cluster's own attributes.
 *
 * The handler-based detection above cannot work on a cache restore: handlers are
 * functions, so they are not cached, and the restore synthesizes empty stubs in
 * their place. That left ColorControl with no features at all, and a persisted
 * `colorTemperatureMireds` or `currentHue` then failed Matter's conformance check
 * ("Matter does not allow you to set this attribute") and took the whole accessory
 * registration down with it.
 *
 * The attributes do survive the cache, so they are what we fall back to - the same
 * approach {@link detectWindowCoveringFeatures} already takes.
 *
 * @param clusters - the accessory's cluster state
 * @returns Array of detected feature names
 */
export declare function determineColorControlFeaturesFromClusters(clusters: Record<string, unknown> | undefined): string[];
/**
 * Detect WindowCovering features from accessory attributes
 * Auto-detects Lift and Tilt capabilities based on cluster attributes
 *
 * @param accessory - Matter accessory to inspect
 * @returns Array of detected feature names
 */
export declare function detectWindowCoveringFeatures(accessory: MatterAccessory): string[];
/**
 * Detect SmokeCoAlarm features from accessory attributes.
 * The Matter spec requires at least one of SmokeAlarm/CoAlarm, so an accessory
 * that declares neither state attribute falls back to SmokeAlarm — matching the
 * friendly device type name "SmokeSensor".
 */
export declare function detectSmokeCoAlarmFeatures(accessory: MatterAccessory): string[];
/**
 * Apply SmokeCoAlarm features to device type.
 * SmokeCoAlarm is not part of the base SmokeCoAlarmDevice — matter.js requires
 * the features to be chosen — so without this the endpoint would be created
 * without the cluster and the accessory's smokeCoAlarm state silently dropped.
 */
export declare function applySmokeCoAlarmFeatures(deviceType: EndpointType, accessory: MatterAccessory, features: string[]): EndpointType;
/**
 * Raise a LevelControl floor of 0 to 1 when the Lighting feature is active.
 *
 * The Lighting feature reserves level 0 for "off", so the spec constrains
 * MinLevel to 1-254 and matter.js rejects 0 outright. Homebridge's own guidance
 * has suggested `minLevel: 0`, so accessories in the wild carry it. Lift those
 * to 1 with a warning rather than refusing to register the accessory.
 */
export declare function applyLevelControlLightingFloor(accessory: MatterAccessory, levelControlFeatures: string[] | null): void;
/**
 * Detect Thermostat features from accessory attributes.
 *
 * A thermostat that only heats should not advertise cooling, so the features
 * follow the setpoints the accessory actually declares. The Matter spec requires
 * at least one of Heating/Cooling, so an accessory declaring neither falls back
 * to Heating. AutoMode is only meaningful when the device can do both, and
 * Occupancy only when the unoccupied setpoints are present.
 */
export declare function detectThermostatFeatures(accessory: MatterAccessory): string[];
/**
 * Check that an AutoMode thermostat's setpoint LIMITS can satisfy its deadband.
 *
 * ⚠️ The deadband applies to the limits, not only to the setpoints. matter.js
 * requires both of these, in 0.01°C:
 *   maxCoolSetpointLimit - maxHeatSetpointLimit >= deadband
 *   minCoolSetpointLimit - minHeatSetpointLimit >= deadband
 *
 * `minSetpointDeadBand` is declared in 0.1°C, so it is multiplied by 10 first.
 *
 * This is easy to get wrong and the symptom is badly disconnected from the
 * cause: the endpoint is created happily, then EVERY later setpoint update
 * fails with "Thermostat setpoints could not be reconciled within the
 * configured limits". matter.js 0.17.6 only validated the attribute being
 * written, so an impossible configuration went unnoticed until 0.17.7 began
 * validating the whole cluster. Warning here points at the real problem.
 *
 * Returns a message describing the problem, or undefined when the limits are
 * satisfiable.
 */
export declare function checkThermostatSetpointLimits(accessory: MatterAccessory, features: string[]): string | undefined;
/**
 * Apply Thermostat features to device type.
 * Thermostat is not part of the base ThermostatDevice — matter.js requires the
 * features to be chosen — so without this the endpoint would be created without
 * the cluster and the accessory's thermostat state silently dropped.
 */
export declare function applyThermostatFeatures(deviceType: EndpointType, accessory: MatterAccessory, features: string[]): EndpointType;
/**
 * Detect ServiceArea features from cluster attributes
 */
export declare function detectServiceAreaFeatures(serviceAreaCluster: Record<string, unknown> | undefined): string[];
/**
 * Apply WindowCovering features to device type
 */
export declare function applyWindowCoveringFeatures(deviceType: EndpointType, accessory: MatterAccessory, features: string[]): EndpointType;
/**
 * Build custom behaviors for RoboticVacuumCleaner devices
 */
export declare function buildRvcCustomBehaviors(accessory: MatterAccessory, serviceAreaFeatures: string[] | null): BehaviorType[];
/**
 * Apply detected features to a behavior class
 */
export declare function applyFeaturesToBehavior(behaviorClass: BehaviorType, features: string[] | null, clusterName: string): BehaviorType;
/**
 * The subset of an accessory (or composed-device part) the electrical
 * measurement helpers need - lets the same detection run for both.
 */
export interface ElectricalMeasurementHost {
    clusters?: MatterAccessory['clusters'];
    displayName?: string;
}
/**
 * Result of detecting electrical measurement clusters on an accessory
 */
export interface ElectricalMeasurementDetection {
    /** Accessory declares electricalPowerMeasurement cluster state */
    hasPowerMeasurement: boolean;
    /**
     * ElectricalEnergyMeasurement features derived from the declared attributes
     * (empty when the cluster is not declared)
     */
    energyFeatures: string[];
}
/**
 * Detect electrical measurement clusters from the accessory's declared state.
 *
 * ElectricalEnergyMeasurement is feature-gated in matter.js (Imported/Exported
 * x Cumulative/Periodic), so the features are chosen from which energy
 * attributes the accessory declares.
 */
export declare function detectElectricalMeasurementClusters(accessory: ElectricalMeasurementHost): ElectricalMeasurementDetection;
/**
 * Fill in the mandatory ElectricalPowerMeasurement / ElectricalEnergyMeasurement
 * attributes (powerMode, numberOfMeasurementTypes, accuracy) that plugins should
 * not have to write themselves. Mutates the accessory's declared cluster state
 * so the values flow into the endpoint options and the state cache together.
 */
export declare function applyElectricalMeasurementDefaults(accessory: ElectricalMeasurementHost, detection: ElectricalMeasurementDetection): void;
/**
 * Apply the electrical measurement behaviors to a device type.
 *
 * PowerTopology is mandatory on the ElectricalSensor device type and is
 * feature-gated in matter.js; TreeTopology fits a bridged endpoint that
 * measures itself. The EEM server keeps matter.js's setMeasurement() helper,
 * which also emits the CumulativeEnergyMeasured / PeriodicEnergyMeasured
 * events required by the spec.
 */
export declare function applyElectricalMeasurementClusters(deviceType: EndpointType, accessory: ElectricalMeasurementHost, detection: ElectricalMeasurementDetection): EndpointType;
export {};
//# sourceMappingURL=serverHelpers.d.ts.map