Chapter 8

Composed devices and linked entities

Link scattered Home Assistant sensors, selects, switches and buttons to one primary Matter endpoint, and keep automatic feature flags, explicit linked fields, composed sub-endpoints and controller support apart.

Several HA entities do not have to become several controller cards

Many integrations split one physical device into a primary control entity, a battery, temperature and humidity, power, cumulative energy, a mode select and an action button. If every one of those entities becomes its own Matter endpoint, a controller can end up showing a pile of fragments, or it cannot put the secondary values into the right cluster. The linked fields in Entity Mapping let you say which entity is which kind of data source; composedEntities instead builds the extra entities as sub-endpoints under the same BridgedNodeEndpoint.

Before you compose anything, confirm the unit, the device_class, what the state means and how often it updates. Putting a current sensor into the voltage field does not convert it correctly just because of the field name, and linking the battery sensor of a different physical device to the primary entity produces a false warning. Build one link at a time, then go back to the Devices card and check the mapping and the clusters.

Version limit: the fields in this chapter are the Stable 2.0.55 ones. electrical_utility_meter is an opt-in Matter 1.4 override inside Stable, and the pinned sources do not mark it experimental: Apple / Google / Alexa do not support it, Aqara is unverified, SmartThings supports it. EVSE is a Stable override: Apple / Google / Alexa do not support it, Aqara supports it, SmartThings is unverified; a bridged EVSE can break Alexa's device recognition, so it must not go on an Alexa bridge.

Automatic mapping, explicit links and composed sub-endpoints

ModelWhere to enable itApplies toLimits
Automatic mappingBridge feature flagsBattery, humidity, pressure, power and energy from the same HA deviceDerived from the registry relationship and the device class; it does not cover every vacuum, EVSE, lock or select helper.
An explicit linked fieldThe Entity Mapping dialogSingle-purpose fields such as batteryEntity and powerEntityYou are responsible for picking the right entity, unit and meaning; some fields only appear for a matching domain or type.
composedEntitiesThe composed list in Entity MappingAn extra entityId plus an optional matterDeviceType, forming a sub-endpointThe source comment explicitly requires autoComposedDevices; any entry with an empty entityId is filtered out before saving.

autoComposedDevices is the master toggle for automatic composition: turning it on lets battery, humidity, pressure, power and energy be merged automatically. autoBatteryMapping defaults to false; autoHumidityMapping and autoPressureMapping default to true. Filling in batteryEntity and the other fields by hand is explicit mapping, and you should not describe it in a document as something a flag found automatically.

The Devices card lists the battery, humidity, pressure, power, energy, voltage, current, battery power / energy, charging switch and current limit links in a mapping, and marks the matching clusters from them. That card can be showing runtime automatic mapping and a saved mapping at the same time, so cross-check it against the bridge flags and the entity mapping when you read it.

Battery, temperature/humidity/pressure, filters and faults

FieldData source / effectWatch out
batteryEntityA battery percentage sensor; attaches the PowerSource clusterUsable with any kind of sensor; where it overlaps with automatic battery mapping, check the actual mapping.
disableBatteryMappingStops the same device's automatic battery, and the entity's own battery attributes, from being attachedGood for a mains-powered device that an integration wrongly reports a battery for; defaults to false.
temperatureEntityLinks a temperature sensor to a primary endpoint such as a fan or an air purifierThe UI shows it for an explicit air_purifier type; pick the right temperature unit and a valid state.
humidityEntityAdds humidity to a temperature sensor, or to a fan / air purifierLets you build a temperature-and-humidity combination; not the same as the automatic same-device inference in autoHumidityMapping.
pressureEntityAdds atmospheric pressure to a temperature sensorForms a temperature plus pressure combination; not the same as autoPressureMapping.
filterLifeEntityA 0–100 filter-cartridge life sensor, for monitoring the HEPA filter in an air purifierThe UI shows it for an auto-detected fan or an air_purifier type.
faultEntityA problem / safety binary sensor on the same device; drives hardwareFaultAlert on a smoke/CO alarmIt is declared in EntityMappingConfig, but the v2.0.55 EntityMappingRequest and dialog have no such field, so do not claim the existing UI can save it. Treat it as a capability gap at the source level, and do not hand-edit storage.
chargingStateEntityA vacuum-only charging-state sensor; drives the Matter batChargeState directlyIt replaces the inference from docked plus battery level; profile v1 does not include this field.

Battery Storage has its own batteryPowerEntity and batteryEnergyEntity. Do not confuse them with the battery percentage of an ordinary device: they describe the charge and discharge power and the lifetime throughput of home energy storage, while batteryEntity describes where the device itself draws its charge from.

Power, energy, voltage, current, utility meter and EVSE

FieldExpected entity / valueEffect in Matter
powerEntityA sensor with device_class power and a power unitAdds instantaneous power to ElectricalPowerMeasurement.
energyEntityA sensor with device_class energy holding cumulative energyAdds cumulative energy to ElectricalEnergyMeasurement.
voltageEntityA sensor with device_class voltageMerged into the same device's ElectricalPowerMeasurement.
currentEntityA sensor with device_class currentMerged into the same device's ElectricalPowerMeasurement.
batteryPowerEntityHome energy-storage power; in HA a positive value is discharge and a negative value is chargeOn the BatteryStorage side, charging is reported as a positive imported value and discharging as a negative exported value.
batteryEnergyEntityLifetime energy for home energy storageThe ElectricalEnergyMeasurement of BatteryStorage.
meterSerialNumberA meter serial as textOnly electrical_utility_meter persists it, reported through MeterIdentification; left empty it reports unavailable. In documentation use only <METER_SERIAL>.
pointOfDeliveryA metering point ID as textOnly the utility meter type persists it; in documentation use only <POINT_OF_DELIVERY>, and never publish the real supply identifier.
chargingSwitchEntityThe switch that starts and stops EVSE chargingEnableCharging turns it on, Disable turns it off.
currentLimitEntityA number entity whose value is in ampsSets and reports the maximum charging current; a write is clamped to a sensible range.

An ordinary switch, light or plug-in unit can take power and energy; on_off_switch is presented as a plain On/Off Light, and the UI offers it no electrical fields. electrical_meter, solar_power, electrical_sensor and electrical_utility_meter show the full power/energy/voltage/current group. EVSE shows the charging switch, the current limit and optional power/energy, so it does not duplicate the ordinary group.

Maturity and support: Utility Meter is an opt-in Matter 1.4 override inside Stable, not one the sources designate experimental; Apple / Google / Alexa no, Aqara unknown, SmartThings yes. EVSE is an opt-in Stable override; Apple / Google / Alexa no, Aqara yes, SmartThings unknown. Being able to build an endpoint is not the same as a controller showing it, and EVSE still must not go on an Alexa bridge.

Every lock, vacuum, fan, cover, select and climate helper

Lock

  • disableLockPin: one lock stops requiring credential verification; if the system has credentials configured, the default is still to require them. Never put a real lock code in a document.
  • lockUsercodeService: an optional HA service that syncs the credential a controller sets or clears to the physical lock; without it the credential is only kept in Matter Hub. This is opt-in behavior that writes to an external device, so confirm what the integration's service does first.
  • lockUsercodeSlot: the code slot on the physical lock, default 1; the UI only accepts integers of 1 or more.
  • lockPinMinLength / lockPinMaxLength: the lengths advertised to a controller, 1–20, default 4 and 8; they are fixed attributes and a controller may cache them until the next commissioning. Record the lengths only, never the real credential.

Vacuums and areas

  • cleaningModeEntity: the cleaning-mode select; when it is not set, the backend can derive the conventional name from the vacuum entity ID.
  • suctionLevelEntity and mopIntensityEntity: the suction and mop-water selects, which add intensity variants to the cleaning modes.
  • roomEntities: an array of room / scene buttons; after Matter picks a room, the matching button is pressed. The UI can read the related buttons and also lets you type an entity ID.
  • currentRoomEntity: the current-room sensor. cleanedAreaEntity: the cumulative cleaned-area sensor, which together with each area's sizeSqm advances the progress.
  • vacuumAscendingRoomOrder: dispatch in ascending area-ID order instead of the controller's selection order; it also changes which area the current room and the progress are attributed to.
  • vacuumRoomSwitches: creates a momentary sibling switch per area, for routines on platforms that cannot send an array command.
  • disableCustomAreaRoomModes: does not build custom areas as per-room RvcRunMode entries, so Apple Home uses its multi-room area picker; leave it off where Google or Alexa depends on the modes.
  • valetudoIdentifier: keeps the exact case of the Valetudo MQTT identifier; unset, it is derived from the lowercase entity ID.
  • customFanSpeedTags: a map from HA option strings to Matter ModeTag numbers, overriding the default speed tags.
  • cleanAreaRooms: filled in automatically at runtime when the vacuum supports HA 2026.3 CLEAN_AREA, as a mapping from HA area to Matter ServiceArea ID; it is not a field you fill in the dialog.

