To answer my own question. I decided as there maybe is no immediate solution, I took a sledgehammer to this walnut. I'm posting here in case it's of any use to anyone else. Isn't Chumby great that you can get right in there and change things you don't quite like.
I basically have three files "speakeroncron", "speakeronalm" and "alarmparse" in /psp. "alarmparse" uses the /psp/alarms file that stores alarm times and converts these to cron entries. I have wrapped this is an shell script "speakeroncron" , this checks if the alarms file is newer than the crontab file. If so, it reparses the alarms file and generates new cron entries.
First is speakeroncron
#!/bin/sh
if [ "/psp/alarms" -nt "/psp/crontabs/root" ] ; then
grep -v '/psp/speakeronalm' /psp/crontabs/root >/psp/cleanrootcrontab
cat /psp/cleanrootcrontab | /psp/alarmparse | crontab -
fi
Then the perl I use to parse "alarmparse":
#!/usr/bin/perl
# Script to parse alarms file and create appropriate cron entries
while (<>) { print $_;};
open ($fh,"/psp/alarms") or die "Failed to open alarms file";
read ($fh, $alarms, 20480);
close ($fh);
%daysofw = ("monday",1,"tuesday",2,"wednesday",3,"thursday",4,"friday",5,"saturday",6,"sunday",7);
@alarmlines=split("<alarm name=",$alarms);
foreach (@alarmlines){
/enabled=\"(\d+)" time=\"(\d+)\" when=\"(.+)\"/;
$enabled=$1;
$altime=$2;
$when=$3;
next if (!$enabled);
if ($when eq "once") {
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime($altime*60);
print "$min $hour $mday ",$mon+1," * /psp/speakeronalm\n";
}
else {
$wdays="";
$wdays="1-5" if ($when eq "weekday");
$wdays="6,0" if ($when eq "weekend");
$wdays="\*" if ($when eq "daily");
$wdays=$daysofw{$when} if ($wdays eq "");
next if ($wdays eq "");
$min=$altime%60;
$hour=int($altime/60);
print "$min $hour * * $wdays /psp/speakeronalm\n";
}
}
And finally the job cron runs, "speakeronalm", I put in a 3s delay just to let things settle before turning the speaker on (didn't know if the alarm program is fiddling with stuff so didn't want to tread on it's toes). And didn't want the possibility that the speaker playing earlier than the alarm:
#!/bin/sh
sleep 3
regutil -w HW_AUDIOOUT_SPEAKERCTRL_CLR=0x01000000 >/dev/null 2>/dev/null
Then just cron /psp/speakeroncron this as often as you think necessary, hourly was enough for me ( I don't change alarm times often):
4 * * * * /psp/speakeroncron
When the cron runs it will populate roots cron with /psp/speakeronalm jobs for the times you set your alarms for.
The limitations are a few. One, if you change alarm times to go off sooner than the cron runs, the speaker won't go on. Also after the alarm goes off you need to remember the speaker is now enabled so if you go back to audio say (or have it set to auto go back to audio) then this will also go through the speaker still. I personally want to leave the speaker enabled, as if I hit snooze ,I want that next alarm to come through the speaker too. If not using snooze, I guess you could save the speaker state in the cron script and return it to the correct state using post_alarm_action (not sure how you'd handle the snoozed alarm though).