mpdlistenpy/mpdlisten.py

132 lines
4.3 KiB
Python
Raw Normal View History

2024-03-14 18:37:39 +01:00
#!/bin/env python
# This is adapted from mpdlisten.c : https://gist.github.com/sahib/6718139
# 2024 abelliqueux <contact@arthus.net>
#
# MPD client
import musicpd
from os import environ
import sys
from time import sleep
# Relay
import RPi.GPIO as GPIO
# OLED SSD1306
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306
# MPD config
off_delay = 10
mpd_host='localhost'
mpd_port=6600
mpd_passwd = None
mpd_states = ['play', 'pause', 'stop', 'unknown']
# Relay GPIO setup
GPIO.setmode(GPIO.BCM)
RELAIS_1_GPIO = 17
GPIO.setup(RELAIS_1_GPIO, GPIO.OUT) # GPIO Assign mode
# SSD1306 setup
serial = i2c(port=1, address=0x3C)
device = ssd1306(serial)
# TODO: get ctrlc state
ctrlc_pressed = False
mpd_client_status = {'volume': 'N/A',
'repeat': 'N/A',
'random': 'N/A',
'single': 'N/A',
'consume': 'N/A',
'partition': 'N/A',
'playlist': 'N/A',
'playlistlength': 'N/A',
'mixrampdb': 'N/A',
'state': 'N/A',
'song': 'N/A',
'songid': 'N/A',
'nextsong': 'N/A',
'nextsongid': 'N/A'
}
mpd_client_currentsong = {'file': 'N/A',
'last-modified': 'N/A',
'format': 'N/A',
'artist': 'N/A',
'albumartist': 'N/A',
'title': 'N/A',
'album': 'N/A',
'track': 'N/A',
'date': 'N/A',
'genre': 'N/A',
'time': 'N/A',
'duration': 'N/A',
'pos': 'N/A',
'id': 'N/A'}
# Source host, port from env variables
if 'MPD_HOST' in environ:
mpd_host = environ['MPD_HOST']
# Extract password if provided
if len(mpd_host.split('@')) > 1:
mpd_passwd = mpd_host.split('@')[0]
mpd_host = mpd_host.split('@')[1]
if 'MPD_PORT' in environ:
mpd_port = environ['MPD_PORT']
# ~ client.status() # duration, elapsed, volume, repeat, random, single
# ~ client.currentsong() # artist, title, album
def update_display(device):
with canvas(device) as draw:
draw.rectangle(device.bounding_box, outline="white", fill="black")
draw.text((10, 5), mpd_client_currentsong['artist'], fill="white")
draw.text((10, 25), mpd_client_currentsong['title'], fill="white")
draw.text((10, 40), "{}/{}".format(mpd_client_status['elapsed'], mpd_client_status['duration']), fill="white")
def main(args):
previous_sond_id = None
previous_state = None
paused_since_seconds = 0
# MPDclient setup
client = musicpd.MPDClient()
if mpd_passwd is not None:
client.pwd = mpd_passwd
client.host = mpd_host
client.port = mpd_port
client.mpd_timeout = 5
try:
client.connect()
except musicpd.ConnectionError as errorMessage:
print(repr(errorMessage))
print("Check host and port are correct.")
while ctrlc_pressed is False:
mpd_status = client.status()
if len(mpd_status):
mpd_client_status = mpd_status
mpd_client_currentsong = client.currentsong()
play_state = client.status()['state']
current_song_id = client.status()['songid']
if play_state in mpd_states:
if play_state == 'play':
if (current_song_id != previous_sond_id) and (previous_state != play_state):
# Relay on
GPIO.output(RELAIS_1_GPIO, GPIO.HIGH)
if play_state == 'pause':
paused_since_seconds += 1
if paused_since_seconds > off_delay :
# Relay off
GPIO.output(RELAIS_1_GPIO, GPIO.LOW)
if play_state == 'stop' or play_state == 'unknown':
previous_sond_id = None
# Relay off
GPIO.output(RELAIS_1_GPIO, GPIO.LOW)
previous_state = play_state
sleep(2)
client.disconnect()
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))