code for proxy (for testing)
This commit is contained in:
parent
1a3af2f782
commit
34d0579018
12 changed files with 6619 additions and 933 deletions
|
@ -1,12 +1,12 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = LF
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = LF
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
|
358
.eslintrc
358
.eslintrc
|
@ -1,179 +1,179 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
|
||||
"globals": {
|
||||
"document": false,
|
||||
"escape": false,
|
||||
"navigator": false,
|
||||
"unescape": false,
|
||||
"window": false,
|
||||
"describe": true,
|
||||
"before": true,
|
||||
"it": true,
|
||||
"expect": true,
|
||||
"sinon": true
|
||||
},
|
||||
|
||||
"parser": "babel-eslint",
|
||||
|
||||
"plugins": [
|
||||
|
||||
],
|
||||
|
||||
"rules": {
|
||||
"block-scoped-var": 2,
|
||||
"brace-style": [2, "1tbs", { "allowSingleLine": true }],
|
||||
"camelcase": [2, { "properties": "always" }],
|
||||
"comma-dangle": [2, "always-multiline"],
|
||||
"comma-spacing": [2, { "before": false, "after": true }],
|
||||
"comma-style": [2, "last"],
|
||||
"complexity": 0,
|
||||
"consistent-return": 2,
|
||||
"consistent-this": 0,
|
||||
"curly": [2, "multi-line"],
|
||||
"default-case": 0,
|
||||
"dot-location": [2, "property"],
|
||||
"dot-notation": 0,
|
||||
"eol-last": 2,
|
||||
"eqeqeq": [2, "allow-null"],
|
||||
"func-names": 0,
|
||||
"func-style": 0,
|
||||
"generator-star-spacing": [2, "both"],
|
||||
"guard-for-in": 0,
|
||||
"handle-callback-err": [0, "^(err|error|anySpecificError)$" ],
|
||||
"indent": [2, 2, { "SwitchCase": 1 }],
|
||||
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
|
||||
"keyword-spacing": [2, {"before": true, "after": true}],
|
||||
"linebreak-style": 0,
|
||||
"max-depth": 0,
|
||||
"max-len": [2, 120, 4],
|
||||
"max-nested-callbacks": 0,
|
||||
"max-params": 0,
|
||||
"max-statements": 0,
|
||||
"new-cap": [2, { "newIsCap": true, "capIsNew": false }],
|
||||
"newline-after-var": [2, "always"],
|
||||
"new-parens": 2,
|
||||
"no-alert": 0,
|
||||
"no-array-constructor": 2,
|
||||
"no-bitwise": 0,
|
||||
"no-caller": 2,
|
||||
"no-catch-shadow": 0,
|
||||
"no-cond-assign": 2,
|
||||
"no-console": 0,
|
||||
"no-constant-condition": 0,
|
||||
"no-continue": 0,
|
||||
"no-control-regex": 2,
|
||||
"no-debugger": 2,
|
||||
"no-delete-var": 2,
|
||||
"no-div-regex": 0,
|
||||
"no-dupe-args": 2,
|
||||
"no-dupe-keys": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-else-return": 2,
|
||||
"no-empty": 0,
|
||||
"no-empty-character-class": 2,
|
||||
"no-eq-null": 0,
|
||||
"no-eval": 2,
|
||||
"no-ex-assign": 2,
|
||||
"no-extend-native": 2,
|
||||
"no-extra-bind": 2,
|
||||
"no-extra-boolean-cast": 2,
|
||||
"no-extra-parens": 0,
|
||||
"no-extra-semi": 0,
|
||||
"no-extra-strict": 0,
|
||||
"no-fallthrough": 2,
|
||||
"no-floating-decimal": 2,
|
||||
"no-func-assign": 2,
|
||||
"no-implied-eval": 2,
|
||||
"no-inline-comments": 0,
|
||||
"no-inner-declarations": [2, "functions"],
|
||||
"no-invalid-regexp": 2,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-iterator": 2,
|
||||
"no-label-var": 2,
|
||||
"no-labels": 2,
|
||||
"no-lone-blocks": 0,
|
||||
"no-lonely-if": 0,
|
||||
"no-loop-func": 0,
|
||||
"no-mixed-requires": 0,
|
||||
"no-mixed-spaces-and-tabs": [2, false],
|
||||
"no-multi-spaces": 2,
|
||||
"no-multi-str": 2,
|
||||
"no-multiple-empty-lines": [2, { "max": 1 }],
|
||||
"no-native-reassign": 2,
|
||||
"no-negated-in-lhs": 2,
|
||||
"no-nested-ternary": 0,
|
||||
"no-new": 2,
|
||||
"no-new-func": 2,
|
||||
"no-new-object": 2,
|
||||
"no-new-require": 2,
|
||||
"no-new-wrappers": 2,
|
||||
"no-obj-calls": 2,
|
||||
"no-octal": 2,
|
||||
"no-octal-escape": 2,
|
||||
"no-path-concat": 0,
|
||||
"no-plusplus": 0,
|
||||
"no-process-env": 0,
|
||||
"no-process-exit": 0,
|
||||
"no-proto": 2,
|
||||
"no-redeclare": 2,
|
||||
"no-regex-spaces": 2,
|
||||
"no-reserved-keys": 0,
|
||||
"no-restricted-modules": 0,
|
||||
"no-return-assign": 2,
|
||||
"no-script-url": 0,
|
||||
"no-self-compare": 2,
|
||||
"no-sequences": 2,
|
||||
"no-shadow": 0,
|
||||
"no-shadow-restricted-names": 2,
|
||||
"no-spaced-func": 2,
|
||||
"no-sparse-arrays": 2,
|
||||
"no-sync": 0,
|
||||
"no-ternary": 0,
|
||||
"no-throw-literal": 2,
|
||||
"no-trailing-spaces": 2,
|
||||
"no-undef": 2,
|
||||
"no-undef-init": 2,
|
||||
"no-undefined": 0,
|
||||
"no-underscore-dangle": 0,
|
||||
"no-unneeded-ternary": 2,
|
||||
"no-unreachable": 1,
|
||||
"no-unused-expressions": 0,
|
||||
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
|
||||
"no-use-before-define": 2,
|
||||
"no-var": 2,
|
||||
"no-void": 0,
|
||||
"no-warning-comments": 0,
|
||||
"no-with": 2,
|
||||
"one-var": 0,
|
||||
"operator-assignment": 0,
|
||||
"operator-linebreak": [2, "after"],
|
||||
"padded-blocks": 0,
|
||||
"prefer-const": 2,
|
||||
"quote-props": 0,
|
||||
"quotes": [2, "single", "avoid-escape"],
|
||||
"radix": 2,
|
||||
"semi": [2, "always"],
|
||||
"semi-spacing": 0,
|
||||
"sort-vars": 0,
|
||||
"space-before-blocks": [2, "always"],
|
||||
"space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
|
||||
"space-in-brackets": 0,
|
||||
"space-in-parens": [2, "never"],
|
||||
"space-infix-ops": 2,
|
||||
"space-unary-ops": [2, { "words": true, "nonwords": false }],
|
||||
"spaced-comment": [2, "always"],
|
||||
"strict": 2,
|
||||
"use-isnan": 2,
|
||||
"valid-jsdoc": 0,
|
||||
"valid-typeof": 2,
|
||||
"vars-on-top": 0,
|
||||
"wrap-iife": [2, "any"],
|
||||
"wrap-regex": 0,
|
||||
"yoda": [2, "never"]
|
||||
}
|
||||
}
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
|
||||
"globals": {
|
||||
"document": false,
|
||||
"escape": false,
|
||||
"navigator": false,
|
||||
"unescape": false,
|
||||
"window": false,
|
||||
"describe": true,
|
||||
"before": true,
|
||||
"it": true,
|
||||
"expect": true,
|
||||
"sinon": true
|
||||
},
|
||||
|
||||
"parser": "babel-eslint",
|
||||
|
||||
"plugins": [
|
||||
|
||||
],
|
||||
|
||||
"rules": {
|
||||
"block-scoped-var": 2,
|
||||
"brace-style": [2, "1tbs", { "allowSingleLine": true }],
|
||||
"camelcase": [2, { "properties": "always" }],
|
||||
"comma-dangle": [2, "always-multiline"],
|
||||
"comma-spacing": [2, { "before": false, "after": true }],
|
||||
"comma-style": [2, "last"],
|
||||
"complexity": 0,
|
||||
"consistent-return": 2,
|
||||
"consistent-this": 0,
|
||||
"curly": [2, "multi-line"],
|
||||
"default-case": 0,
|
||||
"dot-location": [2, "property"],
|
||||
"dot-notation": 0,
|
||||
"eol-last": 2,
|
||||
"eqeqeq": [2, "allow-null"],
|
||||
"func-names": 0,
|
||||
"func-style": 0,
|
||||
"generator-star-spacing": [2, "both"],
|
||||
"guard-for-in": 0,
|
||||
"handle-callback-err": [0, "^(err|error|anySpecificError)$" ],
|
||||
"indent": [2, 2, { "SwitchCase": 1 }],
|
||||
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
|
||||
"keyword-spacing": [2, {"before": true, "after": true}],
|
||||
"linebreak-style": 0,
|
||||
"max-depth": 0,
|
||||
"max-len": [2, 120, 4],
|
||||
"max-nested-callbacks": 0,
|
||||
"max-params": 0,
|
||||
"max-statements": 0,
|
||||
"new-cap": [2, { "newIsCap": true, "capIsNew": false }],
|
||||
"newline-after-var": [2, "always"],
|
||||
"new-parens": 2,
|
||||
"no-alert": 0,
|
||||
"no-array-constructor": 2,
|
||||
"no-bitwise": 0,
|
||||
"no-caller": 2,
|
||||
"no-catch-shadow": 0,
|
||||
"no-cond-assign": 2,
|
||||
"no-console": 0,
|
||||
"no-constant-condition": 0,
|
||||
"no-continue": 0,
|
||||
"no-control-regex": 2,
|
||||
"no-debugger": 2,
|
||||
"no-delete-var": 2,
|
||||
"no-div-regex": 0,
|
||||
"no-dupe-args": 2,
|
||||
"no-dupe-keys": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-else-return": 2,
|
||||
"no-empty": 0,
|
||||
"no-empty-character-class": 2,
|
||||
"no-eq-null": 0,
|
||||
"no-eval": 2,
|
||||
"no-ex-assign": 2,
|
||||
"no-extend-native": 2,
|
||||
"no-extra-bind": 2,
|
||||
"no-extra-boolean-cast": 2,
|
||||
"no-extra-parens": 0,
|
||||
"no-extra-semi": 0,
|
||||
"no-extra-strict": 0,
|
||||
"no-fallthrough": 2,
|
||||
"no-floating-decimal": 2,
|
||||
"no-func-assign": 2,
|
||||
"no-implied-eval": 2,
|
||||
"no-inline-comments": 0,
|
||||
"no-inner-declarations": [2, "functions"],
|
||||
"no-invalid-regexp": 2,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-iterator": 2,
|
||||
"no-label-var": 2,
|
||||
"no-labels": 2,
|
||||
"no-lone-blocks": 0,
|
||||
"no-lonely-if": 0,
|
||||
"no-loop-func": 0,
|
||||
"no-mixed-requires": 0,
|
||||
"no-mixed-spaces-and-tabs": [2, false],
|
||||
"no-multi-spaces": 2,
|
||||
"no-multi-str": 2,
|
||||
"no-multiple-empty-lines": [2, { "max": 1 }],
|
||||
"no-native-reassign": 2,
|
||||
"no-negated-in-lhs": 2,
|
||||
"no-nested-ternary": 0,
|
||||
"no-new": 2,
|
||||
"no-new-func": 2,
|
||||
"no-new-object": 2,
|
||||
"no-new-require": 2,
|
||||
"no-new-wrappers": 2,
|
||||
"no-obj-calls": 2,
|
||||
"no-octal": 2,
|
||||
"no-octal-escape": 2,
|
||||
"no-path-concat": 0,
|
||||
"no-plusplus": 0,
|
||||
"no-process-env": 0,
|
||||
"no-process-exit": 0,
|
||||
"no-proto": 2,
|
||||
"no-redeclare": 2,
|
||||
"no-regex-spaces": 2,
|
||||
"no-reserved-keys": 0,
|
||||
"no-restricted-modules": 0,
|
||||
"no-return-assign": 2,
|
||||
"no-script-url": 0,
|
||||
"no-self-compare": 2,
|
||||
"no-sequences": 2,
|
||||
"no-shadow": 0,
|
||||
"no-shadow-restricted-names": 2,
|
||||
"no-spaced-func": 2,
|
||||
"no-sparse-arrays": 2,
|
||||
"no-sync": 0,
|
||||
"no-ternary": 0,
|
||||
"no-throw-literal": 2,
|
||||
"no-trailing-spaces": 2,
|
||||
"no-undef": 2,
|
||||
"no-undef-init": 2,
|
||||
"no-undefined": 0,
|
||||
"no-underscore-dangle": 0,
|
||||
"no-unneeded-ternary": 2,
|
||||
"no-unreachable": 1,
|
||||
"no-unused-expressions": 0,
|
||||
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
|
||||
"no-use-before-define": 2,
|
||||
"no-var": 2,
|
||||
"no-void": 0,
|
||||
"no-warning-comments": 0,
|
||||
"no-with": 2,
|
||||
"one-var": 0,
|
||||
"operator-assignment": 0,
|
||||
"operator-linebreak": [2, "after"],
|
||||
"padded-blocks": 0,
|
||||
"prefer-const": 2,
|
||||
"quote-props": 0,
|
||||
"quotes": [2, "single", "avoid-escape"],
|
||||
"radix": 2,
|
||||
"semi": [2, "always"],
|
||||
"semi-spacing": 0,
|
||||
"sort-vars": 0,
|
||||
"space-before-blocks": [2, "always"],
|
||||
"space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
|
||||
"space-in-brackets": 0,
|
||||
"space-in-parens": [2, "never"],
|
||||
"space-infix-ops": 2,
|
||||
"space-unary-ops": [2, { "words": true, "nonwords": false }],
|
||||
"spaced-comment": [2, "always"],
|
||||
"strict": 2,
|
||||
"use-isnan": 2,
|
||||
"valid-jsdoc": 0,
|
||||
"valid-typeof": 2,
|
||||
"vars-on-top": 0,
|
||||
"wrap-iife": [2, "any"],
|
||||
"wrap-regex": 0,
|
||||
"yoda": [2, "never"]
|
||||
}
|
||||
}
|
||||
|
|
46
.gitignore
vendored
46
.gitignore
vendored
|
@ -1,23 +1,23 @@
|
|||
lib-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
*.dat
|
||||
*.out
|
||||
*.pid
|
||||
*.gz
|
||||
|
||||
pids
|
||||
logs
|
||||
results
|
||||
.DS_Store
|
||||
|
||||
node_modules
|
||||
.project
|
||||
.com.greenworldsoft.syncfolderspro
|
||||
|
||||
# Remove some common IDE working directories
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
.DS_Store
|
||||
lib-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
*.dat
|
||||
*.out
|
||||
*.pid
|
||||
*.gz
|
||||
|
||||
pids
|
||||
logs
|
||||
results
|
||||
.DS_Store
|
||||
|
||||
node_modules
|
||||
.project
|
||||
.com.greenworldsoft.syncfolderspro
|
||||
|
||||
# Remove some common IDE working directories
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
.DS_Store
|
||||
|
|
42
LICENSE
42
LICENSE
|
@ -1,21 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2012-2018 Sebastian Wiedenroth
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2012-2018 Sebastian Wiedenroth
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>Label</key>
|
||||
<string>com.dmx-web.server</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/usr/local/bin/dmx-web</string>
|
||||
<string>-c</string>
|
||||
<string>/Library/Server/DMX/dmx-web.json</string>
|
||||
</array>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/Library/Logs/homebridge/dmxlogfile.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/Library/Logs/homebridge/dmxlogfile.log</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>/usr/local/bin/:$PATH</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>Label</key>
|
||||
<string>com.dmx-web.server</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/usr/local/bin/dmx-web</string>
|
||||
<string>-c</string>
|
||||
<string>/Library/Server/DMX/dmx-web.json</string>
|
||||
</array>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/Library/Logs/homebridge/dmxlogfile.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/Library/Logs/homebridge/dmxlogfile.log</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>/usr/local/bin/:$PATH</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -1,197 +1,197 @@
|
|||
{
|
||||
"_title": "DMX Dashboard",
|
||||
"_comment1": "To have a different page title change _title to title.",
|
||||
"server": {
|
||||
"listen_port": 8080,
|
||||
"listen_host": "::",
|
||||
|
||||
"_uid": "www-data",
|
||||
"_gid": "www-data",
|
||||
"_comment1": "To drop privileges change the '_uid' and '_gid' keys to 'uid' and 'gid'.",
|
||||
"_comment2": "On macOS uid and gid must be set in the launchd script."
|
||||
},
|
||||
"presets": [
|
||||
{
|
||||
"label": "White",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 255, "3": 0, "4": 255, "5": 255, "6": 255, "16": 16, "17": 255, "18": 0, "19": 255, "20": 255, "21": 255 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Natural",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 255, "3": 0, "4":255, "5": 190, "6": 140, "16": 16, "17": 255, "18": 0, "19": 255, "20": 190, "21":140 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Worklight",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 130, "3": 0, "4": 255, "5": 165, "6": 0, "16": 1, "17": 255, "18": 0, "19": 255, "20": 190, "21": 140, "22": 0, "23": 0, "24": 0, "25": 255, "26": 190, "27": 140 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Chill",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 255, "3": 0, "4": 255, "5": 39, "6": 0, "16": 1, "17": 255, "18": 0, "19": 255, "20": 255, "21": 0, "22": 0, "23": 0, "24": 0, "25": 128, "26": 0, "27": 255, "32": 255, "33": 60 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Cinema",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 30, "3":0, "4": 255, "5": 39, "6": 0, "16": 0, "32": 255, "33": 0 }
|
||||
}
|
||||
}
|
||||
],
|
||||
"universes": {
|
||||
"office": {
|
||||
"output": {
|
||||
"driver": "enttec-usb-dmx-pro",
|
||||
"device": "/dev/cu.usbserial-6AVNHXS8"
|
||||
},
|
||||
"devices": [
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 1,
|
||||
"name": "Behind the TV",
|
||||
"_comment1": "name is optional and is shown above the sliders if sets"
|
||||
},
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 16
|
||||
},
|
||||
{
|
||||
"type": "showtec-multidim2",
|
||||
"address": 32
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 64
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 70
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 76
|
||||
},
|
||||
{
|
||||
"type": "oppsk-cob-uv-par",
|
||||
"address": 100
|
||||
},
|
||||
{
|
||||
"type": "lixda-par12-led",
|
||||
"address": 110
|
||||
},
|
||||
{
|
||||
"type": "lixda-par12-led",
|
||||
"address": 120
|
||||
},
|
||||
{
|
||||
"type": "lixda-par12-led",
|
||||
"address": 130
|
||||
},
|
||||
{
|
||||
"type": "lixda-par12-led",
|
||||
"address": 140
|
||||
}
|
||||
]
|
||||
},
|
||||
"bedroom": {
|
||||
"output": {
|
||||
"driver": "dmxking-ultra-dmx-pro",
|
||||
"device": "/dev/cu.usbserial-6AVNHXS9",
|
||||
"options": {
|
||||
"port": "A"
|
||||
}
|
||||
},
|
||||
"devices": [
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 1
|
||||
},
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 16
|
||||
},
|
||||
{
|
||||
"type": "showtec-multidim2",
|
||||
"address": 32
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 64
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 70
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 76
|
||||
}
|
||||
]
|
||||
},
|
||||
"livingroom": {
|
||||
"output": {
|
||||
"driver": "dmxking-ultra-dmx-pro",
|
||||
"device": "/dev/cu.usbserial-6AVNHXS4",
|
||||
"options": {
|
||||
"port": "B"
|
||||
}
|
||||
},
|
||||
"devices": [
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 1
|
||||
},
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 16
|
||||
},
|
||||
{
|
||||
"type": "showtec-multidim2",
|
||||
"address": 32
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 64
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 70
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 76
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"_animPresets": [{
|
||||
"_comment1": "Change _animPresets to animPresets for a new tab with all preset animations",
|
||||
"_comment2": "Check documentation for how to make animations",
|
||||
"label": "test",
|
||||
"anim": {
|
||||
"office": [{
|
||||
"to": {
|
||||
"10": 0,
|
||||
"20": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"to": {
|
||||
"10": 255
|
||||
},
|
||||
"duration": 2000
|
||||
},
|
||||
{
|
||||
"to": {
|
||||
"20": 255
|
||||
},
|
||||
"duration": 1000
|
||||
}
|
||||
]
|
||||
}
|
||||
}]
|
||||
}
|
||||
{
|
||||
"_title": "DMX Dashboard",
|
||||
"_comment1": "To have a different page title change _title to title.",
|
||||
"server": {
|
||||
"listen_port": 8080,
|
||||
"listen_host": "::",
|
||||
|
||||
"_uid": "www-data",
|
||||
"_gid": "www-data",
|
||||
"_comment1": "To drop privileges change the '_uid' and '_gid' keys to 'uid' and 'gid'.",
|
||||
"_comment2": "On macOS uid and gid must be set in the launchd script."
|
||||
},
|
||||
"presets": [
|
||||
{
|
||||
"label": "White",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 255, "3": 0, "4": 255, "5": 255, "6": 255, "16": 16, "17": 255, "18": 0, "19": 255, "20": 255, "21": 255 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Natural",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 255, "3": 0, "4":255, "5": 190, "6": 140, "16": 16, "17": 255, "18": 0, "19": 255, "20": 190, "21":140 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Worklight",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 130, "3": 0, "4": 255, "5": 165, "6": 0, "16": 1, "17": 255, "18": 0, "19": 255, "20": 190, "21": 140, "22": 0, "23": 0, "24": 0, "25": 255, "26": 190, "27": 140 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Chill",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 255, "3": 0, "4": 255, "5": 39, "6": 0, "16": 1, "17": 255, "18": 0, "19": 255, "20": 255, "21": 0, "22": 0, "23": 0, "24": 0, "25": 128, "26": 0, "27": 255, "32": 255, "33": 60 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Cinema",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 30, "3":0, "4": 255, "5": 39, "6": 0, "16": 0, "32": 255, "33": 0 }
|
||||
}
|
||||
}
|
||||
],
|
||||
"universes": {
|
||||
"office": {
|
||||
"output": {
|
||||
"driver": "enttec-usb-dmx-pro",
|
||||
"device": "/dev/cu.usbserial-6AVNHXS8"
|
||||
},
|
||||
"devices": [
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 1,
|
||||
"name": "Behind the TV",
|
||||
"_comment1": "name is optional and is shown above the sliders if sets"
|
||||
},
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 16
|
||||
},
|
||||
{
|
||||
"type": "showtec-multidim2",
|
||||
"address": 32
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 64
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 70
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 76
|
||||
},
|
||||
{
|
||||
"type": "oppsk-cob-uv-par",
|
||||
"address": 100
|
||||
},
|
||||
{
|
||||
"type": "lixda-par12-led",
|
||||
"address": 110
|
||||
},
|
||||
{
|
||||
"type": "lixda-par12-led",
|
||||
"address": 120
|
||||
},
|
||||
{
|
||||
"type": "lixda-par12-led",
|
||||
"address": 130
|
||||
},
|
||||
{
|
||||
"type": "lixda-par12-led",
|
||||
"address": 140
|
||||
}
|
||||
]
|
||||
},
|
||||
"bedroom": {
|
||||
"output": {
|
||||
"driver": "dmxking-ultra-dmx-pro",
|
||||
"device": "/dev/cu.usbserial-6AVNHXS9",
|
||||
"options": {
|
||||
"port": "A"
|
||||
}
|
||||
},
|
||||
"devices": [
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 1
|
||||
},
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 16
|
||||
},
|
||||
{
|
||||
"type": "showtec-multidim2",
|
||||
"address": 32
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 64
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 70
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 76
|
||||
}
|
||||
]
|
||||
},
|
||||
"livingroom": {
|
||||
"output": {
|
||||
"driver": "dmxking-ultra-dmx-pro",
|
||||
"device": "/dev/cu.usbserial-6AVNHXS4",
|
||||
"options": {
|
||||
"port": "B"
|
||||
}
|
||||
},
|
||||
"devices": [
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 1
|
||||
},
|
||||
{
|
||||
"type": "eurolite-led-bar",
|
||||
"address": 16
|
||||
},
|
||||
{
|
||||
"type": "showtec-multidim2",
|
||||
"address": 32
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 64
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 70
|
||||
},
|
||||
{
|
||||
"type": "stairville-led-par-56",
|
||||
"address": 76
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"_animPresets": [{
|
||||
"_comment1": "Change _animPresets to animPresets for a new tab with all preset animations",
|
||||
"_comment2": "Check documentation for how to make animations",
|
||||
"label": "test",
|
||||
"anim": {
|
||||
"office": [{
|
||||
"to": {
|
||||
"10": 0,
|
||||
"20": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"to": {
|
||||
"10": 255
|
||||
},
|
||||
"duration": 2000
|
||||
},
|
||||
{
|
||||
"to": {
|
||||
"20": 255
|
||||
},
|
||||
"duration": 1000
|
||||
}
|
||||
]
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
|
277
dmx-web.js
277
dmx-web.js
|
@ -1,128 +1,149 @@
|
|||
#!/usr/bin/env node
|
||||
const fs = require('fs');
|
||||
const http = require('http');
|
||||
const body = require('body-parser');
|
||||
const express = require('express');
|
||||
const socketio = require('socket.io');
|
||||
const program = require('commander');
|
||||
const DMX = require('dmx');
|
||||
const A = DMX.Animation;
|
||||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-c, --config <file>', 'Read config from file [/etc/dmx-web.json]', '/etc/dmx-web.json')
|
||||
.parse(process.argv);
|
||||
|
||||
const config = JSON.parse(fs.readFileSync(program.config, 'utf8'));
|
||||
|
||||
function DMXWeb() {
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
const io = socketio.listen(server);
|
||||
|
||||
const dmx = new DMX(config);
|
||||
|
||||
for (const universe in config.universes) {
|
||||
dmx.addUniverse(
|
||||
universe,
|
||||
config.universes[universe].output.driver,
|
||||
config.universes[universe].output.device,
|
||||
config.universes[universe].output.options
|
||||
);
|
||||
}
|
||||
|
||||
const listenPort = config.server.listen_port || 8080;
|
||||
const listenHost = config.server.listen_host || '::';
|
||||
|
||||
server.listen(listenPort, listenHost, null, () => {
|
||||
if (config.server.uid && config.server.gid) {
|
||||
try {
|
||||
process.setuid(config.server.uid);
|
||||
process.setgid(config.server.gid);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.use(body.json());
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile(__dirname + '/index.html');
|
||||
});
|
||||
|
||||
app.get('/config', (req, res) => {
|
||||
const response = {'devices': dmx.devices, 'universes': {}};
|
||||
|
||||
Object.keys(config.universes).forEach(key => {
|
||||
response.universes[key] = config.universes[key].devices;
|
||||
});
|
||||
|
||||
res.json(response);
|
||||
});
|
||||
|
||||
app.get('/state/:universe', (req, res) => {
|
||||
if (!(req.params.universe in dmx.universes)) {
|
||||
res.status(404).json({'error': 'universe not found'});
|
||||
return;
|
||||
}
|
||||
|
||||
res.json({'state': dmx.universeToObject(req.params.universe)});
|
||||
});
|
||||
|
||||
app.post('/state/:universe', (req, res) => {
|
||||
if (!(req.params.universe in dmx.universes)) {
|
||||
res.status(404).json({'error': 'universe not found'});
|
||||
return;
|
||||
}
|
||||
|
||||
dmx.update(req.params.universe, req.body);
|
||||
res.json({'state': dmx.universeToObject(req.params.universe)});
|
||||
});
|
||||
|
||||
app.post('/animation/:universe', (req, res) => {
|
||||
try {
|
||||
const universe = dmx.universes[req.params.universe];
|
||||
|
||||
// preserve old states
|
||||
const old = dmx.universeToObject(req.params.universe);
|
||||
|
||||
const animation = new A();
|
||||
|
||||
for (const step in req.body) {
|
||||
animation.add(
|
||||
req.body[step].to,
|
||||
req.body[step].duration || 0,
|
||||
req.body[step].options || {}
|
||||
);
|
||||
}
|
||||
animation.add(old, 0);
|
||||
animation.run(universe);
|
||||
res.json({'success': true});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
res.json({'error': String(e)});
|
||||
}
|
||||
});
|
||||
|
||||
io.sockets.on('connection', socket => {
|
||||
socket.emit('init', {'devices': dmx.devices, 'setup': config});
|
||||
|
||||
socket.on('request_refresh', () => {
|
||||
for (const universe in config.universes) {
|
||||
socket.emit('update', universe, dmx.universeToObject(universe));
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('update', (universe, update) => {
|
||||
dmx.update(universe, update);
|
||||
});
|
||||
|
||||
dmx.on('update', (universe, update) => {
|
||||
socket.emit('update', universe, update);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
DMXWeb();
|
||||
#!/usr/bin/env node
|
||||
const fs = require('fs');
|
||||
const http = require('http');
|
||||
const body = require('body-parser');
|
||||
const express = require('express');
|
||||
const socketio = require('socket.io');
|
||||
const socketioClient = require('socket.io-client');
|
||||
const program = require('commander');
|
||||
const DMX = require('dmx');
|
||||
const A = DMX.Animation;
|
||||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-c, --config <file>', 'Read config from file [/etc/dmx-web.json]', '/etc/dmx-web.json')
|
||||
.parse(process.argv);
|
||||
|
||||
const config = JSON.parse(fs.readFileSync(program.config, 'utf8'));
|
||||
|
||||
function DMXWeb() {
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
const io = socketio.listen(server);
|
||||
|
||||
const dmx = new DMX(config);
|
||||
|
||||
for (const universe in config.universes) {
|
||||
dmx.addUniverse(
|
||||
universe,
|
||||
config.universes[universe].output.driver,
|
||||
config.universes[universe].output.device,
|
||||
config.universes[universe].output.options
|
||||
);
|
||||
}
|
||||
|
||||
const listenPort = config.server.listen_port || 8080;
|
||||
const listenHost = config.server.listen_host || '::';
|
||||
|
||||
server.listen(listenPort, listenHost, null, () => {
|
||||
if (config.server.uid && config.server.gid) {
|
||||
try {
|
||||
process.setuid(config.server.uid);
|
||||
process.setgid(config.server.gid);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.use(body.json());
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile(__dirname + '/index.html');
|
||||
});
|
||||
|
||||
app.get('/config', (req, res) => {
|
||||
const response = {'devices': dmx.devices, 'universes': {}};
|
||||
|
||||
Object.keys(config.universes).forEach(key => {
|
||||
response.universes[key] = config.universes[key].devices;
|
||||
});
|
||||
|
||||
res.json(response);
|
||||
});
|
||||
|
||||
app.get('/state/:universe', (req, res) => {
|
||||
if (!(req.params.universe in dmx.universes)) {
|
||||
res.status(404).json({'error': 'universe not found'});
|
||||
return;
|
||||
}
|
||||
|
||||
res.json({'state': dmx.universeToObject(req.params.universe)});
|
||||
});
|
||||
|
||||
app.post('/state/:universe', (req, res) => {
|
||||
if (!(req.params.universe in dmx.universes)) {
|
||||
res.status(404).json({'error': 'universe not found'});
|
||||
return;
|
||||
}
|
||||
|
||||
dmx.update(req.params.universe, req.body);
|
||||
res.json({'state': dmx.universeToObject(req.params.universe)});
|
||||
});
|
||||
|
||||
app.post('/animation/:universe', (req, res) => {
|
||||
try {
|
||||
const universe = dmx.universes[req.params.universe];
|
||||
|
||||
// preserve old states
|
||||
const old = dmx.universeToObject(req.params.universe);
|
||||
|
||||
const animation = new A();
|
||||
|
||||
for (const step in req.body) {
|
||||
animation.add(
|
||||
req.body[step].to,
|
||||
req.body[step].duration || 0,
|
||||
req.body[step].options || {}
|
||||
);
|
||||
}
|
||||
animation.add(old, 0);
|
||||
animation.run(universe);
|
||||
res.json({'success': true});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
res.json({'error': String(e)});
|
||||
}
|
||||
});
|
||||
|
||||
const socket = socketioClient("https://light.glitches.me");
|
||||
socket.on("register", () => {
|
||||
socket.emit('init', {'devices': dmx.devices, 'setup': config});
|
||||
})
|
||||
|
||||
socket.on('request_refresh', () => {
|
||||
for (const universe in config.universes) {
|
||||
socket.emit('update', universe, dmx.universeToObject(universe));
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('update', (universe, update) => {
|
||||
dmx.update(universe, update);
|
||||
});
|
||||
|
||||
dmx.on('update', (universe, update) => {
|
||||
socket.emit('update', universe, update);
|
||||
});
|
||||
|
||||
io.sockets.on('connection', socket => {
|
||||
console.log("new client")
|
||||
socket.emit('init', {'devices': dmx.devices, 'setup': config});
|
||||
|
||||
socket.on('request_refresh', () => {
|
||||
for (const universe in config.universes) {
|
||||
socket.emit('update', universe, dmx.universeToObject(universe));
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('update', (universe, update) => {
|
||||
dmx.update(universe, update);
|
||||
});
|
||||
|
||||
dmx.on('update', (universe, update) => {
|
||||
socket.emit('update', universe, update);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
DMXWeb();
|
||||
|
|
121
dmx-web.json
Normal file
121
dmx-web.json
Normal file
|
@ -0,0 +1,121 @@
|
|||
{
|
||||
"_title": "DMX Dashboard",
|
||||
"_comment1": "To have a different page title change _title to title.",
|
||||
"server": {
|
||||
"listen_port": 8080,
|
||||
"listen_host": "::",
|
||||
|
||||
"_uid": "www-data",
|
||||
"_gid": "www-data",
|
||||
"_comment1": "To drop privileges change the '_uid' and '_gid' keys to 'uid' and 'gid'.",
|
||||
"_comment2": "On macOS uid and gid must be set in the launchd script."
|
||||
},
|
||||
"presets": [
|
||||
{
|
||||
"label": "White",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 255, "3": 0, "4": 255, "5": 255, "6": 255, "16": 16, "17": 255, "18": 0, "19": 255, "20": 255, "21": 255 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Natural",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 255, "3": 0, "4":255, "5": 190, "6": 140, "16": 16, "17": 255, "18": 0, "19": 255, "20": 190, "21":140 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Worklight",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 130, "3": 0, "4": 255, "5": 165, "6": 0, "16": 1, "17": 255, "18": 0, "19": 255, "20": 190, "21": 140, "22": 0, "23": 0, "24": 0, "25": 255, "26": 190, "27": 140 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Chill",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 255, "3": 0, "4": 255, "5": 39, "6": 0, "16": 1, "17": 255, "18": 0, "19": 255, "20": 255, "21": 0, "22": 0, "23": 0, "24": 0, "25": 128, "26": 0, "27": 255, "32": 255, "33": 60 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Cinema",
|
||||
"values": {
|
||||
"office": { "1": 16, "2": 30, "3":0, "4": 255, "5": 39, "6": 0, "16": 0, "32": 255, "33": 0 }
|
||||
}
|
||||
}
|
||||
],
|
||||
"universes": {
|
||||
"office": {
|
||||
"output": {
|
||||
"driver": "enttec-usb-dmx-pro",
|
||||
"device": "/dev/ttyUSB0"
|
||||
},
|
||||
"devices": [
|
||||
{
|
||||
"type": "generic-rgb",
|
||||
"address": 4,
|
||||
"name": "rgb"
|
||||
},
|
||||
{
|
||||
"type": "generic-rgb",
|
||||
"address": 8,
|
||||
"name": "rgb"
|
||||
},
|
||||
{
|
||||
"type": "generic-rgb",
|
||||
"address": 12,
|
||||
"name": "rgb"
|
||||
},
|
||||
{
|
||||
"type": "generic-rgb",
|
||||
"address": 16,
|
||||
"name": "rgb"
|
||||
},
|
||||
{
|
||||
"type": "generic-rgb",
|
||||
"address": 20,
|
||||
"name": "rgb"
|
||||
},
|
||||
{
|
||||
"type": "generic-rgb",
|
||||
"address": 24,
|
||||
"name": "rgb"
|
||||
},
|
||||
{
|
||||
"type": "generic-rgb",
|
||||
"address": 28,
|
||||
"name": "rgb"
|
||||
},
|
||||
{
|
||||
"type": "generic-rgb",
|
||||
"address": 32,
|
||||
"name": "rgb"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"_animPresets": [{
|
||||
"_comment1": "Change _animPresets to animPresets for a new tab with all preset animations",
|
||||
"_comment2": "Check documentation for how to make animations",
|
||||
"label": "test",
|
||||
"anim": {
|
||||
"office": [{
|
||||
"to": {
|
||||
"10": 0,
|
||||
"20": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"to": {
|
||||
"10": 255
|
||||
},
|
||||
"duration": 2000
|
||||
},
|
||||
{
|
||||
"to": {
|
||||
"20": 255
|
||||
},
|
||||
"duration": 1000
|
||||
}
|
||||
]
|
||||
}
|
||||
}]
|
||||
}
|
512
index.html
512
index.html
|
@ -1,256 +1,256 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>DMX Lichtschalter</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
background: #222;
|
||||
color: #eee;
|
||||
}
|
||||
h1 {
|
||||
clear: both;
|
||||
}
|
||||
input[type=range] {
|
||||
-webkit-appearance: slider-vertical;
|
||||
height: 100px;
|
||||
width: 60px;
|
||||
margin-bottom: 2em;
|
||||
margin-top: 3em;
|
||||
}
|
||||
|
||||
input[type=range]:before {
|
||||
content: attr(value);
|
||||
color: #eee;
|
||||
font-family: monospace;
|
||||
text-align: center;
|
||||
width: 60px;
|
||||
display: block;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: 2em;
|
||||
}
|
||||
.device {
|
||||
clear: both;
|
||||
padding-top: 1em;
|
||||
}
|
||||
.channel {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
</style>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
|
||||
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script>
|
||||
function get_html_id(universe, channel) {
|
||||
return 'channel_' + universe + '_' + channel;
|
||||
}
|
||||
|
||||
function rgb_to_array(str) {
|
||||
matches = str.match(/^#([0-9a-f]{6})$/i)
|
||||
if (!matches) {
|
||||
return [0,0,0]
|
||||
}
|
||||
m = matches[1];
|
||||
if(m) {
|
||||
return [
|
||||
parseInt(m.substr(0,2),16),
|
||||
parseInt(m.substr(2,2),16),
|
||||
parseInt(m.substr(4,2),16)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
function decimalToHex(d, padding) {
|
||||
var hex = Number(d).toString(16);
|
||||
padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;
|
||||
while (hex.length < padding) {
|
||||
hex = "0" + hex;
|
||||
}
|
||||
return hex;
|
||||
}
|
||||
|
||||
function array_to_rgb(arr) {
|
||||
return '#'+decimalToHex(arr[0])+decimalToHex(arr[1])+decimalToHex(arr[2]);
|
||||
}
|
||||
|
||||
var socket = io();
|
||||
socket.on('init', function (msg) {
|
||||
$('#presets').empty();
|
||||
$('#sliders').empty();
|
||||
$('#anim').empty();
|
||||
setup = msg.setup
|
||||
devices = msg.devices
|
||||
|
||||
if(setup.title !== undefined) {
|
||||
document.title = setup.title;
|
||||
}
|
||||
|
||||
/* preset buttons */
|
||||
for(var preset in setup.presets) {
|
||||
var html = '<button class="span2 btn btn-info">' + setup.presets[preset].label + '</button>';
|
||||
var e = $(html)
|
||||
e.hide().appendTo('#presets').fadeIn();
|
||||
e.click(function(values) { return function() {
|
||||
for(var universe in values) {
|
||||
socket.emit('update', universe, values[universe]);
|
||||
}
|
||||
};}(setup.presets[preset].values));
|
||||
}
|
||||
|
||||
/* blackout button */
|
||||
var blackout = $('<button class="span2 btn btn-danger">Black Out</button>');
|
||||
blackout.hide().appendTo('#presets').fadeIn();
|
||||
blackout.click(function() {
|
||||
for(var universe in setup.universes) {
|
||||
var u = {};
|
||||
for(var i = 0; i < 255; i++) {
|
||||
u[i] = 0;
|
||||
}
|
||||
socket.emit('update', universe, u);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/* sliders */
|
||||
for(var universe in setup.universes) {
|
||||
var html = "<div><h1>" + universe + "</h1>";
|
||||
for(var device in setup.universes[universe].devices) {
|
||||
var dev = setup.universes[universe].devices[device];
|
||||
html += '<div class="device">';
|
||||
if(dev.name !== undefined) {
|
||||
html += '<h4 class="name">'+dev.name+'</h4>'
|
||||
}
|
||||
for(var channel in devices[dev.type].channels) {
|
||||
var channel_id = dev.address + Number(channel)
|
||||
var html_id = get_html_id(universe, channel_id);
|
||||
html += '<div class="channel">'
|
||||
html += '<label for="' + html_id + '">' + devices[dev.type].channels[channel] + '</label>';
|
||||
html += '<input id="' + html_id + '" type="range" min="0" value="0" max="255" orient="vertical">'
|
||||
html += '</div>'
|
||||
}
|
||||
if(devices[dev.type].channels.includes('red') && devices[dev.type].channels.includes('blue') && devices[dev.type].channels.includes('green')) {
|
||||
var html_id = get_html_id(universe, dev.address);
|
||||
html += '<input id="picker_'+html_id+'" type="color" data-red="'+devices[dev.type].channels.indexOf('red');
|
||||
html += '" data-green="'+devices[dev.type].channels.indexOf('green')+'" data-blue="'+devices[dev.type].channels.indexOf('blue')+'"/>';
|
||||
}
|
||||
html += '</div>'
|
||||
}
|
||||
html += "</div>";
|
||||
$(html).hide().appendTo('#sliders').fadeIn();
|
||||
}
|
||||
|
||||
/* animations */
|
||||
for(var animation in setup.animPresets) {
|
||||
var html = '<button class="span2 btn btn-info">' + setup.animPresets[animation].label + '</button>';
|
||||
var e = $(html)
|
||||
e.hide().appendTo('#anim').fadeIn();
|
||||
e.click(function(values) { return function() {
|
||||
for(var universe in values) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(values[universe]),
|
||||
url: '/animation/'+universe,
|
||||
processData: false,
|
||||
dataType: 'json'
|
||||
});
|
||||
}
|
||||
};}(setup.animPresets[animation].anim));
|
||||
}
|
||||
|
||||
$("input").live("change", function(e) {
|
||||
var i = e.target.id.split('_');
|
||||
if(i[0] === 'picker') {
|
||||
var u = {};
|
||||
var tar = $(e.target);
|
||||
var value = rgb_to_array(tar.val());
|
||||
u[Number(i[3])+Number(tar.data('red'))] = value[0];
|
||||
u[Number(i[3])+Number(tar.data('green'))] = value[1];
|
||||
u[Number(i[3])+Number(tar.data('blue'))] = value[2];
|
||||
socket.emit('update', i[2], u);
|
||||
}
|
||||
else {
|
||||
var u = {};
|
||||
u[i[2]] = e.target.value;
|
||||
socket.emit('update', i[1], u);
|
||||
}
|
||||
});
|
||||
socket.emit('request_refresh');
|
||||
});
|
||||
socket.on('update', function (universe, update) {
|
||||
for(var k in update) {
|
||||
$('#' + get_html_id(universe, k)).attr('value', update[k]);
|
||||
}
|
||||
$("[id^=picker_channel_"+universe+"]").each(function(index, value){
|
||||
var self = $(this);
|
||||
var id = self.attr('id').split('_');
|
||||
var obj = self.data();
|
||||
var arr = Object.keys(obj).map(function(key){return obj[key];});
|
||||
var _id = Number(id[3]);
|
||||
var min = _id;
|
||||
var max = min;
|
||||
min += Math.min.apply( null, arr );
|
||||
max += Math.max.apply( null, arr );
|
||||
for(var k in update) {
|
||||
if(k >= min && k <= max) {
|
||||
var values = rgb_to_array(self.val());
|
||||
var address = k - _id;
|
||||
if(address === Number(self.data('red'))) {
|
||||
values[0] = update[k];
|
||||
}
|
||||
else if(address === Number(self.data('green'))) {
|
||||
values[1] = update[k];
|
||||
}
|
||||
else if(address === Number(self.data('blue'))) {
|
||||
values[2] = update[k];
|
||||
}
|
||||
self.val(array_to_rgb(values));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-inverse">
|
||||
<div class="navbar-inner">
|
||||
<ul class="nav" id="myTab">
|
||||
<li class="active"><a href="#home" data-toggle="tab">Home</a></li>
|
||||
<li><a href="#sliders" data-toggle="tab">Sliders</a></li>
|
||||
<li><a href="#anim" data-toggle="tab">Animations</a></li>
|
||||
<!--<li><a href="#scripts" data-toggle="tab">Scripts</a></li>-->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="tab-content">
|
||||
<div id="home" class="tab-pane active">
|
||||
<div class="row-fluid" id="presets">
|
||||
</div>
|
||||
</div>
|
||||
<div id="sliders" class="tab-pane">
|
||||
|
||||
</div>
|
||||
<div id="anim" class="tab-pane">
|
||||
|
||||
</div>
|
||||
<div id="scripts" class="tab-pane">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>DMX Lichtschalter</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
background: #222;
|
||||
color: #eee;
|
||||
}
|
||||
h1 {
|
||||
clear: both;
|
||||
}
|
||||
input[type=range] {
|
||||
-webkit-appearance: slider-vertical;
|
||||
height: 100px;
|
||||
width: 60px;
|
||||
margin-bottom: 2em;
|
||||
margin-top: 3em;
|
||||
}
|
||||
|
||||
input[type=range]:before {
|
||||
content: attr(value);
|
||||
color: #eee;
|
||||
font-family: monospace;
|
||||
text-align: center;
|
||||
width: 60px;
|
||||
display: block;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: 2em;
|
||||
}
|
||||
.device {
|
||||
clear: both;
|
||||
padding-top: 1em;
|
||||
}
|
||||
.channel {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
</style>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
|
||||
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script>
|
||||
function get_html_id(universe, channel) {
|
||||
return 'channel_' + universe + '_' + channel;
|
||||
}
|
||||
|
||||
function rgb_to_array(str) {
|
||||
matches = str.match(/^#([0-9a-f]{6})$/i)
|
||||
if (!matches) {
|
||||
return [0,0,0]
|
||||
}
|
||||
m = matches[1];
|
||||
if(m) {
|
||||
return [
|
||||
parseInt(m.substr(0,2),16),
|
||||
parseInt(m.substr(2,2),16),
|
||||
parseInt(m.substr(4,2),16)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
function decimalToHex(d, padding) {
|
||||
var hex = Number(d).toString(16);
|
||||
padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;
|
||||
while (hex.length < padding) {
|
||||
hex = "0" + hex;
|
||||
}
|
||||
return hex;
|
||||
}
|
||||
|
||||
function array_to_rgb(arr) {
|
||||
return '#'+decimalToHex(arr[0])+decimalToHex(arr[1])+decimalToHex(arr[2]);
|
||||
}
|
||||
|
||||
var socket = io();
|
||||
socket.on('init', function (msg) {
|
||||
$('#presets').empty();
|
||||
$('#sliders').empty();
|
||||
$('#anim').empty();
|
||||
setup = msg.setup
|
||||
devices = msg.devices
|
||||
|
||||
if(setup.title !== undefined) {
|
||||
document.title = setup.title;
|
||||
}
|
||||
|
||||
/* preset buttons */
|
||||
for(var preset in setup.presets) {
|
||||
var html = '<button class="span2 btn btn-info">' + setup.presets[preset].label + '</button>';
|
||||
var e = $(html)
|
||||
e.hide().appendTo('#presets').fadeIn();
|
||||
e.click(function(values) { return function() {
|
||||
for(var universe in values) {
|
||||
socket.emit('update', universe, values[universe]);
|
||||
}
|
||||
};}(setup.presets[preset].values));
|
||||
}
|
||||
|
||||
/* blackout button */
|
||||
var blackout = $('<button class="span2 btn btn-danger">Black Out</button>');
|
||||
blackout.hide().appendTo('#presets').fadeIn();
|
||||
blackout.click(function() {
|
||||
for(var universe in setup.universes) {
|
||||
var u = {};
|
||||
for(var i = 0; i < 255; i++) {
|
||||
u[i] = 0;
|
||||
}
|
||||
socket.emit('update', universe, u);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/* sliders */
|
||||
for(var universe in setup.universes) {
|
||||
var html = "<div><h1>" + universe + "</h1>";
|
||||
for(var device in setup.universes[universe].devices) {
|
||||
var dev = setup.universes[universe].devices[device];
|
||||
html += '<div class="device">';
|
||||
if(dev.name !== undefined) {
|
||||
html += '<h4 class="name">'+dev.name+'</h4>'
|
||||
}
|
||||
for(var channel in devices[dev.type].channels) {
|
||||
var channel_id = dev.address + Number(channel)
|
||||
var html_id = get_html_id(universe, channel_id);
|
||||
html += '<div class="channel">'
|
||||
html += '<label for="' + html_id + '">' + devices[dev.type].channels[channel] + '</label>';
|
||||
html += '<input id="' + html_id + '" type="range" min="0" value="0" max="255" orient="vertical">'
|
||||
html += '</div>'
|
||||
}
|
||||
if(devices[dev.type].channels.includes('red') && devices[dev.type].channels.includes('blue') && devices[dev.type].channels.includes('green')) {
|
||||
var html_id = get_html_id(universe, dev.address);
|
||||
html += '<input id="picker_'+html_id+'" type="color" data-red="'+devices[dev.type].channels.indexOf('red');
|
||||
html += '" data-green="'+devices[dev.type].channels.indexOf('green')+'" data-blue="'+devices[dev.type].channels.indexOf('blue')+'"/>';
|
||||
}
|
||||
html += '</div>'
|
||||
}
|
||||
html += "</div>";
|
||||
$(html).hide().appendTo('#sliders').fadeIn();
|
||||
}
|
||||
|
||||
/* animations */
|
||||
for(var animation in setup.animPresets) {
|
||||
var html = '<button class="span2 btn btn-info">' + setup.animPresets[animation].label + '</button>';
|
||||
var e = $(html)
|
||||
e.hide().appendTo('#anim').fadeIn();
|
||||
e.click(function(values) { return function() {
|
||||
for(var universe in values) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(values[universe]),
|
||||
url: '/animation/'+universe,
|
||||
processData: false,
|
||||
dataType: 'json'
|
||||
});
|
||||
}
|
||||
};}(setup.animPresets[animation].anim));
|
||||
}
|
||||
|
||||
$("input").live("change", function(e) {
|
||||
var i = e.target.id.split('_');
|
||||
if(i[0] === 'picker') {
|
||||
var u = {};
|
||||
var tar = $(e.target);
|
||||
var value = rgb_to_array(tar.val());
|
||||
u[Number(i[3])+Number(tar.data('red'))] = value[0];
|
||||
u[Number(i[3])+Number(tar.data('green'))] = value[1];
|
||||
u[Number(i[3])+Number(tar.data('blue'))] = value[2];
|
||||
socket.emit('update', i[2], u);
|
||||
}
|
||||
else {
|
||||
var u = {};
|
||||
u[i[2]] = e.target.value;
|
||||
socket.emit('update', i[1], u);
|
||||
}
|
||||
});
|
||||
socket.emit('request_refresh');
|
||||
});
|
||||
socket.on('update', function (universe, update) {
|
||||
for(var k in update) {
|
||||
$('#' + get_html_id(universe, k)).attr('value', update[k]);
|
||||
}
|
||||
$("[id^=picker_channel_"+universe+"]").each(function(index, value){
|
||||
var self = $(this);
|
||||
var id = self.attr('id').split('_');
|
||||
var obj = self.data();
|
||||
var arr = Object.keys(obj).map(function(key){return obj[key];});
|
||||
var _id = Number(id[3]);
|
||||
var min = _id;
|
||||
var max = min;
|
||||
min += Math.min.apply( null, arr );
|
||||
max += Math.max.apply( null, arr );
|
||||
for(var k in update) {
|
||||
if(k >= min && k <= max) {
|
||||
var values = rgb_to_array(self.val());
|
||||
var address = k - _id;
|
||||
if(address === Number(self.data('red'))) {
|
||||
values[0] = update[k];
|
||||
}
|
||||
else if(address === Number(self.data('green'))) {
|
||||
values[1] = update[k];
|
||||
}
|
||||
else if(address === Number(self.data('blue'))) {
|
||||
values[2] = update[k];
|
||||
}
|
||||
self.val(array_to_rgb(values));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-inverse">
|
||||
<div class="navbar-inner">
|
||||
<ul class="nav" id="myTab">
|
||||
<li class="active"><a href="#home" data-toggle="tab">Home</a></li>
|
||||
<li><a href="#sliders" data-toggle="tab">Sliders</a></li>
|
||||
<li><a href="#anim" data-toggle="tab">Animations</a></li>
|
||||
<!--<li><a href="#scripts" data-toggle="tab">Scripts</a></li>-->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="tab-content">
|
||||
<div id="home" class="tab-pane active">
|
||||
<div class="row-fluid" id="presets">
|
||||
</div>
|
||||
</div>
|
||||
<div id="sliders" class="tab-pane">
|
||||
|
||||
</div>
|
||||
<div id="anim" class="tab-pane">
|
||||
|
||||
</div>
|
||||
<div id="scripts" class="tab-pane">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
5543
package-lock.json
generated
Normal file
5543
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
71
package.json
71
package.json
|
@ -1,35 +1,36 @@
|
|||
{
|
||||
"name": "dmx-web",
|
||||
"version": "1.0.1",
|
||||
"author": "Sebastian Wiedenroth <wiedi@frubar.net>",
|
||||
"description": "DMX webservice and web ui powered by node-dmx",
|
||||
"url": "https://github.com/node-dmx/dmx-web",
|
||||
"bin": {
|
||||
"dmx-web": "./dmx-web.js"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node_modules/eslint/bin/eslint.js -c .eslintrc .; exit 0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/node-dmx/dmx-web.git"
|
||||
},
|
||||
"keywords": [
|
||||
"DMX",
|
||||
"light control"
|
||||
],
|
||||
"dependencies": {
|
||||
"dmx": "^0.2.0",
|
||||
"commander": "^2.12.2",
|
||||
"express": "^4.16.2",
|
||||
"socket.io": "^2.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^10.0.1",
|
||||
"eslint": "^5.0.1"
|
||||
},
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "dmx-web",
|
||||
"version": "1.0.1",
|
||||
"author": "Sebastian Wiedenroth <wiedi@frubar.net>",
|
||||
"description": "DMX webservice and web ui powered by node-dmx",
|
||||
"url": "https://github.com/node-dmx/dmx-web",
|
||||
"bin": {
|
||||
"dmx-web": "./dmx-web.js"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node_modules/eslint/bin/eslint.js -c .eslintrc .; exit 0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/node-dmx/dmx-web.git"
|
||||
},
|
||||
"keywords": [
|
||||
"DMX",
|
||||
"light control"
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "^2.12.2",
|
||||
"dmx": "^0.2.0",
|
||||
"express": "^4.16.2",
|
||||
"socket.io": "^2.0.4",
|
||||
"socket.io-client": "^4.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^10.0.1",
|
||||
"eslint": "^5.0.1"
|
||||
},
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
}
|
||||
|
|
110
readme.md
110
readme.md
|
@ -1,55 +1,55 @@
|
|||
# node-dmx
|
||||
|
||||
Webinterface and HTTP API using [node-dmx](https://github.com/node-dmx/dmx)
|
||||
|
||||
## Install
|
||||
|
||||
`npm install -g dmx-web`
|
||||
|
||||
## Webinterface
|
||||
|
||||
### Configuration
|
||||
|
||||
The Daemon `dmx-web` looks for a configuration file in `/etc/dmx-web.json`. An alternate location can be passed as a command line argument.
|
||||
|
||||
This configuration file consists of three sections:
|
||||
|
||||
- Server
|
||||
- Universes
|
||||
- Presets
|
||||
|
||||
In the Server section you can set the listen port and host.
|
||||
Under Universes you describe the DMX Universes with details like which output driver to use and which devices are at which address.
|
||||
The presets section allows you to specify a state some channels should be set when the preset is called.
|
||||
|
||||
A example configuration is in the repository by the name `dmx-web-example.conf`
|
||||
|
||||
### Run
|
||||
|
||||
`dmx-web [-c <full-path to config file>]`
|
||||
|
||||
### Run as a service
|
||||
|
||||
On MacOS you can run dmx-web as a service by adding a launch script to `/Library/LaunchDaemons`. See the example file.
|
||||
|
||||
### Animation HTTP API
|
||||
|
||||
A List of Channel Transistions can be POSTed to `/animation/<universe>`. Each transistion is a JSON Object with at least the `to` property present. The Value of which also has to be an Object describing the channel end-states.
|
||||
|
||||
A duration for this transistion can be given in the `duration` property.
|
||||
If not specified 0ms is assumed.
|
||||
|
||||
Example:
|
||||
|
||||
[
|
||||
{"to": {"10": 0, "20": 0}},
|
||||
{"to": {"10": 255}, "duration": 2000},
|
||||
{"to": {"20": 255}, "duration": 1000}
|
||||
]
|
||||
|
||||
This sets channels 10 and 20 to zero. Then transistions channel 10 to 255 in 2 seconds. After that channel 20 is faded to 255 in 1 second.
|
||||
|
||||
|
||||
## Community
|
||||
|
||||
We're happy to help. Chat with us on IRC in #dmx on libera.chat.
|
||||
# node-dmx
|
||||
|
||||
Webinterface and HTTP API using [node-dmx](https://github.com/node-dmx/dmx)
|
||||
|
||||
## Install
|
||||
|
||||
`npm install -g dmx-web`
|
||||
|
||||
## Webinterface
|
||||
|
||||
### Configuration
|
||||
|
||||
The Daemon `dmx-web` looks for a configuration file in `/etc/dmx-web.json`. An alternate location can be passed as a command line argument.
|
||||
|
||||
This configuration file consists of three sections:
|
||||
|
||||
- Server
|
||||
- Universes
|
||||
- Presets
|
||||
|
||||
In the Server section you can set the listen port and host.
|
||||
Under Universes you describe the DMX Universes with details like which output driver to use and which devices are at which address.
|
||||
The presets section allows you to specify a state some channels should be set when the preset is called.
|
||||
|
||||
A example configuration is in the repository by the name `dmx-web-example.conf`
|
||||
|
||||
### Run
|
||||
|
||||
`dmx-web [-c <full-path to config file>]`
|
||||
|
||||
### Run as a service
|
||||
|
||||
On MacOS you can run dmx-web as a service by adding a launch script to `/Library/LaunchDaemons`. See the example file.
|
||||
|
||||
### Animation HTTP API
|
||||
|
||||
A List of Channel Transistions can be POSTed to `/animation/<universe>`. Each transistion is a JSON Object with at least the `to` property present. The Value of which also has to be an Object describing the channel end-states.
|
||||
|
||||
A duration for this transistion can be given in the `duration` property.
|
||||
If not specified 0ms is assumed.
|
||||
|
||||
Example:
|
||||
|
||||
[
|
||||
{"to": {"10": 0, "20": 0}},
|
||||
{"to": {"10": 255}, "duration": 2000},
|
||||
{"to": {"20": 255}, "duration": 1000}
|
||||
]
|
||||
|
||||
This sets channels 10 and 20 to zero. Then transistions channel 10 to 255 in 2 seconds. After that channel 20 is faded to 255 in 1 second.
|
||||
|
||||
|
||||
## Community
|
||||
|
||||
We're happy to help. Chat with us on IRC in #dmx on libera.chat.
|
||||
|
|
Loading…
Reference in a new issue