@@ -123,7 +123,7 @@ function hasPendingOperations(bleDevice) {
123123 if ( ! bleDevice ) {
124124 return false ;
125125 }
126- if ( ( bleDevice . _writeRequests . length > 0 ) || ( bleDevice . _readRequests . length > 0 ) ) {
126+ if ( ( bleDevice . _writeRequests . length > 0 ) || ( bleDevice . _readRequests . length > 0 ) || ( bleDevice . _notifyRequests . length > 0 ) ) {
127127 return true ;
128128 }
129129 if ( bleDevice . muteNotifyEvents ) {
@@ -246,14 +246,26 @@ function characteristicsTask(services, bleDevice) {
246246 }
247247 process . nextTick ( loop ) ;
248248 } ) . then ( ( ) => {
249- if ( bleDevice . muteNotifyEvents ) {
250- return Promise . resolve ( ) ;
251- }
252- let notifiables = bleDevice . characteristics . filter ( c => c . notifiable ) ;
253- if ( notifiables . length === 0 ) {
254- return Promise . resolve ( ) ;
249+ let notifiables = [ ] ;
250+ let notifyRequest = bleDevice . _notifyRequests . shift ( ) || [ ] ;
251+ let notifyUuidList = notifyRequest . map ( c => {
252+ operationTimeoutMs += c . period ;
253+ return c . uuid ;
254+ } ) ;
255+ notifiables = notifyUuidList . length > 0 ?
256+ characteristics . filter ( c => c && notifyUuidList . indexOf ( c . uuid ) >= 0 ) : [ ] ;
257+
258+ if ( notifyRequest . length === 0 ) {
259+ if ( bleDevice . muteNotifyEvents ) {
260+ return Promise . resolve ( ) ;
261+ }
262+ operationTimeoutMs += ( bleDevice . operationTimeout || BLE_OPERATION_WAIT_MS ) * notifiables . length ;
263+ notifiables = bleDevice . characteristics . filter ( c => c . notifiable ) ;
264+ if ( notifiables . length === 0 ) {
265+ return Promise . resolve ( ) ;
266+ }
255267 }
256- operationTimeoutMs += ( bleDevice . operationTimeout || BLE_OPERATION_WAIT_MS ) * notifiables . length ;
268+
257269 return new Promise ( ( taskResolve , taskReject ) => {
258270 timeout = addTimeout ( ( ) => {
259271 if ( TRACE ) {
@@ -708,6 +720,7 @@ export default function(RED) {
708720 this . nodes = { } ;
709721 this . _writeRequests = [ ] ; // {uuid:'characteristic-uuid-to-write', data:Buffer()}
710722 this . _readRequests = [ ] ; // {uuid:'characteristic-uuid-to-read'}
723+ this . _notifyRequests = [ ] ; // {uuid:'characteristic-uuid-to-subscribe', period:subscription period}
711724 this . operations = {
712725 register : ( node ) => {
713726 this . nodes [ node . id ] = node ;
@@ -777,6 +790,31 @@ export default function(RED) {
777790 return { uuid : r . uuid } ;
778791 } ) ) ;
779792 return true ;
793+ } ,
794+ subscribe : ( uuids = '' , period = 3000 ) => {
795+ uuids = uuids . split ( ',' ) . map ( ( uuid ) => uuid . trim ( ) ) . filter ( ( uuid ) => uuid ) ;
796+ let notifiables = this . characteristics . filter ( c => {
797+ if ( c . notifiable ) {
798+ if ( uuids . length === 0 ) {
799+ return true ;
800+ }
801+ return uuids . indexOf ( c . uuid ) >= 0 ;
802+ }
803+ } ) ;
804+ if ( TRACE ) {
805+ this . log ( `characteristics => ${ JSON . stringify ( this . characteristics ) } ` ) ;
806+ this . log ( `notifiables.length => ${ notifiables . length } ` ) ;
807+ }
808+ if ( notifiables . length === 0 ) {
809+ return false ;
810+ }
811+ if ( this . _notifyRequests . length >= MAX_REQUESTS ) {
812+ return false ;
813+ }
814+ this . _notifyRequests . push ( notifiables . map ( ( r ) => {
815+ return { uuid : r . uuid , period : period } ;
816+ } ) ) ;
817+ return true ;
780818 }
781819 } ;
782820 [ 'connected' , 'disconnected' , 'subscribed' , 'unsubscribed' , 'error' , 'timeout' ] . forEach ( ev => {
@@ -869,7 +907,18 @@ export default function(RED) {
869907 if ( TRACE ) {
870908 this . log ( `input arrived!` ) ;
871909 }
872- this . genericBleNode . operations . read ( msg . topic ) ;
910+ let obj = msg . payload || { } ;
911+ try {
912+ if ( typeof ( obj ) === 'string' ) {
913+ obj = JSON . parse ( msg . payload ) ;
914+ }
915+ } catch ( _ ) {
916+ }
917+ if ( obj . notify ) {
918+ this . genericBleNode . operations . subscribe ( msg . topic , obj . period ) ;
919+ } else {
920+ this . genericBleNode . operations . read ( msg . topic ) ;
921+ }
873922 } ) ;
874923 this . on ( 'close' , ( ) => {
875924 if ( this . genericBleNode ) {
0 commit comments