0

I am not familiar with this function, however I am seeing intermittent failures, sometimes the timer function will execute and the newState variable switches, sometimes it doesn't. Please can you check my understanding of what this is doing?

function motionHandler() {
        console.log('im in motionhandler func')
        var newState = true;
        changeAction(newState);
        if(this.timer !== undefined) clearTimeout(this.timer);
        this.timer = setTimeout(function(){changeAction(!newState);}, this.window_seconds * 1000);
    };

From what I understand, when this function executes I set the newState variable to true. I then execute changeAction which sets my motion detector to "true" (motion detected).

I then create a timer. If this.timer has something in it, then clear. I then create a timeout which will countdown from window_seconds * 1000 (ie. 5x1000 milliseconds = 5 seconds). Once that timeout is reached, I will execute the changeAction function and set newState to the opposite of what it currently is?

Assuming all of that is correct, sometimes newState gets reset, other times it doesn't.

I am executing the motionHandler function every time I receive a particular RF code from a transmitter. The timeout is there to reset the motion detector back to false when no codes are received.

The full code is actually a plugin for home bridge, and can be seen here:

https://github.com/mattnewham/homebridge-RFReceiver/blob/master/index.js

This is my first real foray into Javascript/NodeJS so I don't really know how to troubleshoot this (other than my console.logs!)

Full code:

var Service;
var Characteristic;
var rpi433 = require("rpi-433"),
    rfSniffer = rpi433.sniffer({
      pin: 2,                     //Snif on GPIO 2 (or Physical PIN 13)
      debounceDelay: 1000          //Wait 500ms before reading another code
    }),
    rfEmitter = rpi433.emitter({
      pin: 0,                     //Send through GPIO 0 (or Physical PIN 11)
      pulseLength: 350            //Send the code with a 350 pulse length
    });

var debug = require("debug")("RFReceiverAccessory");
var crypto = require("crypto");

module.exports = function(homebridge) {
    Service = homebridge.hap.Service;
    Characteristic = homebridge.hap.Characteristic;

    homebridge.registerAccessory("homebridge-RFReceiver", "RFReceiver", RFReceiverAccessory);
}

function RFReceiverAccessory(log, config) {
  this.log = log;

  // url info
  this.name = config["name"];
  this.rfcode = config["rfcode"] || 4;
  this.window_seconds = config["window_seconds"] || 5;
  this.sensor_type = config["sensor_type"] || "m";
  this.inverse = config["inverse"] || false;

}

RFReceiverAccessory.prototype = {

  getServices: function() {

    // you can OPTIONALLY create an information service if you wish to override
    // the default values for things like serial number, model, etc.
    var informationService = new Service.AccessoryInformation();

    informationService
      .setCharacteristic(Characteristic.Name, this.name)
      .setCharacteristic(Characteristic.Manufacturer, "Homebridge")
      .setCharacteristic(Characteristic.Model, "RF Receiver")
      .setCharacteristic(Characteristic.SerialNumber, "12345");

    var service, changeAction;
    if(this.sensor_type === "c"){
        service = new Service.ContactSensor();
        changeAction = function(newState){
            service.getCharacteristic(Characteristic.ContactSensorState)
                    .setValue(newState ? Characteristic.ContactSensorState.CONTACT_DETECTED : Characteristic.ContactSensorState.CONTACT_NOT_DETECTED);
        };
    } else {
        service = new Service.MotionSensor();
        changeAction = function(newState){
     console.log('changing state');
            service.getCharacteristic(Characteristic.MotionDetected)
                    .setValue(newState);
        };
    }

function motionHandler() {
        console.log('im in motionhandler func')
        var newState = true;
        changeAction(newState);
        if(this.timer !== undefined) clearTimeout(this.timer);
        this.timer = setTimeout(function(){changeAction(!newState);}, this.window_seconds * 1000);
    };


    
 
    var code = this.rfcode
    var name = this.name

    rfSniffer.on('data', function (data) {
    console.log('Code received: '+data.code+' pulse length : '+data.pulseLength);
    console.log(code);
    if(data.code == code){
            console.log("Motion Detected In" +name);
            motionHandler()};
    });


   
    

    return [informationService, service];
  }
};
  • 1
    What is `this` in that code? – T.J. Crowder Sep 17 '16 at 08:53
  • 1
    (Side note: Function *declarations* don't end with `;` Statements, such as an assignment statement where the value is a function *expression*, end with semicolons, but not function declarations. [Details of the various function creation declarations/expressions here](http://stackoverflow.com/questions/336859/javascript-function-declaration-syntax-var-fn-function-vs-function-fn/22173438#22173438).) – T.J. Crowder Sep 17 '16 at 08:55
  • 1
    I can't see any reason the above code wouldn't fire the timeout. I suspect the problem is in code you haven't quoted. – T.J. Crowder Sep 17 '16 at 08:55
  • @T.J.Crowder I edited the question to include the entire piece. `this` as far as I can tell is nothing, it is just what the variable was called in the original code I borrowed from the example plugin. Thus this.window_seconds just refers to the config variable declared above. – Matt Newham Sep 17 '16 at 17:43
  • I am aware (I think) of how bad this is probably written, however I don't really understand functions in Javascript. Have I done something wrong by adding the semicolon? It doesn't run if I exclude it. – Matt Newham Sep 17 '16 at 17:45
  • @ Matt - I was referring to your first code block (the only code block when I made the comment). As quoted, the `;` in that code does nothing whatsoever and the function will work perfectly without it. See the link in my previous content for details of various function creation methods. – T.J. Crowder Sep 17 '16 at 17:49

0 Answers0