03-16-2020, 11:27 PM
(03-13-2020, 09:53 AM)NishaChavan Wrote: Great Information was very useful for me. Thank you for sharing this information.
I've added some more, but it's a bit rough at the moment and needs more testing.
Added ability to send alerts
Added ability to send timers (aka kitchen timer)
Added skip and ffwd commands ( > >>)
So long as all hostnames are different, added ability to listen for:
moode/hostname or
moode/all (which sends commands to every player subscribed to moode/#)
Also in current state without installing additional software to moode, timer and alert can only work with wav files
Timer function needs work and currently only accepts minutes so the example is like: timer 60 /home/pi/timer.wav
Code:
#!/usr/bin/env python
'''
Getting Started
---------------
1.edit settings section of this script using your mqtt broker settings
2.copy to /home/pi folder
3.create a systemd service to auto start at boot
4.reboot
5.test
Basic Commands
--------------
volume up 10
volume dn 10
volume 25
mute
stop
pause
toggle
status
stream http://stream.radioparadise.com/mp3-320
alert /home/pi/doorbell.wav
timer 60 /home/pi/timer.wav
reboot
Advanced Commands
-----------------
Any valid mpc command in the format of:
mpc command
'''
# settings
mqttHost = "192.168.1.5"
mqttPort = 1883
mqttKeep = 60 #keep alive seconds
mqttUser = "test"
mqttPass = "password"
topicVal = "moode"
alertVol = "75%"
fastForw = 30 #fast forward seconds
# don't change anything below unless you know what you are doing ;-)
import paho.mqtt.client as mqtt
import subprocess
ip = subprocess.check_output("hostname -I", shell=True).strip()
host = subprocess.check_output("hostname", shell=True).strip()
subTopic = topicVal + "/#"
pubTopic = topicVal + "/" + host + "/status"
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
client.subscribe(subTopic)
client.publish(pubTopic, "Online", qos=0, retain=True)
volume = subprocess.check_output("/var/www/vol.sh", shell=True).strip()
client.publish(pubTopic + "/ip", ip, qos=0, retain=True)
client.publish(pubTopic + "/hostname", host, qos=0, retain=True)
client.publish(pubTopic + "/volume", volume, qos=0, retain=True)
#TODO add log error
def on_message(client, userdata, msg):
topic = msg.topic.decode("utf-8")
if (topic == topicVal + "/" + host) or (topic == topicVal + "/all"):
action = msg.payload.decode("utf-8")
if action.startswith("volume"):
vol = action.replace("volume ", "")
subprocess.check_output("/var/www/vol.sh " + vol, shell=True)
vol = subprocess.check_output("/var/www/vol.sh", shell=True).strip()
client.publish(pubTopic + "/volume" , vol, qos=0, retain=True)
elif action.startswith("mpc"):
subprocess.check_output(action, shell=True)
elif action == "mute":
subprocess.check_output("/var/www/vol.sh mute", shell=True)
client.publish(pubTopic + "/volume" , "Muted", qos=0, retain=False)
elif action == "stop":
subprocess.check_output("mpc stop", shell=True)
elif action == "pause" or action == "toggle":
subprocess.check_output("mpc toggle", shell=True)
elif action == "status":
#import imp
#f = open("/var/local/www/currentsong.txt")
#global data
#data = imp.load_source('data', '', f)
#f.close()
status = subprocess.check_output("mpc status", shell=True)
#status2 = subprocess.check_output("mpc status", shell=True)
client.publish(pubTopic + "/mpc-status" , status, qos=0, retain=True)
#client.publish(pubTopic + "/other-status" , status2, qos=0, retain=True)
#client.publish(pubTopic + "/more-status" , data, qos=0, retain=True)
vol = subprocess.check_output("/var/www/vol.sh", shell=True).strip()
client.publish(pubTopic + "/volume" , vol, qos=0, retain=True)
elif action == "sync":
pass
elif action.startswith("stream"):
url = action.replace("stream ", "")
subprocess.check_output("mpc clear && mpc add " + url + " && mpc play", shell=True)
elif action.startswith("alert"):
url = action.replace("alert ", "")
status = subprocess.check_output("mpc status", shell=True)
if "[playing]" in status:
subprocess.check_output("mpc toggle && amixer set Digital " + alertVol, shell=True)
subprocess.check_output("aplay " + url, shell=True)
subprocess.check_output("amixer set Digital 100% && mpc toggle", shell=True)
else:
subprocess.check_output("amixer set Digital " + alertVol, shell=True)
subprocess.check_output("aplay " + url, shell=True)
subprocess.check_output("amixer set Digital 100%", shell=True)
elif action == "reboot":
subprocess.check_output("mpc stop && sudo systemctl stop nginx && sudo reboot", shell=True)
elif action == ">":
subprocess.check_output("mpc seek +" + fastFwd, shell=True)
elif action == ">>":
subprocess.check_output("mpc next", shell=True)
elif action.startswith("timer"):
cmd = action.replace("timer ", "")
out = subprocess.check_output("/home/pi/timer.py " + cmd, shell=True)
client.publish(pubTopic + "/timer" , out, qos=0, retain=True)
else:
try:
float(action)
subprocess.check_output("/var/www/vol.sh " + action, shell=True)
vol = subprocess.check_output("/var/www/vol.sh", shell=True).strip()
client.publish(pubTopic + "/volume" , vol, qos=0, retain=True)
except ValueError:
print("Error")
# do nothing - command in payload not defined
# pass
else:
# do nothing - the message was not for me
pass
def on_publish(client, userdata, mid):
print("mid: " + str(mid))
def on_subscribe(client, userdata, mid, granted_qos):
print("Subscribed: " + str(mid) + " " + str(granted_qos))
def on_log(client, userdata, level, buf):
print(buf)
client = mqtt.Client()
client.username_pw_set(mqttUser,mqttPass)
# last will
client.will_set(pubTopic, "Offline", qos=0, retain=True)
# event callbacks
client.on_message = on_message
client.on_connect = on_connect
client.on_publish = on_publish
client.on_subscribe = on_subscribe
# connect
client.connect(mqttHost,mqttPort,mqttKeep)
# keep listening for messages
client.loop_forever()
timer.py (also located in home/pi folder)
Code:
#!/usr/bin/env python1
import subprocess
import time
import sys
from os.path import expanduser
timerVol = "75%"
total = len(sys.argv)
status = subprocess.check_output("mpc status", shell=True)
if (total == 2):
wavfil = expanduser("~") + "/timer.wav"
else:
wavfil = expanduser("~") + "/" + str(sys.argv[2])
timer = (float(sys.argv[1]) * 60)
time.sleep(timer)
#subprocess.check_output("aplay " + wavfil, shell=True)
status = subprocess.check_output("mpc status", shell=True)
Please remember. I'm not a programmer but have a need ;-)