Skip to Content

The override that fixes one endpoint, and the merge that turns five entities into one

one badge, not five cards
Matter Hub Guide · Part 5

The override that fixes one endpoint, and the merge that turns five entities into one

Part 4 controlled which entities become candidates at all. This part picks up the survivors of that filter and does two more jobs. First, Entity Mapping: a scoped, explicit override for one entity on one bridge — a new name, a different Matter device type, an identity detail, a disabled switch — that never touches the Home Assistant entity registry and never turns Matter Hub into a controller. Second, composition: the three separate ways Matter Hub can take a battery sensor, a power sensor and a mode select that Home Assistant keeps as five loose entities and present them to a controller as one device with one card, instead of a pile of fragments.

12
Default page size on the Devices list. 10, 25, 50, 100, a custom number or All are also on offer, and your pick is remembered in the browser
0
The endpoint number a leaf device card never carries. Endpoint 0 is the bridge's root node and the aggregator, and neither becomes an ordinary card
4
Controller chips on the type picker — Apple Home, Google Home, Alexa, Aqara Home. SmartThings gets no chip at all, which is not the same as being unsupported
Order of operations

Filtering picks the candidates. Mapping decides how they show up

The Devices page collects the leaf endpoints of every bridge you have — the actual Matter endpoints Matter Hub built, one card per endpoint, so you can work back from what Matter actually produced to the Home Assistant entity behind it. Entity Mapping is the explicit override for one entity on one bridge, and only that entity: it can change the name, the Matter device type, the identity details, the disabled state, and which helper entities feed it. It does not change the Home Assistant entity registry, and it does not turn Matter Hub into a controller of its own.

Work in this order. The Filter Preview from the previous part controls the candidate set. The Devices page confirms the endpoint that actually got built from that candidate. A mapping is added only for the entities that are exceptions to what Auto Detect already got right. If you override the type and the identity for every entity from the start, you lose the benefit of automatic detection, and you are more likely to land on a type the controller does not support, or an identity that shifts after the device is already commissioned.

flowchart LR
  F["Filter Preview:
which entities become
candidate endpoints"] --> D["Devices page:
confirm the endpoint
Matter actually built"] D --> M["Entity Mapping:
override only the
exceptions"]
One straight chain, no loop backThree boxes and two arrows, and both arrows point the same direction. An override is layered on top of a confirmed candidate; nothing here feeds back to change what the filter itself lets through.
Keep three separate facts apart. Devices and the mapping workflow are settled, shipped features of Stable 2.0.55. Whether the Matter device type itself is experimental is a different question — the type list marks some types that way. And whether a given controller — Apple Home, Google Home, Alexa or Aqara Home — actually shows that type is a third, separate question, answered only by the support chips in the next section. Do not let a settled UI feature stand in for a mature device type, and do not let a mature device type stand in for controller support.
The Devices page

Search, filter, sort, failures and paging — and what each one actually touches

Every control on this page looks like it does one obvious thing. A couple of them do something narrower than the label suggests, and knowing the actual scope saves you a search that comes back empty for no good reason.

ControlActual scopeHow to use it
SearchThe endpoint display name, the bridge name, and the device type nameIt does not search entity_id directly. If the name does not find it, narrow by bridge or type first, then expand the card and look for yourself
Bridge filterEvery bridge that is loadedShows only the leaf endpoints of the selected bridge, which keeps you from editing the wrong mapping among devices that happen to share a name
Type filterThe type names present in the current endpointsThe list is deduplicated and sorted from the device types that actually exist right now; it is not a full catalog of every Matter type you could override to
SortName, type, bridge; ascending or descendingWhen the type and the bridge are equal, it sorts by name next
Page size12 by default; 10, 25, 50, 100, a custom value, or AllYour choice is written to the browser's local storage. All is stored as 0 and turns off the page slicing entirely
RefreshReloads the bridge metadataDevice state is loaded per bridge. It is not Force Sync, and it changes nothing in the controller
?showFailed=trueA summary of the failed entities across every bridgeThe Dashboard can link to this focused view, which lists entity_id, the bridge, the reason, and an optional failed time. In Stable 2.0.55 the ordinary cards are still shown below it — the card grid itself is not filtered down to just the failures

Devices collects only the leaves of the endpoint tree whose endpoint number is not 0; the root node and the aggregator never become ordinary device cards. A card can show reachable, the Home Assistant state, the clusters, the battery percentage, whether the mapping is automatic or explicit, and the matching controller-status chips. When something is missing from the controller, Devices is the first place to check, because it sits one layer closer to the bridge than any controller's own UI does.

The failure focus does not filter what is under it. If the URL carries showFailed and there happen to be no failures, the page shows an “everything loaded successfully” message. Closing that message removes the query parameter from the address bar; it does not clear the failure record on the backend. And when there are failures, remember the ordinary cards are still rendered below the summary — you are looking at an added list, not a narrowed one.
Editing one mapping

A minimal edit, and the fields that make it possible

  1. Step 1

    Lock on to the right bridge

    Go to Devices in the sidebar, pick the target bridge with the Bridge filter first, then search by name or type. Expand the card and confirm the entity it maps to; in your own notes, write that entity as the placeholder <ENTITY_ID> rather than the real value.

  2. Step 2

    Open Edit Mapping

    Press the mapping edit button in the top right of the card. The dialog first loads that bridge's mappings and looks for an existing entry with the same entityId. If the load fails, the dialog opens as though there were no existing mapping — which is exactly the wrong moment to start overriding fields.

  3. Step 3

    Keep Auto Detect as the baseline

    Leave Matter Device Type on Auto Detect unless there is a clear, specific problem with it. If you do override it, read the suggested types and the controller-support chips on each row first, then read the support warning that follows your choice.

  4. Step 4

    Fill in only the fields you need

    For a naming problem, fill in Custom Name only. Fill in Custom Product Name only when a controller displays the productName. Change the type only when the endpoint itself is wrong. Turn on Disabled only to pause exposure. An empty field is sent as undefined, not as a blank string.

  5. Step 5

    Save and read the feedback

    Press Save. Success shows a saved message; failure keeps the error on screen. Go back to the card and check the mapping and the clusters. Do not run Force Sync, change the filter, and commission again all in the same sitting — one change, one check.

  6. Step 6

    Verify in the controller

    Confirm the support status of the type first, then watch the target controller. If a change to the type or the cluster topology means it has to be discovered or commissioned again, deal with only this one exception device, and keep a way back before you start.

You can also add, edit or delete a mapping in the Entity Mapping section on a single bridge's detail page. When you add one, you search for or type an entity ID. Deleting a mapping returns that entity to automatic detection and its defaults — which is a different thing from excluding it with a filter rule, and does not remove it from the candidate set.

FieldPrecedence / limitsWhen to use it
entityIdOne of the mapping's primary keys; bridgeId keeps bridges apartUse the real Home Assistant entity ID when you add a mapping. In notes and documentation write only <ENTITY_ID> — never a value from a live environment
matterDeviceTypeOmitted means Auto DetectOverride it only when automatic detection is wrong, or you need a specific alternative presentation. Changing the type can change the endpoint's clusters
customNameHighest precedence when the resolved nodeLabel name is builtChanges only the name a Matter controller displays, not the Home Assistant entity_id. Good for a local rename that stays inside Matter
customProductNameBeats the HA device model / model_id, and also the bridge's productNameFromNodeLabelUse it when a controller displays the name from productName
customVendorNameBeats the HA device manufacturer fieldCorrects or pins the text vendorName. It is not the numeric vendorId — the two are unrelated fields
customSerialNumberBeats the HA registry serial and the default hashSet it only when you understand the controller caching risk. Never paste a real serial number into a document or a shared diagnostic — use <CUSTOM_SERIAL>
customVendorIdAn integer from 1 to 0xFFFE, entered in decimal or 0x formatBridge Mode can override the numeric vendorId. In Server Mode the root vendorId is fixed at commissioning, so this field is not a safe way to change a controller that is already commissioned
disabledBooleanKeeps the mapping but disables that one entity. Not the same thing as a filter Exclude, and it does not disable the entity inside Home Assistant itself
In plain terms

Custom Name is a nickname on a name tag, not a change of legal name. The Matter controller reads the nickname on the badge you handed it. Home Assistant's own entity_id is still the name in the filing cabinet, unrelated to what the badge currently says, and the cabinet does not get reindexed just because you wrote a new name on the tag.

Two kinds of rename exist, and they are not interchangeable. Custom Name is a Matter-side override and leaves the Home Assistant entity_id completely alone. Actually renaming the entity inside Home Assistant is a separate operation, and it can pull the endpoint's identity along with it. The bridge feature flag stableIdentity anchors identity to the HA registry unique_id instead of to the name, so a rename does not mint a new device in the controller. Without stable identity turned on, do not bundle a Home Assistant rename, a custom serial change, and a suffix change into one batch on an environment that is already commissioned — any one of the three could look, from the controller's side, like a brand-new device.

flowchart TD
  A["Endpoint currently on
Auto Detect"] --> B{"Is the detected type
actually wrong for
this endpoint?"} B -->|"no"| C["Leave it on Auto Detect"] B -->|"yes"| D["Open the type picker and
read the A / G / X / Q
chips on each row"] D --> E{"Does any controller
chip read explicit no?"} E -->|"none does"| F["Save the override,
then verify in that
controller"] E -->|"at least one does"| G["Read the warning and
the type note before
you save"]
Three end boxesLeaving Auto Detect alone, saving after a clean chip check, and saving anyway after reading a warning — those are the three places this decision can land. Only the branch where a chip already reads explicit no reaches the warning box; a clean check skips it entirely.
Do not share identity data. Tutorials, issues, and profile examples must not contain a real serial number, a numeric vendor identity, or any other live node or fabric data, and must never contain a pairing or lock credential. Use documentation-only placeholders such as <CUSTOM_SERIAL> instead.
Reading the controller chips

Four round chips, and the difference between “no” and “nobody's checked”

Each row of the type picker can show four round chips: A is Apple Home, G is Google Home, X is Alexa, and Q is Aqara Home. Green means it works, orange means it partly works. Both no and unknown render as gray at a lower opacity, which is the trap — you have to rest the cursor on the chip and read the tooltip to tell “not supported” from “unverified.”

Once you pick a type, the dialog shows an information warning if any controller chip is explicitly no. Some types carry a note of their own on top of that, such as the limits on how a standalone fan is presented in Apple Home. All of this is a point-in-time snapshot taken from the Stable 2.0.55 source, not a permanent guarantee from any controller vendor. SmartThings is not part of this set of four UI chips at all — a missing chip is no basis for inferring either support or the lack of it.

StatusUIYour call
yesGreenThe snapshot marks it usable; still verify the functional details against the controller version you actually run
partialOrangeIt may present only some clusters or operations. Read the type note and plan for the degraded case
noGray, tooltip reads “not supported”It may not appear at all. Do not let repeated recommissioning stand in for an actual type-compatibility check
unknownGray, tooltip reads “unverified”There is no verification data either way. Do not write it down as supported or unsupported
In plain terms

A gray chip is a locked door with no sign on it. It might be locked because nobody is allowed in — that is no. Or it might be locked because nobody has tried the handle yet — that is unknown. From across the room the two doors look identical. You have to walk up and read the tooltip, the way you would knock, before you can tell which one it is.

Experimental types are a separate axis again. Type labels such as Doorbell and Mounted On/Off Control are marked experimental in the type list. Some Matter 1.4 types appear in Stable and still have no presentation in any controller at all. Whether the menu offers a type, whether that type is mature, and whether a specific controller supports it are three facts that each have to be checked on their own — none of the three implies either of the others.
Three ways to combine entities

One physical device, five scattered entities, and three different ways to bring them back together

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

Confirm the meaning before you link anything. Check the unit, the device_class, what the state actually means, and how often it updates. Putting a current sensor into a voltage field does not convert the numbers just because of the field name. Linking the battery sensor of a different physical device to your primary entity produces a false low-battery warning, not a working link. Build one link at a time, then go back to the Devices card and check the mapping and the clusters before moving to the next.

Automatic mapping

Enabled by bridge feature flags. Applies to battery, humidity, pressure, power and energy from the same HA device. Derived from the registry relationship and the device class; it does not cover every vacuum, EVSE, lock or select helper.

An explicit linked field

Set in the Entity Mapping dialog. Applies to single-purpose fields such as batteryEntity and powerEntity. You are responsible for picking the right entity, unit and meaning; some fields only appear for a matching domain or type.

composedEntities

Set in the composed list in Entity Mapping. Takes an extra entityId plus an optional matterDeviceType, forming a sub-endpoint. Requires the bridge's autoComposedDevices flag; any entry with an empty entityId is filtered out before saving.

flowchart TD
  H["One Home Assistant device
with several related entities"] --> M1["Automatic mapping:
a bridge feature flag such
as autoComposedDevices"] H --> M2["An explicit linked field:
batteryEntity, powerEntity
and similar, set by hand"] H --> M3["composedEntities:
an extra entityId becomes
its own sub-endpoint"] M1 --> R1["Battery, humidity, pressure,
power and energy merged
into the primary endpoint"] M2 --> R2["One named field feeds one
specific cluster on the
primary endpoint"] M3 --> R3["A new sub-endpoint under
the same BridgedNodeEndpoint"]
Three branches, three outcomesAll three leave the same starting box, one per model, and none of the three outcome boxes overlaps with another: a merge into the primary endpoint, a single field feeding one cluster, or a brand-new sub-endpoint. Picking the wrong one of the three is why an entity ends up in the wrong place.

autoComposedDevices is the master toggle for automatic composition: turning it on is what allows battery, humidity, pressure, power and energy to be merged automatically at all. Within that, autoBatteryMapping defaults to false; autoHumidityMapping and autoPressureMapping default to true. Filling in batteryEntity and the other linked fields by hand is explicit mapping, and it is worth being precise about that distinction in your own notes — do not describe a hand-filled field as something a flag “found automatically.”

The Devices card lists the battery, humidity, pressure, power, energy, voltage, current, battery-power / battery-energy, charging-switch and current-limit links a mapping carries, and marks the clusters those links produce. A card can be showing runtime automatic mapping and a saved explicit mapping at the same time, so cross-check it against both the bridge flags and the entity mapping before you assume you know which one is responsible for what you see.

Battery, temperature, humidity, pressure, 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 shown on the card
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 purifierBuilds 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 alarmDeclared in EntityMappingConfig, but the Stable 2.0.55 EntityMappingRequest and dialog have no such field — the existing UI cannot save it. Treat it as a capability gap at the source level, and do not hand-edit storage to work around it
chargingStateEntityA vacuum-only charging-state sensor; drives the Matter batChargeState directlyReplaces 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 own 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 reports 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 notes, use only <METER_SERIAL>
pointOfDeliveryA metering point ID as textOnly the utility-meter type persists it. Use only <POINT_OF_DELIVERY> in documentation, 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
Wrong linkYou drop a current sensor with device_class current into powerEntity because the two numbers look close enough. The field name does not fix the meaning — ElectricalPowerMeasurement now reports current values as if they were power, and nothing in the UI stops you from saving it.
Right linkOnly a sensor whose device_class is power, in a power unit, goes into powerEntity. The current sensor belongs in currentEntity instead, where it merges into the same device's ElectricalPowerMeasurement correctly labeled as current.

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 at all. 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 — it does not duplicate the ordinary electrical group.

Maturity and controller support, kept separate for each override. Utility Meter is an opt-in Matter 1.4 override inside Stable, and the pinned source does not mark it experimental: Apple Home, Google Home and Alexa do not support it, Aqara Home is unverified, and SmartThings supports it. EVSE is an opt-in Stable override: Apple Home, Google Home and Alexa do not support it, Aqara Home does, and SmartThings is unverified — and a bridged EVSE can break Alexa's own device recognition, so it must not go on an Alexa bridge at all, regardless of anything else about the setup.
Device-specific helpers

Lock, vacuum, fan, cover, select, climate — and the two timers that are not the same thing

Lock

  • disableLockPin: one lock stops requiring credential verification. If the system already has credentials configured, the default is still to require them. Never put a real lock code in a document — use a placeholder.
  • lockUsercodeService: an optional HA service that syncs the credential a controller sets or clears back to the physical lock; without it, the credential is only kept inside Matter Hub. This is opt-in behavior that writes to an external device, so confirm what the integration's service actually does before you enable it.
  • 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 a 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 directly.
  • currentRoomEntity: the current-room sensor. cleanedAreaEntity: the cumulative cleaned-area sensor, which together with each area's sizeSqm advances the progress.
  • vacuumAscendingRoomOrder: dispatches in ascending area-ID order instead of the controller's own 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: skips building custom areas as per-room RvcRunMode entries, so Apple Home falls back to its own multi-room area picker. Leave this off wherever Google Home or Alexa depends on those 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 yourself 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 Home Assistant at the smallest scope first, before trusting them to a controller-driven room pick.

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, ignores the 100% / High a controller injects and restores the last speed. You can still specify a lower speed while the fan is off.
  • coverSwapOpenClose: swaps open and close for one cover, overriding 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 option strings have to match exactly, and after the change that device has to be commissioned again.
  • disableClimateOnOff: skips the climate OnOff cluster, 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. Home Assistant can still control the fan modes underneath.
  • climateKeepModeOnIdle: when HA is off and hvac_action is idle, keeps reporting the last mode so an internal cleaning cycle can still be cancelled — HA and Matter deliberately disagree for a while here.
  • climateExposeFan: builds a companion Fan tile alongside the same HA climate entity. 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 entities stop sending the optimistic on→off report, while the underlying HA action still runs. It is a workaround for Echo units that get stuck on that report pair.

Throttle and debounce are not interchangeable

FieldDirectionScope / precedenceWhat it is for
coverSliderDebounceMsController → HA commandPer-entity UI accepts a positive value, clamped 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, clamped 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 milliseconds
In plain terms

Debounce is waiting for someone to stop knocking before you open the door — you act once, after the knocking stops, and you act on whatever the last knock actually asked for. Throttle is a doorman who lets through at most one person every few seconds, no matter how many are lined up outside; some of the queue simply never gets an individual answer. One waits for quiet before acting; the other rations how often it will act at all.

flowchart LR
  C["Controller sends a slider
or speed command"] -->|"debounce waits for
the last write"| H["Home Assistant
service call"] S["Home Assistant sensor
state changes"] -->|"throttle limits how
often this fires"| R["Matter attribute report
back to the controller"]
Opposite directions, opposite jobsThe arrow labeled debounce runs from the controller toward Home Assistant, smoothing a command before it is acted on. The arrow labeled throttle runs the other way, from a Home Assistant state change toward the report a controller sees. They never touch the same traffic, which is why one cannot substitute for the other.

Do not use updateThrottleMs to stop a cover from moving several times, and do not use fan debounce to thin out a power sensor that reports too often — each field is built for the direction of traffic in its own row above, not the other one. Start with one entity and a small value, then adjust from what you see in the logs and how the control actually feels. Profile v1 carries the cover and fan debounce fields but not updateThrottleMs; if you move settings with a profile, cross-check the throttle by hand after the import, and do not assume a profile carried a bridge's global debounce setting across with it.

  1. Step 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. Step 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 device alone.

  3. Step 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. Step 4

    Set up one group of helpers

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

  5. Step 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 fails, delete the mapping you just added to get back to the baseline — do not reset the whole bridge.

  6. Step 6

    Run the controller-specific check

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

Keep a rollback point. Deleting a single mapping returns that entity to automatic detection, and turning an auto flag off stops the automatic composition for that class of entity. 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 recorded before you start changing anything.
Profiles and device images

Move mappings between bridges, and give a card a picture — neither one touches the controller

Mapping profiles

A Mapping Profile is JSON at version: 1, holding name, createdAt, domains, entryCount and entries. What it carries is a set of mapping rules, not bridge identity, the fabric, pairing data, or a full backup. The export dialog preselects the existing mappings; you can select or clear all of them, tick them one by one, and give the profile a name.

  1. Step 1

    Choose what to export

    In Entity Mapping on the bridge detail page, press Export. Tick only the entity mappings you intend to share or move, and use a profile name that carries nothing confidential about the environment.

  2. Step 2

    Save the JSON

    Check the downloaded file name and its contents. Before you share it, review entityIdPattern, custom names, service names, area data and the identity fields by hand, and remove anything that identifies a live environment. A profile is not an automatic de-identification tool.

  3. Step 3

    Pick the import file

    Press Import and choose the .json file. The frontend requires version and entries first; then the backend preview validates the entries against the entity IDs that are actually available.

  4. Step 4

    Review the preview

    Check the profile name, the total count, matched, unmatched, matchType (exact or domain) and existing mapping. Every match is ticked by default, so clear the ones you do not want to overwrite.

  5. Step 5

    Apply selectively

    After you apply, read applied, skipped and errors. In Stable 2.0.55, apply matches the profile entry's entityIdPattern against the selected IDs, so an exact entity ID match is the most reliable way to work across environments — do not read a domain fallback in the preview as certain to succeed.

  6. Step 6

    Reload and verify one by one

    The mappings reload after the import. Look at a few devices first, then widen it. If the result is wrong, delete that mapping to return to automatic detection instead of resetting the whole bridge.

The Stable 2.0.55 profile is not a full backup of EntityMappingConfig. It holds type, customName, disabled, and most of the battery, sensor, energy, vacuum, lock, cover, fan and climate helpers; but the profile type and the export conversion have no customProductName, customVendorName, customSerialNumber, customVendorId, composedEntities, chargingStateEntity, currentRoomEntity, cleanedAreaEntity, coverExposeAsDimmableLight, the select-switch helpers, updateThrottleMs, or disableCustomAreaRoomModes. When you need full disaster recovery, use the real Backup rather than treating a profile as a complete snapshot of the mappings.

Device images

The image sources for a Devices card have this precedence: a custom uploaded file → the Zigbee2MQTT model URL → none. The backend sanitizes the entity_id first, then looks for a file of the same name in the device-images directory in persistent storage. When there is no custom file and the HA device registry has a model, it builds the official Zigbee2MQTT image URL instead. The image affects the Matter Hub UI card only; no image is synced to any Matter controller.

flowchart TD
  A["Devices card needs
an image"] --> B{"Is there a custom
uploaded file for
this entity_id?"} B -->|"yes"| C["Show the custom file"] B -->|"no"| D{"Does the HA device
registry have a model?"} D -->|"yes"| E["Build the Zigbee2MQTT
image URL and try it"] D -->|"no"| F["Show the built-in
device-type icon"] E --> G{"Does the remote
image load?"} G -->|"yes"| I["Show the z2m image"] G -->|"no"| F
Three pictures, reached by four pathsOnly three things a card can actually show — a custom file, the z2m image, or the built-in icon — but the built-in icon has two separate routes into it: no model in the registry at all, or a model whose z2m image URL fails to load. A custom upload wins outright whenever one exists.
ActionLimitsResult
UploadPNG, JPG / JPEG, GIF, WebP, SVG; 5 MB maximumSaved under a file name that matches the entity_id. A new extension deletes the file with the old extension for the same entity
RemoveShown only when the source is customDeletes the custom file. After it resolves again it may fall back to the z2m image rather than always turning into an icon
Auto resolveNeeds a model in the device registryBuilds the z2m image URL. When nothing is there at the far end, the image fails to load and the card falls back to the device icon
No imageNo custom file and no modelShows the built-in icon chosen by the Matter device type

To upload, press the camera button on the card; on success the page bumps the cache version and runs the batch resolve again. A delete resolves again as well. Use only images you have the right to use, and do not upload files that contain pictures of a home interior, serial numbers on labels, or other personal data. When you back up or migrate, count the persistent device-images directory among the assets you plan for — a profile export never carries it.

Exact match beats domain fallback, and images stay local. When you apply a profile, an exact entityIdPattern match is the reliable path; a domain fallback preview is not certain to succeed once the target environment's entity IDs differ. And regardless of how a device's image resolves, it is display-only inside the Matter Hub UI — nothing about it reaches Apple Home, Google Home, Alexa or any other controller.
When it does not add up

The symptom you will actually hit, mapped to the page that explains it

SymptomLikely causeWhat to do
Search cannot find an entity_id you know exists Search looks only at the display name, the bridge name and the type Pick the bridge and the type first, then expand the cards to find the HA entity; or go to that bridge's Entity Mapping section and search with the Entity Autocomplete
Failed focus still shows healthy devices That is what Stable 2.0.55 actually does — showFailed=true shows a summary but does not filter the cards below it Take the bridge and the entity_id from the summary and go back to the filter, the mapping and the failed reason to work it out
The controller shows nothing after a type override The chosen type is unsupported or unverified on that controller Go back to the picker and read the support chips, the tooltip and the warning. Restore Auto Detect first; do not start by changing the identity or by commissioning the whole bridge again
The import preview says matched but applying skips it The profile's entityIdPattern is not exactly the same as the target In Stable 2.0.55, apply matches the selected IDs against the entry pattern, and a domain fallback preview is unreliable when the entity IDs differ. Use an exact match, or create the mapping by hand
There is still an image after you delete one Deleting a custom image triggers a fresh resolve If the HA device has a model, the source falls back to z2m — that is not a failed delete. When the remote URL has no image, the built-in icon appears only after the load error
A new device appears in the controller after an HA rename Identity was not anchored to the registry unique_id Confirm whether the bridge uses stableIdentity, and check whether the serial, the unique suffix or the custom serial changed at the same time. Undo the identity changes you did not need. In an environment that is already commissioned, start from the backup and an assessment of the controller impact rather than renaming over and over
A manual link saves but shows no value The linked entity's state is unavailable, or its device_class and unit do not 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
Composed entities did not become sub-endpoints autoComposedDevices is off, or an entry has an empty entityId 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
A mains-powered device shows a low battery in the controller Automatic battery mapping, a manual batteryEntity, or the entity's own battery attribute is misattached Work out which of the three it came in through. Turn disableBatteryMapping on for that primary entity; do not switch battery mapping off globally for every device
The utility meter or EVSE endpoint does not appear The target controller is a known no or unknown for that override Read the pinned matrix first: Utility Meter is an opt-in override where only SmartThings is a yes; EVSE is an opt-in override where only Aqara Home is a yes, and it must never 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
Vacuum room progress lands on the wrong area Dispatch order or a sensor mapping does not match how the machine actually works 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 own selection order
The slider lags, or the device keeps moving Debounce and throttle are being confused for one another 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
faultEntity is documented but the UI has no field A gap between the Stable 2.0.55 type definitions and the request / 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
Questions people ask

The ones that come up again and again

What is the difference between Disabled and Exclude?
Exclude removes a candidate at the bridge filter stage, before Matter Hub ever builds an endpoint for it. A mapping's disabled is an explicit disable saved for one bridge and one entity, on an endpoint that still exists. Deleting the mapping returns to the automatic settings, which is not the same thing as Exclude either.
Does Custom Name change the name or the entity_id in Home Assistant?
No, it overrides the Matter nodeLabel only. Renaming in Home Assistant itself is a separate operation; if you want the identity to hold steady in the controller across that rename, look at stableIdentity separately.
Does a gray controller chip always mean it is unsupported?
Not necessarily. Both no and unknown render gray, so read the tooltip — unknown says only that it is unverified, not that it fails. SmartThings is not one of the four chips at all, so its absence from the row tells you nothing either way.
Is a Mapping Profile a full backup?
It is not. It holds no bridge identity or pairing data, and the Stable 2.0.55 profile schema covers only a subset of EntityMappingConfig — the identity fields, composedEntities and several vacuum and select-switch helpers are all missing from it. Use the Backup mechanism for a full restore.
Does a device image show up in Apple Home or Alexa?
No. The upload and z2m resolution exist to display on the Matter Hub Devices and Endpoint cards; it is not image transport over a Matter endpoint, and no controller ever sees it.
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 fields are still explicit helpers you set by hand.
Are composedEntities and humidityEntity the same thing?
No. composedEntities builds a sub-endpoint carrying an entityId and an optional type, and it requires autoComposedDevices. humidityEntity links humidity data into the relevant cluster on the primary device instead — no sub-endpoint is created.
Can I put any sensor into powerEntity?
You should not. The field expects the power device_class and a matching power unit. It will not reliably correct a wrong meaning just because you picked it in the autocomplete, so cross-check the HA state metadata first.
Do the lock helpers put a real credential into a tutorial or a profile?
No. This part only covers the disable flag, the service, the slot and the length metadata; none of them record a real credential. A mapping profile is not a channel for sharing secrets either, so check any export by hand before you send it anywhere.
Does a larger updateThrottleMs mean more stability?
Not necessarily. The larger the value, the less often a controller sees an update at all. It suits chatty sensors, not a control entity that needs its state reported right away. Start small, on a single entity, before you touch anything else.
Why does the utility meter or EVSE type not show up on my controller?
Both are opt-in overrides with a narrow support matrix. Utility Meter is a yes only on SmartThings; EVSE is a yes only on Aqara Home, and it must never be placed on an Alexa bridge because it can break Alexa's own device recognition. Being able to build the endpoint in Matter Hub is not the same as any given controller choosing to show it.
Next

Where to go from here

one card, five entities

You can now fix one endpoint by hand, and merge scattered entities into one Matter device instead of a pile of fragments.

The next part goes device by device: the exact mapping rules for switches, lights, covers, fans and climate controls, and then the sensor and energy side — which device class becomes which Matter measurement, and where the edge cases live for each one.

Open the full guide

Part 5 of the Home Assistant Matter Hub Complete Guide series on the Apporo blog.

Adapted from the Home Assistant Matter Hub Complete Guide, produced by WoowTech and released under CC BY 4.0. This adaptation is published by Apporo under the same licence.

Light · Air · Water · Control · apporo

Decide what's in the bridge, then decide how it behaves