.
This commit is contained in:
+129
@@ -0,0 +1,129 @@
|
||||
from mqtt import MqttMessage, MqttConfigMessage
|
||||
|
||||
from workers.base import BaseWorker
|
||||
import logger
|
||||
import subprocess
|
||||
import traceback
|
||||
|
||||
REQUIREMENTS = []
|
||||
_LOGGER = logger.get(__name__)
|
||||
|
||||
|
||||
class MpdWorker(BaseWorker):
|
||||
|
||||
def mqttHomieDevice(self, name, nodes):
|
||||
return [
|
||||
MqttConfigMessage(self.format_topic(), "$state", payload="ready"),
|
||||
MqttConfigMessage(self.format_topic(), "$homie", payload="3.0"),
|
||||
MqttConfigMessage(self.format_topic(), "$name", payload=name),
|
||||
MqttConfigMessage(self.format_topic(), "$nodes", payload=nodes)
|
||||
]
|
||||
|
||||
|
||||
def mqttHomieNode(self, label, name, properties):
|
||||
return [
|
||||
MqttConfigMessage(self.format_topic(label), "$name", payload=name),
|
||||
MqttConfigMessage(self.format_topic(label), "$properties", payload=properties),
|
||||
]
|
||||
|
||||
|
||||
def mqttHomieProperty(self, node, prop, name, dtype, settable = False, retained = False, unit = None, dformat = None):
|
||||
retval = [
|
||||
MqttConfigMessage(self.format_topic(node, prop), "$name", payload=name),
|
||||
MqttConfigMessage(self.format_topic(node, prop), "$datatype", payload=dtype),
|
||||
MqttConfigMessage(self.format_topic(node, prop), "$settable", payload="true" if settable else "false"),
|
||||
MqttConfigMessage(self.format_topic(node, prop), "$retained", payload="true" if retained else "false")
|
||||
]
|
||||
if unit is not None:
|
||||
retval.append(MqttConfigMessage(self.format_topic(node, prop), "$unit", payload=unit))
|
||||
if dformat is not None:
|
||||
retval.append(MqttConfigMessage(self.format_topic(node, prop), "$format", payload=dformat))
|
||||
return retval
|
||||
|
||||
|
||||
def _setup(self):
|
||||
if not hasattr(self, 'mpc_path'):
|
||||
self.mpc_path = '/usr/bin/mpc'
|
||||
|
||||
|
||||
def config(self):
|
||||
_LOGGER.debug("Configuring")
|
||||
retval = self.mqttHomieDevice("Media Player Daemon (MyRoom)", "controls")
|
||||
retval += self.mqttHomieNode("controls", "Player Controls", "volume,control,play,playlist,current")
|
||||
retval += self.mqttHomieProperty("controls", "volume", "Volume", "integer", True, True, "%", "0:100")
|
||||
retval += self.mqttHomieProperty("controls", "control", "Media Control", "enum", True, True, dformat = "play,pause,stop")
|
||||
retval += self.mqttHomieProperty("controls", "play", "Play Button", "boolean", True, True)
|
||||
retval += self.mqttHomieProperty("controls", "playlist", "Playlist", "string", True, True)
|
||||
retval += self.mqttHomieProperty("controls", "current", "Currently Playing", "string", False, False)
|
||||
return retval
|
||||
|
||||
|
||||
def status_update(self):
|
||||
retval = []
|
||||
try:
|
||||
retval.append(MqttMessage(topic=self.format_topic("controls", "current"), payload=self.mpc_get_current(), retain=True))
|
||||
except Exception as e:
|
||||
_LOGGER.error("Caught exception in MpdWorker.on_command(): {}".format(e))
|
||||
traceback.print_exc();
|
||||
return retval
|
||||
|
||||
|
||||
def on_command(self, topic, value):
|
||||
retval = []
|
||||
try:
|
||||
value = value.decode('utf-8')
|
||||
_, nodename, propname, operation = topic.split('/')
|
||||
_LOGGER.debug("Command \"%s\", on %s.%s: %s", operation, nodename, propname, value)
|
||||
if propname == "volume" and operation == "set":
|
||||
if self.mpc_set_volume(value):
|
||||
retval.append(MqttMessage(topic=self.format_topic("controls", "volume"), payload=value, retain=True))
|
||||
elif propname == "control" and operation == "set":
|
||||
if (value == "play" or value == "PLAY") and self.call_mpc(["play"]) == 0:
|
||||
retval.append(MqttMessage(topic=self.format_topic("controls", "control"), payload=value, retain=True))
|
||||
elif (value == "pause" or value == "PAUSE") and self.call_mpc(["pause"]) == 0:
|
||||
retval.append(MqttMessage(topic=self.format_topic("controls", "control"), payload=value, retain=True))
|
||||
elif (value == "stop" or value == "STOP") and self.call_mpc(["stop"]) == 0:
|
||||
retval.append(MqttMessage(topic=self.format_topic("controls", "control"), payload=value, retain=True))
|
||||
elif propname == "play" and operation == "set":
|
||||
if (value == "true" or value == "on") and self.call_mpc(["play"]) == 0:
|
||||
retval.append(MqttMessage(topic=self.format_topic("controls", "play"), payload="true", retain=True))
|
||||
elif (value == "false" or value == "off") and self.call_mpc(["stop"]) == 0:
|
||||
retval.append(MqttMessage(topic=self.format_topic("controls", "play"), payload="false", retain=True))
|
||||
elif propname == "playlist" and operation == "set":
|
||||
if self.mpc_set_playlist(value):
|
||||
retval.append(MqttMessage(topic=self.format_topic("controls", "playlist"), payload=value, retain=True))
|
||||
retval.append(MqttMessage(topic=self.format_topic("controls", "current"), payload=self.mpc_get_current(), retain=True))
|
||||
except Exception as e:
|
||||
_LOGGER.error("Caught exception in MpdWorker.on_command(): {}".format(e))
|
||||
traceback.print_exc();
|
||||
return retval
|
||||
|
||||
|
||||
def run_mpc(self, args):
|
||||
args = [self.mpc_path] + args
|
||||
result = subprocess.run(args, stdout=subprocess.PIPE)
|
||||
_LOGGER.debug("run_mpc: %s -> %s", str(args), str(result))
|
||||
return (result.returncode, result.stdout)
|
||||
|
||||
|
||||
def call_mpc(self, args):
|
||||
args = [self.mpc_path] + args
|
||||
_LOGGER.debug("call_mpc: %s", str(args))
|
||||
return subprocess.call(args)
|
||||
|
||||
|
||||
def mpc_set_volume(self, volume):
|
||||
return self.call_mpc(["volume", str(volume)]) == 0
|
||||
|
||||
|
||||
def mpc_set_playlist(self, pl):
|
||||
return self.call_mpc(["load", str(pl)]) == 0
|
||||
|
||||
|
||||
def mpc_get_current(self):
|
||||
retcode, out = self.run_mpc(["current"])
|
||||
if retcode == 0:
|
||||
return out
|
||||
else:
|
||||
return ""
|
||||
|
||||
Reference in New Issue
Block a user