smart-nodes 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/SmartNodesContext.json +1 -0
- package/__tests__/compare.test.js +57 -0
- package/__tests__/counter.test.js +54 -0
- package/__tests__/forwarder.test.js +54 -0
- package/__tests__/heating-curve.test.js +54 -0
- package/__tests__/hysteresis.test.js +54 -0
- package/__tests__/light.test.js +49 -0
- package/__tests__/logic.test.js +61 -0
- package/__tests__/long-press.test.js +54 -0
- package/__tests__/mixing-valve.test.js +54 -0
- package/__tests__/mode-selector.test.js +54 -0
- package/__tests__/multi-press.test.js +54 -0
- package/__tests__/scene.test.js +54 -0
- package/__tests__/scheduler.test.js +54 -0
- package/__tests__/shutter-complex.test.js +54 -0
- package/__tests__/shutter.test.js +54 -0
- package/__tests__/statistics.test.js +54 -0
- package/__tests__/test-helper.js +40 -0
- package/__tests__/text-exec.test.js +54 -0
- package/forwarder/forwarder.js +16 -13
- package/heating-curve/heating-curve.html +5 -5
- package/jest.config.js +5 -0
- package/light/light.js +7 -1
- package/mixing-valve/mixing-valve.js +12 -4
- package/package.json +8 -4
- package/persistence.js +38 -8
- package/smart_helper.js +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -218,3 +218,9 @@
|
|
|
218
218
|
## Version 0.5.2:
|
|
219
219
|
|
|
220
220
|
- Added alarm mode to mixing-valve.
|
|
221
|
+
|
|
222
|
+
## Version 0.6.0:
|
|
223
|
+
|
|
224
|
+
- Reduced amount of messages sent by light node when it is in alarm mode.
|
|
225
|
+
- Fixed forwarder node causing an error when no topic was sent.
|
|
226
|
+
- Added Jest example for all nodes to be able to debug nodes in vscode.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"idn1":{"temperature_outside":10,"last_flow_temperature":null}}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../compare/compare.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_compare";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("compare", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-compare",
|
|
16
|
+
comparator: "SMALLER",
|
|
17
|
+
value1: 5,
|
|
18
|
+
value2: 9,
|
|
19
|
+
wires: [["n2"]]
|
|
20
|
+
},
|
|
21
|
+
{ id: "n2", type: "helper" }
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
helper.load(nodeModule, flow, () =>
|
|
25
|
+
{
|
|
26
|
+
try
|
|
27
|
+
{
|
|
28
|
+
const n1 = helper.getNode("n1");
|
|
29
|
+
const n2 = helper.getNode("n2");
|
|
30
|
+
|
|
31
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
32
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
33
|
+
|
|
34
|
+
n2.on("input", (msg) =>
|
|
35
|
+
{
|
|
36
|
+
try
|
|
37
|
+
{
|
|
38
|
+
console.log("Received:", msg);
|
|
39
|
+
expect(msg).toBeDefined();
|
|
40
|
+
}
|
|
41
|
+
catch (err)
|
|
42
|
+
{
|
|
43
|
+
done(err);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
48
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
49
|
+
|
|
50
|
+
setImmediate(() => { done(); });
|
|
51
|
+
}
|
|
52
|
+
catch (err)
|
|
53
|
+
{
|
|
54
|
+
done(err);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../counter/counter.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_counter";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("counter", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-counter",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../forwarder/forwarder.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_forwarder";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("forwarder", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-forwarder",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../heating-curve/heating-curve.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_heating-curve";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("heating-curve", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-heating-curve",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../hysteresis/hysteresis.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_hysteresis";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("hysteresis", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-hysteresis",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../light/light.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_light-control";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("light node", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{ id: "n1", type: nodeType, name: "test-light", wires: [["n2"]] },
|
|
13
|
+
{ id: "n2", type: "helper" }
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
helper.load(nodeModule, flow, () =>
|
|
17
|
+
{
|
|
18
|
+
try
|
|
19
|
+
{
|
|
20
|
+
const n1 = helper.getNode("n1");
|
|
21
|
+
const n2 = helper.getNode("n2");
|
|
22
|
+
|
|
23
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
24
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
25
|
+
|
|
26
|
+
n2.on("input", (msg) =>
|
|
27
|
+
{
|
|
28
|
+
try
|
|
29
|
+
{
|
|
30
|
+
console.log("Received:", msg);
|
|
31
|
+
expect(msg).toBeDefined();
|
|
32
|
+
}
|
|
33
|
+
catch (err)
|
|
34
|
+
{
|
|
35
|
+
done(err);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
n1.receive({ topic: "toggle" });
|
|
40
|
+
n1.receive({ topic: "toggle" });
|
|
41
|
+
|
|
42
|
+
setImmediate(() => { done(); });
|
|
43
|
+
}
|
|
44
|
+
catch (err)
|
|
45
|
+
{
|
|
46
|
+
done(err);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../logic/logic.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_logic";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("logic", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-logic",
|
|
16
|
+
out_true: "{}",
|
|
17
|
+
out_true_type: "json",
|
|
18
|
+
out_false: "{}",
|
|
19
|
+
out_false_type: "json",
|
|
20
|
+
inverts: "",
|
|
21
|
+
send_only_change: true,
|
|
22
|
+
outputs: 1,
|
|
23
|
+
wires: [["n2"]]
|
|
24
|
+
},
|
|
25
|
+
{ id: "n2", type: "helper" }
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
helper.load(nodeModule, flow, () =>
|
|
29
|
+
{
|
|
30
|
+
try
|
|
31
|
+
{
|
|
32
|
+
const n1 = helper.getNode("n1");
|
|
33
|
+
const n2 = helper.getNode("n2");
|
|
34
|
+
|
|
35
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
36
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
37
|
+
|
|
38
|
+
n2.on("input", (msg) =>
|
|
39
|
+
{
|
|
40
|
+
try
|
|
41
|
+
{
|
|
42
|
+
console.log("Received:", msg);
|
|
43
|
+
expect(msg).toBeDefined();
|
|
44
|
+
}
|
|
45
|
+
catch (err)
|
|
46
|
+
{
|
|
47
|
+
done(err);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
52
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
53
|
+
|
|
54
|
+
setImmediate(() => { done(); });
|
|
55
|
+
}
|
|
56
|
+
catch (err)
|
|
57
|
+
{
|
|
58
|
+
done(err);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../long-press/long-press.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_long-press-control";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("long-press", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-long-press",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../mixing-valve/mixing-valve.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_mixing-valve";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("mixing-valve", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-mixing-valve",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../mode-selector/mode-selector.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_mode-selector";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("mode-selector", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-mode-selector",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../multi-press/multi-press.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_multi-press";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("multi-press", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-multi-press",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../scene/scene.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_scene-control";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("scene", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-scene",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../scheduler/scheduler.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_scheduler";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("scheduler", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-scheduler",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../shutter-complex/shutter-complex.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_shutter-complex-control";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("shutter-complex", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-shutter-complex",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../shutter/shutter.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_shutter-control";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("shutter", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-shutter",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../statistics/statistics.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_statistics";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("statistics", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-statistics",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const helper = require("node-red-node-test-helper");
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
helper,
|
|
5
|
+
|
|
6
|
+
init: function ()
|
|
7
|
+
{
|
|
8
|
+
// init must be called once per test file before startServer
|
|
9
|
+
helper.init(require.resolve("node-red"));
|
|
10
|
+
|
|
11
|
+
beforeAll(() => this.startServer());
|
|
12
|
+
afterAll(() => this.stopServer());
|
|
13
|
+
afterEach(() => this.unload().then(() =>
|
|
14
|
+
{
|
|
15
|
+
process.removeAllListeners("uncaughtException");
|
|
16
|
+
process.removeAllListeners("unhandledRejection");
|
|
17
|
+
}));
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
startServer: function ()
|
|
21
|
+
{
|
|
22
|
+
return new Promise((resolve, reject) =>
|
|
23
|
+
{
|
|
24
|
+
helper.startServer((err) => (err ? reject(err) : resolve()));
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
stopServer: function ()
|
|
29
|
+
{
|
|
30
|
+
return new Promise((resolve) =>
|
|
31
|
+
{
|
|
32
|
+
helper.stopServer(() => resolve());
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
unload: function ()
|
|
37
|
+
{
|
|
38
|
+
return helper.unload().catch(() => { });
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const th = require("./test-helper");
|
|
2
|
+
const helper = th.helper;
|
|
3
|
+
const nodeModule = require("../text-exec/text-exec.js");
|
|
4
|
+
|
|
5
|
+
const nodeType = "smart_text-exec";
|
|
6
|
+
|
|
7
|
+
th.init();
|
|
8
|
+
|
|
9
|
+
test("text-exec", (done) =>
|
|
10
|
+
{
|
|
11
|
+
const flow = [
|
|
12
|
+
{
|
|
13
|
+
id: "n1",
|
|
14
|
+
type: nodeType,
|
|
15
|
+
name: "test-text-exec",
|
|
16
|
+
wires: [["n2"]]
|
|
17
|
+
},
|
|
18
|
+
{ id: "n2", type: "helper" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
helper.load(nodeModule, flow, () =>
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
const n1 = helper.getNode("n1");
|
|
26
|
+
const n2 = helper.getNode("n2");
|
|
27
|
+
|
|
28
|
+
if (!n1) return done(new Error("Node n1 wurde nicht erstellt"));
|
|
29
|
+
if (!n2) return done(new Error("Helper-Node n2 fehlt"));
|
|
30
|
+
|
|
31
|
+
n2.on("input", (msg) =>
|
|
32
|
+
{
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
console.log("Received:", msg);
|
|
36
|
+
expect(msg).toBeDefined();
|
|
37
|
+
}
|
|
38
|
+
catch (err)
|
|
39
|
+
{
|
|
40
|
+
done(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
n1.receive({ topic: "1", payload: 7 });
|
|
45
|
+
n1.receive({ topic: "1", payload: 17 });
|
|
46
|
+
|
|
47
|
+
setImmediate(() => { done(); });
|
|
48
|
+
}
|
|
49
|
+
catch (err)
|
|
50
|
+
{
|
|
51
|
+
done(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
package/forwarder/forwarder.js
CHANGED
|
@@ -80,28 +80,31 @@ module.exports = function (RED)
|
|
|
80
80
|
let handleTopic = msg =>
|
|
81
81
|
{
|
|
82
82
|
let real_topic = helper.getTopicName(msg.topic);
|
|
83
|
+
let new_state = null;
|
|
83
84
|
|
|
84
|
-
if (real_topic
|
|
85
|
-
real_topic = real_topic.replace("set_state", "set");
|
|
86
|
-
|
|
87
|
-
if (real_topic == "set_inverted")
|
|
85
|
+
if (real_topic != null)
|
|
88
86
|
{
|
|
89
|
-
real_topic
|
|
90
|
-
|
|
87
|
+
if (real_topic.startsWith("set_state"))
|
|
88
|
+
real_topic = real_topic.replace("set_state", "set");
|
|
89
|
+
|
|
90
|
+
if (real_topic == "set_inverted")
|
|
91
|
+
{
|
|
92
|
+
real_topic = "set";
|
|
93
|
+
msg.payload = !msg.payload;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (real_topic == "enable" || (real_topic == "set" && msg.payload))
|
|
97
|
+
new_state = true;
|
|
98
|
+
else if (real_topic == "disable" || (real_topic == "set" && !msg.payload))
|
|
99
|
+
new_state = false;
|
|
91
100
|
}
|
|
92
101
|
|
|
93
|
-
let new_state = null;
|
|
94
|
-
if (real_topic == "enable" || (real_topic == "set" && msg.payload))
|
|
95
|
-
new_state = true;
|
|
96
|
-
else if (real_topic == "disable" || (real_topic == "set" && !msg.payload))
|
|
97
|
-
new_state = false;
|
|
98
|
-
|
|
99
102
|
switch (real_topic)
|
|
100
103
|
{
|
|
101
104
|
case "debug":
|
|
102
105
|
helper.nodeDebug(node, {
|
|
103
106
|
node_settings,
|
|
104
|
-
forward_true,
|
|
107
|
+
forward_true,
|
|
105
108
|
forward_false,
|
|
106
109
|
forward_last_on_enable,
|
|
107
110
|
});
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
$("#node-input-room_setpoint")
|
|
28
28
|
.css("max-width", "4rem")
|
|
29
29
|
.spinner({
|
|
30
|
-
min:
|
|
31
|
-
max:
|
|
30
|
+
min: 5,
|
|
31
|
+
max: 100,
|
|
32
32
|
step: 0.5,
|
|
33
33
|
change: function (event, ui)
|
|
34
34
|
{
|
|
@@ -77,8 +77,8 @@
|
|
|
77
77
|
$("#node-input-flow_max")
|
|
78
78
|
.css("max-width", "4rem")
|
|
79
79
|
.spinner({
|
|
80
|
-
min:
|
|
81
|
-
max:
|
|
80
|
+
min: 5,
|
|
81
|
+
max: 100,
|
|
82
82
|
change: function (event, ui)
|
|
83
83
|
{
|
|
84
84
|
var value = parseFloat(this.value);
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
.css("max-width", "4rem")
|
|
95
95
|
.spinner({
|
|
96
96
|
min: 5,
|
|
97
|
-
max:
|
|
97
|
+
max: 100,
|
|
98
98
|
change: function (event, ui)
|
|
99
99
|
{
|
|
100
100
|
var value = parseFloat(this.value);
|
package/jest.config.js
ADDED
package/light/light.js
CHANGED
|
@@ -46,6 +46,7 @@ module.exports = function (RED)
|
|
|
46
46
|
let alarm_action = config.alarm_action || "NOTHING";
|
|
47
47
|
let alarm_off_action = config.alarm_off_action || "NOTHING";
|
|
48
48
|
let mode = config.mode || "BOOL";
|
|
49
|
+
let current_output_state = null;
|
|
49
50
|
|
|
50
51
|
// ##################
|
|
51
52
|
// # Runtime values #
|
|
@@ -149,6 +150,7 @@ module.exports = function (RED)
|
|
|
149
150
|
doRestartTimer = false;
|
|
150
151
|
|
|
151
152
|
node_settings.last_value = msg.payload;
|
|
153
|
+
current_output_state = node_settings.last_value;
|
|
152
154
|
break;
|
|
153
155
|
|
|
154
156
|
case "off":
|
|
@@ -360,8 +362,11 @@ module.exports = function (RED)
|
|
|
360
362
|
}
|
|
361
363
|
}
|
|
362
364
|
|
|
363
|
-
if (
|
|
365
|
+
if (real_topic != "status" && current_output_state !== node_settings.last_value)
|
|
366
|
+
{
|
|
364
367
|
node.send({ payload: node_settings.last_value });
|
|
368
|
+
current_output_state = node_settings.last_value;
|
|
369
|
+
}
|
|
365
370
|
|
|
366
371
|
// Output is on, now
|
|
367
372
|
if (node_settings.last_value && doRestartTimer)
|
|
@@ -410,6 +415,7 @@ module.exports = function (RED)
|
|
|
410
415
|
node_settings.last_value = 0;
|
|
411
416
|
|
|
412
417
|
node.send({ payload: node_settings.last_value });
|
|
418
|
+
current_output_state = node_settings.last_value;
|
|
413
419
|
notifyCentral(false);
|
|
414
420
|
|
|
415
421
|
setStatus();
|
|
@@ -155,6 +155,9 @@ module.exports = function (RED)
|
|
|
155
155
|
|
|
156
156
|
let real_topic = helper.getTopicName(msg.topic);
|
|
157
157
|
|
|
158
|
+
if (real_topic == null)
|
|
159
|
+
node.warn("No topic set");
|
|
160
|
+
|
|
158
161
|
if (real_topic.startsWith("set_state"))
|
|
159
162
|
real_topic = real_topic.replace("set_state", "set");
|
|
160
163
|
|
|
@@ -354,16 +357,21 @@ module.exports = function (RED)
|
|
|
354
357
|
node_settings.alarm_active = false;
|
|
355
358
|
return;
|
|
356
359
|
}
|
|
360
|
+
|
|
361
|
+
stopSampling();
|
|
362
|
+
startSampling();
|
|
357
363
|
}
|
|
358
364
|
else
|
|
359
365
|
{
|
|
360
366
|
force_position = null;
|
|
361
|
-
|
|
367
|
+
stopSampling();
|
|
368
|
+
stopChanging();
|
|
369
|
+
|
|
370
|
+
if (node_settings.enabled)
|
|
371
|
+
startSampling();
|
|
372
|
+
else
|
|
362
373
|
doOffMode();
|
|
363
374
|
}
|
|
364
|
-
|
|
365
|
-
stopSampling();
|
|
366
|
-
startSampling();
|
|
367
375
|
break;
|
|
368
376
|
|
|
369
377
|
default:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smart-nodes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Controls light, shutters and more. Includes common used logic and statistic nodes to control your home.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node-red",
|
|
@@ -27,7 +27,9 @@
|
|
|
27
27
|
"text execution"
|
|
28
28
|
],
|
|
29
29
|
"scripts": {
|
|
30
|
-
"test": "
|
|
30
|
+
"test": "jest",
|
|
31
|
+
"test:watch": "jest --watch",
|
|
32
|
+
"test:debug": "node --inspect-brk node_modules/jest/bin/jest.js --runInBand"
|
|
31
33
|
},
|
|
32
34
|
"author": "Samuel Bergen",
|
|
33
35
|
"license": "MIT",
|
|
@@ -59,9 +61,11 @@
|
|
|
59
61
|
"type": "git",
|
|
60
62
|
"url": "https://github.com/BergenSoft/smart-nodes"
|
|
61
63
|
},
|
|
62
|
-
"dependencies": {},
|
|
63
64
|
"devDependencies": {
|
|
64
|
-
"font-awesome": "^4.7.0"
|
|
65
|
+
"font-awesome": "^4.7.0",
|
|
66
|
+
"jest": "^27.5.1",
|
|
67
|
+
"node-red": "^4.1.1",
|
|
68
|
+
"node-red-node-test-helper": "^0.3.5"
|
|
65
69
|
},
|
|
66
70
|
"engines": {
|
|
67
71
|
"node": ">=10"
|
package/persistence.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const { log } = require('console');
|
|
2
|
+
|
|
1
3
|
let instance = null;
|
|
2
4
|
|
|
3
5
|
module.exports = function (_RED)
|
|
@@ -5,21 +7,31 @@ module.exports = function (_RED)
|
|
|
5
7
|
if (instance != null)
|
|
6
8
|
return instance;
|
|
7
9
|
|
|
8
|
-
let RED = _RED;
|
|
9
10
|
let hasChanges = false;
|
|
11
|
+
let inTestMode = _RED.settings.userDir == null;
|
|
12
|
+
|
|
13
|
+
// used for local debugging
|
|
14
|
+
if (inTestMode)
|
|
15
|
+
console.log("####### Test Mode detected #######");
|
|
10
16
|
|
|
11
17
|
const fs = require('fs');
|
|
12
|
-
const
|
|
18
|
+
const pathLib = require('path');
|
|
19
|
+
|
|
20
|
+
// Fallback, falls RED.settings.userDir in Tests nicht gesetzt ist
|
|
21
|
+
const userDir = (_RED.settings && _RED.settings.userDir) ? _RED.settings.userDir : process.cwd();
|
|
22
|
+
const filePath = pathLib.join(userDir, 'SmartNodesContext.json');
|
|
13
23
|
|
|
14
24
|
let globalData = {};
|
|
15
25
|
|
|
16
|
-
if (fs.existsSync(
|
|
26
|
+
if (fs.existsSync(filePath))
|
|
17
27
|
{
|
|
18
28
|
try
|
|
19
29
|
{
|
|
20
|
-
let fileContent = fs.readFileSync(
|
|
30
|
+
let fileContent = fs.readFileSync(filePath, "utf8");
|
|
21
31
|
globalData = Object.assign({}, JSON.parse(fileContent));
|
|
22
|
-
|
|
32
|
+
|
|
33
|
+
if (inTestMode)
|
|
34
|
+
console.log("Loaded:", globalData);
|
|
23
35
|
}
|
|
24
36
|
catch (error)
|
|
25
37
|
{
|
|
@@ -35,12 +47,18 @@ module.exports = function (_RED)
|
|
|
35
47
|
|
|
36
48
|
}, 30 * 1000);
|
|
37
49
|
|
|
50
|
+
// Prevent the interval from keeping the process alive (important for Jest)
|
|
51
|
+
if (interval && typeof interval.unref === "function")
|
|
52
|
+
interval.unref();
|
|
53
|
+
|
|
38
54
|
function save()
|
|
39
55
|
{
|
|
40
56
|
try
|
|
41
57
|
{
|
|
42
|
-
|
|
43
|
-
|
|
58
|
+
if (inTestMode)
|
|
59
|
+
console.log("Save SmartNodeContext", globalData);
|
|
60
|
+
|
|
61
|
+
fs.writeFile(filePath, JSON.stringify(globalData), err =>
|
|
44
62
|
{
|
|
45
63
|
if (err)
|
|
46
64
|
console.error(err);
|
|
@@ -57,6 +75,9 @@ module.exports = function (_RED)
|
|
|
57
75
|
{
|
|
58
76
|
hasChanges = true;
|
|
59
77
|
globalData["id" + id] = data;
|
|
78
|
+
|
|
79
|
+
if (inTestMode)
|
|
80
|
+
save();
|
|
60
81
|
}
|
|
61
82
|
|
|
62
83
|
function get(id)
|
|
@@ -70,6 +91,15 @@ module.exports = function (_RED)
|
|
|
70
91
|
delete globalData["id" + id];
|
|
71
92
|
}
|
|
72
93
|
|
|
73
|
-
|
|
94
|
+
function close()
|
|
95
|
+
{
|
|
96
|
+
if (interval)
|
|
97
|
+
{
|
|
98
|
+
clearInterval(interval);
|
|
99
|
+
interval = null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
instance = { set, get, del, close };
|
|
74
104
|
return instance;
|
|
75
105
|
};
|
package/smart_helper.js
CHANGED
|
@@ -291,16 +291,16 @@ module.exports = {
|
|
|
291
291
|
* Target range = 100 to 200
|
|
292
292
|
*
|
|
293
293
|
* current number = 0
|
|
294
|
-
* scale(
|
|
294
|
+
* scale(0, 0, 10, 100, 200) => 100
|
|
295
295
|
*
|
|
296
296
|
* current number = 5
|
|
297
297
|
* scale(5, 0, 10, 100, 200) => 150
|
|
298
298
|
*
|
|
299
299
|
* current number = 10
|
|
300
|
-
* scale(
|
|
300
|
+
* scale(10, 0, 10, 100, 200) => 200
|
|
301
301
|
*
|
|
302
|
-
* current number = 20 (out of
|
|
303
|
-
* scale(
|
|
302
|
+
* current number = 20 (input out of range!)
|
|
303
|
+
* scale(20, 0, 10, 100, 200) => 300 (output out of range!)
|
|
304
304
|
*/
|
|
305
305
|
scale(number, inMin, inMax, outMin, outMax)
|
|
306
306
|
{
|