@@ -3,135 +3,112 @@ import {
33 type PromptContext ,
44 type PromptResponse ,
55} from "../../prompt-handlers.ts" ;
6+ import type {
7+ DUTCapabilityId ,
8+ CCCapabilityQueryMessage ,
9+ } from "../../../../src/ctt-message-types.ts" ;
610
7- const questions : {
8- pattern : RegExp ;
9- answer : PromptResponse | ( ( ctx : PromptContext ) => PromptResponse ) ;
10- } [ ] = [
11- { pattern : / a l l o w s t h e e n d u s e r t o e s t a b l i s h a s s o c i a t i o n / i, answer : "No" } ,
12- { pattern : / ( c a p a b l e | a b l e ) t o d i s p l a y t h e l a s t .+ s t a t e / i, answer : "Yes" } ,
13- {
14- pattern : / ( D U T ' s U I | c u r r e n t .+ s t a t e | v i s u a l i [ s z ] a t i o n ) .+ i s v i s i b l e / i,
15- answer : "Ok" ,
16- } ,
17- { pattern : / i c o n t y p e .+ m a t c h t h e a c t u a l d e v i c e / i, answer : "Yes" } ,
18- {
19- pattern : / D o e s t h e D U T u s e t h e i d e n t i f y c o m m a n d f o r a n y o t h e r p u r p o s e / i,
20- answer : "No" ,
21- } ,
22- { pattern : / a b l e t o s e n d a S t a r t \/ S t o p L e v e l C h a n g e / i, answer : "Yes" } ,
23- {
24- pattern : / a l l o w t o s e t a d i m m i n g ' D u r a t i o n ' f o r ' S e t t i n g t h e L e v e l ' / i,
25- answer : "Yes" ,
26- } ,
27- {
28- pattern :
29- / a l l o w t o s e t a ( ' S t a r t L e v e l ' | d i m m i n g ' D u r a t i o n ' ) f o r ' ( S t a r t | S t o p ) L e v e l C h a n g e ' / i,
30- answer : "Yes" ,
31- } ,
32- {
33- pattern :
34- / a c t i v a t e a n d d e a c t i v a t e t h e ' ( a u d i b l e | v i s u a l ) n o t i f i c a t i o n ' s u b s y s t e m / i,
35- answer : "Yes" ,
36- } ,
37- {
38- pattern : / D o e s t h e D U T c o n t r o l .+ C O M M A N D _ C L A S S _ B A S I C .+ v e r s i o n 1 / i,
39- answer : "Yes" ,
40- } ,
41- {
42- pattern : / D o e s t h e D U T c o n t r o l .+ C O M M A N D _ C L A S S _ I N D I C A T O R .+ v e r s i o n 3 / i,
43- answer : "Yes" ,
44- } ,
45- {
46- pattern : / D o e s t h e D U T c o n t r o l .+ C O M M A N D _ C L A S S _ V E R S I O N .+ v e r s i o n 2 / i,
47- answer : "Yes" ,
48- } ,
49- {
50- pattern : / D o e s t h e D U T c o n t r o l .+ C O M M A N D _ C L A S S _ W A K E _ U P .+ v e r s i o n 2 / i,
51- answer : "Yes" ,
11+ // DUT capability responses by capabilityId
12+ const dutCapabilityResponses : Record <
13+ DUTCapabilityId ,
14+ PromptResponse | ( ( ctx : PromptContext ) => PromptResponse )
15+ > = {
16+ ESTABLISH_ASSOCIATION : "No" ,
17+ DISPLAY_LAST_STATE : "Yes" ,
18+ QR_CODE : "Yes" ,
19+ LEARN_MODE : "No" ,
20+ LEARN_MODE_ACCESSIBLE : "No" ,
21+ FACTORY_RESET : "Yes" ,
22+ REMOVE_FAILED_NODE : "Yes" ,
23+ ICON_TYPE_MATCH : "Yes" ,
24+ IDENTIFY_OTHER_PURPOSE : "No" ,
25+ CONTROLS_UNLISTED_CCS : "No" ,
26+ ALL_DOCUMENTED_AS_CONTROLLED : "Yes" ,
27+ PARTIAL_CONTROL_DOCUMENTED : ( ctx ) => {
28+ // Entry Control CC and User Code CC is marked as partial control in the certification portal
29+ if (
30+ ctx . testName . includes ( "CCR_EntryControlCC" ) ||
31+ ctx . testName . includes ( "CCR_UserCodeCC" )
32+ ) {
33+ return "Yes" ;
34+ }
35+ return "No" ;
5236 } ,
53- { pattern : / p r o v i d e a Q R C o d e s c a n n i n g c a p a b i l i t y / i, answer : "Yes" } ,
54- { pattern : / c a n b e r e s e t t o f a c t o r y s e t t i n g s / i, answer : "Yes" } ,
55- { pattern : / D o e s t h e D U T s u p p o r t L e a r n M o d e / i, answer : "No" } ,
56- { pattern : / I s t h e L e a r n M o d e a c c e s s i b l e / i, answer : "No" } ,
57- { pattern : / l o c k o r u n l o c k t h e A n t i - T h e f t f e a t u r e / i, answer : "No" } ,
58- { pattern : / o f f e r i n g a p o s s i b i l i t y t o r e m o v e t h e f a i l e d / i, answer : "Yes" } ,
37+ MAINS_POWERED : "Yes" ,
38+ } ;
5939
60- // Command Class Control
61- {
62- pattern : / c o n t r o l a n y f u r t h e r C o m m a n d C l a s s e s w h i c h a r e n o t l i s t e d / i,
63- answer : "No" ,
64- } ,
65- {
66- pattern : / A r e a l l o f t h e m c o r r e c t l y d o c u m e n t e d a s c o n t r o l l e d / i,
67- answer : "Yes" ,
68- } ,
40+ // CC capability responses by commandClass and capabilityId
41+ type CCCapabilityKey = `${string } :${string } `;
42+ const ccCapabilityResponses : Record <
43+ CCCapabilityKey ,
44+ PromptResponse | ( ( msg : CCCapabilityQueryMessage ) => PromptResponse )
45+ > = {
46+ // Multilevel Switch capabilities
47+ "Multilevel Switch:START_STOP_LEVEL_CHANGE" : "Yes" ,
48+ "Multilevel Switch:SET_DIMMING_DURATION" : "Yes" ,
49+ "Multilevel Switch:SET_LEVEL_CHANGE_PARAMS" : "Yes" ,
6950
70- // Door Lock
71- {
72- pattern : / c o n f i g u r e t h e d o o r h a n d l e s o f a v [ 1 4 ] s u p p o r t i n g e n d n o d e / i,
73- answer : "Yes" ,
74- } ,
51+ // Barrier Operator capabilities
52+ "Barrier Operator:CONTROL_EVENT_SIGNALING" : "Yes" ,
7553
76- // Configuration CC
77- {
78- pattern : / a l l o w t o r e s e t o n e p a r t i c u l a r c o n f i g u r a t i o n p a r a m e t e r / i,
79- answer : "Yes" ,
80- } ,
54+ // Anti-Theft capabilities
55+ "Anti-Theft:LOCK_UNLOCK" : "No" ,
8156
82- // Notification CC
83- {
84- pattern :
85- / a l l o w t o c r e a t e r u l e s o r c o m m a n d s b a s e d o n r e c e i v e d n o t i f i c a t i o n s / i,
86- answer : "Yes" ,
87- } ,
88- {
89- pattern : / c a p a b i l i t y t o u p d a t e i t s N o t i f i c a t i o n l i s t / i,
90- answer : "Yes" ,
91- } ,
57+ // Door Lock capabilities
58+ "Door Lock:CONFIGURE_DOOR_HANDLES" : "Yes" ,
9259
93- // Notification Report verification ready
94- {
95- pattern : / v e r i f i e s i f t h e D U T d i s p l a y s .+ N o t i f i c a t i o n R e p o r t .+ c l i c k ' O K ' / i,
96- answer : "Ok" ,
97- } ,
60+ // Configuration capabilities
61+ "Configuration:RESET_SINGLE_PARAM" : "Yes" ,
9862
99- // User Code CC
100- { pattern : / a b l e t o ( m o d i f y | e r a s e | a d d ) .+ U s e r C o d e / i, answer : "Yes" } ,
101- { pattern : / a b l e t o s e t t h e K e y p a d M o d e / i, answer : "Yes" } ,
102- { pattern : / a b l e t o ( s e t | d i s a b l e ) .+ A d m i n C o d e / i, answer : "Yes" } ,
63+ // Notification capabilities
64+ "Notification:CREATE_RULES_FROM_NOTIFICATIONS" : "Yes" ,
65+ "Notification:UPDATE_NOTIFICATION_LIST" : "Yes" ,
10366
104- // Entry Control CC
105- { pattern : / a b l e t o c o n f i g u r e t h e k e y p a d / i, answer : "Yes" } ,
67+ // User Code capabilities
68+ "User Code:MODIFY_USER_CODE" : "Yes" ,
69+ "User Code:SET_KEYPAD_MODE" : "Yes" ,
70+ "User Code:SET_ADMIN_CODE" : "Yes" ,
10671
107- // Multilevel Sensor CC
108- {
109- pattern : / n a v i g a t e t o ' [ ^ ' ] + ' o n D U T ' s U I a n d m a k e ' [ ^ ' ] + ' s c a l e v i s i b l e / i,
110- answer : "Ok" ,
111- } ,
72+ // Entry Control capabilities
73+ "Entry Control:CONFIGURE_KEYPAD" : "Yes" ,
74+ } ;
11275
113- // Generic
114- { pattern : / R e t r y \? / i, answer : "No" } ,
115- {
116- pattern : / p a r t i a l c o n t r o l b e h a v i o r d o c u m e n t e d / i,
117- answer : ( ctx ) => {
118- if ( ctx . testName . includes ( "CCR_EntryControlCC" ) ) {
119- return "Yes" ; // Entry Control CC is marked as partial control in the certification portal
120- }
121- return "No" ;
122- } ,
123- } ,
124- ] ;
76+ // CC version control - which CC versions we control
77+ const controlledCCVersions : Record < string , number [ ] > = {
78+ Basic : [ 1 , 2 ] ,
79+ Indicator : [ 1 , 2 , 3 , 4 ] ,
80+ Version : [ 1 , 2 , 3 ] ,
81+ "Wake Up" : [ 1 , 2 , 3 ] ,
82+ } ;
12583
12684registerHandler ( / .* / , {
12785 onPrompt : async ( ctx ) => {
128- for ( const q of questions ) {
129- if ( q . pattern . test ( ctx . promptText ) ) {
130- if ( typeof q . answer === "function" ) {
131- return q . answer ( ctx ) ;
132- } else {
133- return q . answer ;
86+ if ( ctx . message ?. type === "DUT_CAPABILITY_QUERY" ) {
87+ const response = dutCapabilityResponses [ ctx . message . capabilityId ] ;
88+ if ( response !== undefined ) {
89+ return typeof response === "function" ? response ( ctx ) : response ;
90+ }
91+ }
92+
93+ if ( ctx . message ?. type === "CC_CAPABILITY_QUERY" ) {
94+ const { commandClass, capabilityId } = ctx . message ;
95+
96+ // Special handling for CONTROLS_CC with version
97+ if ( capabilityId === "CONTROLS_CC" && "version" in ctx . message ) {
98+ const versions = controlledCCVersions [ commandClass ] ;
99+ if ( versions ?. includes ( ctx . message . version ) ) {
100+ return "Yes" ;
134101 }
102+ return "No" ;
103+ }
104+
105+ // Look up standard capability response
106+ const key : CCCapabilityKey = `${ commandClass } :${ capabilityId } ` ;
107+ const response = ccCapabilityResponses [ key ] ;
108+ if ( response !== undefined ) {
109+ return typeof response === "function"
110+ ? response ( ctx . message )
111+ : response ;
135112 }
136113 }
137114
0 commit comments