User avatar
Kratos
Posts: 395
Joined: Sun Apr 12, 2015 12:41 pm

Alarm Clock

Thu Dec 10, 2015 9:20 pm

I've been working on an alarm clock program that has an alarm, light show, but does not display time. If you want to check it out, here it is:

Code: Select all

#Sense Hat alarm clock
#Author Kratos
#Version 12.10.15

from sense_hat import SenseHat
import time
import os
import pygame
from pygame.locals import *

pygame.init()
pygame.display.set_mode((640, 480))

sense = SenseHat()

green = 0, 255, 0
red = 255, 0, 0
blue = 0, 0, 255
light = False
running = True
not_executed = 1
hr = 6
current = 6
do_hr = 0
do_minu = 1
minu = 0
moodh = 20
moodm = 0
r = 255
g = 0
b = 0
pixels = [
    [255, 0, 0], [255, 0, 0], [255, 87, 0], [255, 196, 0], [205, 255, 0], [95, 255, 0], [0, 255, 13], [0, 255, 122],
    [255, 0, 0], [255, 96, 0], [255, 205, 0], [196, 255, 0], [87, 255, 0], [0, 255, 22], [0, 255, 131], [0, 255, 240],
    [255, 105, 0], [255, 214, 0], [187, 255, 0], [78, 255, 0], [0, 255, 30], [0, 255, 140], [0, 255, 248], [0, 152, 255],
    [255, 223, 0], [178, 255, 0], [70, 255, 0], [0, 255, 40], [0, 255, 148], [0, 253, 255], [0, 144, 255], [0, 34, 255],
    [170, 255, 0], [61, 255, 0], [0, 255, 48], [0, 255, 157], [0, 243, 255], [0, 134, 255], [0, 26, 255], [83, 0, 255],
    [52, 255, 0], [0, 255, 57], [0, 255, 166], [0, 235, 255], [0, 126, 255], [0, 17, 255], [92, 0, 255], [201, 0, 255],
    [0, 255, 66], [0, 255, 174], [0, 226, 255], [0, 117, 255], [0, 8, 255], [100, 0, 255], [210, 0, 255], [255, 0, 192],
    [0, 255, 183], [0, 217, 255], [0, 109, 255], [0, 0, 255], [110, 0, 255], [218, 0, 255], [255, 0, 183], [255, 0, 74]
]
msleep = lambda x: time.sleep(x / 1000.0)

sense.clear()
sense.low_light = light

sense.show_message("Please set your alarm.", text_colour=green)
time.sleep(1)

while running:
    message = current
    message = int(message)
    sense.show_message(str(message), text_colour=blue)
    for event in pygame.event.get():
        if (event.type == KEYUP) or (event.type == KEYDOWN):
            if do_hr == 0:               
                if (event.key == K_DOWN) and hr >= 0:
                    sense.clear()
                    hr = hr - 0.5
                    current = hr
                elif (event.key == K_UP) and hr <= 24:
                    sense.clear()
                    hr = hr + 0.5
                    current = hr
                elif (event.key == K_RIGHT):
                    hr = int(hr)
                    sense.clear()
                    do_hr = 1
                    do_minu = 0
                    current = minu
                    time.sleep(1)
            if do_minu == 0:
                if (event.key == K_DOWN) and minu >= 0:
                    sense.clear()
                    minu = minu - 0.5
                    current = minu
                elif (event.key == K_UP) and minu <= 60:
                    sense.clear()
                    minu = minu + 0.5
                    current = minu
                elif (event.key == K_RETURN):
                    minu = int(minu)
                    sense.clear()
                    message = "Alarm at: {0:02}:{1:02}".format(hr, minu)
                    sense.show_message(message, text_colour=green)
                    pygame.quit ()
                    running = False
time.sleep(1)

message = "Light show at: {0:02}:{1:02}".format(moodh, moodm)
sense.show_message(message, text_colour=red)

try:
    def pulse():            
        sense.clear(red)
        os.popen("sudo omxplayer /home/pi/alarm.mp3")
        sense.clear()
        time.sleep(0.5)
        return

    def rainbow():
        light = True
        sense.low_light = light
        def next_colour(pix):
            r = pix[0]
            g = pix[1]
            b = pix[2]

            if (r == 255 and g < 255 and b == 0):
                g += 1

            if (g == 255 and r > 0 and b == 0):
                r -= 1

            if (g == 255 and b < 255 and r == 0):
                b += 1

            if (b == 255 and g > 0 and r == 0):
                g -= 1

            if (b == 255 and r < 255 and g == 0):
                r += 1

            if (r == 255 and b > 0 and g == 0):
                b -= 1

            pix[0] = r
            pix[1] = g
            pix[2] = b
            
        for pix in pixels:
            next_colour(pix)
        sense.set_pixels(pixels)
        msleep(2)
        
	    
    while(not_executed):
        tm = list(time.localtime())
        hour = tm[3]
        minute = tm[4]
        if hour == moodh:
            rainbow()
        if hour == 1 + moodh:
            sense.clear()
        if hour == hr and minute >= minu:
            light = False
            sense.low_light = light
            pulse()
    not_executed = 0

except KeyboardInterrupt:
    not_executed = 0
    sense.clear()
    print("Stopping...")

For it to work you'll need a sound called alarm.mp3 in your /home/pi directory.
I copied the light show part from the demo programs, so I won't take credit for that piece. Enjoy!
Kratos
I have posted mostly with a Pi 2 running either Ubuntu MATE, or Raspbian.

W. H. Heydt
Posts: 12431
Joined: Fri Mar 09, 2012 7:36 pm
Location: Vallejo, CA (US)

Re: Alarm Clock

Fri Dec 11, 2015 1:38 am

