Skip to content

Commit 8e196d7

Browse files
authored
Add files via upload
1 parent ff2d4ab commit 8e196d7

File tree

10 files changed

+450
-657
lines changed

10 files changed

+450
-657
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Bitfocus AS - Open Source
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

actions.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
module.exports = {
2+
getActions: function (instance) {
3+
const choices = instance.getSeatChoices()
4+
const interpreterChoices = instance.getInterpreterSeatChoices()
5+
6+
return {
7+
custom_command: {
8+
name: 'Custom Command',
9+
options: [
10+
{
11+
type: 'textinput',
12+
label: 'Operation',
13+
id: 'operation',
14+
default: '',
15+
},
16+
{
17+
type: 'textinput',
18+
label: 'Parameters (JSON)',
19+
id: 'parameters',
20+
default: '{}',
21+
},
22+
],
23+
callback: async (action) => {
24+
try {
25+
const parameters = JSON.parse(action.options.parameters)
26+
const message = {
27+
operation: action.options.operation,
28+
parameters: parameters,
29+
}
30+
if (instance.ws && instance.ws.readyState === WebSocket.OPEN) {
31+
instance.ws.send(JSON.stringify(message))
32+
} else {
33+
instance.log('error', '[CUSTOM] WebSocket not connected')
34+
}
35+
} catch (error) {
36+
instance.log('error', `[CUSTOM] Error parsing parameters JSON: ${error.message}`)
37+
}
38+
},
39+
},
40+
toggle_microphone: {
41+
name: 'Toggle Microphone',
42+
options: [
43+
{
44+
type: 'dropdown',
45+
label: 'Seat',
46+
id: 'seat',
47+
default: choices[0]?.id || '',
48+
choices: choices,
49+
},
50+
],
51+
callback: async (action) => {
52+
instance.toggleMicrophone(action.options.seat)
53+
},
54+
},
55+
activate_microphone: {
56+
name: 'Activate Microphone',
57+
options: [
58+
{
59+
type: 'dropdown',
60+
label: 'Seat',
61+
id: 'seat',
62+
default: choices[0]?.id || '',
63+
choices,
64+
},
65+
],
66+
callback: async (action) => {
67+
instance.activateMicrophone(instance.seats[action.options.seat]?.seatId)
68+
},
69+
},
70+
deactivate_microphone: {
71+
name: 'Deactivate Microphone',
72+
options: [
73+
{
74+
type: 'dropdown',
75+
label: 'Seat',
76+
id: 'seat',
77+
default: choices[0]?.id || '',
78+
choices,
79+
},
80+
],
81+
callback: async (action) => {
82+
instance.deactivateMicrophone(instance.seats[action.options.seat]?.seatId)
83+
},
84+
},
85+
grant_interpretation: {
86+
name: 'Grant Interpretation',
87+
options: [
88+
{
89+
type: 'dropdown',
90+
label: 'Interpreter Seat',
91+
id: 'interpreter_seat',
92+
default: interpreterChoices[0]?.id || '',
93+
choices: interpreterChoices,
94+
},
95+
{
96+
type: 'dropdown',
97+
label: 'State',
98+
id: 'state',
99+
default: 'off',
100+
choices: [
101+
{ id: 'off', label: 'Off' },
102+
{ id: 'activeOnOutputA', label: 'Active on Output A' },
103+
{ id: 'activeOnOutputB', label: 'Active on Output B' },
104+
{ id: 'activeOnOutputC', label: 'Active on Output C' },
105+
],
106+
},
107+
],
108+
callback: async (action) => {
109+
instance.grantInterpretation(instance.interpreterSeats[action.options.interpreter_seat]?.seatId, action.options.state)
110+
},
111+
},
112+
}
113+
},
114+
}

companion/manifest.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
"description": "Control and monitor Bosch Dicentis conference system",
66
"version": "1.0.0",
77
"license": "MIT",
8-
"repository": "https://github.com/mko1989/Bosch-Dicentis-Companion-Module.git",
9-
"bugs": "https://github.com/mko1989/Bosch-Dicentis-Companion-Module/issues",
8+
"repository": "https://github.com/bitfocus/companion-module-bosch-dicentis.git",
9+
"bugs": "https://github.com/bitfocus/companion-module-bosch-dicentis/issues",
1010
"maintainers": [
1111
{
12-
"name": "Marcin Wardecki with help from Codeium Windsurf",
12+
"name": "Marcin Wardecki",
1313
"email": "m.wardecki89@gmail.com"
1414
}
1515
],

config.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// config.js
2+
const { Regex } = require('@companion-module/base')
3+
4+
module.exports = {
5+
getConfigFields() {
6+
return [
7+
{
8+
type: 'textinput',
9+
id: 'server_ip',
10+
label: 'Target IP',
11+
width: 8,
12+
regex: Regex.IP, // Added IP validation
13+
},
14+
{
15+
type: 'textinput',
16+
id: 'username',
17+
label: 'Username',
18+
width: 6,
19+
},
20+
{
21+
type: 'textinput',
22+
id: 'password',
23+
label: 'Password',
24+
width: 6,
25+
},
26+
{
27+
type: 'number',
28+
id: 'pollInterval',
29+
label: 'Polling Interval (ms)',
30+
tooltip: 'How often to request updates (e.g., mic status). Lower values are more responsive but increase network traffic.',
31+
width: 6,
32+
default: 100,
33+
min: 50,
34+
max: 10000,
35+
},
36+
]
37+
},
38+
}

feedbacks.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const { combineRgb } = require('@companion-module/base')
2+
3+
module.exports = {
4+
getFeedbacks: function (instance) {
5+
return {
6+
mic_state: {
7+
type: 'boolean',
8+
name: 'Microphone State',
9+
description: 'Change button color based on microphone state',
10+
defaultStyle: {
11+
bgcolor: combineRgb(255, 0, 0),
12+
},
13+
options: [
14+
{
15+
type: 'dropdown',
16+
label: 'Seat',
17+
id: 'seat',
18+
default: '',
19+
choices: instance.getSeatChoices(),
20+
},
21+
],
22+
callback: (feedback) => {
23+
const seatId = instance.seats[feedback.options.seat]?.seatId
24+
if (!seatId) {
25+
return false
26+
}
27+
return instance.isMicrophoneActive(seatId)
28+
},
29+
// subscribe/unsubscribe are typically handled by checkFeedbacks internally if polling or websocket updates trigger it
30+
},
31+
interpreter_state: {
32+
type: 'boolean',
33+
name: 'Interpreter State',
34+
description: 'Change button color based on interpreter state',
35+
defaultStyle: {
36+
bgcolor: combineRgb(255, 0, 0),
37+
},
38+
options: [
39+
{
40+
type: 'dropdown',
41+
label: 'Interpreter Seat',
42+
id: 'interpreter_seat',
43+
default: '',
44+
choices: instance.getInterpreterSeatChoices(),
45+
},
46+
],
47+
callback: (feedback) => {
48+
const seatId = instance.interpreterSeats[feedback.options.interpreter_seat]?.seatId
49+
if (!seatId) {
50+
return false
51+
}
52+
return instance.isInterpreterActive(seatId)
53+
},
54+
// subscribe/unsubscribe are typically handled by checkFeedbacks internally if polling or websocket updates trigger it
55+
},
56+
}
57+
},
58+
}

0 commit comments

Comments
 (0)