21
21
import queue
22
22
import threading
23
23
import time
24
+ # from time import time
24
25
25
26
import chip .clusters as Clusters
26
27
from chip .ChipDeviceCtrl import ChipDeviceController
27
28
from chip .clusters import ClusterObjects as ClusterObjects
28
- from chip .clusters .Attribute import AttributePath , TypedAttributePath , AsyncReadTransaction
29
+ from chip .clusters .Attribute import AttributePath , TypedAttributePath , AsyncReadTransaction , SubscriptionTransaction
29
30
from chip .exceptions import ChipStackError
30
31
from chip .interaction_model import Status
31
32
from matter_testing_support import AttributeChangeCallback , MatterBaseTest , TestStep , async_test_body , default_matter_test_main , EventChangeCallback
@@ -122,6 +123,10 @@ def on_notify_subscription_still_active(self):
122
123
123
124
self .fprint (f"NotifyLogic { time .time ()} >>> t: { diff } " , "red" )
124
125
126
+ def on_notify_subscription_still_active_empty_report (self ):
127
+ self .report_data_received = True
128
+ self .empty_report_time = time .time ()
129
+
125
130
def wait_for_attribute_update_report (self , expected_attribute , output ):
126
131
try :
127
132
path , transaction = output .get (block = True , timeout = 10 )
@@ -141,127 +146,157 @@ def wait_for_attribute_update_report(self, expected_attribute, output):
141
146
except KeyError :
142
147
asserts .fail ("[AttributeChangeCallback | Local] Attribute {expected_attribute} not found in returned report" )
143
148
144
- current_report_data_time : time = 0
145
- previous_report_data_time : time = 0
146
- attr_update_report_data_time : time = 0
149
+ current_report_data_time = 0
150
+ previous_report_data_time = 0
151
+ attr_update_report_data_time = 0
147
152
148
153
min_interval_floor_sec : int = 1
149
154
max_interval_ceiling_sec : int = 3
150
155
156
+ empty_report_time = None
157
+ report_data_received = False
158
+
151
159
@async_test_body
152
160
async def test_TC_IDM_4_3 (self ):
153
161
154
162
# Test setup
155
163
# Mandatory writable attributes
156
164
node_label_attr = Clusters .BasicInformation .Attributes .NodeLabel
157
165
# bc = Clusters.GeneralCommissioning.Attributes.Breadcrumb
158
-
166
+
159
167
# Event
160
168
# acl = Clusters.AccessControl.Events.
161
-
169
+
162
170
node_label_attr_path = [(0 , node_label_attr )]
163
171
TH : ChipDeviceController = self .default_controller
164
172
165
- # *** Step 1a ***
166
- # DUT and TH activate the subscription.
173
+ # # *** Step 1a ***
174
+ # # DUT and TH activate the subscription.
167
175
self .step ("1a" )
168
176
169
- # Subscribe to attribute
170
- sub_th_step1ab = await TH .ReadAttribute (
171
- nodeid = self .dut_node_id ,
172
- attributes = node_label_attr_path ,
173
- reportInterval = (self .min_interval_floor_sec , self .max_interval_ceiling_sec ),
174
- keepSubscriptions = False
175
- )
177
+ # # Subscribe to attribute
178
+ # sub_th_step1ab = await TH.ReadAttribute(
179
+ # nodeid=self.dut_node_id,
180
+ # attributes=node_label_attr_path,
181
+ # reportInterval=(self.min_interval_floor_sec, self.max_interval_ceiling_sec),
182
+ # keepSubscriptions=False
183
+ # )
176
184
177
- sub_th_step1ab .SetNotifySubscriptionStillActiveCallback (self .on_notify_subscription_still_active )
185
+ # sub_th_step1ab.SetNotifySubscriptionStillActiveCallback(self.on_notify_subscription_still_active)
178
186
179
- secs = 15
180
- print (f"\n \n \n \n \n Time to sleep { secs } second(s)" )
181
- time .sleep (secs )
182
- print (f"Rise and shine after { secs } second(s)\n \n \n \n \n " )
187
+ # secs = 3
188
+ # print(f"\n\n\n\n\nTime to sleep {secs} second(s)")
189
+ # time.sleep(secs)
190
+ # print(f"Rise and shine after {secs} second(s)\n\n\n\n\n")
183
191
184
- # Verify that the subscription is activated between TH and DUT
185
- # Verify on the TH, a report data message is received.
186
- asserts .assert_true (sub_th_step1ab .subscriptionId , "Subscription not activated" )
192
+ # # Verify that the subscription is activated between TH and DUT
193
+ # # Verify on the TH, a report data message is received.
194
+ # asserts.assert_true(sub_th_step1ab.subscriptionId, "Subscription not activated")
187
195
188
- # Verify subscriptionId field is present
189
- asserts .assert_is_not_none (sub_th_step1ab .subscriptionId , "SubscriptionId field not present" )
196
+ # # Verify subscriptionId field is present
197
+ # asserts.assert_is_not_none(sub_th_step1ab.subscriptionId, "SubscriptionId field not present")
190
198
191
- # Verify MaxInterval field is present
192
- sub_th_step1ab_min_interval_sec , sub_th_step1ab_max_interval_sec = sub_th_step1ab .GetReportingIntervalsSeconds ()
193
- asserts .assert_is_not_none (sub_th_step1ab_max_interval_sec , "MaxInterval field not present" )
199
+ # # Verify MaxInterval field is present
200
+ # sub_th_step1ab_min_interval_sec, sub_th_step1ab_max_interval_sec = sub_th_step1ab.GetReportingIntervalsSeconds()
201
+ # asserts.assert_is_not_none(sub_th_step1ab_max_interval_sec, "MaxInterval field not present")
194
202
195
203
# *** Step 1b ***
196
204
# Change the value of the attribute which has been subscribed on the DUT by manually changing some
197
205
# settings on the device. Example: Temperature sensor may update the value of the room temperature.
198
206
# Turning on/off on a light bulb.
199
207
self .step ("1b" )
200
208
201
- # Set Attribute Update Callback
202
- node_label_update_cb = AttributeChangeCallback (node_label_attr )
203
- sub_th_step1ab .SetAttributeUpdateCallback (node_label_update_cb )
209
+ # # Set Attribute Update Callback
210
+ # node_label_update_cb = AttributeChangeCallback(node_label_attr)
211
+ # sub_th_step1ab.SetAttributeUpdateCallback(node_label_update_cb)
204
212
205
- # Update attribute value
206
- new_node_label_write = "NewNodeLabel_11001100"
207
- await TH .WriteAttribute (
208
- self .dut_node_id ,
209
- [(0 , node_label_attr (value = new_node_label_write ))]
210
- )
213
+ # # Update attribute value
214
+ # new_node_label_write = "NewNodeLabel_11001100"
215
+ # await TH.WriteAttribute(
216
+ # self.dut_node_id,
217
+ # [(0, node_label_attr(value=new_node_label_write))]
218
+ # )
211
219
212
- self .wait_for_attribute_update_report (node_label_attr , node_label_update_cb ._output )
220
+ # self.wait_for_attribute_update_report(node_label_attr, node_label_update_cb._output)
213
221
214
- # Number of seconds elapsed between the last report data event
215
- # and the arrival of the attribute update report data
216
- elapsed_time_since_report = self .attr_update_report_data_time - self .previous_report_data_time
222
+ # # Number of seconds elapsed between the last report data event
223
+ # # and the arrival of the attribute update report data
224
+ # elapsed_time_since_report = self.attr_update_report_data_time - self.previous_report_data_time
217
225
226
+ # # Convert the current time to a datetime object
227
+ # update_time = datetime.fromtimestamp(self.attr_update_report_data_time)
228
+ # previous_time = datetime.fromtimestamp(self.previous_report_data_time)
218
229
219
- # Convert the current time to a datetime object
220
- update_time = datetime . fromtimestamp ( self . attr_update_report_data_time )
221
- previous_time = datetime . fromtimestamp ( self . previous_report_data_time )
230
+ # # Format the datetime object into the desired string format
231
+ # update_time_f = update_time.strftime("%H:%M:%S.%f" )
232
+ # previous_time_f = previous_time.strftime("%H:%M:%S.%f" )
222
233
223
- # Format the datetime object into the desired string format
224
- update_time_f = update_time .strftime ("%H:%M:%S.%f" )
225
- previous_time_f = previous_time .strftime ("%H:%M:%S.%f" )
234
+ # self.fprint(f"\n\n\t\elapsed_time_since_report: {elapsed_time_since_report}s\n\t\tattr_update_report_data_time: {update_time_f}s\n\t\tprevious_report_data_time: {previous_time_f}s\n\n", "green")
226
235
227
- self .fprint (f"\n \n \t \elapsed_time_since_report: { elapsed_time_since_report } s\n \t \t attr_update_report_data_time: { update_time_f } s\n \t \t previous_report_data_time: { previous_time_f } s\n \n " , "green" )
236
+ # # Verify that the attribute update report data is sent
237
+ # # after MinInterval time and before MaxInterval time
238
+ # asserts.assert_greater(elapsed_time_since_report, self.min_interval_floor_sec,
239
+ # f"Attribute update report data must be sent after the MinInterval")
240
+ # asserts.assert_less(elapsed_time_since_report, self.max_interval_ceiling_sec,
241
+ # f"Attribute update report data must be sent before the MaxInterval")
228
242
229
- # Verify that the attribute update report data is sent
230
- # after MinInterval time and before MaxInterval time
231
- asserts .assert_greater (elapsed_time_since_report , self .min_interval_floor_sec ,
232
- f"Attribute update report data must be sent after the MinInterval" )
233
- asserts .assert_less (elapsed_time_since_report , self .max_interval_ceiling_sec ,
234
- f"Attribute update report data must be sent before the MaxInterval" )
243
+ # sub_th_step1ab.Shutdown()
235
244
236
- sub_th_step1ab .Shutdown ()
237
-
238
245
# DUT and TH activate the subscription. Change the value of the attribute which has been
239
246
# subscribed on the DUT by sending an IMWrite or Invoke message to the DUT from the TH.
240
247
# Verify that there is a report data message sent from the DUT for the changed value of
241
248
# the attribute. Verify that the Report Data is sent when the minimum interval time is
242
249
# reached and before the MaxInterval time.
243
250
self .step (2 )
244
-
251
+
245
252
# DUT and TH activate the subscription for an attribute. Do not change the value of the
246
253
# attribute which has been subscribed. Verify that there is an empty report data message
247
254
# sent from the DUT to the TH after the MinInterval time and no later than the
248
255
# MaxInterval time plus an additional duration equal to the total retransmission time
249
256
# according to negotiated MRP parameters.
250
257
self .step (3 )
251
-
258
+
252
259
# Subscribe to attribute
253
- sub_th_step3 = await TH .ReadAttribute (
260
+ sub_th_step3 : SubscriptionTransaction = await TH .ReadAttribute (
254
261
nodeid = self .dut_node_id ,
255
262
attributes = node_label_attr_path ,
256
263
reportInterval = (self .min_interval_floor_sec , self .max_interval_ceiling_sec ),
257
264
keepSubscriptions = False
258
265
)
259
-
260
-
266
+
267
+ # Record time after subscription
268
+ sub_time = time .time ()
269
+
270
+ # Get subscription timeout
271
+ sub_timeout_sec = sub_th_step3 .GetSubscriptionTimeoutMs () / 1000
272
+
273
+ # Records the time the first empty report after subscription arrives
274
+ sub_th_step3 .SetNotifySubscriptionStillActiveCallback (self .on_notify_subscription_still_active_empty_report )
275
+
276
+ # Waint for empty report data
277
+ wait_increments = self .min_interval_floor_sec / 10
278
+ while not self .report_data_received :
279
+ time .sleep (wait_increments )
280
+ self .fprint (f"Time: { time .time ()} " , "blue" )
281
+ self .fprint (f"Empty Rport time: { self .empty_report_time } " , "green" )
282
+ if self .report_data_received :
283
+ break
284
+
285
+ # Elapsed time between subscription established and first report data
286
+ sub_report_data_elapsed_time = self .empty_report_time - sub_time
287
+
288
+ self .fprint (f"min_interval_floor_sec: { self .min_interval_floor_sec } " , "red" )
289
+ self .fprint (f"sub_report_data_elapsed_time: { sub_report_data_elapsed_time } " , "red" )
290
+ self .fprint (f"sub_timeout_sec: { sub_timeout_sec } " , "red" )
291
+
292
+ # Verify that the empty report data message from the DUT to the TH was sent
293
+ # after the MinInterval time and no later than the MaxInterval time plus an
294
+ # additional duration equal to the total retransmission time according to
295
+ # negotiated MRP parameters
296
+ asserts .assert_greater (sub_report_data_elapsed_time , self .min_interval_floor_sec , "Empty report not received after the MinInterval time" )
297
+ asserts .assert_less (sub_report_data_elapsed_time , sub_timeout_sec , "Empty report not received before the MaxInterval time" )
298
+
261
299
sub_th_step3 .Shutdown ()
262
-
263
-
264
-
265
300
266
301
267
302
if __name__ == "__main__" :
0 commit comments