I use a Pi (2b, now, used to be a 256MB Model B) for an alarm clock. I do it all through cron. That lets me stream a radio station. Shutting it down is a little clunky for most people, since it's done by logging in and killing the mplayer instance.

Longer term plan is to add an RPF display and use dclock to chow the time, plus redirect the metadata output to a short, wide LXTerminal session so one can read off what is being played in the music stream. One thing that part of the project is waiting on is to see if it ever becomes possible to dim the display at night (again, controlling that by cron).

stderr
Posts: 2178
Joined: Sat Dec 01, 2012 11:29 pm

Re: Alarm Clock

Fri Dec 11, 2015 3:04 am

W. H. Heydt wrote:I use a Pi (2b, now, used to be a 256MB Model B) for an alarm clock. I do it all through cron. That lets me stream a radio station. Shutting it down is a little clunky for most people, since it's done by logging in and killing the mplayer instance.
One nice thing about all this is that it is possible to start up more than one stream. So one can listen to music without words, say classical or jazz, something like that, and a lecture or podcast or the news.

Apparently in similar fashion to your scheme, I was starting up the player, whatever that might be, and then later killing it. But because I wasn't continuing to run the process that started the player, I had to refigure out what the pid of the player was or save it somehow but I was trying to avoid that because ultimately the player could be on a different computer than the process that started it.

Basically I'm running the program as:

radio some_station

where some_station is the first hit in a line in a file station.data that looks like this following:

abc http://www.abc.net.au/res/streaming/aud ... _radio.pls
ABC Classic FM http://www.abc.net.au/res/streaming/aud ... sic_fm.pls
ABC Classic 2 http://www.abc.net.au/res/streaming/aud ... ic_two.pls
ABC NewsRadio http://www.abc.net.au/res/streaming/aud ... _radio.pls
ABC RN http://www.abc.net.au/res/streaming/aud ... tional.pls
triple j http://www.abc.net.au/res/streaming/aud ... riplej.pls
triple j Unearthed http://www.abc.net.au/res/streaming/aud ... arthed.pls
891 ABC Adelaide http://www.abc.net.au/res/streaming/aud ... elaide.pls
612 ABC Brisbane http://www.abc.net.au/res/streaming/aud ... isbane.pls
666 ABC Canberra http://www.abc.net.au/res/streaming/aud ... nberra.pls
105.7 ABC Darwin http://www.abc.net.au/res/streaming/aud ... darwin.pls
936 ABC Hobart http://www.abc.net.au/res/streaming/aud ... hobart.pls

This means that I could type in the name of the station, its frequency or some nickname I might add, e.g.

radio 891

and it would play the station for Adelaide. But if I didn't remember it, I could write,

radio darwin

I converted everything to a single case so avoid questions of capitalisation, which I knew would bring me trouble. This way of doing it would play the first hit though so in this case "radio abc" misses everything but the first station even though in the example they are mostly all abc stations.

How do you handle this aspect in your version of radio? Before I did it this way, I was just using scripts with fixed urls for each station. But that got clunky to update and keep track of.

I remember also having to download the .pls files and parse them to find the real url which they apparently like to change. Some media players can read .pls files but refuse to actually play the redirects inside.
Longer term plan is to add an RPF display and use dclock to chow the time, plus redirect the metadata output to a short, wide LXTerminal session so one can read off what is being played in the music stream. One thing that part of the project is waiting on is to see if it ever becomes possible to dim the display at night (again, controlling that by cron).
If you output to your display in the framebuffer, you might be able to get closer to controlling the brightness by using an image that you create that becomes darker depending on the time of day. This isn't perfect, of course, but it certainly is better to output a blackened image than a white screen.

W. H. Heydt
Posts: 12431
Joined: Fri Mar 09, 2012 7:36 pm
Location: Vallejo, CA (US)

Re: Alarm Clock

Fri Dec 11, 2015 5:23 am

Killing the process to shut down the streaming station is no problem... We use "ps -C mplayer" to find it and there's the process IDs..

stderr
Posts: 2178
Joined: Sat Dec 01, 2012 11:29 pm

Re: Alarm Clock

Fri Dec 11, 2015 5:30 pm

W. H. Heydt wrote:Killing the process to shut down the streaming station is no problem... We use "ps -C mplayer" to find it and there's the process IDs..
That or top or something like that was how I was finding the pid to kill the process by hand which absolutely does work fine. I use that to kill ssh -X stuff coming into a machine that doesn't need to run anymore, well, mostly just firefox fits that for me. One problem is that directly killing an application from another account might require sudo or at least giving that controlling program extra permissions on the account that the snd/vid program was run on. Sending it a message to do a predefined thing doesn't and would seem to keep permissions more separated and easy to keep track of.

In the case of my version of radio, I started to worry that if I had more than one copy of mplayer, or some other program like omxplayer or vlc, that I'd not know which was which, nor would I know from the controlling program whether it was vlc, mplayer, omxplayer or something else. I also hoped to have the controller capable of starting and stopping the sound/video from a different machine than it was actually running on.

The direction I went was to add in another python program whose job it was to start the snd/vid program. Then I could send a message to that program telling it to quit playing or ultimately, I didn't get this far yet, controlling the pause, the volume and all that. One problem with doing this in general is that each program seems to have its own way of being remotely controlled, which again brings up the indirection of having my own program starting and controlling the snd/vid program remotely from commands given to a general command line program that started everything. I believe that the program running on the snd/vid machine is best equipped to decide which player to use and how to control it.

What I think I want is to be able to type the command line on any machine and then it sends a message to a daemon running on the machine to output the snd/vid. Control at the command line is returned to the user after each command, although I can see holding a connection open and allowing repeated changes like position in a file or sound volume. It's interesting how these sorts of personal programs can evolve.

Return to “Astro Pi”