First of all, thanks for this great tool. I ran into an issue and used AI to help me resolve it, so I'm sharing here my findings and solution, hope it helps
Description
When mac_mapping_* entries in configuration.yaml use non-sequential numbering (e.g., mac_mapping_1, _2, _3, _6, _8...), only the first batch up to the first gap is imported. All mappings after the gap are silently dropped.
In my case, I have 91 mappings defined in YAML but only 15 (with ID less or equal 25) were saved to the config entry.
Root Cause
Both config_flow.py and sensor.py iterate MAC mappings sequentially and break on the first missing key:
config_flow.py — the while True loop starting at i=26:
i = 26
while True:
key = f"mac_mapping_{i}"
if key in yaml_config:
...
i += 1
else:
break # Stops here at first gap
sensor.py — same pattern in async_setup_entry:
i = 25
while True:
key = f"mac_mapping_{i+1}"
if key in config_entry.data:
...
i += 1
else:
break # Stops here at first gap
This means any gap in numbering (e.g., no mac_mapping_26 because numbering jumps to _28) causes everything after to be lost.
Additionally
config_flow.py passes user_input directly to async_create_entry(). Since all mac_mapping_* fields are vol.Optional, any field the user doesn't explicitly fill in is dropped from user_input. With 90+ fields this means most mappings are lost even if the form renders them.
Suggested Fix
config_flow.py — collect all mac_mapping_* keys dynamically instead of sequential iteration:
Replace the for/while loops with:
mac_keys = sorted(
(k for k in yaml_config if k.startswith("mac_mapping_")),
key=lambda k: int(k.split("_")[2]),
)
for key in mac_keys:
data_schema_dict[vol.Optional(key, description={"suggested_value": yaml_config.get(key)})] = str
And merge YAML mappings on form submit so optional fields left blank aren't lost:
if user_input is not None:
merged = dict(user_input)
for key, value in yaml_config.items():
if key.startswith("mac_mapping_") and key not in merged:
merged[key] = value
return self.async_create_entry(title="Network Scanner", data=merged)
sensor.py — same dynamic collection:
mac_keys = sorted(
(k for k in config_entry.data if k.startswith("mac_mapping_")),
key=lambda k: int(k.split("_")[2]),
)
mac_mappings_list = [config_entry.data.get(k, "") for k in mac_keys]
NetworkScannerOptionsFlow — same pattern for the options flow form.
Steps to Reproduce
- Define mac_mapping_* entries in configuration.yaml with non-sequential numbers (e.g., _1, _2, _3, _6, _8, _28, _50...)
- Set up the integration via the UI
- Check config entry data — only mappings up to the first gap are saved
Environment
- Integration version: v1.0.7
- Home Assistant version: 2025.10.3
Regards, Marianok
First of all, thanks for this great tool. I ran into an issue and used AI to help me resolve it, so I'm sharing here my findings and solution, hope it helps
Description
When mac_mapping_* entries in configuration.yaml use non-sequential numbering (e.g., mac_mapping_1, _2, _3, _6, _8...), only the first batch up to the first gap is imported. All mappings after the gap are silently dropped.
In my case, I have 91 mappings defined in YAML but only 15 (with ID less or equal 25) were saved to the config entry.
Root Cause
Both config_flow.py and sensor.py iterate MAC mappings sequentially and break on the first missing key:
config_flow.py — the while True loop starting at i=26:
sensor.py — same pattern in async_setup_entry:
This means any gap in numbering (e.g., no mac_mapping_26 because numbering jumps to _28) causes everything after to be lost.
Additionally
config_flow.py passes user_input directly to async_create_entry(). Since all mac_mapping_* fields are vol.Optional, any field the user doesn't explicitly fill in is dropped from user_input. With 90+ fields this means most mappings are lost even if the form renders them.
Suggested Fix
config_flow.py — collect all mac_mapping_* keys dynamically instead of sequential iteration:
Replace the for/while loops with:
And merge YAML mappings on form submit so optional fields left blank aren't lost:
sensor.py — same dynamic collection:
NetworkScannerOptionsFlow — same pattern for the options flow form.
Steps to Reproduce
Environment
Regards, Marianok