node-web-gpio 1.0.10 → 1.0.11
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 +2 -2
- package/dist/index.js +31 -21
- package/package.json +10 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { EventEmitter } from
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
3
|
declare type PortNumber = number;
|
|
4
4
|
declare type PortName = string;
|
|
5
5
|
declare type PinName = string;
|
|
6
|
-
declare type DirectionMode =
|
|
6
|
+
declare type DirectionMode = 'in' | 'out';
|
|
7
7
|
declare type GPIOValue = 0 | 1;
|
|
8
8
|
interface GPIOChangeEvent {
|
|
9
9
|
readonly value: GPIOValue;
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ const path = require("path");
|
|
|
8
8
|
* Interval of file system polling, in milliseconds.
|
|
9
9
|
*/
|
|
10
10
|
const PollingInterval = 100;
|
|
11
|
-
const SysfsGPIOPath =
|
|
11
|
+
const SysfsGPIOPath = '/sys/class/gpio';
|
|
12
12
|
const GPIOPortMapSizeMax = 1024;
|
|
13
13
|
const Uint16Max = 65535;
|
|
14
14
|
function parseUint16(string) {
|
|
@@ -19,13 +19,15 @@ function parseUint16(string) {
|
|
|
19
19
|
throw new RangeError(`Must be between 0 and ${Uint16Max}.`);
|
|
20
20
|
}
|
|
21
21
|
class GPIOAccess extends events_1.EventEmitter {
|
|
22
|
+
_ports;
|
|
23
|
+
onchange;
|
|
22
24
|
constructor(ports) {
|
|
23
25
|
super();
|
|
24
26
|
this._ports = ports == null ? new GPIOPortMap() : ports;
|
|
25
|
-
this._ports.forEach(port => port.on(
|
|
26
|
-
this.emit(
|
|
27
|
+
this._ports.forEach((port) => port.on('change', (event) => {
|
|
28
|
+
this.emit('change', event);
|
|
27
29
|
}));
|
|
28
|
-
this.on(
|
|
30
|
+
this.on('change', (event) => {
|
|
29
31
|
if (this.onchange !== undefined)
|
|
30
32
|
this.onchange(event);
|
|
31
33
|
});
|
|
@@ -37,7 +39,7 @@ class GPIOAccess extends events_1.EventEmitter {
|
|
|
37
39
|
* Unexport all exported GPIO ports.
|
|
38
40
|
*/
|
|
39
41
|
async unexportAll() {
|
|
40
|
-
await Promise.all([...this.ports.values()].map(port => port.exported ? port.unexport() : undefined));
|
|
42
|
+
await Promise.all([...this.ports.values()].map((port) => port.exported ? port.unexport() : undefined));
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
exports.GPIOAccess = GPIOAccess;
|
|
@@ -48,14 +50,22 @@ class GPIOPortMap extends Map {
|
|
|
48
50
|
}
|
|
49
51
|
exports.GPIOPortMap = GPIOPortMap;
|
|
50
52
|
class GPIOPort extends events_1.EventEmitter {
|
|
53
|
+
_portNumber;
|
|
54
|
+
_pollingInterval;
|
|
55
|
+
_direction;
|
|
56
|
+
_exported;
|
|
57
|
+
_exportRetry;
|
|
58
|
+
_value;
|
|
59
|
+
_timeout;
|
|
60
|
+
onchange;
|
|
51
61
|
constructor(portNumber) {
|
|
52
62
|
super();
|
|
53
63
|
this._portNumber = parseUint16(portNumber.toString());
|
|
54
64
|
this._pollingInterval = PollingInterval;
|
|
55
|
-
this._direction = new OperationError(
|
|
56
|
-
this._exported = new OperationError(
|
|
65
|
+
this._direction = new OperationError('Unknown direction.');
|
|
66
|
+
this._exported = new OperationError('Unknown export.');
|
|
57
67
|
this._exportRetry = 0;
|
|
58
|
-
this.on(
|
|
68
|
+
this.on('change', (event) => {
|
|
59
69
|
if (this.onchange !== undefined)
|
|
60
70
|
this.onchange(event);
|
|
61
71
|
});
|
|
@@ -68,7 +78,7 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
68
78
|
}
|
|
69
79
|
get pinName() {
|
|
70
80
|
// NOTE: Unknown pinName.
|
|
71
|
-
return
|
|
81
|
+
return '';
|
|
72
82
|
}
|
|
73
83
|
get direction() {
|
|
74
84
|
if (this._direction instanceof OperationError)
|
|
@@ -94,10 +104,10 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
94
104
|
try {
|
|
95
105
|
clearInterval(this._timeout);
|
|
96
106
|
if (!this.exported) {
|
|
97
|
-
await fs_1.promises.writeFile(path.join(SysfsGPIOPath,
|
|
107
|
+
await fs_1.promises.writeFile(path.join(SysfsGPIOPath, 'export'), String(this.portNumber));
|
|
98
108
|
}
|
|
99
|
-
await fs_1.promises.writeFile(path.join(SysfsGPIOPath, this.portName,
|
|
100
|
-
if (direction ===
|
|
109
|
+
await fs_1.promises.writeFile(path.join(SysfsGPIOPath, this.portName, 'direction'), direction);
|
|
110
|
+
if (direction === 'in') {
|
|
101
111
|
this._timeout = setInterval(
|
|
102
112
|
// eslint-disable-next-line
|
|
103
113
|
this.read.bind(this), this._pollingInterval);
|
|
@@ -106,7 +116,7 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
106
116
|
catch (error) {
|
|
107
117
|
if (this._exportRetry == 0) {
|
|
108
118
|
await sleep(100);
|
|
109
|
-
console.warn(
|
|
119
|
+
console.warn('May be the first time port access. Retry..');
|
|
110
120
|
++this._exportRetry;
|
|
111
121
|
await this.export(direction);
|
|
112
122
|
}
|
|
@@ -120,7 +130,7 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
120
130
|
async unexport() {
|
|
121
131
|
clearInterval(this._timeout);
|
|
122
132
|
try {
|
|
123
|
-
await fs_1.promises.writeFile(path.join(SysfsGPIOPath,
|
|
133
|
+
await fs_1.promises.writeFile(path.join(SysfsGPIOPath, 'unexport'), String(this.portNumber));
|
|
124
134
|
}
|
|
125
135
|
catch (error) {
|
|
126
136
|
throw new OperationError(error);
|
|
@@ -128,15 +138,15 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
128
138
|
this._exported = false;
|
|
129
139
|
}
|
|
130
140
|
async read() {
|
|
131
|
-
if (!(this.exported && this.direction ===
|
|
141
|
+
if (!(this.exported && this.direction === 'in')) {
|
|
132
142
|
throw new InvalidAccessError(`The exported must be true and value of direction must be "in".`);
|
|
133
143
|
}
|
|
134
144
|
try {
|
|
135
|
-
const buffer = await fs_1.promises.readFile(path.join(SysfsGPIOPath, this.portName,
|
|
145
|
+
const buffer = await fs_1.promises.readFile(path.join(SysfsGPIOPath, this.portName, 'value'));
|
|
136
146
|
const value = parseUint16(buffer.toString());
|
|
137
147
|
if (this._value !== value) {
|
|
138
148
|
this._value = value;
|
|
139
|
-
this.emit(
|
|
149
|
+
this.emit('change', { value, port: this });
|
|
140
150
|
}
|
|
141
151
|
return value;
|
|
142
152
|
}
|
|
@@ -145,11 +155,11 @@ class GPIOPort extends events_1.EventEmitter {
|
|
|
145
155
|
}
|
|
146
156
|
}
|
|
147
157
|
async write(value) {
|
|
148
|
-
if (!(this.exported && this.direction ===
|
|
158
|
+
if (!(this.exported && this.direction === 'out')) {
|
|
149
159
|
throw new InvalidAccessError(`The exported must be true and value of direction must be "out".`);
|
|
150
160
|
}
|
|
151
161
|
try {
|
|
152
|
-
await fs_1.promises.writeFile(path.join(SysfsGPIOPath, this.portName,
|
|
162
|
+
await fs_1.promises.writeFile(path.join(SysfsGPIOPath, this.portName, 'value'), parseUint16(value.toString()).toString());
|
|
153
163
|
}
|
|
154
164
|
catch (error) {
|
|
155
165
|
throw new OperationError(error);
|
|
@@ -174,9 +184,9 @@ exports.OperationError = OperationError;
|
|
|
174
184
|
// Web GPIOの仕様に基づく意図的なasync関数の使用なので、ルールを無効化
|
|
175
185
|
// eslint-disable-next-line
|
|
176
186
|
async function requestGPIOAccess() {
|
|
177
|
-
const ports = new GPIOPortMap([...Array(GPIOPortMapSizeMax).keys()].map(portNumber => [
|
|
187
|
+
const ports = new GPIOPortMap([...Array(GPIOPortMapSizeMax).keys()].map((portNumber) => [
|
|
178
188
|
portNumber,
|
|
179
|
-
new GPIOPort(portNumber)
|
|
189
|
+
new GPIOPort(portNumber),
|
|
180
190
|
]));
|
|
181
191
|
return new GPIOAccess(ports);
|
|
182
192
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-web-gpio",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "GPIO access with Node.js",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,16 +14,20 @@
|
|
|
14
14
|
"author": "Kohei Watanabe <kou029w@gmail.com>",
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@types/node": "^16.
|
|
18
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
19
|
-
"@typescript-eslint/parser": "^5.
|
|
20
|
-
"eslint": "^8.
|
|
17
|
+
"@types/node": "^16.11.11",
|
|
18
|
+
"@typescript-eslint/eslint-plugin": "^5.5.0",
|
|
19
|
+
"@typescript-eslint/parser": "^5.5.0",
|
|
20
|
+
"eslint": "^8.4.0",
|
|
21
|
+
"husky": "^7.0.4",
|
|
22
|
+
"lint-staged": "^12.1.2",
|
|
23
|
+
"prettier": "^2.5.1",
|
|
21
24
|
"typescript": "^4.2.3"
|
|
22
25
|
},
|
|
23
26
|
"scripts": {
|
|
24
27
|
"build": "tsc",
|
|
25
28
|
"lint": "eslint index.ts",
|
|
26
|
-
"prepare": "rm -rf dist && npm run build"
|
|
29
|
+
"prepare": "husky install && rm -rf dist && npm run build",
|
|
30
|
+
"precommit": "lint-staged"
|
|
27
31
|
},
|
|
28
32
|
"keywords": [
|
|
29
33
|
"gpio",
|