@thehighestbit/node-red-contrib-hdc302x 1.0.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/README.md +43 -0
- package/hdc302x.html +74 -0
- package/hdc302x.js +73 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# node-red-contrib-hdc302x
|
|
2
|
+
|
|
3
|
+
A Node-RED node for reading temperature and humidity data from Texas Instruments HDC302x sensors over I2C.
|
|
4
|
+
|
|
5
|
+
## Supported Sensors
|
|
6
|
+
|
|
7
|
+
- HDC3020
|
|
8
|
+
- HDC3021
|
|
9
|
+
- HDC3022
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cd ~/.node-red
|
|
15
|
+
npm install @thehighestbit/node-red-contrib-hdc302x
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Configuration
|
|
19
|
+
|
|
20
|
+
| Property | Description |
|
|
21
|
+
|----------|-------------|
|
|
22
|
+
| I2C Address | Sensor address: 0x44, 0x45, 0x46, or 0x47 |
|
|
23
|
+
| I2C Bus | I2C bus number (default: 1) |
|
|
24
|
+
| Read Interval | Polling interval in ms (minimum 1000ms). Leave blank to disable polling. |
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
The node outputs temperature and humidity readings as a JSON payload:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"payload": {
|
|
33
|
+
"temperature": 25.5,
|
|
34
|
+
"humidity": 45.2
|
|
35
|
+
},
|
|
36
|
+
"topic": "hdc302x/0x44"
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Triggering Reads
|
|
41
|
+
|
|
42
|
+
- **Automatic polling**: Set a read interval to poll the sensor automatically
|
|
43
|
+
- **Manual trigger**: Send any message to the node input to trigger an immediate read
|
package/hdc302x.html
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('hdc302x', {
|
|
3
|
+
category: 'input',
|
|
4
|
+
color: '#d6d6d6',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: { value: '' },
|
|
7
|
+
i2c_address: { value: '0x44', required: true },
|
|
8
|
+
i2c_bus: { value: 1, required: true, validate: RED.validators.number() },
|
|
9
|
+
read_interval: {
|
|
10
|
+
value: '',
|
|
11
|
+
required: false,
|
|
12
|
+
validate: function(v) { return v === '' || (!isNaN(v) && Number(v) >= 1000); }
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
inputs: 1,
|
|
16
|
+
outputs: 1,
|
|
17
|
+
icon: 'font-awesome/fa-thermometer-half',
|
|
18
|
+
label: function () {
|
|
19
|
+
return this.name || `HDC302x ${this.i2c_address}`;
|
|
20
|
+
},
|
|
21
|
+
oneditprepare: function () {
|
|
22
|
+
const $address = $('#node-input-i2c_address');
|
|
23
|
+
$address.typedInput({
|
|
24
|
+
types: [{
|
|
25
|
+
value: 'i2c_address',
|
|
26
|
+
options: [
|
|
27
|
+
{ value: '0x44', label: '0x44' },
|
|
28
|
+
{ value: '0x45', label: '0x45' },
|
|
29
|
+
{ value: '0x46', label: '0x46' },
|
|
30
|
+
{ value: '0x47', label: '0x47' }
|
|
31
|
+
]
|
|
32
|
+
}]
|
|
33
|
+
});
|
|
34
|
+
$address.typedInput('value', this.i2c_address || '0x44');
|
|
35
|
+
},
|
|
36
|
+
oneditsave: function () {
|
|
37
|
+
this.i2c_address = $('#node-input-i2c_address').typedInput('value');
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<script type="text/html" data-template-name="hdc302x">
|
|
43
|
+
<div class="form-row">
|
|
44
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
45
|
+
<input type="text" id="node-input-name">
|
|
46
|
+
</div>
|
|
47
|
+
<div class="form-row">
|
|
48
|
+
<label for="node-input-i2c_address"><i class="fa fa-microchip"></i> I2C Address</label>
|
|
49
|
+
<input type="text" id="node-input-i2c_address">
|
|
50
|
+
</div>
|
|
51
|
+
<div class="form-row">
|
|
52
|
+
<label for="node-input-i2c_bus"><i class="fa fa-plug"></i> I2C Bus</label>
|
|
53
|
+
<input type="number" id="node-input-i2c_bus" min="0" max="10" value="1">
|
|
54
|
+
</div>
|
|
55
|
+
<div class="form-row">
|
|
56
|
+
<label for="node-input-read_interval"><i class="fa fa-clock-o"></i> Interval (ms)</label>
|
|
57
|
+
<input type="number" id="node-input-read_interval" min="1000" step="100" placeholder="Not polling">
|
|
58
|
+
</div>
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<script type="text/markdown" data-help-name="hdc302x">
|
|
62
|
+
Enables reading of Texas Instruments HDC302x temperature and humidity sensor data over I2C.
|
|
63
|
+
|
|
64
|
+
### Outputs
|
|
65
|
+
: payload (JSON) : Temperature (°C) and humidity (%) readings.
|
|
66
|
+
|
|
67
|
+
### Configuration
|
|
68
|
+
- **I2C Address**: Address of the sensor (0x44, 0x45, 0x46, or 0x47).
|
|
69
|
+
- **I2C Bus**: I2C bus number (default: 1).
|
|
70
|
+
- **Read Interval**: Polling interval in milliseconds (>= 1000). Leave blank to disable polling.
|
|
71
|
+
|
|
72
|
+
### Triggering Reads
|
|
73
|
+
Send any message to the input to trigger an immediate sensor read.
|
|
74
|
+
</script>
|
package/hdc302x.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const { HDC302x } = require('hdc302x');
|
|
2
|
+
|
|
3
|
+
module.exports = function (RED) {
|
|
4
|
+
function HDC302xNode(config) {
|
|
5
|
+
RED.nodes.createNode(this, config);
|
|
6
|
+
|
|
7
|
+
var node = this;
|
|
8
|
+
this.i2c_address = parseInt(config.i2c_address, 16);
|
|
9
|
+
this.i2c_bus = Number(config.i2c_bus);
|
|
10
|
+
const intervalMs = Number(config.read_interval);
|
|
11
|
+
this.read_interval = Number.isFinite(intervalMs) && intervalMs >= 1000 ? intervalMs : null;
|
|
12
|
+
|
|
13
|
+
const MAX_ATTEMPTS = 3;
|
|
14
|
+
let timer = null;
|
|
15
|
+
let active = true;
|
|
16
|
+
let sensor = null;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
sensor = new HDC302x({
|
|
20
|
+
i2cBusNumber: node.i2c_bus,
|
|
21
|
+
address: node.i2c_address
|
|
22
|
+
});
|
|
23
|
+
} catch (err) {
|
|
24
|
+
node.error(`Failed to initialize HDC302x sensor: ${err.message}`);
|
|
25
|
+
node.status({ fill: "red", shape: "ring", text: "init failed" });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function scheduleNext(delayMs) {
|
|
30
|
+
if (!active || node.read_interval === null) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
clearTimeout(timer);
|
|
34
|
+
timer = setTimeout(() => readSensor(), delayMs);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function readSensor(attempt = 1, msg = {}) {
|
|
38
|
+
try {
|
|
39
|
+
const { temperature, humidity } = await sensor.read();
|
|
40
|
+
|
|
41
|
+
node.status({ fill: "green", shape: "dot", text: `${temperature.toFixed(1)}°C, ${humidity.toFixed(1)}%` });
|
|
42
|
+
node.send({
|
|
43
|
+
payload: {
|
|
44
|
+
temperature: temperature,
|
|
45
|
+
humidity: humidity
|
|
46
|
+
},
|
|
47
|
+
topic: msg.topic || node.name || `hdc302x/0x${node.i2c_address.toString(16)}`
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
scheduleNext(node.read_interval);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
if (attempt < MAX_ATTEMPTS) {
|
|
53
|
+
node.status({ fill: "yellow", shape: "ring", text: `retry ${attempt}` });
|
|
54
|
+
setTimeout(() => readSensor(attempt + 1, msg), 1000);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
node.status({ fill: "red", shape: "ring", text: "read failed" });
|
|
58
|
+
node.warn(`Failed to read HDC302x sensor at 0x${node.i2c_address.toString(16)}: ${err.message}`);
|
|
59
|
+
scheduleNext(node.read_interval);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
node.on("input", (msg) => readSensor(1, msg));
|
|
64
|
+
node.on("close", () => {
|
|
65
|
+
active = false;
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
scheduleNext(0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
RED.nodes.registerType("hdc302x", HDC302xNode);
|
|
73
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@thehighestbit/node-red-contrib-hdc302x",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "Node-RED node for Texas Instruments HDC302x temperature and humidity sensor",
|
|
8
|
+
"main": "hdc302x.js",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"node-red": {
|
|
13
|
+
"version": ">=2.0.0",
|
|
14
|
+
"nodes": {
|
|
15
|
+
"hdc302x": "hdc302x.js"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"hdc302x": "1.0.0"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"node-red",
|
|
23
|
+
"hdc302x",
|
|
24
|
+
"hdc3020",
|
|
25
|
+
"hdc3021",
|
|
26
|
+
"hdc3022",
|
|
27
|
+
"temperature",
|
|
28
|
+
"humidity",
|
|
29
|
+
"i2c",
|
|
30
|
+
"raspberry",
|
|
31
|
+
"iot"
|
|
32
|
+
],
|
|
33
|
+
"author": "TheHighestBit",
|
|
34
|
+
"license": "ISC",
|
|
35
|
+
"files": [
|
|
36
|
+
"hdc302x.js",
|
|
37
|
+
"hdc302x.html"
|
|
38
|
+
],
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"hdc302x": "1.0.0"
|
|
41
|
+
},
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/TheHighestBit/node-red-contrib-hdc302x.git"
|
|
45
|
+
}
|
|
46
|
+
}
|