Home Do not allow call of a subscriber with the same argument twice until the first is done
Reply: 2

Do not allow call of a subscriber with the same argument twice until the first is done

bolzano
1#
bolzano Published in 2018-02-12 15:10:47Z

I am currently experimenting with beacons and I want to get the rssi measurements of the beacons in order to trigger an alarm function.

My problem is the following:

alarm function is triggered multiple times once the subscriber is called

What I want:

Do not allow alarm to execute more than once with the previous argument. For example if the alarm function is called with argument 'x' then someone cannot call alarm with 'x' but can call it with 'y' in order to avoid multiple pushes to the database.

My code (I am using noble for beacons and firebase for my db):

// alarm script

import { config, Device, db, auth, productsRef } from './index';
import * as noble from 'noble';
import * as firebase from 'firebase';


var acquiredRef = db.ref('acquired');

function condition(p) {
   // a boolean function that does something


}


function alarm (address) {
  console.log('Alarm!');
  let incident = {
    date : Date(),
    uuid : address,
  }
  db.ref('alarms').push(incident);

}

if (require.main === module) {

  noble.on('stateChange', function (state) {
    if (state === 'poweredOn') noble.startScanning([], true);
    else noble.stopScanning();
  });

  noble.on('discover', function(peripheral) {
    peripheral.address = peripheral.address.toUpperCase();

      if (condition(peripheral)) {
          // query
          acquiredRef.orderByChild('uuid').equalTo(peripheral.address).once('value')
            .then(snap => {
              if(snap.val() == null) alarm(peripheral.address);
            }).catch(err => console.log(err))
      }

  });

}

I tried using queues and async-lock without success. It works the first time alarm is called and then has the same behaviour as above.

Thanks in advance

slinhart
2#
slinhart Reply to 2018-02-12 21:14:49Z

If you are only interested in making sure the alarm function doesn't get called twice (or more) times in a row with the same arguments (in this case just the string 'address') you could just store a variable and compare you most recent argument to your current argument. If the arguments are the same, don't execute the rest of the function.

let previousAddress = null;
function alarm (address) {
  if (address === previousAddress) {
    return; // skip
  }
  console.log('Alarm!');
  let incident = {
    date : Date(),
    uuid : address,
  }
  db.ref('alarms').push(incident);
  previousAddress = address; // update previous argument

}
Cristiano Andaló Tenuta
3#
Cristiano Andaló Tenuta Reply to 2018-02-12 17:21:08Z

I had a problem similar to yours.

On my case an simple elapsed time variable did the trick. This is necessary because the discover callback executes multiple times on the same peripheral.

Take a look at it.

noble.on('discover', function(peripheral) {  

  if (peripheral.advertisement.localName == 'FinishLine') {


      if (lastDetection == null) {
          alert();
      } else {
          if ((Date.now() - lastDetection) / 1000 > 2) {
              alert();
          }
      }
  } 
});

Because of the asynchronous firebase call behavior you can not rely on the query. A pause of 2 or more seconds like I did might solve your problem.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.347715 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO