Home alarm clock update – now with streaming audio

As mentioned in Home alarm clock update, I’d like to work with Snapcast.

Well, right off the bat, all the instructions for getting the Snapcast client to work automatically, did not. When I say “automatically” I mean that after I reboot the machine, I simply want the Snapcast client running without me having to do anything else. There were suggestions about making it a system service, and a user service, and none of those worked. I’m pretty sure it has something to do with my logged-in user having an environment which is different from what systemd or cron sees.

KAlarm to the rescue!

It has an option to launch stuff after reboot. That’s what I needed.

snapclient --host <IP address of MPD server goes here>

It does take a few seconds after reboot for KAlarm to figure out to run this command. But as soon as it does, my machine (whichever machine) taps into the stream, and music starts playing out. But because KAlarm doesn’t launch until after everything in KDE is up and running, I’m not having these weird errors where the Snapcast client cannot see the stream or the audio devices to play it out.

This is great.

However, what about my alarms? Those are music files too (well, sometimes a TTS wave file). The multiplexing nature of computer audio would have the two playing simultaneously. That is less than ideal.

Turns out that VLC has an option for exiting nicely after playing a file. Add a couple of MPC commands, and we’re golden. The magic command for VLC is rc --play-and-exit

I did have to install the MPC client (for controlling MPD servers) on my machines.

But now my KAlarm commands look like this:

mpc --host <IP address> pause
vlc --intf rc --play-and-exit /path/to/friday_morning.pls
mpc --host <IP address> play

I can queue up a whole stream of music files as background music, using Cantata, and when it comes time for my alarm to fire, to let me know it is time for the next event, the background music pauses through the whole house, the alarm does its thing, and then the background music resumes.

This is so neat. I am having fun with my computers again. 🙂

And I enjoy hearing the London Philharmonic Orchestra playing Sonic the Hedgehog: a Symphonic Suite and Elder Scrolls – Skyrim: Far Horizons. The Elder Scrolls V: Skyrim: Original Game Soundtrack has some great orchestral music. And now my whole house is filled with it.

A Future Me email from six months ago, and the situation has not gotten any better (Linode is in decline)

Dear FutureMe,

I am sad that Linode appears to be going to hell. It got acquired by Akamai, and now my personal email server is getting blocked by Microsoft and Comcast for being in a datacenter which is blasting out spam. I haven’t been able to reply to Carol Ann’s emails for five days. My support ticket with Linode has been open and sitting there with no action. I checked my outbound mail log, and it isn’t me who is blasting out spam. I presume that Akamai has opened their doors to be spammer-friendly because spammers have $$$ to spend with them.

I think that I need to ditch Linode and move to some VPS which hasn’t gone through enshitification.

I’m bummed because for the 501(c)(3) I’m a member of, I was the one who made the pitch to move off our previous VPS and to Linode (for a slight increase in cost).

Last time I moved mail servers, it was a chore.

Raspberry Pi MPD server

Notes about starting fresh on a Raspberry Pi and making a Music Player Daemon (MPD) server out of it.

New image preparation

I did use the Raspberry Pi Imager program and put the base Debian with no desktop environment on the SD card. I did use the customizer to put a user and password on it.

I also have put the MAC in my DHCP server so that the Pi gets a static IP address, and I put an entry in DNS so that IP address maps to the host name I want.

First, an update:

sudo apt-get update

Then I install vim. The default is to use nano, but I like vim.

sudo apt-get install vim -y

Followed by

sudo update-alternatives --config editor

Choice 3 picks vim as my editor.

Followed by turning off Wi-Fi. For music streaming, I only want the Raspberry Pi to be hard-wired into the network.

sudo vim /boot/firmware/config.txt

At the very bottom, I added this to the config.txt file:

dtoverlay=disable-wifi

It goes underneath the [all] section. Then I reboot and log in, and perform

sudo apt update
sudo apt upgrade -y

Now I get to install my favorite aliases and history search keystrokes. These are detailed here.

The next steps are so that I can do ssh from my main machine. I followed this, although I wanted to set a root user password first:

sudo passwd root

Then I mostly followed these steps: New Debian install; ssh and sudo changes

Then I did the ssh-copy-id thing and changed Password Authentication back to no in /etc/ssh/sshd_config

Start with the MPD install

The documentation says that the version of MPD that one can install from the Debian repositories is out of date. I can confirm that.

However, going through those motions sets things up well for later.

apt install mpd -y

Followed by

apt install snapserver -y

