Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Zefiro/mpd-bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
Zefiro committed Apr 12, 2023
2 parents b24d7f9 + 3ade395 commit 57f2481
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 20 deletions.
7 changes: 4 additions & 3 deletions mpd.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ module.exports = async function(god, mpdHost = 'localhost', id = 'mpd', _mqttTop

this.registerIoListeners()

this.logger.debug("Subscribing to mqtt")
this.logger.debug("Subscribing to mqtt cmnd/%s", this.mqttTopic)
god.mqtt && god.mqtt.addTrigger('cmnd/' + this.mqttTopic + '/#', 'cmnd-' + this.id, this.onMqttCmnd.bind(this))

this.loadMappings()
},

onMqttCmnd: async function(trigger, topic, message, packet) {
this.logger.debug("mqtt: %s (%s)", topic, message)
this.logger.debug("mqtt received: %s (%s)", topic, message)
if (topic == 'cmnd/' + this.mqttTopic + '/pause') {
let iDelayTimeSec = message && message > 0 && message < 1000 ? message : 0
let res = await this.fadePause(iDelayTimeSec)
Expand Down Expand Up @@ -212,7 +212,7 @@ module.exports = async function(god, mpdHost = 'localhost', id = 'mpd', _mqttTop
await this.tryReconnect()
return await this._getStatus()
}
// this.logger.debug(msg)
// this.logger.debug('getStatus returned: %o', msg)
this.mpdstatus = this.parseKeyValue(msg)

if ('song' in this.mpdstatus) {
Expand Down Expand Up @@ -249,6 +249,7 @@ module.exports = async function(god, mpdHost = 'localhost', id = 'mpd', _mqttTop
_logStatus: function() {
var s = this.mpdstatus
this.logger.debug("Status: state=" + s.state + (s.file ? " on '" + s.file + "'" : " [no file]") + ", volume: " + s.volume + (this.faderTimerId ? " (fading from " + this.volumeFader.startVolume + " to " + this.volumeFader.endVolume + ", target " + this.volumeFader.targetState + ")": " (no fading active)"))
if (s.error) this.logger.warn('MPD returned error: %s', s.error)
},

getQueueRaw: async function() {
Expand Down
37 changes: 27 additions & 10 deletions public/grag3.html
Original file line number Diff line number Diff line change
Expand Up @@ -234,15 +234,31 @@
if (!exp) return { asExpected: true, tooltip: '' }
let thingDisplayName = thing.status == 'dead' ? thing.def.name + ' ☠' : thing.def.name
if (isObject(exp)) {
if (isObject(thing.value)) {
let allRes = true, expString = '', expString2 = []
Object.keys(exp).forEach(key => {
let res = thing.value[key] == exp[key]
if (!res) allRes = false
expString += key + '=' + exp[key] + (res ? ' ✅' : ' ❌')
expString2.push(key + ' should be ' + exp[key])
})
return { asExpected: allRes, tooltip: '\n\nScenario: ' + expString, text: thingDisplayName + ' ' + expString2.join(', ') }
if (true || isObject(thing.value)) {
console.log('!!!!!!!!!!!! ', exp, thing.value)
let deepCompare = (value, expectation, prefix = '', expString = [], expString2 = []) => {
let allRes = true
Object.keys(expectation).forEach(key => {
if (isObject(expectation[key]) && isObject(value[key])) {
let { allRes: _allRes, expString: _expString, expString2: _expString2 } = deepCompare(thing.value[key], expectation[key], key + '.')
if (!_allRes) allRes = false
expString.push(..._expString)
expString2.push(..._expString2)
} else if (!isObject(expectation[key]) && !isObject(value[key])) {
let res = (value[key] == expectation[key]) || (expectation[key] == '' && !(key in value))
if (!res) allRes = false
expString.push(prefix + key + '=' + expectation[key] + (res ? ' ✅' : ' ❌'))
if (!res) expString2.push(prefix + key + ' should be ' + expectation[key])
} else {
allRes = false
expString(prefix + key + ': nesting error')
expString(prefix + key + ': nesting error')
}
})
return { allRes, expString, expString2 }
}
let { allRes, expString, expString2 } = deepCompare(thing.value, exp)
return { asExpected: allRes, tooltip: '\n\nScenario: ' + expString.join(' / '), text: thingDisplayName + ' ' + expString2.join(', ') }
} else {
// default to 'power'
let res = (thing.value == exp.power)
Expand Down Expand Up @@ -356,7 +372,8 @@
let mappedValue = { 'stop': 'Stopped', 'play': 'Playing', 'pause': 'Paused' }[value] ?? 'unknown (' + value + ')'
obj[0].innerHTML = '<div class="shrink-0"><img class="h-12 w-20' + opacity + '" src="img-grag/' + imgsrc + '" alt="Logo"' + onIconclick + '></div>' +
'<div><div class="text-xl font-medium text-black">' + thing.def.name + '</div><p class="text-slate-500">' + mappedValue + '</p></div>'
let mpdTooltip = mappedValue + '\n' + thing.value.status.Name + '\n' + thing.value.status.Title + '\n\nVolume: ' + thing.value.status.volume
let errorStr = thing.value.status?.error ? '\n\nError: ' + thing.value.status.error : ''
let mpdTooltip = mappedValue + '\n' + thing.value.status.Name + '\n' + thing.value.status.Title + '\n\nVolume: ' + thing.value.status.volume + errorStr
obj.attr('title', mpdTooltip + scenarioExpectation.tooltip)
} else if (thing.def.api == 'onkyo') {
let imgsrc = thing.def.render['icon']
Expand Down
13 changes: 9 additions & 4 deletions scenario.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ const winston = require('winston')

initTriggers: function(key, scenario) {
if (!scenario.trigger) return
if (!scenario.trigger.mqtt) return
if (!scenario.trigger.mqtt) return // only mqtt based triggers supported currently
this.logger.info("Adding trigger for scenario %s (%s): %s=%s", scenario.name, key, scenario.trigger.mqtt, scenario.trigger.value)
god.mqtt.addTrigger(scenario.trigger.mqtt, key, this.onMqttCmnd.bind(this))
},

onMqttCmnd: async function(trigger, topic, message, packet) {
this.logger.debug("mqtt: %s (%s)", topic, message)
let scenarioId = trigger.id
if (scenarioId == 'cmnd-scenario') {
if (scenarioId == 'cmnd-scenario') { // not a trigger, but a direct command
await this.activateScenario(message)
} else {
let scenario = god.config.scenarios[scenarioId]
Expand All @@ -83,7 +83,12 @@ const winston = require('winston')
}
let value = scenario.trigger.value
if (value != message) {
this.logger.debug("Received %s, ignored because value=%s is not expected value=%s", topic, message, value)
this.logger.debug("Received %s, ignored because value=%s is not triggering value=%s", topic, message, value)
return
}
let currentThingScenario = god.thingController?.getCurrentScenario()?.id ?? ''
if ([...(scenario?.trigger?.excludedThingScenarios ?? [])].includes(currentThingScenario)) {
this.logger.debug("Received %s, ignored because current scenario '%s' is excluded from trigger", topic, currentThingScenario)
return
}
this.logger.info("Scenario %s (%s) triggered by %s=%s", scenario.name, scenarioId, topic, value)
Expand Down Expand Up @@ -155,8 +160,8 @@ const winston = require('winston')
cb(delay, cmd)
} break
case "thingScenario": {
// set scenario via mqtt instead of directly (using god.thingController.setCurrentScenario) so that we can use the retain feature
await god.mqtt.publish(god.thingController.mqttTopic, cmd.id, {retain: true})
// god.thingController.setCurrentScenario(cmd.id)
} break
}
idx++
Expand Down
11 changes: 8 additions & 3 deletions things.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class Thing {
}
}

// called from timer - with a cached new Date() - to check if our value is stale. If yes, pokes the thing
// called from timer - with now = the current Date() - to check if our value is stale. If yes, pokes the thing
checkAlive(now) {
switch (this.status) {
case ThingStatus.ignored:
Expand Down Expand Up @@ -159,6 +159,12 @@ class MusicPlayer extends Thing {
} catch(e) {
this.logger.error('MQTT: Failed to parse JSON: ' + newState)
}

if (newState.status == 'offline') {
// mpd.js responds, but actual mpd connection is down - treat as 'no answer'
return
}

this.lastState = newState

// calculated values
Expand Down Expand Up @@ -633,7 +639,6 @@ module.exports = function(god2, loggerName = 'things') {
},

async onMqttMessage(trigger, topic, message, packet) {
console.log(packet)
let msg = message.toString()
this.logger.info('Received mqtt thingscenario "' + msg + '"')
let result = await this.setCurrentScenario(msg)
Expand Down Expand Up @@ -677,7 +682,7 @@ module.exports = function(god2, loggerName = 'things') {

async setCurrentScenario(id) {
if (this.currentScenario.id == id) {
this.logger.warn('ThingScenario is already "' + id + '", ignored')
this.logger.info('ThingScenario is already "' + id + '", ignored')
return 'ThingScenario is already "' + id + '", ignored'
}
if (this.scenarioDefinitions[id]) {
Expand Down

0 comments on commit 57f2481

Please sign in to comment.