@@ -178,29 +178,6 @@ def run(self):
178
178
TestFail ("Timeout" , doCrash = True )
179
179
180
180
181
- class TestResult :
182
- def __init__ (self , operationName , result ):
183
- self .operationName = operationName
184
- self .result = result
185
-
186
- def assertStatusEqual (self , expected ):
187
- if self .result is None :
188
- raise Exception (f"{ self .operationName } : no result got" )
189
- if self .result .status != expected :
190
- raise Exception (
191
- f"{ self .operationName } : expected status { expected } , got { self .result .status } " )
192
- return self
193
-
194
- def assertValueEqual (self , expected ):
195
- self .assertStatusEqual (0 )
196
- if self .result is None :
197
- raise Exception (f"{ self .operationName } : no result got" )
198
- if self .result .value != expected :
199
- raise Exception (
200
- f"{ self .operationName } : expected value { expected } , got { self .result .value } " )
201
- return self
202
-
203
-
204
181
class BaseTestHelper :
205
182
def __init__ (self , nodeid : int , paaTrustStorePath : str , testCommissioner : bool = False ,
206
183
keypair : p256keypair .P256Keypair = None ):
@@ -368,15 +345,16 @@ def TestOnNetworkCommissioning(self, discriminator: int, setuppin: int, nodeid:
368
345
def TestUsedTestCommissioner (self ):
369
346
return self .devCtrl .GetTestCommissionerUsed ()
370
347
371
- def TestFailsafe (self , nodeid : int ):
348
+ async def TestFailsafe (self , nodeid : int ):
372
349
self .logger .info ("Testing arm failsafe" )
373
350
374
351
self .logger .info ("Setting failsafe on CASE connection" )
375
- err , resp = self .devCtrl .ZCLSend ("GeneralCommissioning" , "ArmFailSafe" , nodeid ,
376
- 0 , 0 , dict (expiryLengthSeconds = 60 , breadcrumb = 1 ), blocking = True )
377
- if err != 0 :
352
+ try :
353
+ resp = await self .devCtrl .SendCommand (nodeid , 0 ,
354
+ Clusters .GeneralCommissioning .Commands .ArmFailSafe (expiryLengthSeconds = 60 , breadcrumb = 1 ))
355
+ except IM .InteractionModelError as ex :
378
356
self .logger .error (
379
- "Failed to send arm failsafe command error is {} with im response{} " .format (err , resp ))
357
+ "Failed to send arm failsafe command error is {}" .format (ex . status ))
380
358
return False
381
359
382
360
if resp .errorCode is not Clusters .GeneralCommissioning .Enums .CommissioningErrorEnum .kOk :
@@ -387,17 +365,17 @@ def TestFailsafe(self, nodeid: int):
387
365
self .logger .info (
388
366
"Attempting to open basic commissioning window - this should fail since the failsafe is armed" )
389
367
try :
390
- asyncio . run ( self .devCtrl .SendCommand (
368
+ await self .devCtrl .SendCommand (
391
369
nodeid ,
392
370
0 ,
393
371
Clusters .AdministratorCommissioning .Commands .OpenBasicCommissioningWindow (180 ),
394
372
timedRequestTimeoutMs = 10000
395
- ))
373
+ )
396
374
# we actually want the exception here because we want to see a failure, so return False here
397
375
self .logger .error (
398
376
'Incorrectly succeeded in opening basic commissioning window' )
399
377
return False
400
- except Exception :
378
+ except IM . InteractionModelError :
401
379
pass
402
380
403
381
# TODO:
@@ -413,51 +391,52 @@ def TestFailsafe(self, nodeid: int):
413
391
self .logger .info (
414
392
"Attempting to open enhanced commissioning window - this should fail since the failsafe is armed" )
415
393
try :
416
- asyncio . run ( self .devCtrl .SendCommand (
394
+ await self .devCtrl .SendCommand (
417
395
nodeid , 0 , Clusters .AdministratorCommissioning .Commands .OpenCommissioningWindow (
418
396
commissioningTimeout = 180 ,
419
397
PAKEPasscodeVerifier = verifier ,
420
398
discriminator = discriminator ,
421
399
iterations = iterations ,
422
- salt = salt ), timedRequestTimeoutMs = 10000 ))
400
+ salt = salt ), timedRequestTimeoutMs = 10000 )
423
401
424
402
# we actually want the exception here because we want to see a failure, so return False here
425
403
self .logger .error (
426
404
'Incorrectly succeeded in opening enhanced commissioning window' )
427
405
return False
428
- except Exception :
406
+ except IM . InteractionModelError :
429
407
pass
430
408
431
409
self .logger .info ("Disarming failsafe on CASE connection" )
432
- err , resp = self .devCtrl .ZCLSend ("GeneralCommissioning" , "ArmFailSafe" , nodeid ,
433
- 0 , 0 , dict (expiryLengthSeconds = 0 , breadcrumb = 1 ), blocking = True )
434
- if err != 0 :
410
+ try :
411
+ resp = await self .devCtrl .SendCommand (nodeid , 0 ,
412
+ Clusters .GeneralCommissioning .Commands .ArmFailSafe (expiryLengthSeconds = 0 , breadcrumb = 1 ))
413
+ except IM .InteractionModelError as ex :
435
414
self .logger .error (
436
- "Failed to send arm failsafe command error is {} with im response{} " .format (err , resp ))
415
+ "Failed to send arm failsafe command error is {}" .format (ex . status ))
437
416
return False
438
417
439
418
self .logger .info (
440
419
"Opening Commissioning Window - this should succeed since the failsafe was just disarmed" )
441
420
try :
442
- asyncio .run (
443
- self .devCtrl .SendCommand (
444
- nodeid ,
445
- 0 ,
446
- Clusters .AdministratorCommissioning .Commands .OpenBasicCommissioningWindow (180 ),
447
- timedRequestTimeoutMs = 10000
448
- ))
421
+ await self .devCtrl .SendCommand (
422
+ nodeid ,
423
+ 0 ,
424
+ Clusters .AdministratorCommissioning .Commands .OpenBasicCommissioningWindow (180 ),
425
+ timedRequestTimeoutMs = 10000
426
+ )
449
427
except Exception :
450
428
self .logger .error (
451
429
'Failed to open commissioning window after disarming failsafe' )
452
430
return False
453
431
454
432
self .logger .info (
455
433
"Attempting to arm failsafe over CASE - this should fail since the commissioning window is open" )
456
- err , resp = self .devCtrl .ZCLSend ("GeneralCommissioning" , "ArmFailSafe" , nodeid ,
457
- 0 , 0 , dict (expiryLengthSeconds = 60 , breadcrumb = 1 ), blocking = True )
458
- if err != 0 :
434
+ try :
435
+ resp = await self .devCtrl .SendCommand (nodeid , 0 ,
436
+ Clusters .GeneralCommissioning .Commands .ArmFailSafe (expiryLengthSeconds = 60 , breadcrumb = 1 ))
437
+ except IM .InteractionModelError as ex :
459
438
self .logger .error (
460
- "Failed to send arm failsafe command error is {} with im response{} " .format (err , resp ))
439
+ "Failed to send arm failsafe command error is {}" .format (ex . status ))
461
440
return False
462
441
if resp .errorCode is Clusters .GeneralCommissioning .Enums .CommissioningErrorEnum .kBusyWithOtherAdmin :
463
442
return True
@@ -1095,50 +1074,48 @@ def SetNetworkCommissioningParameters(self, dataset: str):
1095
1074
self .devCtrl .SetThreadOperationalDataset (bytes .fromhex (dataset ))
1096
1075
return True
1097
1076
1098
- def TestOnOffCluster (self , nodeid : int , endpoint : int , group : int ):
1077
+ async def TestOnOffCluster (self , nodeid : int , endpoint : int ):
1099
1078
self .logger .info (
1100
1079
"Sending On/Off commands to device {} endpoint {}" .format (nodeid , endpoint ))
1101
- err , resp = self .devCtrl .ZCLSend ("OnOff" , "On" , nodeid ,
1102
- endpoint , group , {}, blocking = True )
1103
- if err != 0 :
1080
+
1081
+ try :
1082
+ await self .devCtrl .SendCommand (nodeid , endpoint ,
1083
+ Clusters .OnOff .Commands .On ())
1084
+ except IM .InteractionModelError as ex :
1104
1085
self .logger .error (
1105
- "failed to send OnOff.On: error is {} with im response{} " .format (err , resp ))
1086
+ "failed to send OnOff.On: error is {}" .format (ex . status ))
1106
1087
return False
1107
- err , resp = self .devCtrl .ZCLSend ("OnOff" , "Off" , nodeid ,
1108
- endpoint , group , {}, blocking = True )
1109
- if err != 0 :
1088
+
1089
+ try :
1090
+ await self .devCtrl .SendCommand (nodeid , endpoint ,
1091
+ Clusters .OnOff .Commands .Off ())
1092
+ except IM .InteractionModelError as ex :
1110
1093
self .logger .error (
1111
- "failed to send OnOff.Off: error is {} with im response {} " .format (err , resp ))
1094
+ "failed to send OnOff.Off: error is {}" .format (ex . status ))
1112
1095
return False
1113
1096
return True
1114
1097
1115
- def TestLevelControlCluster (self , nodeid : int , endpoint : int , group : int ):
1098
+ async def TestLevelControlCluster (self , nodeid : int , endpoint : int ):
1116
1099
self .logger .info (
1117
1100
f"Sending MoveToLevel command to device { nodeid } endpoint { endpoint } " )
1118
- try :
1119
- commonArgs = dict (transitionTime = 0 , optionsMask = 1 , optionsOverride = 1 )
1120
1101
1102
+ commonArgs = dict (transitionTime = 0 , optionsMask = 1 , optionsOverride = 1 )
1103
+
1104
+ async def _moveClusterLevel (setLevel ):
1105
+ await self .devCtrl .SendCommand (nodeid ,
1106
+ endpoint ,
1107
+ Clusters .LevelControl .Commands .MoveToLevel (** commonArgs , level = setLevel ))
1108
+ res = await self .devCtrl .ReadAttribute (nodeid , [(endpoint , Clusters .LevelControl .Attributes .CurrentLevel )])
1109
+ readVal = res [endpoint ][Clusters .LevelControl ][Clusters .LevelControl .Attributes .CurrentLevel ]
1110
+ if readVal != setLevel :
1111
+ raise Exception (f"Read attribute LevelControl.CurrentLevel: expected value { setLevel } , got { readVal } " )
1112
+
1113
+ try :
1121
1114
# Move to 1
1122
- self .devCtrl .ZCLSend ("LevelControl" , "MoveToLevel" , nodeid ,
1123
- endpoint , group , dict (** commonArgs , level = 1 ), blocking = True )
1124
- res = self .devCtrl .ZCLReadAttribute (cluster = "LevelControl" ,
1125
- attribute = "CurrentLevel" ,
1126
- nodeid = nodeid ,
1127
- endpoint = endpoint ,
1128
- groupid = group )
1129
- TestResult ("Read attribute LevelControl.CurrentLevel" ,
1130
- res ).assertValueEqual (1 )
1115
+ await _moveClusterLevel (1 )
1131
1116
1132
1117
# Move to 254
1133
- self .devCtrl .ZCLSend ("LevelControl" , "MoveToLevel" , nodeid ,
1134
- endpoint , group , dict (** commonArgs , level = 254 ), blocking = True )
1135
- res = self .devCtrl .ZCLReadAttribute (cluster = "LevelControl" ,
1136
- attribute = "CurrentLevel" ,
1137
- nodeid = nodeid ,
1138
- endpoint = endpoint ,
1139
- groupid = group )
1140
- TestResult ("Read attribute LevelControl.CurrentLevel" ,
1141
- res ).assertValueEqual (254 )
1118
+ await _moveClusterLevel (254 )
1142
1119
1143
1120
return True
1144
1121
except Exception as ex :
@@ -1171,29 +1148,27 @@ def TestResolve(self, nodeid):
1171
1148
self .logger .exception ("Failed to resolve. {}" .format (ex ))
1172
1149
return False
1173
1150
1174
- def TestReadBasicAttributes (self , nodeid : int , endpoint : int , group : int ):
1151
+ async def TestReadBasicAttributes (self , nodeid : int , endpoint : int ):
1152
+ attrs = Clusters .BasicInformation .Attributes
1175
1153
basic_cluster_attrs = {
1176
- " VendorName" : "TEST_VENDOR" ,
1177
- " VendorID" : 0xFFF1 ,
1178
- " ProductName" : "TEST_PRODUCT" ,
1179
- " ProductID" : 0x8001 ,
1180
- " NodeLabel" : "Test" ,
1181
- " Location" : "XX" ,
1182
- " HardwareVersion" : 0 ,
1183
- " HardwareVersionString" : "TEST_VERSION" ,
1184
- " SoftwareVersion" : 1 ,
1185
- " SoftwareVersionString" : "1.0" ,
1154
+ attrs . VendorName : "TEST_VENDOR" ,
1155
+ attrs . VendorID : 0xFFF1 ,
1156
+ attrs . ProductName : "TEST_PRODUCT" ,
1157
+ attrs . ProductID : 0x8001 ,
1158
+ attrs . NodeLabel : "Test" ,
1159
+ attrs . Location : "XX" ,
1160
+ attrs . HardwareVersion : 0 ,
1161
+ attrs . HardwareVersionString : "TEST_VERSION" ,
1162
+ attrs . SoftwareVersion : 1 ,
1163
+ attrs . SoftwareVersionString : "1.0" ,
1186
1164
}
1187
1165
failed_zcl = {}
1188
1166
for basic_attr , expected_value in basic_cluster_attrs .items ():
1189
1167
try :
1190
- res = self .devCtrl .ZCLReadAttribute (cluster = "BasicInformation" ,
1191
- attribute = basic_attr ,
1192
- nodeid = nodeid ,
1193
- endpoint = endpoint ,
1194
- groupid = group )
1195
- TestResult (f"Read attribute { basic_attr } " , res ).assertValueEqual (
1196
- expected_value )
1168
+ res = await self .devCtrl .ReadAttribute (nodeid , [(endpoint , basic_attr )])
1169
+ readVal = res [endpoint ][Clusters .BasicInformation ][basic_attr ]
1170
+ if readVal != expected_value :
1171
+ raise Exception (f"Read attribute: expected value { expected_value } , got { readVal } " )
1197
1172
except Exception as ex :
1198
1173
failed_zcl [basic_attr ] = str (ex )
1199
1174
if failed_zcl :
@@ -1217,16 +1192,16 @@ class AttributeWriteRequest:
1217
1192
failed_attribute_write = []
1218
1193
for req in requests :
1219
1194
try :
1220
- try :
1221
- await self .devCtrl .WriteAttribute (nodeid , [(endpoint , req .attribute , 0 )])
1222
- if req . expected_status != IM .Status . Success :
1223
- raise AssertionError (
1224
- f"Write attribute { req . attribute . __qualname__ } expects failure but got success response" )
1225
- except Exception as ex :
1226
- if req . expected_status != IM . Status . Success :
1227
- continue
1228
- else :
1229
- raise ex
1195
+ # Errors tested here is in the per-attribute result list (type AttributeStatus)
1196
+ write_res = await self .devCtrl .WriteAttribute (nodeid , [(endpoint , req .attribute ( req . value ) )])
1197
+ status = write_res [ 0 ] .Status
1198
+ if req . expected_status != status :
1199
+ raise AssertionError (
1200
+ f"Write attribute { req . attribute . __qualname__ } expects { req . expected_status } but got { status } " )
1201
+
1202
+ # Only execute read tests where write is successful.
1203
+ if req . expected_status != IM . Status . Success :
1204
+ continue
1230
1205
1231
1206
res = await self .devCtrl .ReadAttribute (nodeid , [(endpoint , req .attribute )])
1232
1207
val = res [endpoint ][req .cluster ][req .attribute ]
0 commit comments