The Snapcast server needs to be configured to look to MPD for the sound source.

vim /etc/snapserver.conf

to say:

[stream]  
source = pipe:///tmp/snapfifo?name=MPD

That line was already there, except the name= was default instead of MPD

So later I get to download the latest .tar.xy file, and copy it to the Raspberry Pi. Then:

tar xf mpd-version.tar.xz
cd mpd-version

At this point, I should simply point you at https://mpd.readthedocs.io/en/stable/user.html

There’s a whole bit about apt install meson g++ pkgconf \ and some whole bunches of packages. Then there’s the compile after that. 696 things it compiles.

After all that is done, it is time to update the /etc/mpd.conf file.

This is what mine looks like with the comments stripped out:

music_directory       "/var/lib/mpd/music"
playlist_directory "/var/lib/mpd/playlists"
db_file "/var/lib/mpd/tag_cache"

state_file "/var/lib/mpd/state"
sticker_file "/var/lib/mpd/sticker.sql"

user "mpd"
bind_to_address "0.0.0.0"
port "6600"

auto_update "yes"
auto_update_depth "0"

zeroconf_enabled "yes"
zeroconf_name "Music Player @ %h"

input {
plugin "curl"
}

decoder {
plugin "hybrid_dsd"
enabled "no"
}

decoder {
plugin "wildmidi"
enabled "no"
#config_file "/etc/timidity/timidity.cfg"
}

audio_output {
type "fifo"
encoder "flac"
name "snapserver"
format "48000:16:2"
path "/tmp/snapfifo"
compression "8"
mixer_type "software"
}

filesystem_charset "UTF-8"

Eventually, we get it installed, which includes creating the /var/lib/mpd/music directory. We need that for the next step.

Access to the sound files

This took an edit of /etc/fstab although this is always more difficult than I think it should be.

I did it for Nextcloud, so it is the same thing, kind of. Nextcloud gets read/write access, where this MPD server doesn’t need to be able to write to the sound files or directory.

First, set up a credentials file, with the login name and password:

touch /root/credentials.smb
vim /root/credentials.smb
username=epstein_did_not_kill_himself
password=Apparently-Child-Rape-Is-Okay-If-0.1%-Richest-People-Opt-In-To-Doing-It,Obviously,Because-Otherwise-The-Rapists-Would-Have-Gone-To-Jail

Then we can edit /etc/fstab

//hostname/smbsharename/data /var/lib/mpd/music cifs vers=3.0,credentials=/root/credentials.smb,_netdev,iocharset=utf8 0 0

One thing that kicked my ass for a couple of hours:

vim /usr/local/lib/systemd/system/mpd.service

And on the ExecStart line, I had to explicitly add the configuration file path and file name.

So before, it looked like this:

ExecStart=/usr/local/bin/mpd --systemd

But that would err out with “could not find config file”. I changed it to this:

ExecStart=/usr/local/bin/mpd --systemd /etc/mpd.conf

And now it magically works. Of course, yesterday the first time I set it up, I had no such problems. Sigh.

I still have one more thing to add: Snapweb, where Snapcast server will show you what is currently running. I had that running yesterday, and liked it.

Home alarm clock update

I am delighted with my current home alarm clock setup.

I have the Morefine M8S N100 Alder Lake PC running Fedora Workstation KDE Spin. It is cabled into an OLED television set. I use the remote on the TV: settings > energy saving > panel > turn the panel completely off.

The Morefine M8S stands out in that crowd of machines for having active cooling, but running quiet. At the moment, they are on sale with 12 GB RAM and a 128 GB NVME drive for $170.

A full kit Raspberry Pi isn’t that much less, doesn’t have full size HDMI, isn’t running Intel hardware (super Linux compatible) and they do have that nasty problem of writing /var/log to the SD card, burning it out. The newer Pi can do an NVME drive, but that’s going to drive the cost up close to the M8S. But I digress.

The tuner part of the TV stays on all the time. The M8S is cabled to the TV via an HDMI cable. Although the OLED panel is off, the tuner keeps the HDMI port active, so the M8S doesn’t disconnect or try to rejigger the display when the panel is turned off for sleep mode.

Previously, to connect to the sound bar, I used Bluetooth, bypassing the TV. This was not great. Specifically, Bluetooth wants to disconnect if not streaming, and Linux doesn’t want to play with an audio source that isn’t there. Sure, there are kludgy ways to get it to light up for a sound, but this is clearly paddling upstream for drudgery and debt.

