Binary switch-able AutoLock module ?

Tips, Tricks and Scripts to enhance your home automation and workaround known device bugs, limitations and incompatibilities
Post Reply
silverhack
Posts: 46
Joined: 23 May 2016 21:41

Binary switch-able AutoLock module ?

Post by silverhack »

I wanted to reach out and get some advice on this since I haven't made any HA user modules yet. Not sure what the best approach is, or if there is already something else that will work.

I have setup the Auto Door Lock module to lock a door after it gets opened/closed based on a door sensor. This is working. However, I would like it to only be functional either during certain scenes or based on a binary switch (dummy device) pre-condition. Or, adjust the Auto Lock module to act like a binary switch, so my scene "Leaving Home" can turn that module "ON" and then when the door gets opened/closed the door gets locked automatically. Then my "Coming Home" scene can turn that switch/module off and unlock the door and then the door won't automatically lock any more. At least, not until that switch/module gets set back to ON.

Any thoughts/ideas? Not sure if I will need to modify the AutoLock module and make my own user module, or if I can do this with a Code Device, or if anyone has a better idea.
silverhack
Posts: 46
Joined: 23 May 2016 21:41

Re: Binary switch-able AutoLock module ?

Post by silverhack »

I have started some work on my own user module, I'm calling it EnhancedAutoLock for now, and hopefully once I get it working correctly I will actually update the AutoLock module in github and create a pull request.
For now, I'm just trying to get it working as my own separate module to hack away at.

I've hit a snag and without any experience with the HA modules, I'm not sure what to do about it. I know I'm probably not doing something right. Any pointers?

My problem is with this line:
var precondition = self.checkPrecondition();
The console output before it works, but I do not get the console output after it, or the one inside the checkPrecondition() function.

Code: Select all

// ----------------------------------------------------------------------------
// --- Class definition, inheritance and setup
// ----------------------------------------------------------------------------
function EnhancedAutoLock (id, controller) {
    // Call superconstructor first (AutomationModule)
    EnhancedAutoLock.super_.call(this, id, controller);

    // Create instance variables
    this.timer = null;
};

inherits(EnhancedAutoLock, AutomationModule);
_module = EnhancedAutoLock;

// ----------------------------------------------------------------------------
// --- Module instance initialized
// ----------------------------------------------------------------------------
EnhancedAutoLock.prototype.init = function (config) {
    // Call superclass' init (this will process config argument and so on)
    EnhancedAutoLock.super_.prototype.init.call(this, config);

    var self = this;
    
    // handler - it is a name of your function
    this.handler = function (vDev) {
        var nowSensorStatus = vDev.get("metrics:level");

        console.log("----------------------------- EnhancedAutoLock", self.config.BinarySensor, "=", nowSensorStatus);

        console.log("Checking preconditions");
        var precondition = self.checkPrecondition();
        console.log("Result=", precondition);

        if (!precondition) {
            console.log("Pre-Conditions failed.  Skipping autolock");

        } else {
            console.log("Pre-Conditions matched");

            // Clear delay if door opened
            if (nowSensorStatus === "on") {
                console.log("Clear delay");
                clearTimeout(self.timer);
            }
            
            // Close lock if sensor false
            if (nowSensorStatus === "off") {
                // Start Timer
                console.log("Start delay");
                self.timer = setTimeout(function () {
                    // Close lock 
                    self.controller.devices.get(self.config.DoorLock).performCommand("close");
                    // And clearing out this.timer variable
                    self.timer = null;
                }, self.config.delay*1000);
            }
        }
    };

    // Setup metric update event listener
    this.controller.devices.on(this.config.BinarySensor, 'change:metrics:level', this.handler);
};

EnhancedAutoLock.prototype.stop = function () {
    EnhancedAutoLock.super_.prototype.stop.call(this);

    if (this.timer)
        clearTimeout(this.timer);

    this.controller.devices.off(this.config.BinarySensor, 'change:metrics:level', this.handler);
};


// Helper to check preconditions
EnhancedAutoLock.prototype.checkPrecondition = function() {
    console.log("Inside checkPrecondition");

    var self = this;

    self.log('Calculating precondition');

    var dateNow         = new Date();
    var dayofweekNow    = dateNow.getDay().toString();
    var condition       = true;

    // Check time
    if (condition === true
        && self.config.preconditions.time.length > 0) {
        var timeCondition = false;
        _.each(self.config.preconditions.time,function(time) {
            if (timeCondition === true) {
                return;
            }

            // Check day of week if set
            if (typeof(time.dayofweek) === 'object'
                && time.dayofweek.length > 0
                && _.indexOf(time.dayofweek, dayofweekNow.toString()) === -1) {
                self.log('Day of week does not match');
                return;
            }

            if (! self.checkPeriod(time.timeFrom,time.timeTo)) {
                self.log('Time does not match');
                return;
            }

            timeCondition = true;
        });
        condition = timeCondition;
    }

    // Check binary
    _.each(self.config.preconditions.binary,function(check) {
        if (condition) {
            var device = self.controller.devices.get(check.device);
            if (! _.isNull(device)) {
                var level = device.get('metrics:level');
                if (check.value !== level) {
                    self.log('Binary does not match: '+device.id);
                    condition = false;
                }
            } else {
                self.error('Could not find device '+check.device);
            }
        }
    });

    // Check multilevel
    _.each(self.config.preconditions.multilevel,function(check) {
        if (condition) {
            var device = self.controller.devices.get(check.device);
            if (! _.isNull(device)) {
                var level = device.get('metrics:level');
                if (! self.compare(level,check.operator,check.value)) {
                    self.log('Multilevel does not match: '+device.id);
                    condition = false;
                }
            } else {
                self.error('Could not find device '+check.device);
            }
        }
    });

    return condition;
};
silverhack
Posts: 46
Joined: 23 May 2016 21:41

Re: Binary switch-able AutoLock module ?

Post by silverhack »

I got my problem fixed. I had not inherited BaseModule which is what provides self.log()
Now my new module works correctly. I will be doing testing, and then try to update the AutoLock module.
Post Reply