@riddix/hamh 2.1.0-alpha.842 → 2.1.0-alpha.844
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ of port forwarding etc.
|
|
|
37
37
|
|
|
38
38
|
| Channel | Branch | Current Version | Description |
|
|
39
39
|
|---------|--------|-----------------|-------------|
|
|
40
|
-
| **Stable** | `main` | v2.0.
|
|
40
|
+
| **Stable** | `main` | v2.0.52 | Production-ready, recommended for most users |
|
|
41
41
|
| **Alpha** | `alpha` | v2.1.0-alpha.x (next) | Currently level with Stable; next pre-release lands here first |
|
|
42
42
|
| **Testing** | `testing` | v4.1.0-testing.x | ⚠️ **Highly unstable!** Experimental features, may break |
|
|
43
43
|
|
|
@@ -61,9 +61,24 @@ Re-assign the affected devices to their rooms after they reconnect. See the [doc
|
|
|
61
61
|
## 🎉 What's New
|
|
62
62
|
|
|
63
63
|
<details>
|
|
64
|
-
<summary><strong>📦 Stable Features (v2.0.
|
|
64
|
+
<summary><strong>📦 Stable Features (v2.0.52)</strong> - Click to expand</summary>
|
|
65
65
|
|
|
66
|
-
**New in v2.0.
|
|
66
|
+
**New in v2.0.52 (hotfix release):**
|
|
67
|
+
|
|
68
|
+
- 🔌 The plugins page no longer fails with a 500 when a server mode bridge exists ([#430](https://github.com/RiDDiX/home-assistant-matter-hub/issues/430))
|
|
69
|
+
|
|
70
|
+
**Previously in v2.0.51:**
|
|
71
|
+
|
|
72
|
+
- 🐕 **Opt-in wedge watchdog**: rotates a controller session that keeps acking but stops talking at the interaction layer, the automated "Play Sound" fix for stuck Apple devices ([#287](https://github.com/RiDDiX/home-assistant-matter-hub/issues/287), [#428](https://github.com/RiDDiX/home-assistant-matter-hub/issues/428))
|
|
73
|
+
- 🧹 **Clean up orphaned records**: bridge menu action with a dry-run preview that removes identity and mapping leftovers of entities deleted from HA (7 day tombstone guards against false positives)
|
|
74
|
+
- 🚗 **EV charger support**: new EVSE device-type override with charging switch and current limit mapping, EnableCharging/Disable from the controller; Aqara and Home Assistant render it, keep it off Alexa bridges
|
|
75
|
+
- 🩺 **Subscription scope on the health card**: see whether each controller holds a whole-node wildcard or watches specific endpoints
|
|
76
|
+
- 📷 **Camera live view signaling completed**: the WebRTC answer now reaches the controller over the requestor cluster, plus full media path logging, HA signaling timeouts, trickle ICE and ICE server support (still experimental until verified on real hardware)
|
|
77
|
+
- 🪟 **Cover stop detection in every position space**: the v2.0.50 cover fix now also works with the Alexa percentage flag and the per-cover swap toggle, and swapped covers report the right direction ([#429](https://github.com/RiDDiX/home-assistant-matter-hub/issues/429))
|
|
78
|
+
- 🤖 **Vacuum on/off crash fixed**: state updates no longer throw on vacuums with the on/off toggle ([#428](https://github.com/RiDDiX/home-assistant-matter-hub/issues/428))
|
|
79
|
+
- 🌍 **Brazilian Portuguese completed**: 602 of 615 strings ([#420](https://github.com/RiDDiX/home-assistant-matter-hub/issues/420))
|
|
80
|
+
|
|
81
|
+
**Previously in v2.0.50:**
|
|
67
82
|
|
|
68
83
|
- 🆔 **Stable device identity (opt-in)**: endpoints keep their identity when an entity is renamed or re-registered, keyed on the HA registry unique id; enable the `stableIdentity` feature flag per bridge ([#404](https://github.com/RiDDiX/home-assistant-matter-hub/issues/404), [#407](https://github.com/RiDDiX/home-assistant-matter-hub/issues/407))
|
|
69
84
|
- ⚡ **Energy suite stage 1**: consumption sensors expose an **Electrical Meter** that Google Home and SmartThings render, home batteries become a **Battery Storage** device with signed charge/discharge power and lifetime energy, and voltage/current/energy sensors group onto one endpoint via new mapping fields
|
|
@@ -255,7 +270,7 @@ Re-assign the affected devices to their rooms after they reconnect. See the [doc
|
|
|
255
270
|
<details>
|
|
256
271
|
<summary><strong>🧪 Alpha Features (v2.1.0-alpha.x)</strong> - Click to expand</summary>
|
|
257
272
|
|
|
258
|
-
**Alpha is currently level with Stable (v2.0.
|
|
273
|
+
**Alpha is currently level with Stable (v2.0.52).** All alpha work up to the latest pre-release has been promoted into v2.0.52. New alpha work continues from the next pre-release tag onward and will appear here as development progresses.
|
|
259
274
|
|
|
260
275
|
</details>
|
|
261
276
|
|
package/dist/backend/cli.js
CHANGED
|
@@ -133183,7 +133183,8 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
|
|
|
133183
133183
|
fanWindPresets: config11.fanWindPresets,
|
|
133184
133184
|
fanRestoreSpeedOnPowerOn: config11.fanRestoreSpeedOnPowerOn,
|
|
133185
133185
|
composedEntities: config11.composedEntities,
|
|
133186
|
-
disableMomentaryFlip: config11.disableMomentaryFlip
|
|
133186
|
+
disableMomentaryFlip: config11.disableMomentaryFlip,
|
|
133187
|
+
vacuumAscendingRoomOrder: config11.vacuumAscendingRoomOrder
|
|
133187
133188
|
});
|
|
133188
133189
|
mappingsRestored++;
|
|
133189
133190
|
}
|
|
@@ -133346,7 +133347,8 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
|
|
|
133346
133347
|
customFanSpeedTags: config11.customFanSpeedTags,
|
|
133347
133348
|
fanWindPresets: config11.fanWindPresets,
|
|
133348
133349
|
composedEntities: config11.composedEntities,
|
|
133349
|
-
disableMomentaryFlip: config11.disableMomentaryFlip
|
|
133350
|
+
disableMomentaryFlip: config11.disableMomentaryFlip,
|
|
133351
|
+
vacuumAscendingRoomOrder: config11.vacuumAscendingRoomOrder
|
|
133350
133352
|
});
|
|
133351
133353
|
mappingsRestored++;
|
|
133352
133354
|
}
|
|
@@ -134195,6 +134197,7 @@ function entityMappingApi(mappingStorage, identityStorage) {
|
|
|
134195
134197
|
fanRestoreSpeedOnPowerOn: body.fanRestoreSpeedOnPowerOn,
|
|
134196
134198
|
currentRoomEntity: body.currentRoomEntity,
|
|
134197
134199
|
cleanedAreaEntity: body.cleanedAreaEntity,
|
|
134200
|
+
vacuumAscendingRoomOrder: body.vacuumAscendingRoomOrder,
|
|
134198
134201
|
disableCustomAreaRoomModes: body.disableCustomAreaRoomModes,
|
|
134199
134202
|
valetudoIdentifier: body.valetudoIdentifier,
|
|
134200
134203
|
coverSwapOpenClose: body.coverSwapOpenClose,
|
|
@@ -134704,7 +134707,8 @@ function configToProfileEntry(config11) {
|
|
|
134704
134707
|
climateKeepModeOnIdle: config11.climateKeepModeOnIdle,
|
|
134705
134708
|
climateExposeFan: config11.climateExposeFan,
|
|
134706
134709
|
climateAutoMode: config11.climateAutoMode,
|
|
134707
|
-
disableMomentaryFlip: config11.disableMomentaryFlip
|
|
134710
|
+
disableMomentaryFlip: config11.disableMomentaryFlip,
|
|
134711
|
+
vacuumAscendingRoomOrder: config11.vacuumAscendingRoomOrder
|
|
134708
134712
|
};
|
|
134709
134713
|
}
|
|
134710
134714
|
function mappingProfileApi(mappingStorage) {
|
|
@@ -134845,7 +134849,8 @@ function mappingProfileApi(mappingStorage) {
|
|
|
134845
134849
|
climateKeepModeOnIdle: entry.climateKeepModeOnIdle,
|
|
134846
134850
|
climateExposeFan: entry.climateExposeFan,
|
|
134847
134851
|
climateAutoMode: entry.climateAutoMode,
|
|
134848
|
-
disableMomentaryFlip: entry.disableMomentaryFlip
|
|
134852
|
+
disableMomentaryFlip: entry.disableMomentaryFlip,
|
|
134853
|
+
vacuumAscendingRoomOrder: entry.vacuumAscendingRoomOrder
|
|
134849
134854
|
});
|
|
134850
134855
|
applied++;
|
|
134851
134856
|
} catch (e) {
|
|
@@ -136622,6 +136627,7 @@ function pluginApi(bridgeService, storageLocation) {
|
|
|
136622
136627
|
const result = [];
|
|
136623
136628
|
for (const bridge of bridgeService.bridges) {
|
|
136624
136629
|
const info = bridge.pluginInfo;
|
|
136630
|
+
if (!info) continue;
|
|
136625
136631
|
const plugins = info.metadata.map((meta) => ({
|
|
136626
136632
|
name: meta.name,
|
|
136627
136633
|
version: meta.version,
|
|
@@ -136644,41 +136650,41 @@ function pluginApi(bridgeService, storageLocation) {
|
|
|
136644
136650
|
}
|
|
136645
136651
|
res.json(result);
|
|
136646
136652
|
});
|
|
136647
|
-
|
|
136648
|
-
const bridge = bridgeService.get(
|
|
136653
|
+
function pluginBridge(bridgeId, res) {
|
|
136654
|
+
const bridge = bridgeService.get(bridgeId);
|
|
136649
136655
|
if (!bridge) {
|
|
136650
136656
|
res.status(404).json({ error: "Bridge not found" });
|
|
136651
|
-
return;
|
|
136657
|
+
return void 0;
|
|
136658
|
+
}
|
|
136659
|
+
if (typeof bridge.enablePlugin !== "function") {
|
|
136660
|
+
res.status(400).json({ error: "Bridge does not support plugins" });
|
|
136661
|
+
return void 0;
|
|
136652
136662
|
}
|
|
136663
|
+
return bridge;
|
|
136664
|
+
}
|
|
136665
|
+
router.post("/:bridgeId/:pluginName/enable", (req, res) => {
|
|
136666
|
+
const bridge = pluginBridge(req.params.bridgeId, res);
|
|
136667
|
+
if (!bridge) return;
|
|
136653
136668
|
const { pluginName } = req.params;
|
|
136654
136669
|
bridge.enablePlugin(pluginName);
|
|
136655
136670
|
res.json({ success: true, pluginName, enabled: true });
|
|
136656
136671
|
});
|
|
136657
136672
|
router.post("/:bridgeId/:pluginName/disable", (req, res) => {
|
|
136658
|
-
const bridge =
|
|
136659
|
-
if (!bridge)
|
|
136660
|
-
res.status(404).json({ error: "Bridge not found" });
|
|
136661
|
-
return;
|
|
136662
|
-
}
|
|
136673
|
+
const bridge = pluginBridge(req.params.bridgeId, res);
|
|
136674
|
+
if (!bridge) return;
|
|
136663
136675
|
const { pluginName } = req.params;
|
|
136664
136676
|
bridge.disablePlugin(pluginName);
|
|
136665
136677
|
res.json({ success: true, pluginName, enabled: false });
|
|
136666
136678
|
});
|
|
136667
136679
|
router.get("/:bridgeId/:pluginName/config-schema", (req, res) => {
|
|
136668
|
-
const bridge =
|
|
136669
|
-
if (!bridge)
|
|
136670
|
-
res.status(404).json({ error: "Bridge not found" });
|
|
136671
|
-
return;
|
|
136672
|
-
}
|
|
136680
|
+
const bridge = pluginBridge(req.params.bridgeId, res);
|
|
136681
|
+
if (!bridge) return;
|
|
136673
136682
|
const schema6 = bridge.getPluginConfigSchema(req.params.pluginName);
|
|
136674
136683
|
res.json({ pluginName: req.params.pluginName, schema: schema6 ?? null });
|
|
136675
136684
|
});
|
|
136676
136685
|
router.post("/:bridgeId/:pluginName/config", async (req, res) => {
|
|
136677
|
-
const bridge =
|
|
136678
|
-
if (!bridge)
|
|
136679
|
-
res.status(404).json({ error: "Bridge not found" });
|
|
136680
|
-
return;
|
|
136681
|
-
}
|
|
136686
|
+
const bridge = pluginBridge(req.params.bridgeId, res);
|
|
136687
|
+
if (!bridge) return;
|
|
136682
136688
|
const { config: config11 } = req.body;
|
|
136683
136689
|
if (!config11 || typeof config11 !== "object") {
|
|
136684
136690
|
res.status(400).json({ error: "config object is required" });
|
|
@@ -136692,11 +136698,8 @@ function pluginApi(bridgeService, storageLocation) {
|
|
|
136692
136698
|
res.json({ success: true, pluginName: req.params.pluginName });
|
|
136693
136699
|
});
|
|
136694
136700
|
router.post("/:bridgeId/:pluginName/reset", (req, res) => {
|
|
136695
|
-
const bridge =
|
|
136696
|
-
if (!bridge)
|
|
136697
|
-
res.status(404).json({ error: "Bridge not found" });
|
|
136698
|
-
return;
|
|
136699
|
-
}
|
|
136701
|
+
const bridge = pluginBridge(req.params.bridgeId, res);
|
|
136702
|
+
if (!bridge) return;
|
|
136700
136703
|
const { pluginName } = req.params;
|
|
136701
136704
|
bridge.resetPlugin(pluginName);
|
|
136702
136705
|
res.json({ success: true, pluginName, reset: true });
|
|
@@ -139566,6 +139569,7 @@ var EntityMappingStorage = class extends Service {
|
|
|
139566
139569
|
fanRestoreSpeedOnPowerOn: request.fanRestoreSpeedOnPowerOn || void 0,
|
|
139567
139570
|
currentRoomEntity: request.currentRoomEntity?.trim() || void 0,
|
|
139568
139571
|
cleanedAreaEntity: request.cleanedAreaEntity?.trim() || void 0,
|
|
139572
|
+
vacuumAscendingRoomOrder: request.vacuumAscendingRoomOrder || void 0,
|
|
139569
139573
|
disableCustomAreaRoomModes: request.disableCustomAreaRoomModes || void 0,
|
|
139570
139574
|
valetudoIdentifier: request.valetudoIdentifier?.trim() || void 0,
|
|
139571
139575
|
coverSwapOpenClose: request.coverSwapOpenClose || void 0,
|
|
@@ -139583,7 +139587,7 @@ var EntityMappingStorage = class extends Service {
|
|
|
139583
139587
|
composedEntities: request.composedEntities?.filter((e) => e.entityId?.trim()) ?? void 0,
|
|
139584
139588
|
disableMomentaryFlip: request.disableMomentaryFlip || void 0
|
|
139585
139589
|
};
|
|
139586
|
-
if (!config11.matterDeviceType && !config11.customName && !config11.customProductName && !config11.customVendorName && !config11.customSerialNumber && config11.customVendorId === void 0 && config11.disabled !== true && !config11.filterLifeEntity && !config11.cleaningModeEntity && !config11.temperatureEntity && !config11.humidityEntity && !config11.batteryEntity && !config11.disableBatteryMapping && !config11.chargingStateEntity && !config11.roomEntities && !config11.disableLockPin && !config11.lockUsercodeService && config11.lockUsercodeSlot === void 0 && config11.lockPinMinLength === void 0 && config11.lockPinMaxLength === void 0 && !config11.powerEntity && !config11.energyEntity && !config11.voltageEntity && !config11.currentEntity && !config11.batteryPowerEntity && !config11.batteryEnergyEntity && !config11.chargingSwitchEntity && !config11.currentLimitEntity && !config11.pressureEntity && !config11.suctionLevelEntity && !config11.mopIntensityEntity && (!config11.customServiceAreas || config11.customServiceAreas.length === 0) && (!config11.customFanSpeedTags || Object.keys(config11.customFanSpeedTags).length === 0) && (!config11.fanWindPresets || (config11.fanWindPresets.natural?.length ?? 0) === 0 && (config11.fanWindPresets.sleep?.length ?? 0) === 0) && !config11.fanRestoreSpeedOnPowerOn && !config11.currentRoomEntity && !config11.cleanedAreaEntity && !config11.disableCustomAreaRoomModes && !config11.valetudoIdentifier && !config11.coverSwapOpenClose && !config11.coverExposeAsDimmableLight && !config11.selectExposeAsSwitch && !config11.selectSwitchOnOption && !config11.selectSwitchOffOption && !config11.coverSliderDebounceMs && !config11.updateThrottleMs && !config11.disableClimateOnOff && !config11.disableClimateFanControl && !config11.climateKeepModeOnIdle && !config11.climateExposeFan && !config11.climateAutoMode && (!config11.composedEntities || config11.composedEntities.length === 0) && !config11.disableMomentaryFlip) {
|
|
139590
|
+
if (!config11.matterDeviceType && !config11.customName && !config11.customProductName && !config11.customVendorName && !config11.customSerialNumber && config11.customVendorId === void 0 && config11.disabled !== true && !config11.filterLifeEntity && !config11.cleaningModeEntity && !config11.temperatureEntity && !config11.humidityEntity && !config11.batteryEntity && !config11.disableBatteryMapping && !config11.chargingStateEntity && !config11.roomEntities && !config11.disableLockPin && !config11.lockUsercodeService && config11.lockUsercodeSlot === void 0 && config11.lockPinMinLength === void 0 && config11.lockPinMaxLength === void 0 && !config11.powerEntity && !config11.energyEntity && !config11.voltageEntity && !config11.currentEntity && !config11.batteryPowerEntity && !config11.batteryEnergyEntity && !config11.chargingSwitchEntity && !config11.currentLimitEntity && !config11.pressureEntity && !config11.suctionLevelEntity && !config11.mopIntensityEntity && (!config11.customServiceAreas || config11.customServiceAreas.length === 0) && (!config11.customFanSpeedTags || Object.keys(config11.customFanSpeedTags).length === 0) && (!config11.fanWindPresets || (config11.fanWindPresets.natural?.length ?? 0) === 0 && (config11.fanWindPresets.sleep?.length ?? 0) === 0) && !config11.fanRestoreSpeedOnPowerOn && !config11.currentRoomEntity && !config11.cleanedAreaEntity && !config11.vacuumAscendingRoomOrder && !config11.disableCustomAreaRoomModes && !config11.valetudoIdentifier && !config11.coverSwapOpenClose && !config11.coverExposeAsDimmableLight && !config11.selectExposeAsSwitch && !config11.selectSwitchOnOption && !config11.selectSwitchOffOption && !config11.coverSliderDebounceMs && !config11.updateThrottleMs && !config11.disableClimateOnOff && !config11.disableClimateFanControl && !config11.climateKeepModeOnIdle && !config11.climateExposeFan && !config11.climateAutoMode && (!config11.composedEntities || config11.composedEntities.length === 0) && !config11.disableMomentaryFlip) {
|
|
139587
139591
|
bridgeMap.delete(request.entityId);
|
|
139588
139592
|
} else {
|
|
139589
139593
|
bridgeMap.set(request.entityId, config11);
|
|
@@ -165087,6 +165091,23 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
165087
165091
|
}
|
|
165088
165092
|
}
|
|
165089
165093
|
}
|
|
165094
|
+
/**
|
|
165095
|
+
* Snapshot the controller selection in the order the vacuum will actually
|
|
165096
|
+
* clean it. Roborock-class devices clean a batch of segments in ascending
|
|
165097
|
+
* id order and ignore the order they were dispatched in, so tracking has
|
|
165098
|
+
* to follow that instead of the tap order (#368).
|
|
165099
|
+
*/
|
|
165100
|
+
orderSelectedAreas(selectedAreas) {
|
|
165101
|
+
const areas = [...selectedAreas];
|
|
165102
|
+
try {
|
|
165103
|
+
const mapping = this.agent.get(HomeAssistantEntityBehavior).state.mapping;
|
|
165104
|
+
if (mapping?.vacuumAscendingRoomOrder) {
|
|
165105
|
+
areas.sort((a, b) => a - b);
|
|
165106
|
+
}
|
|
165107
|
+
} catch {
|
|
165108
|
+
}
|
|
165109
|
+
return areas;
|
|
165110
|
+
}
|
|
165090
165111
|
/** Read the cumulative cleaned-area sensor (m2), or null if not configured. */
|
|
165091
165112
|
readCleanedAreaSqm() {
|
|
165092
165113
|
try {
|
|
@@ -165276,7 +165297,10 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
165276
165297
|
try {
|
|
165277
165298
|
const serviceArea = this.agent.get(ServiceAreaBehavior);
|
|
165278
165299
|
if (serviceArea.state.selectedAreas?.length > 0) {
|
|
165279
|
-
s.activeAreas =
|
|
165300
|
+
s.activeAreas = this.orderSelectedAreas(
|
|
165301
|
+
serviceArea.state.selectedAreas
|
|
165302
|
+
);
|
|
165303
|
+
serviceArea.state.selectedAreas = [...s.activeAreas];
|
|
165280
165304
|
s.completedAreas.clear();
|
|
165281
165305
|
s.lastCurrentArea = null;
|
|
165282
165306
|
s.loggedShortCircuits.clear();
|
|
@@ -165315,7 +165339,10 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
165315
165339
|
try {
|
|
165316
165340
|
const serviceArea = this.agent.get(ServiceAreaBehavior);
|
|
165317
165341
|
if (serviceArea.state.selectedAreas?.length > 0) {
|
|
165318
|
-
s.activeAreas =
|
|
165342
|
+
s.activeAreas = this.orderSelectedAreas(
|
|
165343
|
+
serviceArea.state.selectedAreas
|
|
165344
|
+
);
|
|
165345
|
+
serviceArea.state.selectedAreas = [...s.activeAreas];
|
|
165319
165346
|
s.completedAreas.clear();
|
|
165320
165347
|
s.lastCurrentArea = null;
|
|
165321
165348
|
s.loggedShortCircuits.clear();
|
|
@@ -169994,7 +170021,16 @@ init_esm();
|
|
|
169994
170021
|
|
|
169995
170022
|
// src/matter/behaviors/service-area-server.ts
|
|
169996
170023
|
init_esm();
|
|
170024
|
+
init_home_assistant_entity_behavior();
|
|
169997
170025
|
var logger234 = Logger.get("ServiceAreaServer");
|
|
170026
|
+
function orderSelection(areas, agent) {
|
|
170027
|
+
try {
|
|
170028
|
+
const ascending = agent?.get(HomeAssistantEntityBehavior).state.mapping?.vacuumAscendingRoomOrder === true;
|
|
170029
|
+
return ascending ? [...areas].sort((a, b) => a - b) : areas;
|
|
170030
|
+
} catch {
|
|
170031
|
+
return areas;
|
|
170032
|
+
}
|
|
170033
|
+
}
|
|
169998
170034
|
var ServiceAreaWithProgress = ServiceAreaBehavior.with(
|
|
169999
170035
|
ServiceArea3.Feature.ProgressReporting
|
|
170000
170036
|
);
|
|
@@ -170004,7 +170040,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
|
170004
170040
|
logger234.info(
|
|
170005
170041
|
`ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
|
|
170006
170042
|
);
|
|
170007
|
-
const uniqueAreas = [...new Set(newAreas)];
|
|
170043
|
+
const uniqueAreas = orderSelection([...new Set(newAreas)], this.agent);
|
|
170008
170044
|
const supportedAreaIds = this.state.supportedAreas.map((a) => a.areaId);
|
|
170009
170045
|
const invalidAreas = uniqueAreas.filter(
|
|
170010
170046
|
(id) => !supportedAreaIds.includes(id)
|
|
@@ -170063,7 +170099,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
|
|
|
170063
170099
|
logger234.info(
|
|
170064
170100
|
`ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
|
|
170065
170101
|
);
|
|
170066
|
-
const uniqueAreas = [...new Set(newAreas)];
|
|
170102
|
+
const uniqueAreas = orderSelection([...new Set(newAreas)], this.agent);
|
|
170067
170103
|
const supportedAreaIds = this.state.supportedAreas.map((a) => a.areaId);
|
|
170068
170104
|
const invalidAreas = uniqueAreas.filter(
|
|
170069
170105
|
(id) => !supportedAreaIds.includes(id)
|