But I saw the Toslink optical S/PDIF connector on the sound bar, and the lightbulb went on. Feed everything in to the TV over HDMI, and feed the audio from the TV to the sound bar over Toslink. We’re back to fun and profit. Well, fun, at least.

This is working out great.

The M8S is a Nextcloud client, so it has access to my audio files directory, and via the web, the Music app player.

KAlarm on the M8S runs VideoLAN Client (VLC) headless, pointing at the audio file (or for waking up, a .pls playlist file). I have seven .pls files for seven days of the week.

I also happen to have my source files for iPhone ringtones in Nextcloud, so when I want a short alarm sound, I’ve got a passel of those available.

KAlarm lets me set schedules for every Sunday of the month. I happen to need a different schedule for the second Sunday, where the first, third, fourth, and fifth are a normal schedule.

What is super nice is that I can have Nextcloud playing music at a low volume, but when VLC kicks in, it plays at the normal volume. They don’t interrupt each other, they simply multiplex.

Lastly, I’ve been playing with Coqui TTS (text-to-speech), so sometimes the sound being played by KAlarm is a feminine Scottish voice saying “Do daily inventory”. 🙂

Next, I want to generate Westminster Chimes sound files, and have it play those on the hour. It would be fun to generate the sound file on-the-fly, starting with the announcement chime and then Coqui TTS saying “Seven” or “Noon” or “Thirteen hundred”.

A future project I have in mind is to write a Perl script to pull down my calendar out of Nextcloud, and then write entries into the KAlarm file for special events.

Also, I wouldn’t mind turning the M8S (and my other machines) into Snapcast clients.

Fun indeed.

Quarterly inventory – 2025 Q1

Dear FutureMe,

Today would be a good day to do a quarterly inventory.

How is your personal life going?

How is your work life going?

How is your Volunteer Service life going?

Future Me

Whoops – I’m sixteen days late. I just added twelve reminders to myself, to be delivered by Future Me

I support Future Me, and am delighted when I see an email sent to the future arrive in my mailbox.

Personal Life

Ooooof. I’ve been in such a funk these last four months. It is bordering on problematic.

I still don’t have a girlfriend, and my house is messy enough that I don’t want to bring people over. Saint Valentine’s Day highlighted my awareness that I really need to change things if I don’t want to die alone. I probably will anyway, but keeping things the status quo will guarantee that.

One positive thing I have started is a sun shade for my western facing glass door. The original owner put reflective film on it to try to drive the heat of the sun back, but it isn’t effective. So I got the idea that I’d build a shade from roofing panels. There’s no way that I can transport them in my Ford C-MAX. However, my brother happened to have a need to drive down here with his long bed truck, so I asked him if he would help me. The Lowes buying experience was underwhelming, but by the end of the afternoon, we put four 3′ x 8′ sheets in the bed of his truck and brought them home.

I still need to bolt them together and to a board or rail to hang them. And I’d like to buy some Rust-Oleum to paint the holes after I drill them and put bolts in. And then I need to hang the shade. But I can already tell that without the tree, this summer would be exceedingly hot inside that room.

I did reconfigure my home alarm clock a little bit, and am delighted with it. Previously, it wasn’t very good. Today, I would rate it splendid. I should do did a blog post about it.

Another change is that my main machine and my alarm clock machine are running Fedora Workstation, KDE Spin. Most of my other websites are running Debian, away from Ubuntu.

I do need to redo my personal mail server. This is yet-another task that would be fun if I had a week to do it, but I don’t so then it just adds to my stress level.

Factorio: Space Age was a letdown. It feels too much like a grind, and the really fun part, blasting bugs with artillery, is unreachable until several planets are exploited. That just makes the grind worse. Sigh.

Work Life

If $25,000 fell out of the sky and into my lap, I would retire tomorrow.

I’m counting down: fifteen months to go.

Volunteer Service Life

This was another one that kicked my ass this quarter. I upgraded the version of PHP on the website, and the calendar plugin prompt started killing off the server. We’d get an out-of-memory error within five minutes. The event calendar is just about the second-most important feature of the website. The website became dysfunctional: what to do?

Probably the best event calendar is The Events Calendar by Modern Tribe. Problem is that it didn’t play nice with our theme. I use an older Twenty Fourteen theme, with a child theme, Fourteen Press, too. Since The Events Calendar wasn’t working, I went with Sugar Calendar. Mostly, I liked that it exports and imports JSON instead of ICS or CSV.

