@mschaeffler/node-red-hourmeter 0.1.1 → 0.2.1
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/README.md +49 -3
- package/examples/hourmeter.json +178 -0
- package/examples/hourmeter.png +0 -0
- package/hourmeter.html +10 -2
- package/hourmeter.js +29 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A working hour meter for NodeRed.
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -12,11 +12,57 @@ $ npm install @mschaeffler/node-red-hourmeter
|
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
The counter is started / stopped accortding to the value of the payload:
|
|
16
|
+
|
|
17
|
+
|type|value|counter is|
|
|
18
|
+
|:---|:----|:--------------|
|
|
19
|
+
|bool|false|stopped|
|
|
20
|
+
||true|started|
|
|
21
|
+
|number|0|stopped|
|
|
22
|
+
||1|started|
|
|
23
|
+
|string|false|stopped|
|
|
24
|
+
||0|stopped|
|
|
25
|
+
||off|stopped|
|
|
26
|
+
||stop|stopped|
|
|
27
|
+
||true|started|
|
|
28
|
+
||1|started|
|
|
29
|
+
||on|started|
|
|
30
|
+
||start|started|
|
|
31
|
+
|
|
32
|
+
A [local filesystem context store](https://nodered.org/docs/user-guide/context#saving-context-data-to-the-file-system) called `storeInFile` is needed to store the internal data.
|
|
33
|
+
|
|
34
|
+
### Input
|
|
35
|
+
|
|
36
|
+
|msg. | type | description |
|
|
37
|
+
|:-------|:-------|:----------------------------------|
|
|
38
|
+
|payload | | Starts or stopps the counting. |
|
|
39
|
+
|reset |boolean |If true, resets the counter to 0.|
|
|
40
|
+
|querry |boolean |If true, just querries the state of the counter.|
|
|
41
|
+
|
|
42
|
+
### Outputs
|
|
43
|
+
|
|
44
|
+
#### boolean value
|
|
45
|
+
|
|
46
|
+
|msg. | type | description |
|
|
47
|
+
|:-------|:-------|:----------------------------------|
|
|
48
|
+
|payload | boolean | Is counting active?|
|
|
49
|
+
|
|
50
|
+
#### hour counter
|
|
51
|
+
|
|
52
|
+
|msg. | type | description |
|
|
53
|
+
|:-------|:-------|:----------------------------------|
|
|
54
|
+
|payload | number | Value of the hour counter|
|
|
55
|
+
|
|
56
|
+
### Parameters
|
|
57
|
+
|
|
58
|
+
|config| type | description |
|
|
59
|
+
|:-----|:-------|:----------------------------------|
|
|
60
|
+
|topic| string | Topic to send output values with.|
|
|
61
|
+
|cycle| number |Cyclic time of output; 0 is only at state change.|
|
|
16
62
|
|
|
17
63
|
## Example Flow
|
|
18
64
|
|
|
19
|
-
[example flow](https://github.com/m-schaeffler/node-red-my-nodes/raw/main/node-red-hourmeter/examples/hourmeter
|
|
65
|
+
[example flow](https://github.com/m-schaeffler/node-red-my-nodes/raw/main/node-red-hourmeter/examples/hourmeter.json)
|
|
20
66
|
|
|
21
67
|
## Author
|
|
22
68
|
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "5535ca07b24e93fb",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "Flow 1",
|
|
6
|
+
"disabled": false,
|
|
7
|
+
"info": "",
|
|
8
|
+
"env": []
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": "3412a0829ce8c730",
|
|
12
|
+
"type": "inject",
|
|
13
|
+
"z": "5535ca07b24e93fb",
|
|
14
|
+
"name": "on",
|
|
15
|
+
"props": [
|
|
16
|
+
{
|
|
17
|
+
"p": "payload"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"p": "topic",
|
|
21
|
+
"vt": "str"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"repeat": "",
|
|
25
|
+
"crontab": "",
|
|
26
|
+
"once": false,
|
|
27
|
+
"onceDelay": 0.1,
|
|
28
|
+
"topic": "",
|
|
29
|
+
"payload": "on",
|
|
30
|
+
"payloadType": "str",
|
|
31
|
+
"x": 430,
|
|
32
|
+
"y": 300,
|
|
33
|
+
"wires": [
|
|
34
|
+
[
|
|
35
|
+
"fd93870645a4a85f"
|
|
36
|
+
]
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "bb79f2418e396b81",
|
|
41
|
+
"type": "inject",
|
|
42
|
+
"z": "5535ca07b24e93fb",
|
|
43
|
+
"name": "off",
|
|
44
|
+
"props": [
|
|
45
|
+
{
|
|
46
|
+
"p": "payload"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"p": "topic",
|
|
50
|
+
"vt": "str"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"repeat": "",
|
|
54
|
+
"crontab": "",
|
|
55
|
+
"once": false,
|
|
56
|
+
"onceDelay": 0.1,
|
|
57
|
+
"topic": "",
|
|
58
|
+
"payload": "0",
|
|
59
|
+
"payloadType": "num",
|
|
60
|
+
"x": 430,
|
|
61
|
+
"y": 340,
|
|
62
|
+
"wires": [
|
|
63
|
+
[
|
|
64
|
+
"fd93870645a4a85f"
|
|
65
|
+
]
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "38045f41e57b15fe",
|
|
70
|
+
"type": "debug",
|
|
71
|
+
"z": "5535ca07b24e93fb",
|
|
72
|
+
"name": "debug 8",
|
|
73
|
+
"active": false,
|
|
74
|
+
"tosidebar": true,
|
|
75
|
+
"console": false,
|
|
76
|
+
"tostatus": true,
|
|
77
|
+
"complete": "payload",
|
|
78
|
+
"targetType": "msg",
|
|
79
|
+
"statusVal": "payload",
|
|
80
|
+
"statusType": "auto",
|
|
81
|
+
"x": 840,
|
|
82
|
+
"y": 220,
|
|
83
|
+
"wires": []
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"id": "d9602022a482778b",
|
|
87
|
+
"type": "inject",
|
|
88
|
+
"z": "5535ca07b24e93fb",
|
|
89
|
+
"name": "reset",
|
|
90
|
+
"props": [
|
|
91
|
+
{
|
|
92
|
+
"p": "reset",
|
|
93
|
+
"v": "true",
|
|
94
|
+
"vt": "bool"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"p": "topic",
|
|
98
|
+
"vt": "str"
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
"repeat": "",
|
|
102
|
+
"crontab": "",
|
|
103
|
+
"once": false,
|
|
104
|
+
"onceDelay": 0.1,
|
|
105
|
+
"topic": "",
|
|
106
|
+
"x": 430,
|
|
107
|
+
"y": 180,
|
|
108
|
+
"wires": [
|
|
109
|
+
[
|
|
110
|
+
"fd93870645a4a85f"
|
|
111
|
+
]
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "5d1dc9dc9d3f149c",
|
|
116
|
+
"type": "inject",
|
|
117
|
+
"z": "5535ca07b24e93fb",
|
|
118
|
+
"name": "querry",
|
|
119
|
+
"props": [
|
|
120
|
+
{
|
|
121
|
+
"p": "querry",
|
|
122
|
+
"v": "true",
|
|
123
|
+
"vt": "bool"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"p": "topic",
|
|
127
|
+
"vt": "str"
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
"repeat": "",
|
|
131
|
+
"crontab": "",
|
|
132
|
+
"once": false,
|
|
133
|
+
"onceDelay": 0.1,
|
|
134
|
+
"topic": "",
|
|
135
|
+
"x": 430,
|
|
136
|
+
"y": 240,
|
|
137
|
+
"wires": [
|
|
138
|
+
[
|
|
139
|
+
"fd93870645a4a85f"
|
|
140
|
+
]
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"id": "fd93870645a4a85f",
|
|
145
|
+
"type": "hourmeter",
|
|
146
|
+
"z": "5535ca07b24e93fb",
|
|
147
|
+
"name": "",
|
|
148
|
+
"topic": "test",
|
|
149
|
+
"cycle": "15",
|
|
150
|
+
"x": 650,
|
|
151
|
+
"y": 260,
|
|
152
|
+
"wires": [
|
|
153
|
+
[
|
|
154
|
+
"38045f41e57b15fe"
|
|
155
|
+
],
|
|
156
|
+
[
|
|
157
|
+
"b539377232a19924"
|
|
158
|
+
]
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"id": "b539377232a19924",
|
|
163
|
+
"type": "debug",
|
|
164
|
+
"z": "5535ca07b24e93fb",
|
|
165
|
+
"name": "debug 9",
|
|
166
|
+
"active": false,
|
|
167
|
+
"tosidebar": true,
|
|
168
|
+
"console": false,
|
|
169
|
+
"tostatus": true,
|
|
170
|
+
"complete": "payload",
|
|
171
|
+
"targetType": "msg",
|
|
172
|
+
"statusVal": "payload",
|
|
173
|
+
"statusType": "auto",
|
|
174
|
+
"x": 840,
|
|
175
|
+
"y": 300,
|
|
176
|
+
"wires": []
|
|
177
|
+
}
|
|
178
|
+
]
|
|
Binary file
|
package/hourmeter.html
CHANGED
|
@@ -4,13 +4,17 @@
|
|
|
4
4
|
color: "#dac4b4",
|
|
5
5
|
defaults: {
|
|
6
6
|
name: {value:""},
|
|
7
|
-
topic:{value:""}
|
|
7
|
+
topic:{value:""},
|
|
8
|
+
cycle:{value:"0", required:true, validate:RED.validators.number()}
|
|
8
9
|
},
|
|
9
10
|
inputs:1,
|
|
10
11
|
outputs:2,
|
|
11
12
|
icon: "font-awesome/fa-signal",
|
|
12
13
|
label: function() {
|
|
13
|
-
return this.name||"hour meter";
|
|
14
|
+
return this.name||this.topic||"hour meter";
|
|
15
|
+
},
|
|
16
|
+
labelStyle: function() {
|
|
17
|
+
return this.name?"node_label_italic":"";
|
|
14
18
|
},
|
|
15
19
|
inputLabels: 'on/off message',
|
|
16
20
|
outputLabels: ['boolean value','hour counter'],
|
|
@@ -27,6 +31,10 @@
|
|
|
27
31
|
<label for="node-input-topic"><i class="fa fa-envelope-o"></i> Topic</label>
|
|
28
32
|
<input type="text" id="node-input-topic" placeholder="Topic">
|
|
29
33
|
</div>
|
|
34
|
+
<div class="form-row">
|
|
35
|
+
<label for="node-input-cycle"><i class="fa fa-hourglass-o"></i> Cycle [min]</label>
|
|
36
|
+
<input type="text" id="node-input-cycle">
|
|
37
|
+
</div>
|
|
30
38
|
</script>
|
|
31
39
|
|
|
32
40
|
<script type="text/html" data-help-name="hourmeter">
|
package/hourmeter.js
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
|
-
module.exports = function(RED)
|
|
1
|
+
module.exports = function(RED)
|
|
2
|
+
{
|
|
2
3
|
|
|
3
|
-
function HourMeterNode(config)
|
|
4
|
+
function HourMeterNode(config)
|
|
5
|
+
{
|
|
4
6
|
RED.nodes.createNode(this,config);
|
|
5
7
|
this.config = config;
|
|
6
8
|
this.topic = config.topic;
|
|
7
|
-
|
|
9
|
+
this.cycle = config.cycle;
|
|
10
|
+
this.interval_id = null;
|
|
11
|
+
var node = this;
|
|
8
12
|
var context = this.context();
|
|
9
|
-
|
|
13
|
+
|
|
14
|
+
if( this.cycle > 0 )
|
|
15
|
+
{
|
|
16
|
+
this.interval_id = setInterval( function()
|
|
17
|
+
{
|
|
18
|
+
node.emit( "input", {querry:true} );
|
|
19
|
+
}, this.cycle*60*1000 );
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
node.on( 'input', function(msg,send,done)
|
|
23
|
+
{
|
|
10
24
|
if( msg.reset )
|
|
11
25
|
{
|
|
12
26
|
context.set( "data", undefined, "storeInFile" );
|
|
@@ -28,6 +42,7 @@ module.exports = function(RED) {
|
|
|
28
42
|
case "1":
|
|
29
43
|
case "true":
|
|
30
44
|
case "on":
|
|
45
|
+
case "start":
|
|
31
46
|
if( data.switchOn === undefined )
|
|
32
47
|
{
|
|
33
48
|
data.switchOn = now;
|
|
@@ -38,6 +53,7 @@ module.exports = function(RED) {
|
|
|
38
53
|
case "0":
|
|
39
54
|
case "false":
|
|
40
55
|
case "off":
|
|
56
|
+
case "stop":
|
|
41
57
|
if( data.switchOn !== undefined )
|
|
42
58
|
{
|
|
43
59
|
data.counter += (now - data.switchOn)/1000;
|
|
@@ -62,8 +78,16 @@ module.exports = function(RED) {
|
|
|
62
78
|
send( [ { topic:this.topic, payload:data.switchOn!==undefined }, { topic:this.topic, payload:out } ] );
|
|
63
79
|
}
|
|
64
80
|
done();
|
|
65
|
-
});
|
|
81
|
+
} );
|
|
66
82
|
}
|
|
67
83
|
|
|
68
84
|
RED.nodes.registerType("hourmeter",HourMeterNode);
|
|
85
|
+
|
|
86
|
+
HourMeterNode.prototype.close = function()
|
|
87
|
+
{
|
|
88
|
+
if( this.interval_id != null )
|
|
89
|
+
{
|
|
90
|
+
clearInterval( this.interval_id );
|
|
91
|
+
}
|
|
92
|
+
}
|
|
69
93
|
}
|
package/package.json
CHANGED