-
Notifications
You must be signed in to change notification settings - Fork 184
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
214 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Sennheiser | ||
|
||
Ensures that the Sennheiser TCCM Ceiling Mic is synced with the mute state of the Cisco video device. | ||
|
||
 | ||
|
||
If for any reason the video device is not able to update the Sennheiser mute state, it displays a warning to users on the screen. | ||
|
||
## Installation | ||
|
||
The integration consists of a simple library module containing the HTTP API calls necessary to talk to the ceiling mic, and a macro for calling those APIs whenever the video system mute state changes. | ||
|
||
* Install `sennheiser-lib.js` and `sennheiser-sync.js` on the video device | ||
* Enter the IP address, the api username and password in the `sennheiser-sync.js` file | ||
* Enable the `sennheiser-sync.js` macro | ||
|
||
Try muting / unmuting the mic (in call) - the LED on the ceiling mic should always stay in sync. | ||
|
||
## Pre-requisites | ||
|
||
- A working setup with a Cisco video device and a Sennheiser ceiling mic |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
{ | ||
"version": "1", | ||
"profile": { | ||
"macro": { | ||
"items": [ | ||
{ | ||
"payload": "./sennheiser-lib.js", | ||
"type": "library", | ||
"id": "sennheiser-lib" | ||
}, | ||
{ | ||
"payload": "./sennheiser-sync.js", | ||
"type": "macro", | ||
"id": "sennheiser-sync" | ||
} | ||
] | ||
}, | ||
"userParams": [ | ||
{ | ||
"id": "ip", | ||
"name": "IP address", | ||
"type": "string", | ||
"domain": "sennheiser-sync", | ||
"required": true | ||
}, | ||
{ | ||
"id": "username", | ||
"name": "API username", | ||
"type": "string", | ||
"domain": "sennheiser-sync", | ||
"required": true | ||
}, | ||
{ | ||
"id": "password", | ||
"name": "API password", | ||
"type": "string", | ||
"domain": "sennheiser-sync", | ||
"required": true | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
* HTTP API Driver for Sennheiser ceiling mic | ||
* | ||
* Remember to enable third party api access and set username / password in the Sennheiser TCCM app | ||
* Usage: | ||
* | ||
* import Sennheiser from './sennheiser-lib' | ||
* | ||
* const mic = new Sennheiser('10.192.12.35', 'admin', 'mypassword') | ||
* | ||
* mic.setLed(on) | ||
* .catch(e => console.warn(e)) | ||
* | ||
* mic.setBrightness(55) | ||
* .catch(e => console.warn(e)) | ||
*/ | ||
|
||
import xapi from 'xapi' | ||
|
||
const LED_API_PATH = '/api/device/leds/ring' | ||
|
||
function http(url, username, password, body) { | ||
const token = btoa(`${username}:${password}`) | ||
const auth = `Authorization: Basic ${token}` | ||
const type = 'Content-Type: application/json' | ||
const options = { | ||
AllowInsecureHTTPS: true, | ||
Url: url, | ||
Header: [type, auth], | ||
ResultBody: 'PlainText' | ||
} | ||
|
||
if (!body) { | ||
return xapi.Command.HttpClient.Get(options) | ||
} | ||
return xapi.Command.HttpClient.Put(options, JSON.stringify(body)) | ||
} | ||
|
||
class Driver { | ||
|
||
constructor(ip, username, password) { | ||
this.ip = ip | ||
this.username = username | ||
this.password = password | ||
} | ||
|
||
setLed(muted) { | ||
const url = 'https://' + this.ip + LED_API_PATH | ||
const body = { micOn: { color: muted ? 'Red' : 'Green' } } | ||
|
||
return http(url, this.username, this.password, body) | ||
} | ||
|
||
getStatus() { | ||
const url = 'https://' + this.ip + LED_API_PATH | ||
return http(url, this.username, this.password) | ||
} | ||
|
||
setBrightness(brightness) { | ||
const bri = Number(brightness) | ||
if (bri < 0 || bri > 5) { | ||
throw new Error('Brightness should be btw 0 and 5') | ||
} | ||
const url = 'https://' + this.ip + LED_API_PATH | ||
const body = { brightness: bri } | ||
|
||
return http(url, this.username, this.password, body) | ||
} | ||
} | ||
|
||
export default Driver | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
* Macro that ensures a Sennheiser mic shows the same mute indicator as a Cisco video device during a call. | ||
* | ||
* When the device is out of call, then mute indicator is turned off. | ||
* | ||
* If the macro at any point is unable to indicate the correct status on the Sennheiser mic, | ||
* it will display a prominent warning about this on the main video screen. | ||
*/ | ||
import xapi from 'xapi'; | ||
import Sennheiser from './sennheiser-lib' | ||
|
||
// You must update these yourself: | ||
|
||
const ip = '169.254.1.246' | ||
const username = 'api' | ||
const password = 'xxx' | ||
|
||
const mic = new Sennheiser(ip, username, password) | ||
|
||
function showSyncWarning() { | ||
xapi.Command.UserInterface.Message.TextLine.Display({ | ||
Text: '🚨 Warning: Microphone mute indicator might be wrong. 🚨', | ||
X: 5000, | ||
Y: 5000, | ||
}) | ||
} | ||
|
||
function hideSyncWarning() { | ||
xapi.Command.UserInterface.Message.TextLine.Clear() | ||
} | ||
|
||
async function syncWithMute() { | ||
const onOff = await xapi.Status.Audio.Microphones.Mute.get() | ||
const muted = onOff == 'On' | ||
try { | ||
await mic.setLed(muted) | ||
hideSyncWarning() | ||
} | ||
catch(e) { | ||
console.error(e) | ||
showSyncWarning() | ||
} | ||
} | ||
|
||
async function syncWithCalls() { | ||
const numberOfCalls = await xapi.Status.SystemUnit.State.NumberOfActiveCalls.get() | ||
const brightness = (numberOfCalls > 0) ? 5 : 0 | ||
try { | ||
await mic.setBrightness(brightness) | ||
hideSyncWarning() | ||
} | ||
catch(e) { | ||
console.error(e) | ||
showSyncWarning() | ||
} | ||
} | ||
|
||
function init() { | ||
// Required for the video device to talk http to the mic | ||
xapi.Config.HttpClient.Mode.set('On') | ||
xapi.Config.HttpClient.AllowInsecureHTTPS.set('True') | ||
|
||
// Sync when macro starts: | ||
syncWithMute() | ||
syncWithCalls() | ||
|
||
// Sync whenever incall or mute changes | ||
xapi.Status.Audio.Microphones.Mute.on(syncWithMute) | ||
xapi.Status.SystemUnit.State.NumberOfActiveCalls.on(syncWithCalls) | ||
} | ||
|
||
init() |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters