Skip to content

Commit

Permalink
Merge pull request #15 from Tom-Hirschberger/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
Tom-Hirschberger authored Oct 30, 2024
2 parents c2cb7b6 + 0c59039 commit deab5b1
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 274 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package.json
package-lock.json
*.js
*.mjs
3 changes: 0 additions & 3 deletions .prettierrc.json

This file was deleted.

7 changes: 0 additions & 7 deletions .stylelintrc.json

This file was deleted.

2 changes: 1 addition & 1 deletion MMM-CommandToNotification.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* MagicMirror²
* Module: CommandToNotification
* Module: MMM-CommandToNotification
*
* By Tom Hirschberger
* MIT Licensed.
Expand Down
137 changes: 74 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,70 @@

MagicMirror² module which periodically calls configured scripts and sends the output as value of configurable notifications. The values can be displayed in modules like [MMM-ValuesByNotification](https://github.com/Tom-Hirschberger/MMM-ValuesByNotification).

Example scripts to read the temperature values of DHT11, DHT22, DS18B20, HTU21, SHT31d, SHTC3 or BME280 connected to the raspbarry or Miflora sensors in reach of bluetooth are included in the scripts directory. There is a documentation in the [scripts directory](./scripts/README.md), too.
Example scripts to read the temperature values of DHT11, DHT22, DS18B20, HTU21, SHT31d, SHTC3 or BME280 connected to the raspbarry or Miflora sensors in reach of bluetooth are included in the scripts directory. There is a documentation in the [scripts directory](./scripts/README.md), too.

## Basic installation
## Installation

```bash
cd ~/MagicMirror/modules
git clone https://github.com/Tom-Hirschberger/MMM-CommandToNotification
cd MMM-CommandToNotification
npm install
```

## Update

Just enter the module's directory, pull the update:

```bash
cd ~/MagicMirror/modules/MMM-CommandToNotification
git pull
```

## Basic configuration

Add the following code to your ~/MagicMirror/config/config.js:

```json5
```js
{
module: "MMM-CommandToNotification",
disabled: false,
config: {
commands: [
]
},
module: "MMM-CommandToNotification",
config: {
commands: [
]
},
},
```

### General

<!-- prettier-ignore-start -->
| Option | Description | Type | Default |
| ------- | --- | --- | --- |
| ------- | ----------- | ---- | ------- |
| updateInterval | How often should the scripts be iterated (in seconds) | Integer | 30 |
| commands | A array containing the command definition objects | Array | [] |
| sync | Should the commands called one by one (true) or should all be started as fast as possible (false). Can be overriden for each command in the command configuration | Boolean | true |
| debug | This flag controls if debug messages should be output on the console | Boolean | false |
<!-- prettier-ignore-end -->

### Commands

<!-- prettier-ignore-start -->
| Option | Description | Mandatory | Type | Default |
| ------- | --- | --- | --- | --- |
| ------- | ----------- | --------- | ---- | ------- |
| script | Either a absolute path or the realtive path of a script starting at the "scripts" directory. | true | String | null |
| args | Arguments which should be passed to the script | false | String | "" |
| timeout | Should the script be killed if it does not return within a specific amount of milliseconds? | false | Integer | infinity |
| notifications | A array containing names of the notifications to send if script returns output. If not present the script gets called but no notification will be send. If you want to override the payload instead of using the output please look at the notification section. | false | Array | [] |
| sync | Should the command by run synchronous (next command will be called after this one, true) or asynchronous (directly proceed with the next one and process output when the command finishes, false) | Boolean | true |
| delayNext | Wait some amount of time (milliseconds) before the next command will be processed after this one has called. Make sure to set to updateInterval of the module to a value that is enough time to call and process all commands with all delays summed up! | Integer | 0 |
| sync | Should the command by run synchronous (next command will be called after this one, true) or asynchronous (directly proceed with the next one and process output when the command finishes, false) | Boolean | false | true |
| delayNext | Wait some amount of time (milliseconds) before the next command will be processed after this one has called. Make sure to set to updateInterval of the module to a value that is enough time to call and process all commands with all delays summed up! | false | Integer | 0 |
| conditions | A map containing conditions that need to match to send the notifications | false | Map | null |
<!-- prettier-ignore-end -->

### Notifications

The notifications array contains all notifications that should be send if a command is called (and the conditions matched).
There may be situations where you want send a notification with a specific payload instead of the output of the script. You can do so if you specify a array instead of the string identifiying the notification.
Lets see the following example:

```json
```js
notifications: [
["TEST1","MY_NEW_PAYLOAD"],
"TEST2",
Expand All @@ -68,57 +78,58 @@ In this example the notification "TEST1" will have "MY_NEW_PAYLOAD" as output wh

**All conditions specified need to match to send notifications!**

| Option | Description | Type | Default |
| ------- | --- | --- | --- |
<!-- prettier-ignore-start -->
| Option | Description | Type | Default |
| -------| ----------- | -----| ------- |
| returnCode | Specify either a single return code or a array of return codes that need to match. If a array is specified one of the values need to match (or condition). | Integer or Array of Integer | null |
| outputContains | Specify either a single string or a array of possible strings which of one need to be present in the output (or condition). | null |
| outputContains | Specify either a single string or a array of possible strings which of one need to be present in the output (or condition). | Integer or Array of Integer | null |
<!-- prettier-ignore-end -->

### Example

Add the following example to produce the following result:

* the scripts will be iterated every 10 seconds
* the script "scripts/randomInteger.js" gets called every iteration
* a random number between -10 and 10 is produced
* the timeout of the script is 5 seconds. If the script does not produce any output within 5 seconds the call will be aborted and no notifications will be send
* if the script produces output the output will be send as payload of the notifications TEST1 and TEST2
* the script "scripts/randomNumberJson.js" will be called every fourth iteration because a three skips are configured
* the script calculates a random number between -50 and 20 and produces a json object containing two values ("integer" and "float"). The float value is the random number the integer value the random number rounded as integer.
* the timeout of the script is set to 10 seconds
* the result of the script (JSON object as string) will be send as payload of notification TEST3 while TEST4 will be send with payload "true"
* As the condition `returnCode` is set to `[0,1,2]` the notifications `TEST3` and `TEST4` only will be send if the script `./randomNumberJson.js` only will be send if the script exits with code 0, 1 or 2

```json5
- the scripts will be iterated every 10 seconds
- the script "scripts/randomInteger.js" gets called every iteration
- a random number between -10 and 10 is produced
- the timeout of the script is 1000 milliseconds. If the script does not produce any output within 1000 milliseconds the call will be aborted and no notifications will be send
- if the script produces output the output will be send as payload of the notifications TEST1 and TEST2
- the script "scripts/randomNumberJson.js" will be called every fourth iteration because a three skips are configured
- the script calculates a random number between -50 and 20 and produces a json object containing two values ("integer" and "float"). The float value is the random number the integer value the random number rounded as integer.
- the timeout of the script is set to 2000 milliseconds
- the result of the script (JSON object as string) will be send as payload of notification TEST3 while TEST4 will be send with payload "true"
- As the condition `returnCode` is set to `[0,1,2]` the notifications `TEST3` and `TEST4` only will be send if the script `./randomNumberJson.js` only will be send if the script exits with code 0, 1 or 2

```js
{
module: "MMM-CommandToNotification",
disabled: false,
config: {
updateInterval: 10,
commands: [
{
script: "./randomInteger.js",
args: "-10 10",
timeout: 5,
notifications: [
"TEST1",
"TEST2",
],
},
{
script: "./randomNumberJson.js",
args: "-50 20",
skips: 3,
timeout: 10,
conditions: {
returnCode: [0,1,2]
}
notifications: [
"TEST3",
["TEST4", true]
],
}
]
},
module: "MMM-CommandToNotification",
config: {
updateInterval: 10,
commands: [
{
script: "./randomInteger.js",
args: "-10 10",
timeout: 1000,
notifications: [
"TEST1",
"TEST2",
],
},
{
script: "./randomNumberJson.js",
args: "-50 20",
skips: 3,
timeout: 2000,
conditions: {
returnCode: [0,1,2]
},
notifications: [
"TEST3",
["TEST4", true]
],
}
]
},
},
```

Expand All @@ -128,6 +139,6 @@ Add the following example to produce the following result:

## Developer commands

* `npm install` - Install devDependencies like ESLint.
* `npm run lint` - Run linting and formatter checks.
* `npm run lint:fix` - Fix linting and formatter issues.
- `npm install` - Install devDependencies like ESLint.
- `npm run lint` - Run linting and formatter checks.
- `npm run lint:fix` - Fix linting and formatter issues.
47 changes: 36 additions & 11 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,42 @@ import globals from "globals"

const config = [
{
files: ["**/*.js", "**/*.mjs"],
},
{
ignores: ["**/doc/configs/webcam-config.js"],
},
{
files: ["**/*.js"],
languageOptions: {
globals: {
...globals.browser,
...globals.node,
Log: "readonly",
Module: "readonly",
},
sourceType: "commonjs"
},
plugins: {
...eslintPluginStylistic.configs["recommended-flat"].plugins,
},
rules: {
...eslintPluginJs.configs.all.rules,
...eslintPluginStylistic.configs["recommended-flat"].rules,
"@stylistic/brace-style": ["error", "1tbs", { allowSingleLine: true }],
"@stylistic/brace-style": ["error", "1tbs", {allowSingleLine: true}],
"@stylistic/comma-dangle": ["error", "only-multiline"],
"@stylistic/indent": ["error", "tab"],
"@stylistic/max-statements-per-line": ["error", { max: 2 }],
"@stylistic/max-statements-per-line": ["error", {max: 2}],
"@stylistic/no-tabs": "off",
"@stylistic/quotes": ["error", "double"],
"capitalized-comments": "off",
"complexity": "off",
complexity: "off",
"consistent-this": "off",
"eqeqeq": "warn",
eqeqeq: "warn",
"init-declarations": "off",
"max-depth": "off",
"max-lines": "off",
"max-lines-per-function": "off",
"max-params": "off",
"max-statements": ["error", { max: 80 }],
"max-statements": ["error", {max: 80}],
"no-else-return": "off",
"no-eq-null": "warn",
"no-await-in-loop": "warn",
"no-compare-neg-zero": "warn",
"no-inline-comments": "off",
"no-magic-numbers": "off",
"no-negated-condition": "off",
Expand All @@ -51,7 +49,34 @@ const config = [
"one-var": "off",
"prefer-destructuring": "off",
"sort-keys": "off",
strict: "off",
}
},
{
files: ["**/*.mjs"],
languageOptions: {
globals: {
...globals.node
},
sourceType: "module"
},
plugins: {
...eslintPluginStylistic.configs["all-flat"].plugins
},
rules: {
...eslintPluginStylistic.configs["all-flat"].rules,
"@stylistic/array-element-newline": "off",
"@stylistic/comma-dangle": ["error", "only-multiline"],
"@stylistic/indent": ["error", "tab"],
"@stylistic/object-property-newline": "off",
"@stylistic/padded-blocks": ["error", "never"],
"@stylistic/quote-props": ["error", "as-needed"],
"@stylistic/semi": ["error", "never"],
"func-style": "off",
"max-lines-per-function": ["error", 100],
"no-magic-numbers": "off",
"one-var": "off"
}
}
]

Expand Down
12 changes: 5 additions & 7 deletions node_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
const Log = require("logger")
const NodeHelper = require("node_helper")

const spawnSync = require("child_process").spawnSync
const spawn = require("child_process").spawn
const fs = require("fs")
const path = require("path")
const spawnSync = require("node:child_process").spawnSync
const spawn = require("node:child_process").spawn
const fs = require("node:fs")
const path = require("node:path")
const scriptsDir = path.join(__dirname, "/scripts")

module.exports = NodeHelper.create({
Expand All @@ -24,8 +24,7 @@ module.exports = NodeHelper.create({
},

sleep(milliseconds) {
// eslint-disable-next-line no-promise-executor-return
return new Promise(resolve => setTimeout(resolve, milliseconds))
return new Promise((resolve) => { setTimeout(resolve, milliseconds) })
},

// https://stackoverflow.com/questions/14332721/node-js-spawn-child-process-and-get-terminal-output-live
Expand Down Expand Up @@ -237,7 +236,6 @@ module.exports = NodeHelper.create({
if (self.config.debug) {
Log.log(`${self.name}: Delaying next: ${curCmdConfig.delayNext}`)
}
// eslint-disable-next-line no-await-in-loop
await self.sleep(curCmdConfig.delayNext)
}
} else {
Expand Down
21 changes: 10 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
{
"name": "MMM-CommandToNotification",
"version": "0.0.8",
"name": "mmm-commandtonotification",
"version": "0.0.9",
"description": "A MagicMirror² module which calls system-commands or scripts periodically and sends the output as notifications.",
"main": "MMM-CommandToNotification",
"dependencies": {},
"main": "MMM-CommandToNotification.js",
"repository": {
"type": "git",
"url": "git@github.com:Tom-Hirschberger/MMM-CommandToNotification.git"
},
"keywords": [
"MagicMirror",
"MM",
"scripts",
"commands",
"notifications",
Expand All @@ -27,14 +25,15 @@
},
"homepage": "https://github.com/Tom-Hirschberger/MMM-CommandToNotification/#readme",
"devDependencies": {
"@eslint/js": "^9.10.0",
"@stylistic/eslint-plugin": "^2.8.0",
"eslint": "^9.10.0",
"globals": "^15.9.0"
"@eslint/js": "^9.13.0",
"@stylistic/eslint-plugin": "^2.9.0",
"eslint": "^9.13.0",
"globals": "^15.11.0",
"prettier": "^3.3.3"
},
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"lint": "eslint . && prettier . --check",
"lint:fix": "eslint . --fix && prettier . --write",
"test": "npm run lint"
}
}
5 changes: 5 additions & 0 deletions prettier.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const config = {
trailingComma: "none"
}

export default config
Loading

0 comments on commit deab5b1

Please sign in to comment.