@@ -1503,15 +1503,20 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray<NSDictionary<NSSt
1503
1503
1504
1504
NSMutableArray * attributesToReport = [NSMutableArray array ];
1505
1505
NSMutableArray * attributePathsToReport = [NSMutableArray array ];
1506
- for (NSDictionary <NSString *, id > * attributeReponseValue in reportedAttributeValues) {
1507
- MTRAttributePath * attributePath = attributeReponseValue[MTRAttributePathKey];
1508
- NSDictionary * attributeDataValue = attributeReponseValue[MTRDataKey];
1509
- NSError * attributeError = attributeReponseValue[MTRErrorKey];
1506
+ BOOL dataStoreExists = _deviceController.controllerDataStore != nil ;
1507
+ NSMutableArray * attributesToPersist;
1508
+ if (dataStoreExists) {
1509
+ attributesToPersist = [NSMutableArray array ];
1510
+ }
1511
+ for (NSDictionary <NSString *, id > * attributeResponseValue in reportedAttributeValues) {
1512
+ MTRAttributePath * attributePath = attributeResponseValue[MTRAttributePathKey];
1513
+ NSDictionary * attributeDataValue = attributeResponseValue[MTRDataKey];
1514
+ NSError * attributeError = attributeResponseValue[MTRErrorKey];
1510
1515
NSDictionary * previousValue;
1511
1516
1512
1517
// sanity check either data value or error must exist
1513
1518
if (!attributeDataValue && !attributeError) {
1514
- MTR_LOG_INFO (" %@ report %@ no data value or error: %@" , self, attributePath, attributeReponseValue );
1519
+ MTR_LOG_INFO (" %@ report %@ no data value or error: %@" , self, attributePath, attributeResponseValue );
1515
1520
continue ;
1516
1521
}
1517
1522
@@ -1532,6 +1537,12 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray<NSDictionary<NSSt
1532
1537
previousValue = _readCache[attributePath];
1533
1538
_readCache[attributePath] = nil ;
1534
1539
} else {
1540
+ BOOL readCacheValueChanged = ![self _attributeDataValue: attributeDataValue isEqualToDataValue: _readCache[attributePath]];
1541
+ // Check if attribute needs to be persisted - compare only to read cache and disregard expected values
1542
+ if (dataStoreExists && readCacheValueChanged) {
1543
+ [attributesToPersist addObject: attributeResponseValue];
1544
+ }
1545
+
1535
1546
// if expected values exists, purge and update read cache
1536
1547
NSArray * expectedValue = _expectedValueCache[attributePath];
1537
1548
if (expectedValue) {
@@ -1542,7 +1553,7 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray<NSDictionary<NSSt
1542
1553
}
1543
1554
_expectedValueCache[attributePath] = nil ;
1544
1555
_readCache[attributePath] = attributeDataValue;
1545
- } else if (![ self _attributeDataValue: attributeDataValue isEqualToDataValue: _readCache[attributePath]] ) {
1556
+ } else if (readCacheValueChanged ) {
1546
1557
// otherwise compare and update read cache
1547
1558
previousValue = _readCache[attributePath];
1548
1559
_readCache[attributePath] = attributeDataValue;
@@ -1580,21 +1591,40 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray<NSDictionary<NSSt
1580
1591
1581
1592
if (shouldReportAttribute) {
1582
1593
if (previousValue) {
1583
- NSMutableDictionary * mutableAttributeReponseValue = attributeReponseValue .mutableCopy ;
1584
- mutableAttributeReponseValue [MTRPreviousDataKey] = previousValue;
1585
- [attributesToReport addObject: mutableAttributeReponseValue ];
1594
+ NSMutableDictionary * mutableAttributeResponseValue = attributeResponseValue .mutableCopy ;
1595
+ mutableAttributeResponseValue [MTRPreviousDataKey] = previousValue;
1596
+ [attributesToReport addObject: mutableAttributeResponseValue ];
1586
1597
} else {
1587
- [attributesToReport addObject: attributeReponseValue ];
1598
+ [attributesToReport addObject: attributeResponseValue ];
1588
1599
}
1589
1600
[attributePathsToReport addObject: attributePath];
1590
1601
}
1591
1602
}
1592
1603
1593
1604
MTR_LOG_INFO (" %@ report from reported values %@" , self, attributePathsToReport);
1594
1605
1606
+ if (dataStoreExists && attributesToPersist.count ) {
1607
+ [_deviceController.controllerDataStore storeAttributeValues: attributesToPersist forNodeID: _nodeID];
1608
+ }
1609
+
1595
1610
return attributesToReport;
1596
1611
}
1597
1612
1613
+ - (void )setAttributeValues : (NSArray <NSDictionary *> *)attributeValues reportChanges : (BOOL )reportChanges
1614
+ {
1615
+ if (reportChanges) {
1616
+ [self _handleAttributeReport: attributeValues];
1617
+ } else {
1618
+ os_unfair_lock_lock (&self->_lock );
1619
+ for (NSDictionary * responseValue in attributeValues) {
1620
+ MTRAttributePath * path = responseValue[MTRAttributePathKey];
1621
+ NSDictionary * dataValue = responseValue[MTRDataKey];
1622
+ _readCache[path] = dataValue;
1623
+ }
1624
+ os_unfair_lock_unlock (&self->_lock );
1625
+ }
1626
+ }
1627
+
1598
1628
// If value is non-nil, associate with expectedValueID
1599
1629
// If value is nil, remove only if expectedValueID matches
1600
1630
// previousValue is an out parameter
@@ -1662,9 +1692,9 @@ - (NSArray *)_getAttributesToReportWithNewExpectedValues:(NSArray<NSDictionary<N
1662
1692
1663
1693
NSMutableArray * attributesToReport = [NSMutableArray array ];
1664
1694
NSMutableArray * attributePathsToReport = [NSMutableArray array ];
1665
- for (NSDictionary <NSString *, id > * attributeReponseValue in expectedAttributeValues) {
1666
- MTRAttributePath * attributePath = attributeReponseValue [MTRAttributePathKey];
1667
- NSDictionary * attributeDataValue = attributeReponseValue [MTRDataKey];
1695
+ for (NSDictionary <NSString *, id > * attributeResponseValue in expectedAttributeValues) {
1696
+ MTRAttributePath * attributePath = attributeResponseValue [MTRAttributePathKey];
1697
+ NSDictionary * attributeDataValue = attributeResponseValue [MTRDataKey];
1668
1698
1669
1699
BOOL shouldReportValue = NO ;
1670
1700
NSDictionary <NSString *, id > * attributeValueToReport;
0 commit comments