Skip to content

Commit

Permalink
v1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
bugsounet authored Mar 8, 2024
2 parents 553f2fe + f83c8c1 commit 7dc9367
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 1,813 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/esbuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: "ESBuild Testing"
on: [pull_request]

jobs:
eslint:
esbuild:
name: Run esbuild
runs-on: ubuntu-latest
steps:
Expand Down
24 changes: 8 additions & 16 deletions MMM-Pir.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/****************
* MMM-Pir v1.2 *
* Bugsounet *
* 02/2024 *
*****************/
/*************
* MMM-Pir *
* Bugsounet *
* 03/2024 *
*************/

/* global screenDisplayer, screenTouch */

Expand All @@ -23,7 +23,6 @@ Module.register("MMM-Pir", {
mode6_gpio: 20,
mode6_clearGpioValue: true,
pir_gpio: 21,
pir_reverseValue: false,
xrandrForceRotation: "normal",
wrandrForceRotation: "normal",
wrandrForceMode: null
Expand Down Expand Up @@ -89,29 +88,22 @@ Module.register("MMM-Pir", {
if (payload) this.sendNotification("USER_PRESENCE", true);
else this.sendNotification("USER_PRESENCE", false);
break;
case "WARNING":
case "SCREEN_ERROR":
this.sendNotification("SHOW_ALERT", {
type: "notification",
title: "MMM-Pir",
message: `Warning: Library not loaded: ${payload.library}`,
message: `Screen Error detected: ${payload}`,
timer: 15000
});
break;
case "FatalError":
this.sendNotification("SHOW_ALERT", {
title: "MMM-Pir",
message: `<p>FATAL: ${payload} needed library not loaded !<br>Try to solve it with 'npm run rebuild' in MMM-Pir Folder</p>`,
timer: 0
});
break;
case "SCREEN_ERROR":
case "PIR_ERROR":
this.sendNotification("SHOW_ALERT", {
type: "notification",
title: "MMM-Pir",
message: `Pir Error detected: ${payload}`,
timer: 15000
});
break;
}
},

Expand Down
9 changes: 0 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ To display the module insert it in the config.js file.
displayLastPresence: true,
lastPresenceTimeFormat: "LL H:mm",
pir_gpio: 21,
pir_reverseValue: false,
mode6_gpio: 20,
mode6_clearGpioValue: true,
xrandrForceRotation: "normal",
Expand All @@ -66,7 +65,6 @@ To display the module insert it in the config.js file.
| displayLastPresence| Display the date of the last user presence | Boolean | true |
| lastPresenceTimeFormat| Change the date format (moment.js format) of the last presence | String | LL H:mm |
| pir_gpio | BCM-number of the sensor pin. Use `0`, if you want to disable PIR Sensor detection | Number | 21 |
| pir_reverseValue | Reverse sensor received value | Boolean | false |
| mode6_gpio| **-mode 6 only-** GPIO number for control the relay (switch) | Number | 20 |
| mode6_clearGpioValue| **-mode 6 only-** reset GPIO value script of relay (switch) | Boolean | true |
| xrandrForceRotation | **-mode 9 only-** Forces screen rotation according to the defined value (possible value: "normal", "left", "right", "inverted") | String | normal |
Expand Down Expand Up @@ -126,13 +124,6 @@ cd ~/MagicMirror/modules/MMM-Pir
npm run update
```

## Reinstall
For reinstall this module or when an update of MagicMirror is available, you can use this command:

```sh
cd ~/MagicMirror/modules/MMM-Pir
npm run rebuild
```
## Notes:
`mode 1` works with bullseye OS (raspbian 11)<br>
Just use `dtoverlay=vc4-fkms-v3d` driver in `/boot/config.txt`
31 changes: 31 additions & 0 deletions components/MotionSensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from gpiozero import MotionSensor
from signal import pause
import argparse, sys

parser = argparse.ArgumentParser(
description='Read MotionSensor state from GPIO for MMM-Pir',
epilog="©bugsounet 2024"
)

def gpio_check(x):
x = int(x)
if x < 1 or x > 21:
raise argparse.ArgumentTypeError("GPIO must be between 1 and 21")
return x

parser.add_argument("-g", "--gpio", help="Define GPIO", type=gpio_check, required=True)

args = parser.parse_args(None if sys.argv[1:] else ['-h'])

GPIO = "GPIO" + str(args.gpio)

def detected():
print('Detected')

try:
pir = MotionSensor(GPIO)
pir.when_motion = detected
pause()
except Exception as e:
print("Error:", e)

54 changes: 33 additions & 21 deletions components/pirLib.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@
/** bugsounet **/

var log = (...args) => { /* do nothing */ };
const Gpio = require("onoff").Gpio;
const { PythonShell } = require("python-shell");

class PIR {
constructor (config, callback) {
this.config = config;
this.callback = callback;
this.default = {
debug: false,
gpio: 21,
reverseValue: false
gpio: 21
};
this.config = Object.assign({}, this.default, this.config);
if (this.config.debug) log = (...args) => { console.log("[MMM-Pir] [LIB] [PIR]", ...args); };
Expand All @@ -23,32 +22,45 @@ class PIR {
if (this.running) return;
if (this.config.gpio === 0) return console.log("[MMM-Pir] [LIB] [PIR] Disabled.");
log("Start");
try {
this.pir = new Gpio(this.config.gpio, "in", "both");
this.callback("PIR_STARTED");
console.log("[MMM-Pir] [LIB] [PIR] Started!");
} catch (err) {
console.error(`[MMM-Pir] [LIB] [PIR] ${err}`);
this.running = false;
return this.callback("PIR_ERROR", err.message);
}
let options = {
mode: "text",
scriptPath: __dirname,
pythonOptions: ["-u"],
args: [ "-g", this.config.gpio ]
};

this.pir = new PythonShell("MotionSensor.py", options);
this.callback("PIR_STARTED");
console.log("[MMM-Pir] [LIB] [PIR] Started!");
this.running = true;
this.pir.watch((err, value) => {
if (err) {
console.error(`[MMM-Pir] [LIB] [PIR] ${err}`);
return this.callback("PIR_ERROR", err.message);
}
log(`Sensor read value: ${value}`);
if ((value === 1 && !this.config.reverseValue) || (value === 0 && this.config.reverseValue)) {

this.pir.on("message", (message) => {
// detect pir
if (message === "Detected") {
log("Detected presence");
this.callback("PIR_DETECTED");
log(`Detected presence (value: ${value})`);
} else {
console.error("[MMM-Pir] [LIB] [PIR]", message);
this.callback("PIR_ERROR", message);
this.running = false;
}
});
this.pir.on("stderr", (stderr) => {
// handle stderr (a line of text from stderr)
if (this.config.debug) console.error("[MMM-Pir] [LIB] [PIR]", stderr);
this.running = false;
});

this.pir.end((err,code,signal) => {
if (err) console.error("[MMM-Pir] [LIB] [PIR] [PYTHON]",err);
console.warn(`[MMM-Pir] [LIB] [PIR] [PYTHON] The exit code was: ${code}`);
console.warn(`[MMM-Pir] [LIB] [PIR] [PYTHON] The exit signal was: ${signal}`);
});
}

stop () {
if (!this.running || (this.config.gpio === 0)) return;
this.pir.unexport();
this.pir.kill();
this.pir = null;
this.running = false;
this.callback("PIR_STOP");
Expand Down
56 changes: 9 additions & 47 deletions node_helper.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/*******************************
* node_helper for MMM-Pir v1.2 *
* BuGsounet *
********************************/
/**************************
* node_helper for MMM-Pir *
* BuGsounet *
***************************/

var log = (...args) => { /* do nothing */ };
const NodeHelper = require("node_helper");
const LibScreen = require("./components/screenLib.js");
const LibPir = require("./components/pirLib.js");

module.exports = NodeHelper.create({
start () {
this.lib = { error: 0 };
this.pir = null;
this.screen = null;
},
Expand Down Expand Up @@ -43,13 +44,6 @@ module.exports = NodeHelper.create({
async parse () {
if (this.config.debug) log = (...args) => { console.log("[MMM-Pir]", ...args); };
console.log("[MMM-Pir] Version:", require("./package.json").version, "rev:", require("./package.json").rev);
let bugsounet = await this.libraries();
if (bugsounet) {
console.error("[MMM-Pir] [LIBRARY] Warning:", bugsounet, "needed library not loaded !");
console.error("[MMM-Pir] [LIBRARY] Try to solve it with `npm run rebuild` in MMM-Pir directory");
this.sendSocketNotification("FatalError", bugsounet);
return;
}
var callbacks = {
screen: (noti, params) => {
log("[CALLBACK] Screen:", noti, params || "");
Expand All @@ -63,8 +57,7 @@ module.exports = NodeHelper.create({
};
let pirConfig = {
debug: this.config.debug,
gpio: this.config.pir_gpio,
reverseValue: this.config.pir_reverseValue
gpio: this.config.pir_gpio
};

let screenConfig = {
Expand All @@ -78,42 +71,11 @@ module.exports = NodeHelper.create({
wrandrForceMode: this.config.wrandrForceMode
};

this.pir = new this.lib.Pir(pirConfig, callbacks.pir);
this.pir = new LibPir(pirConfig, callbacks.pir);
this.pir.start();
this.screen = new this.lib.Screen(screenConfig, callbacks.screen);
this.screen = new LibScreen(screenConfig, callbacks.screen);
this.screen.activate();
console.log("[MMM-Pir] Started!");
this.sendSocketNotification("INITIALIZED");
},

/** Load sensible library without black screen **/
libraries () {
let libraries = [
// { "library to load" : "store library name" }
{ "./components/pirLib.js": "Pir" },
{ "./components/screenLib.js": "Screen" }
];
let errors = 0;
return new Promise((resolve) => {
libraries.forEach((library) => {
for (const [name, configValues] of Object.entries(library)) {
let libraryToLoad = name;
let libraryName = configValues;
try {
if (!this.lib[libraryName]) {
this.lib[libraryName] = require(libraryToLoad);
log(`[DATABASE] Loaded: ${libraryToLoad} --> this.lib.${libraryName}`);
}
} catch (e) {
console.error(`[MMM-Pir] [DATABASE] ${libraryToLoad} Loading error!`, e.message);
this.sendSocketNotification("WARNING", { library: libraryToLoad });
errors++;
this.lib.error = errors;
}
}
});
if (!errors) console.log("[MMM-Pir] [DATABASE] All libraries loaded!");
resolve(errors);
});
}
});
Loading

0 comments on commit 7dc9367

Please sign in to comment.