Thank you for your donation!


Cloudsmith graciously provides open-source package management and distribution for our project.


Problem: Detect state changes
#1
Wink 
Hello everyone,

I'm new to this community and have recently discovered Moode.

My project:
I'm building a smart speaker that works on a Raspberry Pi Zero W. The speaker also has a WS2812b LED-strip and some buttons for like play/pause, next/previous track.

I got the button part working with a python script that executes commands like this:
Code:
import RPi.GPIO as GPIO
import time
import os
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)

while True: # Run forever
   input_state = GPIO.input(16)
   if input_state == GPIO.LOW:
       print("Button was pushed!")
       os.system("mpc toggle")
       time.sleep(0.2)

for the LED-strip part, I want to display some animations when; song changes, raising of lowering volume (with current percentage), changing sources, etc.


So for example when a song ends and it autoplays to the next one, it should display an animation on the LED-strip.

is there a way to check for statechanges for these situations?
I've read some form posts on the subject, but can't really find a clean solution.
Reply
#2
@steven4build 

If you are using only the MPD renderer then you have a chance. If you are using alternative renderers which are separate from MPD, such as Bluetooth (in), Airplay, Spotify, UPnP, etc., then many state changes will be difficult or impossible to detect.

As a start, have a look at the moOde code for the LCD update engine (configured via System Config) and also at the MPD Protocol documentation about querying MPD's status, e.g, the idle command.

Regards,
Kent
Reply
#3
(02-05-2021, 03:17 PM)TheOldPresbyope Wrote: @steven4build 

If you are using only the MPD renderer then you have a chance. If you are using alternative renderers which are separate from MPD, such as Bluetooth (in), Airplay, Spotify, UPnP, etc., then many state changes will be difficult or impossible to detect.

As a start, have a look at the moOde code for the LCD update engine (configured via System Config) and also at the MPD Protocol documentation about querying MPD's status, e.g, the idle command.

Regards,
Kent
Thanks Kent for the quick response!

Hmm... interesting, well I was already wondering why I cannot for example skip a track when my phone was connected via bluetooth or UPnP (haven't tried Airplay or Spotify yet).
It would already be pretty awesome if I could get the currently active source and volume. How does the UI know whats going on, since that is everything i need to know.

Mabye the LCD update engine that you mentioned, I will have a look at that!

Also you've mentioned the Music Player Daemon (MPD), I will look into that aswell, I didn't even knew what it was until you've mentioned it, thanks!

I came across the 'worker.php' file. Allot of the connectivity and state stuff seems to be happening here (quote me if i'm wrong Wink ), is it a good idea to edit that file so at cerain actions it will call a python script? or is there another way?

Regards,
Steven
Reply
#4
@steven4build

Yup, the worker.php and playerlib.php routines contain a lot of the meat of moOde's backend, but I'd suggest you look at how the LCD update engine is implemented to get an idea of how you might hook in without hacking at these core routines. Keep in mind that they are subject to change with each update of moOde. The more you can depend only on their "hooks", the better insulated from change your code will be.

And just so there's no mistake, Tim's the primary author of this lovely music player. I started hanging out about 4 years ago and have made only minor contributions, more in the way of quality assurance. What I know about moOde, I learned by reading the code.

Good luck.

Regards,
Kent
Reply
#5
(02-05-2021, 02:55 PM)steven4build Wrote: Hello everyone,

I'm new to this community and have recently discovered Moode.

My project:
I'm building a smart speaker that works on a Raspberry Pi Zero W. The speaker also has a WS2812b LED-strip and some buttons for like play/pause, next/previous track.

I got the button part working with a python script that executes commands like this:
Code:
import RPi.GPIO as GPIO
import time
import os
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)

while True: # Run forever
   input_state = GPIO.input(16)
   if input_state == GPIO.LOW:
       print("Button was pushed!")
       os.system("mpc toggle")
       time.sleep(0.2)

for the LED-strip part, I want to display some animations when; song changes, raising of lowering volume (with current percentage), changing sources, etc.


So for example when a song ends and it autoplays to the next one, it should display an animation on the LED-strip.

is there a way to check for statechanges for these situations?
I've read some form posts on the subject, but can't really find a clean solution.

Have a look in System Config for the GPIO button handler, Metadata file and LCD update engine.

Regarding the LCD update engine, you would edit the required script /var/local/www/commandw/lcdup.py to parse the metadata file /var/local/www/currentsong.txt and do whatever is needed to control your peripheral device. This file is updated within 3 secs anytime playback state changes. The WebUI does not have to be running.

An important aspect of the lcdup.py script is that it must not contain a while loop since the LCD update engine provides event based execution of the script via an inotify wait on the currentsong.txt file.
Enjoy the Music!
moodeaudio.org | Mastodon Feed | GitHub
Reply
#6
@steven4build if your working on a python script, you could use the exellent mpd2 python package.
It provides all the mpd information you ever need :-)

