node-web-gpio 1.0.33 → 1.1.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/dist/index.d.ts +1 -2
- package/dist/index.js +29 -15
- package/package.json +11 -12
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
3
|
+
exports.OperationError = exports.InvalidAccessError = exports.GPIOPort = exports.GPIOPortMap = exports.GPIOAccess = void 0;
|
|
4
|
+
exports.requestGPIOAccess = requestGPIOAccess;
|
|
5
|
+
const node_events_1 = require("node:events");
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const os = require("node:os");
|
|
8
|
+
const path = require("node:path");
|
|
7
9
|
/**
|
|
8
10
|
* Interval of file system polling, in milliseconds.
|
|
9
11
|
*/
|
|
@@ -30,13 +32,21 @@ function parseUint16(parseString) {
|
|
|
30
32
|
const n = Number.parseInt(parseString, 10);
|
|
31
33
|
if (0 <= n && n <= Uint16Max)
|
|
32
34
|
return n;
|
|
35
|
+
// biome-ignore lint/style/noUselessElse:
|
|
33
36
|
else
|
|
34
37
|
throw new RangeError(`Must be between 0 and ${Uint16Max}.`);
|
|
35
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* GPIO0 オフセット
|
|
41
|
+
* @see {@link https://github.com/raspberrypi/linux/issues/6037}
|
|
42
|
+
*/
|
|
43
|
+
const GpioOffset = process.platform === 'linux' && 6.6 <= Number(os.release().match(/\d+\.\d+/))
|
|
44
|
+
? 512
|
|
45
|
+
: 0;
|
|
36
46
|
/**
|
|
37
47
|
* GPIO
|
|
38
48
|
*/
|
|
39
|
-
class GPIOAccess extends
|
|
49
|
+
class GPIOAccess extends node_events_1.EventEmitter {
|
|
40
50
|
/** ポート */
|
|
41
51
|
_ports;
|
|
42
52
|
/** GPIO チェンジイベントハンドラ */
|
|
@@ -48,6 +58,7 @@ class GPIOAccess extends events_1.EventEmitter {
|
|
|
48
58
|
constructor(ports) {
|
|
49
59
|
super();
|
|
50
60
|
this._ports = ports == null ? new GPIOPortMap() : ports;
|
|
61
|
+
// biome-ignore lint/complexity/noForEach:
|
|
51
62
|
this._ports.forEach((port) => port.on('change', (event) => {
|
|
52
63
|
this.emit('change', event);
|
|
53
64
|
}));
|
|
@@ -82,7 +93,7 @@ exports.GPIOPortMap = GPIOPortMap;
|
|
|
82
93
|
/**
|
|
83
94
|
* GPIO ポート
|
|
84
95
|
*/
|
|
85
|
-
class GPIOPort extends
|
|
96
|
+
class GPIOPort extends node_events_1.EventEmitter {
|
|
86
97
|
/** ポート番号 */
|
|
87
98
|
_portNumber;
|
|
88
99
|
/** ポーリング間隔 */
|
|
@@ -105,7 +116,7 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
105
116
|
*/
|
|
106
117
|
constructor(portNumber) {
|
|
107
118
|
super();
|
|
108
|
-
this._portNumber = parseUint16(portNumber.toString());
|
|
119
|
+
this._portNumber = parseUint16(portNumber.toString()) + GpioOffset;
|
|
109
120
|
this._pollingInterval = PollingInterval;
|
|
110
121
|
this._direction = new OperationError('Unknown direction.');
|
|
111
122
|
this._exported = new OperationError('Unknown export.');
|
|
@@ -165,7 +176,7 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
165
176
|
throw new InvalidAccessError(`Must be "in" or "out".`);
|
|
166
177
|
}
|
|
167
178
|
try {
|
|
168
|
-
await
|
|
179
|
+
await node_fs_1.promises.access(path.join(SysfsGPIOPath, this.portName));
|
|
169
180
|
this._exported = true;
|
|
170
181
|
}
|
|
171
182
|
catch {
|
|
@@ -174,17 +185,18 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
174
185
|
try {
|
|
175
186
|
clearInterval(this._timeout);
|
|
176
187
|
if (!this.exported) {
|
|
177
|
-
await
|
|
188
|
+
await node_fs_1.promises.writeFile(path.join(SysfsGPIOPath, 'export'), String(this.portNumber));
|
|
178
189
|
}
|
|
179
|
-
await
|
|
190
|
+
await node_fs_1.promises.writeFile(path.join(SysfsGPIOPath, this.portName, 'direction'), direction);
|
|
180
191
|
if (direction === 'in') {
|
|
181
192
|
this._timeout = setInterval(
|
|
182
193
|
// eslint-disable-next-line
|
|
183
194
|
this.read.bind(this), this._pollingInterval);
|
|
184
195
|
}
|
|
196
|
+
// biome-ignore lint/suspicious/noExplicitAny:
|
|
185
197
|
}
|
|
186
198
|
catch (error) {
|
|
187
|
-
if (this._exportRetry
|
|
199
|
+
if (this._exportRetry === 0) {
|
|
188
200
|
await sleep(100);
|
|
189
201
|
console.warn('May be the first time port access. Retry..');
|
|
190
202
|
++this._exportRetry;
|
|
@@ -205,7 +217,8 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
205
217
|
async unexport() {
|
|
206
218
|
clearInterval(this._timeout);
|
|
207
219
|
try {
|
|
208
|
-
await
|
|
220
|
+
await node_fs_1.promises.writeFile(path.join(SysfsGPIOPath, 'unexport'), String(this.portNumber));
|
|
221
|
+
// biome-ignore lint/suspicious/noExplicitAny:
|
|
209
222
|
}
|
|
210
223
|
catch (error) {
|
|
211
224
|
throw new OperationError(error);
|
|
@@ -221,13 +234,14 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
221
234
|
throw new InvalidAccessError(`The exported must be true and value of direction must be "in".`);
|
|
222
235
|
}
|
|
223
236
|
try {
|
|
224
|
-
const buffer = await
|
|
237
|
+
const buffer = await node_fs_1.promises.readFile(path.join(SysfsGPIOPath, this.portName, 'value'));
|
|
225
238
|
const value = parseUint16(buffer.toString());
|
|
226
239
|
if (this._value !== value) {
|
|
227
240
|
this._value = value;
|
|
228
241
|
this.emit('change', { value, port: this });
|
|
229
242
|
}
|
|
230
243
|
return value;
|
|
244
|
+
// biome-ignore lint/suspicious/noExplicitAny:
|
|
231
245
|
}
|
|
232
246
|
catch (error) {
|
|
233
247
|
throw new OperationError(error);
|
|
@@ -242,7 +256,8 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
242
256
|
throw new InvalidAccessError(`The exported must be true and value of direction must be "out".`);
|
|
243
257
|
}
|
|
244
258
|
try {
|
|
245
|
-
await
|
|
259
|
+
await node_fs_1.promises.writeFile(path.join(SysfsGPIOPath, this.portName, 'value'), parseUint16(value.toString()).toString());
|
|
260
|
+
// biome-ignore lint/suspicious/noExplicitAny:
|
|
246
261
|
}
|
|
247
262
|
catch (error) {
|
|
248
263
|
throw new OperationError(error);
|
|
@@ -287,7 +302,6 @@ async function requestGPIOAccess() {
|
|
|
287
302
|
]));
|
|
288
303
|
return new GPIOAccess(ports);
|
|
289
304
|
}
|
|
290
|
-
exports.requestGPIOAccess = requestGPIOAccess;
|
|
291
305
|
/**
|
|
292
306
|
* 待機 関数
|
|
293
307
|
* @param ms スリープ時間(ミリ秒)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-web-gpio",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "GPIO access with Node.js",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,19 +14,17 @@
|
|
|
14
14
|
"author": "Kohei Watanabe <kou029w@gmail.com>",
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@
|
|
18
|
-
"@
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"typedoc": "^0.25.0",
|
|
25
|
-
"typescript": "^5.0.0"
|
|
17
|
+
"@biomejs/biome": "^1.9.3",
|
|
18
|
+
"@types/node": "^22.7.4",
|
|
19
|
+
"husky": "^9.1.6",
|
|
20
|
+
"lint-staged": "^15.2.10",
|
|
21
|
+
"prettier": "^3.3.3",
|
|
22
|
+
"typedoc": "^0.26.7",
|
|
23
|
+
"typescript": "^5.6.2"
|
|
26
24
|
},
|
|
27
25
|
"scripts": {
|
|
28
26
|
"build": "tsc",
|
|
29
|
-
"lint": "
|
|
27
|
+
"lint": "biome lint index.ts",
|
|
30
28
|
"prepare": "husky install && rm -rf dist && npm run build",
|
|
31
29
|
"precommit": "lint-staged",
|
|
32
30
|
"docs": "npm run remove:docs && npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./ README.md",
|
|
@@ -46,5 +44,6 @@
|
|
|
46
44
|
"robotics",
|
|
47
45
|
"robots",
|
|
48
46
|
"rpi"
|
|
49
|
-
]
|
|
47
|
+
],
|
|
48
|
+
"packageManager": "yarn@1.22.19+sha1.4ba7fc5c6e704fce2066ecbfb0b0d8976fe62447"
|
|
50
49
|
}
|