Every area in customServiceAreas carries a required name and service, plus an optional target, a plain-object data, batchDispatch and sizeSqm. batchDispatch takes the service and target of the first matching area as a template, and can merge arrays, join primitives with commas and inject the selection metadata; the default is to dispatch area by area. data has to be a JSON object — the UI rejects an array or a primitive as invalid. These services make a real device act, so verify them in HA at the smallest scope first.

Fan, cover, select, climate and momentary

  • fanWindPresets.natural / .sleep: arrays of localized HA preset names mapped to the Matter wind modes; the UI takes them comma-separated.
  • fanRestoreSpeedOnPowerOn: when a fan is turned on from off, ignore the 100% / High a controller injects and restore the last speed; you can still specify a lower speed while it is off.
  • coverSwapOpenClose: swaps open and close for one cover and overrides the bridge flag. coverExposeAsDimmableLight: an Alexa workaround that uses level as the position and on/off as open and close; there is no stop, and it should not go into the lights group of an Alexa room.
  • selectExposeAsSwitch together with selectSwitchOnOption / selectSwitchOffOption: turns a select or input_select into a switch; the two options have to match exactly, and after the change that device has to be commissioned again.
  • disableClimateOnOff: skips the climate OnOff, so a voice command that turns a room off does not call climate.turn_off.
  • disableClimateFanControl: skips FanControl and uses ThermostatDevice instead, for controllers that do not recognize RoomAirConditioner; HA can still control the fan modes.
  • climateKeepModeOnIdle: when HA is off and hvac_action is idle, keep reporting the last mode so an internal cleaning cycle can be cancelled; HA and Matter deliberately disagree for a while.
  • climateExposeFan: builds a companion Fan tile alongside the same HA climate; the entity has to report FAN_MODE, and it re-registers that air conditioner as a composed device, which means commissioning that one air conditioner again.
  • climateAutoMode: only heat or cool, pinning the Matter direction of a single-setpoint auto climate.
  • disableMomentaryFlip: script, scene, automation, input_button and button stop sending the optimistic on→off report, while the underlying HA action still runs; it is a workaround for the Echo units that get stuck on that report pair.

Throttle and debounce are not interchangeable

FieldDirectionScope / precedenceWhat it is for
coverSliderDebounceMsController → HA commandThe per-entity UI only accepts a positive value and clamps it to 5000; empty or 0 falls back to the bridge value or the built-in oneWaits for the last write from the slider, so the cover does not travel to an intermediate position first.
fanSliderDebounceMsController → HA commandPer-entity wins over the bridge, and the UI clamps it to 5000; empty or 0 falls back or sends immediatelyMerges consecutive fan speed writes, cutting down repeated IR / UART commands.
updateThrottleMsHA state → Matter reportA positive value in the UI, maximum 60000; 0 or empty keeps the defaultLimits chatty power / energy sensors to at most one update every N ms.

Debounce waits until after the last input before it acts, which adds control latency; throttle limits how often reports go out, which can skip intermediate states. Do not use updateThrottleMs to stop a cover moving several times, and do not use fan debounce to thin out a power sensor that reports too often. Start with one entity and a small value, then adjust from the logs and from how the control feels.

Profile v1 carries the cover and fan debounce but not updateThrottleMs. If you move settings with a profile, cross-check the throttle by hand after the import, and do not assume a mapping profile carried the bridge's global debounce across.