I have my regrets, though.

We paid $100 for it, and as mentioned in the previous quarterly inventory, finances were already so tight that we had had to cut our one employee’s hours 20%. The other regret is that support in the WordPress world is clownish. I tried to get a technical support call going, and they replied that they don’t do support sessions. They want me to create a user on the website with admin privileges and then send them the name and password so they can root around, fixing things.

WTF?

Okay, sure, I’ve got the home lab thing going, and I can copy the website here, and let them root around in the copy of the website, but … this is ridiculous and idiotic. I feel like a fool contemplating the idea.

The third regret is that they advertise that their event calendar can also do ticket sales. Well, that is only true if you set up a Stripe account with them: they don’t do the other payment systems. We’ve got three, and none of them are Stripe. I wouldn’t be surprised if Stripe kicks back a part of the commission to their service partners. So the ticket sales idea was a waste of time for us.

The surveillance state makes things screwy

One of my volunteer service opportunities is to record speakers at meetings and then put the recordings on a website. I use the Sony ICD-UX570 Digital Voice Recorder, which I’ve talked about before. I take the MP3 file and edit it using Audacity, trimming off everything before and after the speaker. Then I export the audio with a smaller bitrate to make a smaller file. Lastly, I rename it and upload it.

Today, a friend called me, and asked if I could burn a recording to CD. His friend, the gentleman who spoke, is almost 80 years old, and he would be best served with a physical CD – none of this Podcast Feed nonsense or USB stick which his truck may or may not be able to use. Sure, I said. This should be easy.

Okay, first I tried Fedora Workstation KDE Spin and got errors. I tried Brasero first, but it was super grumpy. Then I tried K3B which is my old favorite, and it was grumpy too.

I gave up and went to a Windows laptop. Did I want to use Microsoft Windows Media Player or Apple iTunes?

I went with iTunes because I’m not a fan of anything Microsoft.

Freaking iTunes worked, but….

What the hell is the name on this CD?

audiocd:/Philip Kerr – 01 – Game Over – Track 01.wav?device=/dev/sr0

At 80 years old, I’d be acutely aware of my mortality.

Oh! That is certainly what I want this 80-year-old man to see when he pops this gift CD into his truck CD player display:

Philip Kerr - 01 - Game Over

If I’m him, there’s no way I don’t think to myself: What the hell? And then he’d have to say some Hail Mary’s to apologize to God for the cursing.

This gentleman’s name is not Philip Kerr. I did write his name in the various properties fields in iTunes. None of those appear to have come over.

I know that the music industry wants to keep tabs on every sound file ever, so they can in theory collect royalties. But this was my recording, done live and in-person.

This is just screwy.

And apparently, this isn’t a problem on the CD, it is a problem in Fedora. I didn’t know that yet. All I got was the Orwellian vibes.


Okay, back to Fedora KDE Spin.

Ooooooooffffffff.

Thank goodness for Perplexity.AI. It turns out to only be an 8 step problem.

One: Check group memberships – must be a member of cdrom – I’m good

Two: Adjust K3B settings

K3B > Settings > Configure K3B > Programs > Permissions > Change Permissions > Apply

Three: Add a system policy

sudo vim /etc/polkit-1/rules.d/85-cdrecord.rules
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.udisks2.filesystem-mount-system" &&
subject.isInGroup("cdrom")) {
return polkit.Result.YES;
}
});

Four: Restart services

sudo systemctl restart polkit

Five: Update udev rules

sudo vim /etc/udev/rules.d/99-cd-burner.rules
SUBSYSTEM=="block", KERNEL=="sr[0-9]*", MODE="0660", GROUP="cdrom"

Six: Reload udev rules

sudo udevadm control --reload-rules

Seven: reboot the computer.

Eight: try to burn the CD with K3B.

Thank goodness it worked.

I had forgotten that CDs are as small as they are. The older gentleman actually had two recordings on file, one for 45 minutes and another for 55 minutes. That’s too much for a single audio CD. Heh.

AI is getting good

Perplexity AI is proving to be a much better search engine than Google. It is astonishing.

For several years now, Google has been shooting themselves in the foot by trying to reform society through tainting search results. Accordingly, their search results have gone to shit. There are numerous examples of A/B tests against Google search: getting uplifting / supportive results when the female gender is the search, but getting condemning / demoralizing results when the male gender is the search. Ditto A/B test searches for Democrats versus Republicans, and Hillary Clinton versus Donald Trump.

