@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 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
+ }