Files
clocky/clocky.py

606 lines
22 KiB
Python
Executable File

#!/usr/bin/python3
import pickle
import os
import time
import sys
import tm1637
import max7219
import pygame
from time import sleep,strftime
import RPi.GPIO as GPIO
import button
import signal
import clockytracklist
settings= {}
looptype=0
quit=0
print("\n +----------+\n | Clocky |\n | v0.2.5 |\n +----------+\n")
o_configfilename = "clocky.conf"
o_defaultalarmtime = 60*14+10 # hh*60+mm
o_showalarmtime=3 # time that the alarmtime shows after short press
o_showtracktime=2 # note that this is per track, so total time is 10 times longer
o_editdelaytime=3 # time it takes to qualify as longpress
o_showtimeout=6 # timeout to exit edit modus
o_snoozetime = 9 # time to snooze
o_timetomaxvol = 150# seconds it takes to go from 0% to 100% volume
o_maxplaytime = 900 # seconds it to play
o_soundpreviewtime=5
o_defaultbrightness=0
o_loopdelay=0.25
track=0
stopprogram=0
reload=False
#GPIO.setmode(GPIO.BCM) # set up BCM GPIO numbering
#GPIO.setup(16, GPIO.IN, pull_up_down = GPIO.PUD_UP)
#def signal_handler(signal,frame):
# global quit
# print("")
# quit=1
def receive_signal(signum, stack):
global stopprogram
global reload
print('Received signal: %d' %signum)
if signum == signal.SIGHUP:
reload=True
if signum == signal.SIGINT:
stopprogram=1
def stamp():
sys.stdout.write(strftime("[%Y%m%d %H%M%S] "))
def writesettings():
"write settings to conf file"
with open(o_configfilename, 'wb') as handle:
pickle.dump(settings, handle)
handle.close()
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
looptype=0
colon=0
digit=1
showtime=0
playtime=0
soundpreview=0
alarmstarted=0
silencedalarm=0
tvol=0
volume=0.0
brightness=0
snooze=0
count=0
print('My PID is %d' %os.getpid())
signal.signal(signal.SIGHUP, receive_signal)
signal.signal(signal.SIGINT, receive_signal)
but1=button.Button(21)
but2=button.Button(20)
but3=button.Button(26)
#------------------------------------------------------------------
#------------------------------------------------------------------
while not stopprogram:
print("Load config...")
reload=False
# display=tm1637.TM1637(CLK=14, DIO=4, brightness=1)
display=max7219.MAX7219(brightness=1)
display.Clear()
display.SetBrightnessRaw(o_defaultbrightness)
print("reading mp3s from directory:")
tracks=clockytracklist.ClockyTracklist("mp3",recursive=True,verbose=True)
allmp3s=tracks.tracklist
c=0
for m in allmp3s:
print(" %2d : %s"%(c+1,m))
c+=1
stamp()
print("Started")
sys.stdout.flush()
# .................................................................
if not os.path.isfile(o_configfilename):
print("Createconf: \""+o_configfilename+"\":")
settings = {'track0':1, 'track1':2, 'track2':3, 'track3':4, 'track4':5, 'track5':6, 'track6':7, 'track7':8, 'track8':9, 'track9':10 }
settings['alarmtime']=o_defaultalarmtime;
settings['starttrack']=0;
settings['alarmdisabled']=0;
with open(o_configfilename, 'wb') as handle:
pickle.dump(settings, handle)
handle.close()
else:
print("Configfile: \""+o_configfilename+"\":")
with open(o_configfilename, 'rb') as handle:
settings = pickle.load(handle)
handle.close()
a_mins=int(settings['alarmtime']%60)
a_hour=int((settings['alarmtime']-a_mins)/60)
print("Alarmtime : %02d:%02d"%(a_hour,a_mins))
print("Alarmdisable: %d"%(settings['alarmdisabled']))
print("Starttrack : %d"%(settings['starttrack']))
for i in range(0,10):
if i==settings['starttrack']:
print("=>",end='')
else:
print(" ",end='')
print(" [T%01dM%02d] "%(i,settings["track%d"%i]),end='')
if settings["track%d"%i] and (settings["track%d"%i]-1 < len(allmp3s)):
print("\""+allmp3s[settings["track%d"%i]-1]+"\"")
else:
print("")
settings["track%d"%i]=0
writesettings()
# .................................................................
while not reload and not stopprogram:
count+=1;
sleep(o_loopdelay)
mytime=time.localtime(time.time())
currenttime=mytime[3]*60 + mytime[4];
if not settings["alarmdisabled"]:
if currenttime == settings['alarmtime']:
if looptype==0 and not silencedalarm:
looptype=5
else:
silencedalarm=0
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if looptype==0: # normal time display
if but1.WasPressed():
looptype=1
if but1.WasLong():
if but2.WasPressed():
if but2.WasLong():
if settings["alarmdisabled"]==0:
settings["alarmdisabled"]=1
stamp()
print("Alarm disabled")
writesettings()
else:
settings["alarmdisabled"]=0
stamp()
print("Alarm enabled")
writesettings()
looptype=1
else:
looptype=2
if but2.WasPressed():
looptype=3
track=0
if but2.WasLong():
looptype=4
if but3.WasPressed():
if but3.WasLong():
if settings["alarmdisabled"]==0:
settings["alarmdisabled"]=1
stamp()
print("Alarm disabled")
writesettings()
else:
settings["alarmdisabled"]=0
stamp()
print("Alarm enabled")
writesettings()
looptype=1
if colon:
tim="%02d:%02d" % (mytime[3] , mytime[4])
else:
tim="%02d %02d" % (mytime[3] , mytime[4])
display.showclock(tim)
if count % 4 == 0:
colon=1-colon
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if looptype==1: # show alarmtime
if not settings["alarmdisabled"]==1:
a_mins=int(settings['alarmtime']%60)
a_hour=int((settings['alarmtime']-a_mins)/60)
if colon:
tim="%02d:%02d" % (a_hour, a_mins)
else:
tim="%02d %02d" % (a_hour, a_mins)
display.showclock(tim)
colon=1-colon
else:
display.showclock(" O FF")
if showtime > o_showalarmtime:
if but1.WasPressed(): # drop intermediate presses
{}
if but2.WasPressed():
{}
if but3.WasPressed():
{}
showtime=0
looptype=0
else:
showtime+=o_loopdelay
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if looptype==2: # edit alarmtime
delta=0
sm=int(settings['alarmtime']%10)
dm=int(((settings['alarmtime']-sm)/10)%6)
sh=int((settings['alarmtime']-dm)/60%10)
dh=int((settings['alarmtime']-sh)/600)
if colon:
tim="%0d%0d:%0d%0d" % (dh,sh,dm,sm)
else:
if but2.WasPressed():
delta=1
showtime=0
if but3.WasPressed():
delta=-1
showtime=0
if digit==1:
if delta:
dh+=delta
if dh>2:
dh=0
if dh<0:
dh=2
tim=" %0d:%0d%0d" % ( sh,dm,sm)
elif digit==2:
if delta:
sh+=delta
if sh>9:
sh=0
if dh==2 and sh>3:
sh=0
if sh<0:
sh=9
tim="%0d :%0d%0d" % (dh, dm,sm)
elif digit==3:
if delta:
dm+=delta
if dm>5:
dm=0
if dm<0:
dm=5
tim="%0d%0d: %0d" % (dh,sh, sm)
elif digit==4:
if delta:
sm+=delta
if sm>9:
sm=0
if sm<0:
sm=9
tim="%0d%0d:%0d " % (dh,sh,dm )
delta=0
display.showclock(tim)
colon=1-colon
if showtime > o_showtimeout:
showtime=0
if dh==2 and sh>3:
sh=3
looptype=1
else:
looptype=0
if settings["alarmdisabled"]==1:
settings["alarmdisabled"]=0
stamp()
print("Alarm enabled")
settings['alarmtime']=dh*600+sh*60+dm*10+sm
writesettings()
stamp()
print("Set alarmtime = %d%d:%d%d"%(dh,sh,dm,sm))
sys.stdout.flush()
digit=1
else:
showtime+=o_loopdelay
settings['alarmtime']=dh*600+sh*60+dm*10+sm
if but1.WasPressed():
showtime=0
digit+=1
if digit>4:
digit=1
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if looptype==3: # show tracks mode
if but1.WasPressed():
if pygame.mixer.get_init():
pygame.mixer.music.set_volume(0)
pygame.mixer.music.stop()
pygame.mixer.quit()
soundpreview=0
looptype=1
if but1.WasLong():
looptype=2
if but2.WasPressed():
if settings["track%d"%track]>0:
print (allmp3s[settings["track%d"%track]-1])
sys.stdout.flush()
if not pygame.mixer.get_init():
pygame.mixer.init()
if pygame.mixer.get_init():
pygame.mixer.music.load(allmp3s[settings["track%d"%track]-1])
pygame.mixer.music.set_volume(1)
pygame.mixer.music.play()
soundpreview=1
tr=track
tl=int(settings["track%d"%tr]%10)
th=int((settings["track%d"%tr]-tl)/10)
if colon:
tim="%d=:%d%d" % (tr,th,tl)
else:
tim="%d %d%d" % (tr,th,tl)
tr+=1;
if tr>9:
looptype=0
display.showclock(tim)
colon=1-colon
if soundpreview:
if pygame.mixer.music.get_pos() >o_soundpreviewtime*1000:
if pygame.mixer.get_init():
pygame.mixer.music.set_volume(0)
pygame.mixer.music.stop()
pygame.mixer.quit()
soundpreview=0
showtime=0
track+=1;
if track>9:
looptype=0
else:
if showtime > o_showtracktime:
showtime=0
track+=1;
if track>9:
looptype=0
else:
showtime+=o_loopdelay
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if looptype==4: # edit track
delta=0
tr=track
tl=int(settings["track%d"%tr]%10)
th=int((settings["track%d"%tr]-tl)/10)
if colon:
tim="%d=:%d%d" % (tr,th,tl)
else:
if but2.WasPressed():
delta=1
showtime=0
if but3.WasPressed():
delta=-1
showtime=0
if digit==1:
if delta:
tr+=delta
if tr>9:
tr=0
delta=0
tl=settings["track%d"%tr]%10
th=(settings["track%d"%tr]-tl)/10
tim=" =:%0d%0d" % ( th,tl)
elif digit==2:
if delta:
th+=delta
if th>9:
th=0
delta=0
tim="%d=: %d" % (tr, tl)
elif digit==3:
if delta:
tl+=delta
if tl>9:
tl=0
delta=0
tim="%d=:%d " % (tr,th )
delta=0
display.showclock(tim)
colon=1-colon
settings["track%d"%tr]=th*10+tl
track=tr
if showtime > o_showtimeout:
showtime=0
looptype=0
writesettings()
else:
showtime+=o_loopdelay
if but1.WasPressed():
digit+=1
if digit>3:
digit=1
showtime=0
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if looptype==5: # Alarm!
#o_timetomaxvol = 60 # seconds it takes to go from 0% to 100% volume
if colon:
display.SetBrightnessRaw(0)
tim="%02d:%02d" % (mytime[3] , mytime[4])
else:
display.SetBrightnessRaw(brightness)
tim="%02d:%02d" % (mytime[3] , mytime[4])
display.showclock(tim)
if count % 2 == 0:
colon=1-colon
if not alarmstarted:
track=settings['starttrack'];
stamp()
print("[T%02dM%02d] \"%s\""%(track,settings["track%d"%track],(allmp3s[settings["track%d"%track]-1])))
sys.stdout.flush()
if not pygame.mixer.get_init():
pygame.mixer.init()
if pygame.mixer.get_init():
pygame.mixer.music.load(allmp3s[settings["track%d"%track]-1])
pygame.mixer.music.set_volume(volume)
pygame.mixer.music.play()
track+=1
if track > 9:
track=0
if settings["track%d"%track]==0:
track=0
settings['starttrack']=track;
writesettings()
playtime=0
alarmstarted=1
else: # alarmstarted
if playtime < o_timetomaxvol:
brightness=int((playtime / o_timetomaxvol)*255)
volume = float(int((playtime*100) / o_timetomaxvol))/100
# print("------> %d / %d => %f - %f [%d]"%(playtime,o_timetomaxvol,tvol,volume,brightness))
else:
volume=1
if pygame.mixer.get_init():
pygame.mixer.music.set_volume(volume)
playtime+=o_loopdelay
if pygame.mixer.get_init():
if not pygame.mixer.music.get_busy():
track=settings['starttrack']
stamp()
print("[T%02dM%02d] \"%s\""%(track,settings["track%d"%track],(allmp3s[settings["track%d"%track]-1])))
sys.stdout.flush()
pygame.mixer.music.load(allmp3s[settings["track%d"%track]-1])
pygame.mixer.music.play()
track+=1
if track > 9:
track=0
if settings["track%d"%track]==0:
track=0
settings['starttrack']=track;
writesettings()
if playtime > o_maxplaytime:
looptype=0
playtime=0
if pygame.mixer.get_init():
pygame.mixer.music.set_volume(0)
pygame.mixer.music.stop()
pygame.mixer.quit()
display.SetBrightnessRaw(o_defaultbrightness)
alarmstarted=0
stamp()
print("Alarmtime expired")
if but1.WasPressed():
if but1.WasLong(): # Finished
if pygame.mixer.get_init():
pygame.mixer.music.set_volume(0)
pygame.mixer.music.stop()
pygame.mixer.quit()
display.SetBrightnessRaw(o_defaultbrightness)
playtime=0
if but1.WasPressed(): # flush intermediate presses
{}
if but2.WasPressed():
{}
if but3.WasPressed():
{}
looptype=0
alarmstarted=0
silencedalarm=1
stamp()
print("Silenced alarm")
if but2.WasPressed():
if not but1.WasLong():
if pygame.mixer.get_init():
if pygame.mixer.music.get_busy():
pygame.mixer.music.stop()
track=settings['starttrack']
stamp()
print("[T%02dM%02d] \"%s\""%(track,settings["track%d"%track],(allmp3s[settings["track%d"%track]-1])))
sys.stdout.flush()
if pygame.mixer.get_init():
pygame.mixer.music.load(allmp3s[settings["track%d"%track]-1])
pygame.mixer.music.play()
track+=1
if track > 9:
track=0
if settings["track%d"%track]==0:
track=0
settings['starttrack']=track;
writesettings()
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if count % 40 == 0: # every 10 seconds
if tracks.CheckTrackList():
reload = True;
#------------------------------------------------------------------
if pygame.mixer.get_init():
pygame.mixer.music.set_volume(0)
pygame.mixer.music.stop()
pygame.mixer.quit()
display.cleanup()
sys.stdout.flush()
stamp()
print("Shutdown!")