1
0
Fork 0
mirror of https://github.com/moritzruth/node-enttec-open-dmx-usb.git synced 2025-04-21 07:41:22 +02:00

Compare commits

..

No commits in common. "main" and "v3.0.1" have entirely different histories.
main ... v3.0.1

7 changed files with 2362 additions and 687 deletions

1
.gitignore vendored
View file

@ -1,4 +1,3 @@
node_modules/
dist/
.idea/
/test.mjs

2
.nvmrc
View file

@ -1 +1 @@
18
10

View file

@ -1,6 +1,6 @@
# node-enttec-open-dmx-usb 🔌
> A Node.js library for interacting with the
> [Enttec Open DMX USB interface](https://www.enttec.co.uk/en/product/controls/dmx-usb-interfaces/open-dmx-usb/)
> [Enttec Open DMX USB Interface](https://www.enttec.co.uk/en/product/controls/dmx-usb-interfaces/open-dmx-usb/)
As it uses `serialport` under the hood, it should also work in
[these environments](https://serialport.io/docs/guide-platform-support#supported-platforms-and-architectures).
@ -8,7 +8,7 @@ As it uses `serialport` under the hood, it should also work in
## Install
![npm](https://img.shields.io/npm/v/enttec-open-dmx-usb?style=flat-square)
The minimum required Node.js version is `v18.0.0`.
Minimum required Node.js version is `v14.0.0`.
```sh
yarn add enttec-open-dmx-usb
@ -20,7 +20,7 @@ npm install enttec-open-dmx-usb
[**View documentation on jsdocs.io**](https://www.jsdocs.io/package/enttec-open-dmx-usb#EnttecOpenDMXUSBDevice)
```js
import { EnttecOpenDMXUSBDevice as DMXDevice } from "enttec-open-dmx-usb"
import { EnttecOpenDMXUSBDevice as DMXDevice } from "enttec-open-dmx-usb";
(async () => {
const device = new DMXDevice(await DMXDevice.getFirstAvailableDevice())
@ -38,31 +38,7 @@ import { EnttecOpenDMXUSBDevice as DMXDevice } from "enttec-open-dmx-usb"
})()
```
### What to do when this doesnt work
TLDR: Because `setTimeout` is imprecise, install [`easy-sleep`](https://github.com/qufei1993/easy-sleep) and
pass the `usleep` function provided by it as the third parameter to the constructor of `EnttecOpenDMXUSBDevice`.
See the example below.
From [the Node.js documentation](https://nodejs.org/api/timers.html#settimeoutcallback-delay-args) regarding `setTimeout`:
> Node.js makes no guarantees about the exact timing of when callbacks will fire, nor of their ordering.
> The callback will be called as close as possible to the time specified.
Because of this and the passive nature of the Enttec Open DMX USB interface, sometimes the timing requirements of the DMX specification are not met.
Using a library such as [`easy-sleep`](https://github.com/qufei1993/easy-sleep) which allows sleeping (i. e. blocking the event loop) for a precise
amount of microseconds is a possible workaround.
You may pass a function sleeping for `n` *micro*seconds as the third parameter to the constructor of `EnttecOpenDMXUSBDevice`.
For example, using `easy-sleep`:
```js
import { EnttecOpenDMXUSBDevice as DMXDevice } from "enttec-open-dmx-usb"
import easySleep from "easy-sleep"
new DMXDevice(await DMXDevice.getFirstAvailableDevice(), true, easySleep.Thread.usleep)
```
## Events
`ready` - `startSending` may be called.
`ready` - `startSending` can be called.
`error` - An error occurred. `error` events from `serialport` are passed through.

View file

@ -1,7 +1,7 @@
{
"name": "enttec-open-dmx-usb",
"version": "4.0.1",
"description": "A Node.js library for interacting with the Enttec Open DMX USB interface",
"version": "3.0.1",
"description": "A Node.js library for interacting with the Enttec Open DMX USB Interface",
"repository": "https://github.com/moritzruth/node-enttec-open-dmx-usb.git",
"author": "Moritz Ruth <dev@moritzruth.de>",
"license": "MIT",
@ -13,21 +13,25 @@
"usb"
],
"scripts": {
"build": "tsc"
"build": "tsc",
"lint": "eslint src"
},
"files": [
"dist"
],
"engines": {
"node": ">=18.0.0"
"node": ">=14.0.0"
},
"devDependencies": {
"@types/node": "^18.16.10",
"@types/serialport": "^8.0.2",
"typescript": "^5.0.4"
"@types/node": "^14.14.31",
"@types/serialport": "^8.0.1",
"eslint": "^7.20.0",
"eslint-config-awzzm-node": "^1.5.0",
"eslint-config-awzzm-ts": "^1.5.2",
"typescript": "~4.1.5"
},
"dependencies": {
"eventemitter3": "^5.0.1",
"serialport": "^11.0.0"
"eventemitter3": "^4.0.7",
"serialport": "^9.0.7"
}
}

613
pnpm-lock.yaml generated
View file

@ -1,613 +0,0 @@
lockfileVersion: '6.0'
dependencies:
easy-sleep:
specifier: ^1.2.2
version: 1.2.2
eventemitter3:
specifier: ^5.0.1
version: 5.0.1
serialport:
specifier: ^11.0.0
version: 11.0.0
devDependencies:
'@types/node':
specifier: ^18.16.10
version: 18.16.10
'@types/serialport':
specifier: ^8.0.2
version: 8.0.2
typescript:
specifier: ^5.0.4
version: 5.0.4
packages:
/@serialport/binding-mock@10.2.2:
resolution: {integrity: sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==}
engines: {node: '>=12.0.0'}
dependencies:
'@serialport/bindings-interface': 1.2.2
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/@serialport/bindings-cpp@11.0.1:
resolution: {integrity: sha512-3I1mniVg3osYuIUXxU0jB5AHPsxWmErmc3JC3WfUSlfXsjWMHkHfFzbW9Scuv/z/6DLCJIDyltabRa2FoW2qsQ==}
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@serialport/bindings-interface': 1.2.2
'@serialport/parser-readline': 10.5.0
debug: 4.3.4
node-addon-api: 6.1.0
node-gyp-build: 4.6.0
transitivePeerDependencies:
- supports-color
dev: false
/@serialport/bindings-interface@1.2.2:
resolution: {integrity: sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==}
engines: {node: ^12.22 || ^14.13 || >=16}
dev: false
/@serialport/parser-byte-length@11.0.0:
resolution: {integrity: sha512-rExsdFKdzOIHOBqTwzxUF1A9nrluVIZKZOtvMq5i0Hc3euooGdmkx0VXYNRlI2rd6kJLTL2P+uIR+ZtCTRyT+w==}
engines: {node: '>=12.0.0'}
dev: false
/@serialport/parser-cctalk@11.0.0:
resolution: {integrity: sha512-eN1MvEIFwI4GedWJhte6eWF+NZtrjchZbMf0CE6NV9TRzJI1KLnFf90ZOj/mhGuANojX4sqWfJKQXwN6E8VSHQ==}
engines: {node: '>=12.0.0'}
dev: false
/@serialport/parser-delimiter@10.5.0:
resolution: {integrity: sha512-/uR/yT3jmrcwnl2FJU/2ySvwgo5+XpksDUR4NF/nwTS5i3CcuKS+FKi/tLzy1k8F+rCx5JzpiK+koqPqOUWArA==}
engines: {node: '>=12.0.0'}
dev: false
/@serialport/parser-delimiter@11.0.0:
resolution: {integrity: sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==}
engines: {node: '>=12.0.0'}
dev: false
/@serialport/parser-inter-byte-timeout@11.0.0:
resolution: {integrity: sha512-RLgqZC50IET6FtEIt6Oi0vdRsesSBWLNwB7ldzR9OzyXKgK0XHRzqKqbB0u5Q+tC5OScdWeiQ2AO6jooKUZtsw==}
engines: {node: '>=12.0.0'}
dev: false
/@serialport/parser-packet-length@11.0.0:
resolution: {integrity: sha512-6ZkOiaCooabpV/EM7ttSRbisbDWpGEf7Yxyr13t28LicYR43THRdjdMZcRnWxEM/jpwfskkLLXAR6wziVpKrlw==}
engines: {node: '>=8.6.0'}
dev: false
/@serialport/parser-readline@10.5.0:
resolution: {integrity: sha512-0aXJknodcl94W9zSjvU+sLdXiyEG2rqjQmvBWZCr8wJZjWEtv3RgrnYiWq4i2OTOyC8C/oPK8ZjpBjQptRsoJQ==}
engines: {node: '>=12.0.0'}
dependencies:
'@serialport/parser-delimiter': 10.5.0
dev: false
/@serialport/parser-readline@11.0.0:
resolution: {integrity: sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==}
engines: {node: '>=12.0.0'}
dependencies:
'@serialport/parser-delimiter': 11.0.0
dev: false
/@serialport/parser-ready@11.0.0:
resolution: {integrity: sha512-lSsCPIctoc5kADCKnZDYBz1j69TsFqtnaWUicBzUAIAoUXpYKeYld8YX5NrvjViuVfIJeiqLZeGjxOWe5fqQqQ==}
engines: {node: '>=12.0.0'}
dev: false
/@serialport/parser-regex@11.0.0:
resolution: {integrity: sha512-aKuc/+/KE9swahTbYpSuOsQa7LggPx7jhfobJLPVVbAic80OpfCIY+MKr6Ax4R6UtQwF90O5Yk6OEmbbvtEmiA==}
engines: {node: '>=12.0.0'}
dev: false
/@serialport/parser-slip-encoder@11.0.0:
resolution: {integrity: sha512-3ZI/swd2it20vmu2tzqDbkyE4dqy+kExEDY6T33YQ210HDKPVhqj7FAVGo5P++MZ3dup1of11t4P9UPBNkuJnQ==}
engines: {node: '>=12.0.0'}
dev: false
/@serialport/parser-spacepacket@11.0.0:
resolution: {integrity: sha512-+hqRckrTEqz+/uAUZY0Tq6YIRyCl4oQOH1MeVzKiFiGNjZP7hDJCDoY7LTr9CeJhxvcT0ItTbtjGBqGumV8fxg==}
engines: {node: '>=12.0.0'}
dev: false
/@serialport/stream@11.0.0:
resolution: {integrity: sha512-Zty7B8C1H2XRnay2mVmW1ygEHXRHXQDcaC5wAVvOZMbQSc7ye03rMlPvviDS+pGxU2t2A2bMo34CUrRduSBong==}
engines: {node: '>=12.0.0'}
dependencies:
'@serialport/bindings-interface': 1.2.2
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/@types/node@18.16.10:
resolution: {integrity: sha512-sMo3EngB6QkMBlB9rBe1lFdKSLqljyWPPWv6/FzSxh/IDlyVWSzE9RiF4eAuerQHybrWdqBgAGb03PM89qOasA==}
dev: true
/@types/serialport@8.0.2:
resolution: {integrity: sha512-z4b1I8/vdZE3upgCcAL9VAWlVVFUVn5uo3faAHavkVfK/Hb1LUxKwp9YCtA5AZqEUCWoSWl20SRTOvAI/5fQWQ==}
dependencies:
'@types/node': 18.16.10
dev: true
/abbrev@1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
dev: false
/ansi-regex@2.1.1:
resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==}
engines: {node: '>=0.10.0'}
dev: false
/aproba@1.2.0:
resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==}
dev: false
/are-we-there-yet@1.1.7:
resolution: {integrity: sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==}
dependencies:
delegates: 1.0.0
readable-stream: 2.3.8
dev: false
/balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: false
/brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
dev: false
/chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
dev: false
/code-point-at@1.1.0:
resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==}
engines: {node: '>=0.10.0'}
dev: false
/concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: false
/console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
dev: false
/core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
dev: false
/debug@3.2.7:
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.2
dev: false
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.2
dev: false
/deep-extend@0.6.0:
resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
engines: {node: '>=4.0.0'}
dev: false
/delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
dev: false
/detect-libc@1.0.3:
resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==}
engines: {node: '>=0.10'}
hasBin: true
dev: false
/easy-sleep@1.2.2:
resolution: {integrity: sha512-mn+XCd6xKQWkLKnFFyg/3QZ2QvXqIFgUZNo/gWUYRilYHYdg9BdxPO0fPVWm+rhx3wzDaKJePK5tYC8x5aKIKg==}
requiresBuild: true
dependencies:
node-pre-gyp: 0.17.0
transitivePeerDependencies:
- supports-color
dev: false
/eventemitter3@5.0.1:
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
dev: false
/fs-minipass@1.2.7:
resolution: {integrity: sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==}
dependencies:
minipass: 2.9.0
dev: false
/fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: false
/gauge@2.7.4:
resolution: {integrity: sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==}
dependencies:
aproba: 1.2.0
console-control-strings: 1.1.0
has-unicode: 2.0.1
object-assign: 4.1.1
signal-exit: 3.0.7
string-width: 1.0.2
strip-ansi: 3.0.1
wide-align: 1.1.5
dev: false
/glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
dependencies:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
dev: false
/has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
dev: false
/iconv-lite@0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
dependencies:
safer-buffer: 2.1.2
dev: false
/ignore-walk@3.0.4:
resolution: {integrity: sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==}
dependencies:
minimatch: 3.1.2
dev: false
/inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
dependencies:
once: 1.4.0
wrappy: 1.0.2
dev: false
/inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
dev: false
/ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
dev: false
/is-fullwidth-code-point@1.0.0:
resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==}
engines: {node: '>=0.10.0'}
dependencies:
number-is-nan: 1.0.1
dev: false
/isarray@1.0.0:
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
dev: false
/minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
dependencies:
brace-expansion: 1.1.11
dev: false
/minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
dev: false
/minipass@2.9.0:
resolution: {integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==}
dependencies:
safe-buffer: 5.2.1
yallist: 3.1.1
dev: false
/minizlib@1.3.3:
resolution: {integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==}
dependencies:
minipass: 2.9.0
dev: false
/mkdirp@0.5.6:
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
hasBin: true
dependencies:
minimist: 1.2.8
dev: false
/ms@2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: false
/needle@2.9.1:
resolution: {integrity: sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==}
engines: {node: '>= 4.4.x'}
hasBin: true
dependencies:
debug: 3.2.7
iconv-lite: 0.4.24
sax: 1.2.4
transitivePeerDependencies:
- supports-color
dev: false
/node-addon-api@6.1.0:
resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==}
dev: false
/node-gyp-build@4.6.0:
resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==}
hasBin: true
dev: false
/node-pre-gyp@0.17.0:
resolution: {integrity: sha512-abzZt1hmOjkZez29ppg+5gGqdPLUuJeAEwVPtHYEJgx0qzttCbcKFpxrCQn2HYbwCv2c+7JwH4BgEzFkUGpn4A==}
deprecated: 'Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future'
hasBin: true
dependencies:
detect-libc: 1.0.3
mkdirp: 0.5.6
needle: 2.9.1
nopt: 4.0.3
npm-packlist: 1.4.8
npmlog: 4.1.2
rc: 1.2.8
rimraf: 2.7.1
semver: 5.7.1
tar: 4.4.19
transitivePeerDependencies:
- supports-color
dev: false
/nopt@4.0.3:
resolution: {integrity: sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==}
hasBin: true
dependencies:
abbrev: 1.1.1
osenv: 0.1.5
dev: false
/npm-bundled@1.1.2:
resolution: {integrity: sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==}
dependencies:
npm-normalize-package-bin: 1.0.1
dev: false
/npm-normalize-package-bin@1.0.1:
resolution: {integrity: sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==}
dev: false
/npm-packlist@1.4.8:
resolution: {integrity: sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==}
dependencies:
ignore-walk: 3.0.4
npm-bundled: 1.1.2
npm-normalize-package-bin: 1.0.1
dev: false
/npmlog@4.1.2:
resolution: {integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==}
dependencies:
are-we-there-yet: 1.1.7
console-control-strings: 1.1.0
gauge: 2.7.4
set-blocking: 2.0.0
dev: false
/number-is-nan@1.0.1:
resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==}
engines: {node: '>=0.10.0'}
dev: false
/object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
dev: false
/once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
wrappy: 1.0.2
dev: false
/os-homedir@1.0.2:
resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==}
engines: {node: '>=0.10.0'}
dev: false
/os-tmpdir@1.0.2:
resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
engines: {node: '>=0.10.0'}
dev: false
/osenv@0.1.5:
resolution: {integrity: sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==}
dependencies:
os-homedir: 1.0.2
os-tmpdir: 1.0.2
dev: false
/path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
dev: false
/process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
dev: false
/rc@1.2.8:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
hasBin: true
dependencies:
deep-extend: 0.6.0
ini: 1.3.8
minimist: 1.2.8
strip-json-comments: 2.0.1
dev: false
/readable-stream@2.3.8:
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
dependencies:
core-util-is: 1.0.3
inherits: 2.0.4
isarray: 1.0.0
process-nextick-args: 2.0.1
safe-buffer: 5.1.2
string_decoder: 1.1.1
util-deprecate: 1.0.2
dev: false
/rimraf@2.7.1:
resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
hasBin: true
dependencies:
glob: 7.2.3
dev: false
/safe-buffer@5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
dev: false
/safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
dev: false
/safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
dev: false
/sax@1.2.4:
resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==}
dev: false
/semver@5.7.1:
resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==}
hasBin: true
dev: false
/serialport@11.0.0:
resolution: {integrity: sha512-bxs3XejQcOHWpzPAaXMhxVRlbem6fjNUrux3ToqrGvFR6BcjOYhqE5CsHOuutv37kmhmnuHrn+/hN+1BpTmaFg==}
engines: {node: '>=12.0.0'}
dependencies:
'@serialport/binding-mock': 10.2.2
'@serialport/bindings-cpp': 11.0.1
'@serialport/parser-byte-length': 11.0.0
'@serialport/parser-cctalk': 11.0.0
'@serialport/parser-delimiter': 11.0.0
'@serialport/parser-inter-byte-timeout': 11.0.0
'@serialport/parser-packet-length': 11.0.0
'@serialport/parser-readline': 11.0.0
'@serialport/parser-ready': 11.0.0
'@serialport/parser-regex': 11.0.0
'@serialport/parser-slip-encoder': 11.0.0
'@serialport/parser-spacepacket': 11.0.0
'@serialport/stream': 11.0.0
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
dev: false
/signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: false
/string-width@1.0.2:
resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==}
engines: {node: '>=0.10.0'}
dependencies:
code-point-at: 1.1.0
is-fullwidth-code-point: 1.0.0
strip-ansi: 3.0.1
dev: false
/string_decoder@1.1.1:
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
dependencies:
safe-buffer: 5.1.2
dev: false
/strip-ansi@3.0.1:
resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==}
engines: {node: '>=0.10.0'}
dependencies:
ansi-regex: 2.1.1
dev: false
/strip-json-comments@2.0.1:
resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
engines: {node: '>=0.10.0'}
dev: false
/tar@4.4.19:
resolution: {integrity: sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==}
engines: {node: '>=4.5'}
dependencies:
chownr: 1.1.4
fs-minipass: 1.2.7
minipass: 2.9.0
minizlib: 1.3.3
mkdirp: 0.5.6
safe-buffer: 5.2.1
yallist: 3.1.1
dev: false
/typescript@5.0.4:
resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==}
engines: {node: '>=12.20'}
hasBin: true
dev: true
/util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: false
/wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
dependencies:
string-width: 1.0.2
dev: false
/wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: false
/yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
dev: false

View file

@ -1,5 +1,5 @@
import { EventEmitter } from "eventemitter3"
import { SerialPort } from "serialport"
import SerialPort from "serialport"
export const VENDOR_ID = "0403" // Enttec
export const PRODUCT_ID = "6001" // Open DMX USB
@ -9,26 +9,21 @@ interface Events {
error: [Error]
}
type Usleep = (microSeconds: number) => unknown
export class EnttecOpenDMXUSBDevice extends EventEmitter<Events> {
private shouldBeSending = false
private sendTimeout: ReturnType<typeof setTimeout> | null = null
private buffer = Buffer.alloc(513)
private readonly port: SerialPort
private readonly usleep: Usleep | null
/**
* @param path A path returned by {@link EnttecOpenDMXUSBDevice.listDevices} or
* @param {string} path A path returned by {@link EnttecOpenDMXUSBDevice.listDevices} or
* {@link EnttecOpenDMXUSBDevice.getFirstAvailableDevice}.
* @param [startSending=true] Whether the device should start sending as soon as it is ready.
* @param [usleep=null] A function blocking the event loop for `n` microseconds. See the README.md for more information.
* @param {boolean} [startSending=true] Whether the device should start sending as soon as it is ready.
*/
constructor(path: string, startSending = true, usleep: Usleep | null = null) {
constructor(path: string, startSending = true) {
super()
this.port = new SerialPort({
path,
this.port = new SerialPort(path, {
baudRate: 250000,
dataBits: 8,
stopBits: 2,
@ -45,14 +40,12 @@ export class EnttecOpenDMXUSBDevice extends EventEmitter<Events> {
this.port.on("error", (error: Error) => {
this.emit("error", error)
})
this.usleep = usleep
}
/**
* Start sending.
* @param [interval=0] The milliseconds between each attempt to send. Most of the time `0` works fine.
* @throws When the device is not ready yet.
* @param {number} [interval=0] The time between each attempt to send. Most of the time, `0` works.
* @throws Error When the device is not ready yet.
*/
startSending(interval = 0) {
if (!this.port.isOpen) throw new Error("The device is not ready yet. Wait for the 'ready' event.")
@ -61,7 +54,7 @@ export class EnttecOpenDMXUSBDevice extends EventEmitter<Events> {
// eslint-disable-next-line unicorn/consistent-function-scoping
const send = () => {
this._sendUniverse()
this.sendUniverse()
.then(() => {
if (this.shouldBeSending)
// eslint-disable-next-line @typescript-eslint/no-misused-promises
@ -83,11 +76,11 @@ export class EnttecOpenDMXUSBDevice extends EventEmitter<Events> {
}
/**
* Set channel values.
* Set the channel values.
* If channels is an Object, the keys are the channel numbers.
*
* @param channels
* @param [clear=false] Whether all previously assigned channels should be set to `0`
* @param {Buffer|Object|Array} channels
* @param {boolean} [clear=false] Whether all previously assigned channels should be set to 0
*/
setChannels(channels: Buffer | number[] | Record<number, number>, clear = false) {
if (clear) {
@ -126,34 +119,26 @@ export class EnttecOpenDMXUSBDevice extends EventEmitter<Events> {
}
/**
* @returns A Promise resolved when the whole universe was sent.
* @returns {Promise} Resolves when the whole universe was sent.
* @private
*/
async _sendUniverse(): Promise<void> {
private async sendUniverse(): Promise<void> {
return new Promise(resolve => {
this.port.set({ brk: true, rts: false }, () => {
if (this.usleep === null) {
setTimeout(() => {
this.port.set({ brk: false, rts: false }, () => {
setTimeout(() => {
this.port.write(this.buffer, () => resolve())
}, 1)
})
}, 1)
} else {
this.usleep(92)
setTimeout(() => {
this.port.set({ brk: false, rts: false }, () => {
this.usleep!(12)
this.port.write(this.buffer, () => resolve())
setTimeout(() => {
this.port.write(this.buffer, () => resolve())
}, 0)
})
}
}, 0)
})
})
}
/**
* Get the paths of all available devices.
* @returns {Promise<string[]>}
*/
static async listDevices(): Promise<string[]> {
const allPorts = await SerialPort.list()
@ -164,7 +149,8 @@ export class EnttecOpenDMXUSBDevice extends EventEmitter<Events> {
/**
* Get the path of the first available device.
* @throws When no device is found.
* @throws Error When no device is found.
* @returns {Promise<string>}
*/
static async getFirstAvailableDevice(): Promise<string> {
const devices = await EnttecOpenDMXUSBDevice.listDevices()

2323
yarn.lock Normal file

File diff suppressed because it is too large Load diff