-
Notifications
You must be signed in to change notification settings - Fork 0
/
gpioWrapper.js
executable file
·173 lines (153 loc) · 6.17 KB
/
gpioWrapper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
'use strict';
let Gpio = require('onoff').Gpio; //include onoff to interact with the GPIO
let gpioMock = require('gpio-mock');
let DHTSensor = require("node-dht-sensor");
//GPIO Definitions
let GPIO_PIN_25 = 25; // Motion Sensor
let GPIO_PIN_16 = 16; // LED
let GPIO_PIN_12 = 12; // Buzzer
let GPIO_PIN_21 = 21; // Hygrothermograph Sensor
let STATUS_OFF = 0;
let STATUS_ON = 1;
let HYGRO_THERMO_GRAPH_SENSOR_TYPE_DHT11 = 11;
// Motion detection modes
const MODE_ON_ONLY= 'MODE_ON_ONLY';
const MODE_OFF_ONLY = 'MODE_OFF_ONLY';
const MODE_BOTH = 'MODE_BOTH';
const SENSOR_QUERY_INTERVAL = 1000; // .1 sec
// Presence detection time to switch to user search screen
const DEFAULT_PRESENCE_ON_DELAY = 1000; // 1 second
// Time to switch back to splash screen after no more presence
const DEFAULT_PRESENCE_OFF_DELAY = 10000; // 10 seconds
// Time before starting motion after initialization
const DEFAULT_INITIAL_MOTION_DETECTION_DELAY = 0;
// LED Flashing on and off default times
const LED_FLASH_SPEED_DEFAULT_TIME = 500; // 500 ms
let GpioHelper = function (logger, mock) {
let motionSensor;
let LED;
let buzzer;
let motionSensorTimer;
let presenceNotificationDelayTimer;
let currentDetectionStatus = null;
let ledFlashingTimer;
let motionSensorOptions;
let self = this;
if (mock) {
logger.debug('[GPIO] It seems we are not running on an actual RPI. Mocking of GPIO shall start');
gpioMock.start(function () {
logger.debug('[GPIO] GPIO Mocking Started');
});
}
this.initMotionSensor = function(gpioPin) {
motionSensor = new Gpio(gpioPin || GPIO_PIN_25, 'in', 'both');
};
this.initPresenceChangeSensor = function(options) {
if (!options || !options.callback) {
logger.error('[GPIO] Not enough options to initialize motion sensor');
return;
}
motionSensorOptions = options;
motionSensor = new Gpio(motionSensorOptions.gpioPin || GPIO_PIN_25, 'in', 'both');
if(options.detection === STATUS_ON) {
setTimeout(() => self.restartPresenceDetection(motionSensorOptions),
options.initialDelay || DEFAULT_INITIAL_MOTION_DETECTION_DELAY);
}
};
this.restartPresenceDetection = function(options) {
logger.debug('[GPIO] Restart Precense Detection');
options = options || motionSensorOptions;
if (!options.callback) {
logger.error('[GPIO] Not enough options to initialize motion sensor');
return;
}
if (motionSensorTimer) {
clearInterval(motionSensorTimer);
}
motionSensorTimer = setInterval(() => {
motionSensor.read((error, status) => {
if (!error) {
if (currentDetectionStatus === null || currentDetectionStatus !== status) {
logger.debug(`[GPIO] Status change. Old status = ${currentDetectionStatus}. New status ${status}.`);
if (presenceNotificationDelayTimer) {
clearTimeout(presenceNotificationDelayTimer);
}
presenceNotificationDelayTimer = setTimeout(() => {
logger.debug(`[GPIO] Invoke callback with status ${status}`);
options.callback(status);
}, status === STATUS_OFF ? motionSensorOptions.presenceOffDelay || DEFAULT_PRESENCE_OFF_DELAY
: motionSensorOptions.presenceOnDelay || DEFAULT_PRESENCE_ON_DELAY);
}
currentDetectionStatus = status;
return;
}
logger(`[GPIO] Error querying sensor: Error ${error}`);
});
}, options.presenceCheckTime || SENSOR_QUERY_INTERVAL);
};
this.stopPresenceDetection = function() {
logger.debug('[GPIO] Stop Precense Detection');
if(motionSensorTimer) {
clearInterval(motionSensorTimer);
motionSensorTimer = null;
}
};
this.initLED = function(gpioPin, status) {
LED = new Gpio(gpioPin || GPIO_PIN_16, 'out');
self.setLED(status);
};
this.setLED = function(status) {
if (ledFlashingTimer) {
clearInterval(ledFlashingTimer);
ledFlashingTimer = null;
}
LED.writeSync(status);
};
this.flashLED = function(speed) {
speed = speed || LED_FLASH_SPEED_DEFAULT_TIME;
let status = STATUS_ON;
LED.writeSync(status);
if (ledFlashingTimer) {
clearInterval(ledFlashingTimer);
}
ledFlashingTimer = setInterval(() => {
status = status === STATUS_ON ? STATUS_OFF : STATUS_ON;
LED.writeSync(status);
}, speed);
};
this.initBuzzer = function(gpioPin, status) {
buzzer = new Gpio(gpioPin || GPIO_PIN_12, 'out');
self.setBuzzer(status);
};
this.setBuzzer = function(status) {
buzzer.writeSync(status);
};
this.readTempAndHumidity = function (cb, gpioPin, dhtType) {
cb = cb || {};
if (mock) {
cb(25,45);
return;
}
DHTSensor.read(dhtType || HYGRO_THERMO_GRAPH_SENSOR_TYPE_DHT11, gpioPin || GPIO_PIN_21, function(err, temp, humidity) {
if(!err) {
logger.debug(`Temperature: ${temp.toFixed(1)} °C. Humidity: ${humidity.toFixed(1)} %`);
cb(temp, humidity);
} else {
logger.error(`Error reading DHT11. Error: ${err}`);
}
});
};
this.getCurrentMotionSensorStatus = function () {
if (!motionSensor) {
logger.error('[GPIO] Motion sensor has not be initialized yet');
return;
}
return motionSensor.readSync();
};
};
module.exports = GpioHelper;
module.exports.MODE_BOTH = MODE_BOTH;
module.exports.MODE_ON_ONLY = MODE_ON_ONLY;
module.exports.MODE_OFF_ONLY = MODE_OFF_ONLY;
module.exports.STATUS_OFF = STATUS_OFF;
module.exports.STATUS_ON = STATUS_ON;