Example (little bit messy) script that use an oled display, a few buttons andthe mpd lib is here.
Reply
#7
(02-05-2021, 10:04 PM)Tim Curtis Wrote:
(02-05-2021, 02:55 PM)steven4build Wrote: Hello everyone,

I'm new to this community and have recently discovered Moode.

My project:
I'm building a smart speaker that works on a Raspberry Pi Zero W. The speaker also has a WS2812b LED-strip and some buttons for like play/pause, next/previous track.

I got the button part working with a python script that executes commands like this:
Code:
import RPi.GPIO as GPIO
import time
import os
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)

while True: # Run forever
   input_state = GPIO.input(16)
   if input_state == GPIO.LOW:
       print("Button was pushed!")
       os.system("mpc toggle")
       time.sleep(0.2)

for the LED-strip part, I want to display some animations when; song changes, raising of lowering volume (with current percentage), changing sources, etc.


So for example when a song ends and it autoplays to the next one, it should display an animation on the LED-strip.

is there a way to check for statechanges for these situations?
I've read some form posts on the subject, but can't really find a clean solution.

Have a look in System Config for the GPIO button handler, Metadata file and LCD update engine.

Regarding the LCD update engine, you would edit the required script /var/local/www/commandw/lcdup.py to parse the metadata file /var/local/www/currentsong.txt and do whatever is needed to control your peripheral device. This file is updated within 3 secs anytime playback state changes. The WebUI does not have to be running.

An important aspect of the lcdup.py script is that it must not contain a while loop since the LCD update engine provides event based execution of the script via an inotify wait on the currentsong.txt file.

Thanks!

I found the setting and will definitetly use that!

So if I understand correctly, you're suggesting to do this in lcdup.py:
Code:
with open("/var/local/www/currentsong.txt") as file1:
    # 1. Decode currentsong.txt (btw. is there a good looking way to do this?)
    # 2. Findout what changed
    # 3. Do something accordingly to that event
    
    with open("/home/pi/lcd.txt", "w") as file2:
        for line in file1:
            file2.write(line)

Thank you for your help!

Regards,

Steven
Reply
#8
(02-06-2021, 07:49 PM)bitlab Wrote: @steven4build if your working on a python script, you could use the exellent mpd2 python package.
It provides all the mpd information you ever need :-)

Example (little bit messy) script that use an oled display, a few buttons andthe mpd lib is here.

Thank you for your reply,

Wow looks quite simple aswell, will definelty look into that! Thank you!

Regards,

Steven
Reply
#9
Wink 
Alright, it's been a while, but I figured it out with MPD.

For the people who want to get a clean solution (but who are not using the GUI)

A lot of things can be done by using the Music Player Deamon.

To help others to visualize this a bit more, open up PuTTY and connect to your device on port 6600 (this is the MPD).
you can now send commands. For example, you can use currentsong to see the current music playing, so artist, song title, stream-url, etc.
Also, u can use status to get the play-state, volume, bitrate, and much more.
for a complete command reference, take a look here (Thanks to TheOldPresbyope).

Quote:Note

Thanks to the developers, you can also send these commands just from your browser, for more information for how to do this, see this post.

My solution

Since I found out about this, I noticed that sending commands directly over the socket is waaaaay faster than with the GUI (especially with changing volume and changing the play-state).
So with that, I came to the conclusion to rebuild almost everything. the structure will be as follows:

- A backend, that communicates with (for now at least) the MPD. 
I communicate to the backend via a REST API and reacts to changes and calls a python script for reacting with LEDs.
(Programmed in Java, but can easily be done in python)

- A frontend, which is written in Vue.JS. This is a huge improvement in speed because everything is rendered client-side instead of server-side(PHP).
The frontend also makes use of server-side-events, which sinks the state of the speaker FAST across everyone who is using the GUI. Wink
Bonus feature: It's a PWA so it can be installed like an app.

What now?

Right now, the backend supports most of the MPD commands and is of course accessible by RESTful API.
The frontend, in my opinion, is a bit less dated. Also has part of the API integrated. As a bonus, it's PWA and integrated some other APIs in it to add a bit more personality.

Screenshot of the GUI

I definitely continue to expand the functionality of MoOdeAudio. I would like to get some more information, forum-posts, references to all the other services, like how Bluetooth, UPnP, Airplay, and all the other services work and which tools are used.

Regards,

Steven
Reply
#10
It sounds like you are developing your own music player software and in that case you should be posting on diyAudio or some other Forum.
Enjoy the Music!
moodeaudio.org | Mastodon Feed | GitHub
Reply


Forum Jump: