node-web-gpio 1.0.10 → 1.0.14

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 CHANGED
@@ -1,24 +1,53 @@
1
1
  /// <reference types="node" />
2
- import { EventEmitter } from "events";
2
+ import { EventEmitter } from 'events';
3
+ /** ポート番号 */
3
4
  declare type PortNumber = number;
5
+ /** ポート名 */
4
6
  declare type PortName = string;
7
+ /** ピン名 */
5
8
  declare type PinName = string;
6
- declare type DirectionMode = "in" | "out";
9
+ /** 入出力方向 */
10
+ declare type DirectionMode = 'in' | 'out';
11
+ /** GPIO 値 0: LOW / 1: HIGH */
7
12
  declare type GPIOValue = 0 | 1;
13
+ /**
14
+ * GPIO チェンジイベント
15
+ */
8
16
  interface GPIOChangeEvent {
17
+ /** 入出力値 */
9
18
  readonly value: GPIOValue;
19
+ /** ポート */
10
20
  readonly port: GPIOPort;
11
21
  }
22
+ /**
23
+ * GPIO チェンジイベントハンドラ
24
+ */
12
25
  interface GPIOChangeEventHandler {
26
+ /** イベント */
13
27
  (event: GPIOChangeEvent): void;
14
28
  }
29
+ /**
30
+ * GPIO
31
+ */
15
32
  export declare class GPIOAccess extends EventEmitter {
33
+ /** ポート */
16
34
  private readonly _ports;
35
+ /** GPIO チェンジイベントハンドラ */
17
36
  onchange: GPIOChangeEventHandler | undefined;
37
+ /**
38
+ * Creates an instance of GPIOAccess.
39
+ * @param ports ポート番号
40
+ */
18
41
  constructor(ports?: GPIOPortMap);
42
+ /**
43
+ * ポート情報取得処理
44
+ * @return 現在のポート情報
45
+ */
19
46
  get ports(): GPIOPortMap;
20
47
  /**
21
48
  * Unexport all exported GPIO ports.
49
+ * 全てのポート開放をする
50
+ * @return ポート開放結果
22
51
  */
23
52
  unexportAll(): Promise<void>;
24
53
  }