Build a linked mapping you can roll back

  1. Confirm the primary entity and the same-device sources

    In Home Assistant, read-only, confirm the primary entity, the device relationship, and each sensor's device_class, unit and valid state. Record them in a local list; do not paste a live entity ID or a supply identifier into a document.

  2. Check the bridge's automatic flags

    Look at autoComposedDevices and the auto battery, humidity and pressure flags. If the automatic result is already right, do not link it again by hand; if only one device is the exception, use Entity Mapping for that one.

  3. Open the primary entity's mapping

    On the Devices card, press Edit Mapping and keep the correct primary Matter type. Use the field autocomplete to pick the battery, humidity, power and other sources; the dedicated groups only appear for a matching type or domain.

  4. Set up one group of helpers

    Fill in only the fields that serve one purpose at a time, for example power plus energy, or humidity plus pressure. Add a composed entity only when you need an extra sub-endpoint, and confirm the bridge already has autoComposedDevices on.

  5. Save and check the endpoint

    Go back to the Devices card, expand the clusters and confirm the linked entity labels and their values. If the endpoint failed, delete the mapping you just added to get back to the baseline; do not reset the bridge.

  6. Run the controller-specific check

    Check the target controller against the support chips and the maturity. For power, utility and EVSE, confirm they appear before you test the readings; for features that issue commands, such as a lock or a vacuum service area, run only the smallest authorized test.

Rollback point: deleting a single mapping returns you to automatic detection, and turning an auto flag off stops the automatic composition. A composed entity, a climate companion fan or select-as-switch changes the endpoint topology and may need that device rediscovered or commissioned again, so keep the original mapping before you start.

Troubleshooting composed and linked entities

  1. A manual link saves but shows no value

    Check whether the linked entity's state is available and whether its device_class and unit match the field. Being able to pick it in the autocomplete does not mean the value means the right thing. Clear that link first and confirm the primary endpoint recovers.

  2. Composed entities did not become sub-endpoints

    Confirm the bridge has autoComposedDevices on, and that every composed entityId is non-empty and its type is supported. Then look at the failed entities; do not mistake an ordinary linked field for a composed sub-endpoint.

  3. A mains-powered device shows a low battery in the controller

    Work out whether it came in through automatic battery, a manual batteryEntity or the entity's own battery attribute. Turn disableBatteryMapping on for that primary entity; do not switch battery off globally for every device.

  4. The utility meter or EVSE endpoint does not appear

    Read the pinned matrix first: Utility Meter is an opt-in Stable override and only SmartThings is a yes; for EVSE only Aqara is a yes, and it must not be added to an Alexa bridge. On the other no / unknown platforms, go back to a type the controller supports rather than changing the identity or re-running commissioning over and over.

  5. Vacuum room progress lands on the wrong area

    Confirm currentRoomEntity, cleanedAreaEntity, each area's sizeSqm and the actual dispatch order. Turn vacuumAscendingRoomOrder on only if the machine works in area-ID order; otherwise keep the controller's selection order.

  6. The slider lags, or the device keeps moving

    Tell the two directions apart: consecutive commands call for cover or fan debounce, and state reports that are too dense call for update throttle. Lower or clear the per-entity value step by step to fall back to the bridge default; do not change the global value and the per-entity value at the same time.

  7. faultEntity is documented but the UI has no field

    This is a gap between the v2.0.55 types and the request and the dialog. Do not hand-edit storage and do not invent a procedure; keep the default smoke/CO mapping and wait for a version with real API and UI support.

Composed and linked entity FAQ

Do I still need manual mapping once Auto Composed Devices is on?
It depends on the device. The master toggle handles battery, humidity, pressure, power and energy from the same HA device automatically; the EVSE current limit, the vacuum selects, the lock service and the utility meter identification are still explicit helpers.
Are composedEntities and humidityEntity the same thing?
No. The first builds a sub-endpoint carrying an entityId and an optional type, and it requires autoComposedDevices; the second links humidity data into the relevant cluster on the primary device.
Can I put any sensor into powerEntity?
You should not. The source comment requires the power device_class and a matching power unit. The field will not reliably correct a wrong meaning, so cross-check the HA state metadata first.
Do the lock helpers put a real credential into a tutorial or a profile?
This chapter only covers the disable flag, the service, the slot and the length metadata; it never records a real credential. A mapping profile is not a channel for sharing secrets either, so check an export by hand.
Does a larger updateThrottleMs mean more stability?
Not necessarily. The larger the value, the less often a controller sees an update. It suits chatty sensors, not a control entity that needs its state right away; start small, on a single entity.

Stable 2.0.55 pinned-version sources