Skip to content
This repository has been archived by the owner on Mar 6, 2022. It is now read-only.

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
paviro committed Jul 15, 2018
2 parents cca44fc + 0b63947 commit 55d3aa9
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 106 deletions.
45 changes: 21 additions & 24 deletions MMM-PIR-Sensor.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,48 @@
/* global Module */

/* Magic Mirror
* Module: MMM-PIR-Sensor
*
* By Paul-Vincent Roll http://paulvincentroll.com
* MIT Licensed.
*/

* Module: MMM-PIR-Sensor
*
* By Paul-Vincent Roll http://paulvincentroll.com
* MIT Licensed.
*/

Module.register('MMM-PIR-Sensor',{

requiresVersion: "2.1.0",

requiresVersion: '2.1.0',
defaults: {
sensorPIN: 22,
invertSensorValue: false,
relayPIN: false,
relayOnState: 1,
sensorPin: 22,
sensorState: 1,
relayPin: false,
relayState: 1,
alwaysOnPin: false,
alwaysOnState: 1,
alwaysOffPin: false,
alwaysOffState: 1,
powerSaving: true,
powerSavingDelay: 0,
powerSavingNotification: false,
powerSavingMessage: "Monitor will be turn Off by PIR module",
},

// Override socket notification handler.
socketNotificationReceived: function(notification, payload) {
if (notification === "USER_PRESENCE"){
socketNotificationReceived: function (notification, payload) {
if (notification === 'USER_PRESENCE') {
this.sendNotification(notification, payload)
} else if (notification === 'SHOW_ALERT') {
this.sendNotification(notification, payload)
if (payload === false && this.config.powerSavingNotification === true){
this.sendNotification("SHOW_ALERT",{type:"notification", message:this.config.powerSavingMessage});
}
}
},

notificationReceived: function(notification, payload) {
if (notification === "SCREEN_WAKEUP"){
notificationReceived: function (notification, payload) {
if (notification === 'SCREEN_WAKEUP') {
this.sendNotification(notification, payload)
}
},

start: function() {
if (this.config.relayOnState == 1){
this.config.relayOffState = 0
}
else if (this.config.relayOnState == 0){
this.config.relayOffState = 1
}
start: function () {
this.sendSocketNotification('CONFIG', this.config);
Log.info('Starting module: ' + this.name);
}
Expand Down
49 changes: 39 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ modules: [
]
````

## Configuration options
## Configuration Options

The following properties can be configured:


<table width="100%">
<!-- why, markdown... -->
<thead>
Expand All @@ -37,18 +36,18 @@ The following properties can be configured:
<thead>
<tbody>
<tr>
<td><code>sensorPIN</code></td>
<td><code>sensorPin</code></td>
<td>The pin your PIR-sensor is connected to.<br>
<br><b>Possible values:</b> <code>int</code>
<br><b>Default value:</b> <code>22</code>
<br><b>Note:</b> Please use BCM-numbering.
</td>
</tr>
<tr>
<td><code>invertSensorValue</code></td>
<td>Invert the sensor value on the given sensorPIN. 1 -> no pressence, 0 -> presence detected<br>
<br><b>Possible values:</b> <code>boolean</code>
<br><b>Default value:</b> <code>false</code>
<td><code>sensorState</code></td>
<td>Invert the GPIO-state that triggers user presence. For example, a <code>0</code> value would tell the mirror to trigger user presence when the GPIO pin receives <code>0</code> value.<br>
<br><b>Possible values:</b> <code>int (0 or 1)</code>
<br><b>Default value:</b> <code>1</code>
</td>
</tr>
<tr>
Expand All @@ -66,17 +65,47 @@ The following properties can be configured:
</td>
</tr>
<tr>
<td><code>relayPIN</code></td>
<td><code>relayPin</code></td>
<td>If you want to use a relay to turn of the mirror provide the pin here. If no pin is provided HDMI is turned off instead.<br>
<br><b>Possible values:</b> <code>int</code>
<br><b>Default value:</b> <code>none</code>
<br><b>Default value:</b> <code>false</code>
<br><b>Note:</b> Please use BCM-numbering.
</td>
</tr>
<tr>
<td><code>relayOnState</code></td>
<td><code>relayState</code></td>
<td>GPIO-state your relay is turned on.<br>
<br><b>Possible values:</b> <code>int (0 or 1)</code>
<br><b>Default value:</b> <code>1</code>
</td>
</tr>
<tr>
<td><code>alwaysOnPin</code></td>
<td>If you would like to use a GPIO pin to trigger power-saving mode. Ideal for users who want to have a physical switch that controls whether or not to use the motion sensor.<br>
<br><b>Possible values:</b> <code>int</code>
<br><b>Default value:</b> <code>false</code>
<br><b>Note:</b> Please use BCM-numbering.
</td>
</tr>
<tr>
<td><code>alwaysOnState</code></td>
<td>GPIO-state to trigger always-on.<br>
<br><b>Possible values:</b> <code>int (0 or 1)</code>
<br><b>Default value:</b> <code>1</code>
</td>
</tr>
<tr>
<td><code>alwaysOffPin</code></td>
<td>If you would like to use a GPIO pin to trigger sleep mode. Ideal for users who want to have a physical switch to shut off the screen (perhaps the mirror is too bright at night).<br>
<br><b>Possible values:</b> <code>int</code>
<br><b>Default value:</b> <code>false</code>
<br><b>Note:</b> Please use BCM-numbering.
</td>
</tr>
<tr>
<td><code>alwaysOffState</code></td>
<td>GPIO-state to trigger always-off.<br>
<br><b>Possible values:</b> <code>int (0 or 1)</code>
<br><b>Default value:</b> <code>1</code>
</td>
</tr>
Expand Down
200 changes: 128 additions & 72 deletions node_helper.js
Original file line number Diff line number Diff line change
@@ -1,90 +1,146 @@
'use strict';

/* Magic Mirror
* Module: MMM-PIR-Sensor
*
* By Paul-Vincent Roll http://paulvincentroll.com
* MIT Licensed.
*/
* Module: MMM-PIR-Sensor
*
* By Paul-Vincent Roll http://paulvincentroll.com
* MIT Licensed.
*/

const NodeHelper = require('node_helper');
const Gpio = require('onoff').Gpio;
const exec = require('child_process').exec;

module.exports = NodeHelper.create({
start: function () {
this.started = false;
},
start: function () {
this.started = false;
},

activateMonitor: function () {
if (this.config.relayPIN != false) {
this.relay.writeSync(this.config.relayOnState);
}
else if (this.config.relayPIN == false){
// Check if hdmi output is already on
exec("/usr/bin/vcgencmd display_power").stdout.on('data', function(data) {
if (data.indexOf("display_power=0") == 0)
exec("/usr/bin/vcgencmd display_power 1", null);
});
}
},

deactivateMonitor: function () {
if (this.config.relayPIN != false) {
this.relay.writeSync(this.config.relayOffState);
}
else if (this.config.relayPIN == false){
exec("/usr/bin/vcgencmd display_power 0", null);
}
},

// Subclass socketNotificationReceived received.
socketNotificationReceived: function(notification, payload) {
if (notification === 'CONFIG' && this.started == false) {
const self = this;
this.config = payload;

// Setup value which represent on and off
const valueOn = this.config.invertSensorValue ? 0 : 1;
const valueOff = this.config.invertSensorValue ? 1 : 0;

//Setup pins
this.pir = new Gpio(this.config.sensorPIN, 'in', 'both');
// exec("echo '" + this.config.sensorPIN.toString() + "' > /sys/class/gpio/export", null);
// exec("echo 'in' > /sys/class/gpio/gpio" + this.config.sensorPIN.toString() + "/direction", null);

if (this.config.relayPIN) {
this.relay = new Gpio(this.config.relayPIN, 'out');
this.relay.writeSync(this.config.relayOnState);
exec("/usr/bin/vcgencmd display_power 1", null);
}

//Detected movement
this.pir.watch(function(err, value) {
if (value == valueOn) {
self.sendSocketNotification("USER_PRESENCE", true);
if (self.config.powerSaving){
clearTimeout(self.deactivateMonitorTimeout);
self.activateMonitor();
}
}
else if (value == valueOff) {
self.sendSocketNotification("USER_PRESENCE", false);
if (!self.config.powerSaving){
activateMonitor: function () {
// If always-off is enabled, keep monitor deactivated
let alwaysOffTrigger = this.alwaysOff && (this.alwaysOff.readSync() === this.config.alwaysOffState)
if (alwaysOffTrigger) {
return;
}
}
// If relays are being used in place of HDMI
if (this.config.relayPin !== false) {
this.relay.writeSync(this.config.relayState);
}
else if (this.config.relayPin === false) {
// Check if hdmi output is already on
exec("/usr/bin/vcgencmd display_power").stdout.on('data', function(data) {
if (data.indexOf("display_power=0") === 0)
exec("/usr/bin/vcgencmd display_power 1", null);
});
}
},

self.deactivateMonitorTimeout = setTimeout(function() {
self.deactivateMonitor();
}, self.config.powerSavingDelay * 1000);
deactivateMonitor: function () {
// If always-on is enabled, keep monitor activated
let alwaysOnTrigger = this.alwaysOn && (this.alwaysOn.readSync() === this.config.alwaysOnState)
let alwaysOffTrigger = this.alwaysOff && (this.alwaysOff.readSync() === this.config.alwaysOffState)
if (alwaysOnTrigger && !alwaysOffTrigger) {
return;
}
// If relays are being used in place of HDMI
if (this.config.relayPin !== false) {
this.relay.writeSync((this.config.relayState + 1) % 2);
}
});
else if (this.config.relayPin === false) {
exec("/usr/bin/vcgencmd display_power 0", null);
}
},

// Subclass socketNotificationReceived received.
socketNotificationReceived: function (notification, payload) {
if (notification === 'CONFIG' && this.started == false) {
const self = this;
this.config = payload;

// Setup for relay pin
if (this.config.relayPin) {
this.relay = new Gpio(this.config.relayPin, 'out');
this.relay.writeSync(this.config.relayState);
exec("/usr/bin/vcgencmd display_power 1", null);
}

// Setup for alwaysOn switch
if (this.config.alwaysOnPin) {
this.alwaysOn = new Gpio(this.config.alwaysOnPin, 'in', 'both');
const alwaysOnState = this.config.alwaysOnState
this.alwaysOn.watch(function (err, value) {
if (value === alwaysOnState) {
self.sendSocketNotification('ALWAYS_ON', true);
self.sendSocketNotification('SHOW_ALERT', {
title: 'Always-On Activated',
message: 'Mirror will not activate power-saving mode',
timer: 4000
});
if (self.config.powerSaving){
clearTimeout(self.deactivateMonitorTimeout);
}
} else if (value === (alwaysOnState + 1) % 2) {
self.sendSocketNotification('ALWAYS_ON', false);
self.sendSocketNotification('SHOW_ALERT', {
title: 'Always-On Deactivated',
message: 'Mirror will now use motion sensor to activate',
timer: 4000
});
}
})
}

// Setup for alwaysOff switch
if (this.config.alwaysOffPin) {
this.alwaysOff = new Gpio(this.config.alwaysOffPin, 'in', 'both');
const alwaysOffState = this.config.alwaysOffState
this.alwaysOff.watch(function (err, value) {
if (value === alwaysOffState) {
self.sendSocketNotification('ALWAYS_OFF', true);
self.deactivateMonitor();
} else if (value === (alwaysOffState + 1) % 2) {
self.sendSocketNotification('ALWAYS_OFF', false);
self.activateMonitor();
if (self.config.powerSaving){
clearTimeout(self.deactivateMonitorTimeout);
}
}
})
}

this.started = true;
// Setup for sensor pin
this.pir = new Gpio(this.config.sensorPin, 'in', 'both');

} else if (notification === 'SCREEN_WAKEUP') {
this.activateMonitor();
// Setup value which represent on and off
const valueOn = this.config.sensorState;
const valueOff = (this.config.sensorState + 1) % 2;

// Detected movement
this.pir.watch(function (err, value) {
if (value == valueOn) {
self.sendSocketNotification('USER_PRESENCE', true);
if (self.config.powerSaving){
clearTimeout(self.deactivateMonitorTimeout);
self.activateMonitor();
}
}
else if (value == valueOff) {
self.sendSocketNotification('USER_PRESENCE', false);
if (!self.config.powerSaving){
return;
}

self.deactivateMonitorTimeout = setTimeout(function() {
self.deactivateMonitor();
}, self.config.powerSavingDelay * 1000);
}
});

this.started = true;

} else if (notification === 'SCREEN_WAKEUP') {
this.activateMonitor();
}
}
}

});

0 comments on commit 55d3aa9

Please sign in to comment.