A catalog install ships source only, and a catalog update deletes the module folder — a previously built ltc-capture binary with it — so every install or update left LTC dead until someone compiled the tool by hand. The build also still used the blocking spawnSync that once froze the whole server (the bug spl-meter fixed in 0.4.0), and only ran when a listener started: no tool meant no device list, and no device meant no listener. ensureCaptureBinary() (module scope in ltc-listener.js, the spl-meter 0.4.2 pattern) now builds the tool in the background as part of coming up: kicked when the LTC source starts and by the admin device picker, single-flight, built to a temp name and renamed so a killed build can't leave a truncated binary, and rebuilt behind a still-serving binary when a module update leaves the source newer. The waiting listener starts itself the moment the build lands. Tile-side warnings are now one line — 'Not configured — see Admin', 'Unreachable', 'Capture tool building…' — with the client's source-label prefix no longer repeated. The full diagnostics (host:port, errno, the capture tool's own words, build instructions) move to the admin health line and the log, where the person who can act on them is looking. Verified: build from the exact catalog-install state (source only) lands and lists 12 real devices; touching the source triggers an atomic rebuild while the old binary keeps serving; /ltc/devices kicks the build and answers with the device list; live server shows terse source messages on the tile and the detailed story in /api/admin/state health. ltc and phase selftests still pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
229 lines
5.4 KiB
JSON
229 lines
5.4 KiB
JSON
{
|
||
"id": "propresenter-timers",
|
||
"name": "Timers",
|
||
"version": "1.5.0",
|
||
"proddash": ">=1.4.0",
|
||
"description": "Timers, Clocks, and LTC From configured Modules",
|
||
"provides": [
|
||
"timers"
|
||
],
|
||
"permissions": [
|
||
{
|
||
"kind": "microphone",
|
||
"reason": "Decoding SMPTE LTC timecode from an audio input on this machine"
|
||
},
|
||
{
|
||
"kind": "local-network",
|
||
"reason": "Reaching ProPresenter on this network"
|
||
}
|
||
],
|
||
"client": "client.js",
|
||
"server": "server.js",
|
||
"style": "style.css",
|
||
"minSize": {
|
||
"w": 2,
|
||
"h": 1
|
||
},
|
||
"defaultSize": {
|
||
"w": 4,
|
||
"h": 3
|
||
},
|
||
"configGroups": {
|
||
"ProPresenter": {
|
||
"toggle": "ppEnabled",
|
||
"help": "The timers configured in ProPresenter, read over its network API. Enable the network in ProPresenter's Preferences › Network and enter the host and port shown there. Switch it off on a day ProPresenter isn't running and nothing is polled."
|
||
},
|
||
"LTC Timecode": {
|
||
"toggle": "ltcEnabled",
|
||
"help": "SMPTE LTC decoded from an audio input on this machine, shown as a running timecode. Pick the device and the channel the timecode arrives on; macOS has to grant ProdDash the microphone (see the launcher's Permissions)."
|
||
},
|
||
"PCO Plan": {
|
||
"toggle": "pcoEnabled",
|
||
"help": "Timers the PCO Plan module offers — service elapsed, current item, countdown to service — appear here under a PCO Plan heading when that module is installed and configured. Nothing to set up on this side."
|
||
}
|
||
},
|
||
"configSchema": {
|
||
"ppEnabled": {
|
||
"type": "switch",
|
||
"label": "ProPresenter timers",
|
||
"group": "ProPresenter",
|
||
"default": true
|
||
},
|
||
"propresenter": {
|
||
"type": "endpoint",
|
||
"label": "ProPresenter",
|
||
"group": "ProPresenter",
|
||
"default": {
|
||
"host": "",
|
||
"port": 1025
|
||
}
|
||
},
|
||
"password": {
|
||
"type": "password",
|
||
"label": "API password",
|
||
"group": "ProPresenter",
|
||
"default": "",
|
||
"help": "Only if a password is set in ProPresenter's network preferences."
|
||
},
|
||
"ltcEnabled": {
|
||
"type": "switch",
|
||
"label": "LTC timecode",
|
||
"group": "LTC Timecode",
|
||
"default": false
|
||
},
|
||
"ltcDevice": {
|
||
"type": "select",
|
||
"label": "Audio device",
|
||
"group": "LTC Timecode",
|
||
"showWhen": "ltcEnabled",
|
||
"default": "",
|
||
"optionsRoute": "/ltc/devices"
|
||
},
|
||
"ltcChannel": {
|
||
"type": "number",
|
||
"label": "Channel",
|
||
"group": "LTC Timecode",
|
||
"showWhen": "ltcEnabled",
|
||
"default": 1,
|
||
"help": "The channel on that device carrying the timecode, counted from 1."
|
||
},
|
||
"pcoEnabled": {
|
||
"type": "switch",
|
||
"label": "PCO Plan timers",
|
||
"group": "PCO Plan",
|
||
"default": true
|
||
},
|
||
"timerFont": {
|
||
"type": "select",
|
||
"label": "Timer font",
|
||
"group": "Display",
|
||
"default": "default",
|
||
"options": [
|
||
{
|
||
"value": "default",
|
||
"label": "Default (system)"
|
||
},
|
||
{
|
||
"value": "monospace",
|
||
"label": "Monospace — steadier changing digits"
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"instanceGroups": {
|
||
"Show": {
|
||
"collapsed": true,
|
||
"columns": 2
|
||
},
|
||
"Clock": {
|
||
"collapsed": false,
|
||
"columns": 2
|
||
},
|
||
"Colours": {
|
||
"collapsed": true,
|
||
"columns": 2
|
||
}
|
||
},
|
||
"instanceSchema": {
|
||
"showNames": {
|
||
"type": "switch",
|
||
"label": "Names",
|
||
"default": true,
|
||
"group": "Show"
|
||
},
|
||
"showStatus": {
|
||
"type": "switch",
|
||
"label": "Status lines",
|
||
"default": true,
|
||
"group": "Show"
|
||
},
|
||
"showDetail": {
|
||
"type": "switch",
|
||
"label": "Detail lines",
|
||
"default": true,
|
||
"group": "Show"
|
||
},
|
||
"showSeconds": {
|
||
"type": "switch",
|
||
"label": "Seconds",
|
||
"default": true,
|
||
"group": "Show"
|
||
},
|
||
"leadingZeros": {
|
||
"type": "switch",
|
||
"label": "Leading zeros",
|
||
"default": false,
|
||
"group": "Show"
|
||
},
|
||
"groupBySource": {
|
||
"type": "switch",
|
||
"label": "Group by source",
|
||
"default": false,
|
||
"group": "Show"
|
||
},
|
||
"showHeadings": {
|
||
"type": "switch",
|
||
"label": "Source headings",
|
||
"default": true,
|
||
"group": "Show",
|
||
"showWhen": "groupBySource"
|
||
},
|
||
"clock24h": {
|
||
"type": "switch",
|
||
"label": "24-hour",
|
||
"default": true,
|
||
"group": "Clock"
|
||
},
|
||
"clockSeconds": {
|
||
"type": "switch",
|
||
"label": "Seconds",
|
||
"default": true,
|
||
"group": "Clock"
|
||
},
|
||
"clockDate": {
|
||
"type": "switch",
|
||
"label": "Date",
|
||
"default": false,
|
||
"group": "Clock"
|
||
},
|
||
"dateShortDay": {
|
||
"type": "switch",
|
||
"label": "Short day",
|
||
"default": false,
|
||
"group": "Clock",
|
||
"showWhen": "clockDate"
|
||
},
|
||
"dateShortMonth": {
|
||
"type": "switch",
|
||
"label": "Short month",
|
||
"default": false,
|
||
"group": "Clock",
|
||
"showWhen": "clockDate"
|
||
},
|
||
"runningColor": {
|
||
"type": "color",
|
||
"label": "Running",
|
||
"default": "#2ee59a",
|
||
"group": "Colours"
|
||
},
|
||
"warningColor": {
|
||
"type": "color",
|
||
"label": "Warning",
|
||
"default": "#f0b429",
|
||
"group": "Colours"
|
||
},
|
||
"overrunColor": {
|
||
"type": "color",
|
||
"label": "Overrun",
|
||
"default": "#f4433c",
|
||
"group": "Colours"
|
||
},
|
||
"idleColor": {
|
||
"type": "color",
|
||
"label": "Idle",
|
||
"default": "#8b98a5",
|
||
"group": "Colours"
|
||
}
|
||
}
|
||
}
|