Skip to content

Commit

Permalink
New macro: Sennheiser mute sync
Browse files Browse the repository at this point in the history
  • Loading branch information
tbjolset committed Aug 31, 2024
1 parent 0349089 commit 95cb9a8
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 0 deletions.
21 changes: 21 additions & 0 deletions Sennheiser Mute Sync/README.md
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.

![Sennheiser TCC M](./sennheiser-tcc-m.jpg)

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
42 changes: 42 additions & 0 deletions Sennheiser Mute Sync/manifest.json
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
}
]
}
}
72 changes: 72 additions & 0 deletions Sennheiser Mute Sync/sennheiser-lib.js
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

72 changes: 72 additions & 0 deletions Sennheiser Mute Sync/sennheiser-sync.js
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()
Binary file added Sennheiser Mute Sync/sennheiser-tcc-m.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions macro-list.json
Original file line number Diff line number Diff line change
Expand Up @@ -269,5 +269,12 @@
"description": "Monitors web apps so, upon exit, a prompt appears that asks the user to clear their cached login credentials.",
"symbol": "🔐",
"tags": "meeting room, web, whiteboard"
},
{
"title": "Sennheiser Mute Sync",
"description": "Sync the mute state on a Sennheiser TCCM ceiling microphone",
"symbol": "🔇",
"tags": "calling, audio, peripherals"
}

]

0 comments on commit 95cb9a8

Please sign in to comment.