#!/bin/env python # This is adapted from mpdlisten.c : https://gist.github.com/sahib/6718139 # 2024 abelliqueux # # 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:]))