Okay, I’m done: I have replaced my search engine in all my browsers with Perplexity AI.

So while Google was going to shit, Large Language Models became capable. Jeff Bezos of Amazon spun up his own, trained it, and is now putting it out there as Perplexity AI. They have a commercial license for $20 per month, which is too rich for my blood. If they had a $5 per month plan, I’d pay for it now.

But currently, I’m freeloading. I do pay for Twitter, so I might start using Grok (Grok3 just came out) instead. I prefer to spread my activity over different services. Yet, I feel that freeloading is something I don’t like in other people; therefore, if I want to live a high integrity life, I shouldn’t be a freeloader. Anyway….

Today I get to do the minutes for a monthly meeting that I am Recording Secretary for.

On my Windows machine that plays nice with the Sony ICD-UX570 Digital Voice Recorder, I uploaded the recorded MP3 file to Nextcloud. It syncs to the server, and the file ends up in my folder where all these recorded MP3s go. That folder syncs to my main machine I’m working on now.

I had that moment of inspiration that finding these files / messing with the folders is more trouble than it should be. I’m in these folders a lot. Windows has a “Favorites” feature, surely KDE has such too?

Asking of Perplexity AI “does KDE Dolphin have a Favorites feature” instantly took me to a page which presented a ZD Net article “How to use KDE Plasma Places for a much more efficient desktop“. This is precisely what I was looking for, yet I had no idea that it was called Places.

This is great. Google search might have gotten me to this page eventually, but I doubt that I’d have gotten to it without going through many different page views (thereby increasing Google’s ad revenue).

And yes, I’ve asked Perplexity AI to generate a Perl program for reading a Nextcloud calendar, and it took no time at all to do it. Now, the program did not work….

But troubleshooting the problem with Perplexity AI was pretty easy. It suggested I try curl and that worked perfectly.

As it turns out, Nextcloud doesn’t play nice with Net::CalDAVTalk.

Whether this is a problem with Nextcloud (which doesn’t try to do anything on its own – it uses SaberDAV underneath) or this is a problem with Net::CalDAVTalk isn’t a terribly fruitful pursuit. What is almost trivial to do is to ask Perplexity AI to generate the Perl program without Net::CalDAVTalk. The whole thing can be done with HTTP::Request, LWP::UserAgent, and XML::LibXML.

It is astonishing how well this is working, and how quickly this change is taking place.

Text-to-speech notes

This is simply for my own notes, on how to do Coqui text-to-speech

Initial setup required this:

python -m venv tts_env
source tts_env/bin/activate
pip install --upgrade pip
pip install coqui-tts

Subsequent invocations needed only this:

python -m venv tts_env
source tts_env/bin/activate

tts --text "Insert text here" --model_name tts_models/en/jenny/jenny --pipe_out --out_path /home/path/to/tts_output/whatever.wav | aplay


How to make (whatever) Linux have a nice bash shell with my favorite aliases

This is a newer version of my post How to make Ubuntu have a nice bash shell like OpenSuSE which should supersede it. I keep coming back to this topic, and think that the right way to do this is:

touch ~/.bash_aliases
vim ~/.bash_aliases
alias ll='ls -la'
alias ..='cd ..'

And then alter .bashrc to include this aliases file:

vim ~/.bashrc

At the end of the file, insert this:

if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi

Finally, reload bash with this:

source ~/.bashrc

The other change I always make is to edit /etc/inputrc and make the history search keys the PgUp key.

sudo vim /etc/inputrc

Find # "\e[5~": history-search-backward and uncomment it

New Fedora KDE Spin: re-do power saving setting

There is a bug in my AMD Ryzen 1700 which manifests on Linux during power sleep states. Now that I’m on Fedora KDE Spin, I need to implement it again. Fedora KDE Spin does startup scripts a little differently than the previous systems I’ve used before.

Previously, I’d used /etc/init.d/

Well, Fedora KDE Spin doesn’t use that; it uses Systemd and systemctl

As root:

cd /etc/systemd/system

vim set_c6_acpi_state_disabled.service

Paste in the following:

[Unit]
Description=Set C6 ACPI State Disabled
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/bazoozle/zenstates.py --c6-disable

[Install]
WantedBy=multi-user.target

Technically, I don’t need to wait until after the network is started to run the zenstates.py python script. But it isn’t obvious what would be the equivalent to @reboot in a crontab.

Then we do this:

systemctl start set_c6_acpi_state_disabled.service

systemctl enable set_c6_acpi_state_disabled.service