@@ -27,30 +56,97 @@ export declare class GPIOAccess extends EventEmitter {
27
56
  */
28
57
  export declare class GPIOPortMap extends Map<PortNumber, GPIOPort> {
29
58
  }
59
+ /**
60
+ * GPIO ポート
61
+ */
30
62
  export declare class GPIOPort extends EventEmitter {
63
+ /** ポート番号 */
31
64
  private readonly _portNumber;
65
+ /** ポーリング間隔 */
32
66
  private readonly _pollingInterval;
67
+ /** 入出力方向 */
33
68
  private _direction;
69
+ /** エクスポート */
34
70
  private _exported;
71
+ /** エクスポートリトライ回数 */
35
72
  private _exportRetry;
73
+ /** 入出力値 */
36
74
  private _value;
75
+ /** タイムアウト値 */
37
76
  private _timeout;
77
+ /** GPIO チェンジイベントハンドラ */
38
78
  onchange: GPIOChangeEventHandler | undefined;
79
+ /**
80
+ * Creates an instance of GPIOPort.
81
+ * @param portNumber ポート番号
82
+ */
39
83
  constructor(portNumber: PortNumber);
84
+ /**
85
+ * ポート番号取得処理
86
+ * @return 現在のポート番号
87
+ */
40
88
  get portNumber(): PortNumber;
89
+ /**
90
+ * ポート名取得処理
91
+ * @return 現在のポート名
92
+ */
41
93
  get portName(): PortName;
94
+ /**
95
+ * ピン名取得処理
96
+ * @return 現在のピン名
97
+ */
42
98
  get pinName(): PinName;
99
+ /**
100
+ * GPIO 入出力方向 getter
101
+ * @return 現在のGPIO 入出力方向
102
+ */
43
103
  get direction(): DirectionMode;
104
+ /**
105
+ * GPIO export の有無 getter
106
+ * @return 現在のGPIO 出力
107
+ */
44
108
  get exported(): boolean;
109
+ /**
110
+ * GPIO 出力処理
111
+ * @param direction GPIO 入出力方向
112
+ * @return export 処理の完了
113
+ */
45
114
  export(direction: DirectionMode): Promise<void>;
115
+ /**
116
+ * Unexport exported GPIO ports.
117
+ * ポート開放をする
118
+ * @return ポート開放処理の完了
119
+ */
46
120
  unexport(): Promise<void>;
121
+ /**
122
+ * 入力値読み取り処理
123
+ * @return 読み取り処理の完了
124
+ */
47
125
  read(): Promise<GPIOValue>;
126
+ /**
127
+ * 出力値書き込み処理
128
+ * @return 読み取り処理の完了
129
+ */
48
130
  write(value: GPIOValue): Promise<void>;
49
131
  }
132
+ /**
133
+ * 無効なアクセスエラー
134
+ */
50
135
  export declare class InvalidAccessError extends Error {
136
+ /**
137
+ * Creates an instance of InvalidAccessError.
138
+ * @param message エラーメッセージ
139
+ */
51
140
  constructor(message: string);
52
141
  }
142
+ /**
143
+ * 操作エラー
144
+ */
53
145
  export declare class OperationError extends Error {
146
+ /**
147
+ * Creates an instance of OperationError.
148
+ * @param message エラーメッセージ
149
+ */
54
150
  constructor(message: string);
55
151
  }
56
152
  export declare function requestGPIOAccess(): Promise<GPIOAccess>;
package/dist/index.js CHANGED
@@ -8,36 +8,68 @@ const path = require("path");
8
8
  * Interval of file system polling, in milliseconds.
9
9
  */
10
10
  const PollingInterval = 100;
11
- const SysfsGPIOPath = "/sys/class/gpio";
11
+ /**
12
+ * GPIO パス
13
+ */
14
+ const SysfsGPIOPath = '/sys/class/gpio';
15
+ /**
16
+ * GPIO ポートマップサイズ
17
+ */
12
18
  const GPIOPortMapSizeMax = 1024;
19
+ /**
20
+ * Uint16 Max サイズ
21
+ */
13
22
  const Uint16Max = 65535;
14
- function parseUint16(string) {
15
- const n = Number.parseInt(string, 10);
23
+ /**
24
+ *
25
+ * Uint16型変換処理
26
+ * @param parseString 変換文字列
27
+ * @return Uint16型変換値
28
+ */
29
+ function parseUint16(parseString) {
30
+ const n = Number.parseInt(parseString, 10);
16
31
  if (0 <= n && n <= Uint16Max)
17
32
  return n;
18
33
  else
19
34
  throw new RangeError(`Must be between 0 and ${Uint16Max}.`);
20
35
  }
36
+ /**
37
+ * GPIO
38
+ */
21
39
  class GPIOAccess extends events_1.EventEmitter {
40
+ /** ポート */
41
+ _ports;
42
+ /** GPIO チェンジイベントハンドラ */
43
+ onchange;
44
+ /**
45
+ * Creates an instance of GPIOAccess.
46
+ * @param ports ポート番号
47
+ */
22
48
  constructor(ports) {
23
49
  super();
24
50
  this._ports = ports == null ? new GPIOPortMap() : ports;
25
- this._ports.forEach(port => port.on("change", event => {
26
- this.emit("change", event);
51
+ this._ports.forEach((port) => port.on('change', (event) => {
52
+ this.emit('change', event);
27
53
  }));
28
- this.on("change", (event) => {
54
+ this.on('change', (event) => {
29
55
  if (this.onchange !== undefined)
30
56
  this.onchange(event);
31
57
  });
32
58
  }
59
+ /**
60
+ * ポート情報取得処理
61
+ * @return 現在のポート情報
62
+ */
33
63
  get ports() {
34
64
  return this._ports;
35
65
  }
36
66
  /**
37
67
  * Unexport all exported GPIO ports.
68
+ * 全てのポート開放をする
69
+ * @return ポート開放結果
38
70
  */
39
71
  async unexportAll() {
40
- await Promise.all([...this.ports.values()].map(port => port.exported ? port.unexport() : undefined));
72
+ await Promise.all([...this.ports.values()].map((port) => port.exported ? port.unexport() : undefined));
41
73
  }
42
74
  }
43
75
  exports.GPIOAccess = GPIOAccess;
@@ -47,39 +79,87 @@ exports.GPIOAccess = GPIOAccess;
47
79
  class GPIOPortMap extends Map {
48
80
  }
49
81
  exports.GPIOPortMap = GPIOPortMap;
82
+ /**
83
+ * GPIO ポート
84
+ */
50
85
  class GPIOPort extends events_1.EventEmitter {
86
+ /** ポート番号 */
87
+ _portNumber;
88
+ /** ポーリング間隔 */
89
+ _pollingInterval;
90
+ /** 入出力方向 */
91
+ _direction;
92
+ /** エクスポート */
93
+ _exported;
94
+ /** エクスポートリトライ回数 */
95
+ _exportRetry;
96
+ /** 入出力値 */
97
+ _value;
98
+ /** タイムアウト値 */
99
+ _timeout;
100
+ /** GPIO チェンジイベントハンドラ */
101
+ onchange;
102
+ /**
103
+ * Creates an instance of GPIOPort.
104
+ * @param portNumber ポート番号
105
+ */
51
106
  constructor(portNumber) {
52
107
  super();
53
108
  this._portNumber = parseUint16(portNumber.toString());
54
109
  this._pollingInterval = PollingInterval;
55
- this._direction = new OperationError("Unknown direction.");
56
- this._exported = new OperationError("Unknown export.");
110
+ this._direction = new OperationError('Unknown direction.');
111
+ this._exported = new OperationError('Unknown export.');
57
112
  this._exportRetry = 0;
58
- this.on("change", (event) => {
113
+ this.on('change', (event) => {
59
114
  if (this.onchange !== undefined)
60
115
  this.onchange(event);
61
116
  });
62
117
  }
118
+ /**
119
+ * ポート番号取得処理
120
+ * @return 現在のポート番号
121
+ */
63
122
  get portNumber() {
64
123
  return this._portNumber;
65
124
  }
125
+ /**
126
+ * ポート名取得処理
127
+ * @return 現在のポート名
128
+ */
66
129
  get portName() {
67
130
  return `gpio${this.portNumber}`;
68
131
  }
132
+ /**
133
+ * ピン名取得処理
134
+ * @return 現在のピン名
135
+ */
69
136
  get pinName() {
70
137
  // NOTE: Unknown pinName.
71
- return "";
138
+ return '';
72
139
  }
140
+ /**
141
+ * GPIO 入出力方向 getter
142
+ * @return 現在のGPIO 入出力方向
143
+ */
73
144
  get direction() {
74
145
  if (this._direction instanceof OperationError)
75
146
  throw this._direction;
76
147
  return this._direction;
77
148
  }
149
+ /**
150
+ * GPIO export の有無 getter
151
+ * @return 現在のGPIO 出力
152
+ */
78
153
  get exported() {
79
154
  if (this._exported instanceof OperationError)
80
155
  throw this._exported;
81
156
  return this._exported;
82
157
  }
158
+ /**
159
+ * GPIO 出力処理
160
+ * @param direction GPIO 入出力方向
161
+ * @return export 処理の完了
162
+ */
83
163
  async export(direction) {
84
164
  if (!/^(in|out)$/.test(direction)) {
85
165
  throw new InvalidAccessError(`Must be "in" or "out".`);
@@ -94,10 +174,10 @@ class GPIOPort extends events_1.EventEmitter {
94
174
  try {
95
175
  clearInterval(this._timeout);
96
176
  if (!this.exported) {
97
- await fs_1.promises.writeFile(path.join(SysfsGPIOPath, "export"), String(this.portNumber));
177
+ await fs_1.promises.writeFile(path.join(SysfsGPIOPath, 'export'), String(this.portNumber));
98
178
  }
99
- await fs_1.promises.writeFile(path.join(SysfsGPIOPath, this.portName, "direction"), direction);
100
- if (direction === "in") {
179
+ await fs_1.promises.writeFile(path.join(SysfsGPIOPath, this.portName, 'direction'), direction);
180
+ if (direction === 'in') {
101
181
  this._timeout = setInterval(
102
182
  // eslint-disable-next-line
103
183
  this.read.bind(this), this._pollingInterval);
@@ -106,7 +186,7 @@ class GPIOPort extends events_1.EventEmitter {
106
186
  catch (error) {
107
187
  if (this._exportRetry == 0) {
108
188
  await sleep(100);
109
- console.warn("May be the first time port access. Retry..");
189
+ console.warn('May be the first time port access. Retry..');
110
190
  ++this._exportRetry;
111
191
  await this.export(direction);
112
192
  }
@@ -117,26 +197,35 @@ class GPIOPort extends events_1.EventEmitter {
117
197
  this._direction = direction;
118
198
  this._exported = true;
119
199
  }
200
+ /**
201
+ * Unexport exported GPIO ports.
202
+ * ポート開放をする
203
+ * @return ポート開放処理の完了
204
+ */
120
205
  async unexport() {
121
206
  clearInterval(this._timeout);
122
207
  try {
123
- await fs_1.promises.writeFile(path.join(SysfsGPIOPath, "unexport"), String(this.portNumber));
208
+ await fs_1.promises.writeFile(path.join(SysfsGPIOPath, 'unexport'), String(this.portNumber));
124
209
  }
125
210
  catch (error) {
126
211
  throw new OperationError(error);
127
212
  }
128
213
  this._exported = false;
129
214
  }
215
+ /**
216
+ * 入力値読み取り処理
217
+ * @return 読み取り処理の完了
218
+ */
130
219
  async read() {
131
- if (!(this.exported && this.direction === "in")) {
220
+ if (!(this.exported && this.direction === 'in')) {
132
221
  throw new InvalidAccessError(`The exported must be true and value of direction must be "in".`);
133
222
  }
134
223
  try {
135
- const buffer = await fs_1.promises.readFile(path.join(SysfsGPIOPath, this.portName, "value"));
224
+ const buffer = await fs_1.promises.readFile(path.join(SysfsGPIOPath, this.portName, 'value'));
136
225
  const value = parseUint16(buffer.toString());
137
226
  if (this._value !== value) {
138
227
  this._value = value;
139
- this.emit("change", { value, port: this });
228
+ this.emit('change', { value, port: this });
140
229
  }
141
230
  return value;
142
231
  }
@@ -144,12 +233,16 @@ class GPIOPort extends events_1.EventEmitter {
144
233
  throw new OperationError(error);
145
234
  }
146
235
  }
236
+ /**
237
+ * 出力値書き込み処理
238
+ * @return 読み取り処理の完了
239
+ */
147
240
  async write(value) {
148
- if (!(this.exported && this.direction === "out")) {
241
+ if (!(this.exported && this.direction === 'out')) {
149
242
  throw new InvalidAccessError(`The exported must be true and value of direction must be "out".`);
150
243
  }
151
244
  try {
152
- await fs_1.promises.writeFile(path.join(SysfsGPIOPath, this.portName, "value"), parseUint16(value.toString()).toString());
245
+ await fs_1.promises.writeFile(path.join(SysfsGPIOPath, this.portName, 'value'), parseUint16(value.toString()).toString());
153
246
  }
154
247
  catch (error) {
155
248
  throw new OperationError(error);
@@ -157,14 +250,28 @@ class GPIOPort extends events_1.EventEmitter {
157
250
  }
158
251
  }
159
252
  exports.GPIOPort = GPIOPort;
253
+ /**
254
+ * 無効なアクセスエラー
255
+ */
160
256
  class InvalidAccessError extends Error {
257
+ /**
258
+ * Creates an instance of InvalidAccessError.
259
+ * @param message エラーメッセージ
260
+ */
161
261
  constructor(message) {
162
262
  super(message);
163
263
  this.name = this.constructor.name;
164
264
  }
165
265
  }
166
266
  exports.InvalidAccessError = InvalidAccessError;
267
+ /**
268
+ * 操作エラー
269
+ */
167
270
  class OperationError extends Error {
271
+ /**
272
+ * Creates an instance of OperationError.
273
+ * @param message エラーメッセージ
274
+ */
168
275
  constructor(message) {
169
276
  super(message);
170
277
  this.name = this.constructor.name;
@@ -174,13 +281,18 @@ exports.OperationError = OperationError;
174
281
  // Web GPIOの仕様に基づく意図的なasync関数の使用なので、ルールを無効化
175
282
  // eslint-disable-next-line
176
283
  async function requestGPIOAccess() {
177
- const ports = new GPIOPortMap([...Array(GPIOPortMapSizeMax).keys()].map(portNumber => [
284
+ const ports = new GPIOPortMap([...Array(GPIOPortMapSizeMax).keys()].map((portNumber) => [
178
285
  portNumber,
179
- new GPIOPort(portNumber)
286
+ new GPIOPort(portNumber),
180
287
  ]));
181
288
  return new GPIOAccess(ports);
182
289
  }
183
290
  exports.requestGPIOAccess = requestGPIOAccess;
291
+ /**
292
+ * 待機 関数
293
+ * @param ms スリープ時間(ミリ秒)
294
+ * @return 待機完了
295
+ */
184
296
  function sleep(ms) {
185
297
  return new Promise((resolve) => {
186
298
  return setTimeout(resolve, ms);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-web-gpio",
3
- "version": "1.0.10",
3
+ "version": "1.0.14",
4
4
  "description": "GPIO access with Node.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -14,16 +14,24 @@
14
14
  "author": "Kohei Watanabe <kou029w@gmail.com>",
15
15
  "license": "MIT",
16
16
  "devDependencies": {
17
- "@types/node": "^16.0.0",
18
- "@typescript-eslint/eslint-plugin": "^5.0.0",
19
- "@typescript-eslint/parser": "^5.0.0",
20
- "eslint": "^8.0.0",
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",
24
+ "typedoc": "^0.22.10",
21
25
  "typescript": "^4.2.3"
22
26
  },
23
27
  "scripts": {
24
28
  "build": "tsc",
25
29
  "lint": "eslint index.ts",
26
- "prepare": "rm -rf dist && npm run build"
30
+ "prepare": "husky install && rm -rf dist && npm run build",
31
+ "precommit": "lint-staged",
32
+ "docs": "npm run remove:docs && npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./ README.md",
33
+ "typedoc": "typedoc",
34
+ "remove:docs": "rm -rf docs"
27
35
  },
28
36
  "keywords": [
29
37
  "gpio",