HP Forums

Full Version: Z LIGHTS: Prime's answer to mobile phone torches
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
As the clocks change and the nights get darker, it seems the right time for this little program...It can also be called from ZIPP, another of my programs.

Given that the HP Prime has no external accessible lights, this program may be of little practical use...unless the lights go out whilst you are using your calculator.

The design aim is a compromise between maximising the limited illumination available, and including some information that a torch would not (the time the light was activated).

Version 0.1:
Code:


 LOCAL CRID:="Z LIGHTS V0.1 © 2015 StephenG1CMZ";
 LOCAL NL:=CHAR(10);

 LOCAL COLRNAME:={"RED","GREEN","BLUE","WHITE"};
 LOCAL COLRGB:={#FF0000h,#00FF00h,#0000FFh,#FFFFFFh};
 
 LOCAL LIGHTON:=" ON: Tap Esc to exit";
 LOCAL LIGHTT:="Tap a key to see elapsed time s";
 LOCAL WABTHLP:={"ABOUT/Help"};
 LOCAL WBCN:={"Beacon"};
 LOCAL WBLNKLIGHT:={"Blink Light"};
 LOCAL WCOLR:={"Colour"};
 LOCAL WSTDYLIGHT:={"Steady Light"};
 LOCAL CHOICES:={WABTHLP(1),"INFO",WSTDYLIGHT(1),WCOLR(1),WBLNKLIGHT(1),WBCN(1)};
 LOCAL LGL:="No liability is accepted.";
 LOCAL COLR:=#FFFFFFh;
 LOCAL TS;

 CLS()
 BEGIN
  RECT_P(0,0,320-45,240,COLR);
  RECT_P(0,20,320,240,COLR);
 END;

 SCRID()
 BEGIN
  IF 1 THEN
   TEXTOUT_P(CRID,0,0,0,0,320,COLR);
  END;
 END;

  LIGHTELF()
  BEGIN
   LOCAL ELFST:={"Use of lights may have health and legal consequences.
The user is responsible.
"+LGL};
   RETURN MSGBOX(ELFST(1),1);
  END;

 EXPORT ABOUT()
 BEGIN
  LOCAL ST:="StephenG1CMZ is a programmer and can work to your requirements."+NL;
  LOCAL SZ:="LIGHTS provides useful practical results.
Ask, if you have specific requirements."+NL;
  LOCAL THANX:=""; 
  //LOCAL LGL:="No liability is accepted.";
  PRINT(); PRINT(CRID);
  PRINT(ST+NL+SZ);
  PRINT(THANX);
  PRINT(LGL);
  WAIT;

  LIGHTELF();
 END;

 EXPORT INFO()
 BEGIN
  LIGHTELF();
 END;


 EXPORT LIGHTCOLR()
 BEGIN
  LOCAL CHS;

  CHOOSE(CHS,"",COLRNAME);
  IF CHS THEN
    COLR:=COLRGB(CHS);
  END;
 END;

 EXPORT LIGHTSTEADY()
 BEGIN
  LOCAL WR;
  LOCAL DUN:=0;
  //RECT_P(0,0,320-45,240,0,COLR);
  CLS();
  TS:=Time;
  SCRID();
  TEXTOUT_P(TS+LIGHTON,0,180);
  TEXTOUT_P(LIGHTT,0,220);
  TEXTOUT_P("DEMO TEXT",0,100,7);
  
  REPEAT
   TEXTOUT_P((Time-TS),0,200,0,#FFFFFFh,320,0);
   WR:=WAIT(−1);
   IF TYPE(WR)==0 THEN 
    IF WR==4 THEN
     DUN:=1;
    END;
   END;
  UNTIL DUN; //WR==4;
 END;

 EXPORT LIGHTBLINK()
 BEGIN
  TS:=Time;
  REPEAT
   RECT_P(0,20,320,240,0,COLR);
   TEXTOUT_P(TS+LIGHTON,0,180);
   TEXTOUT_P(Time-TS,0,200,0,#FFFFFFh,320,0);
   TEXTOUT_P("DEMO TEXT",0,100,7);
   SCRID();
   WAIT(1);
   RECT_P(0,20,320,240,0,0);
   WAIT(1);
  UNTIL GETKEY==4;//CHECK BOTH TBD
 END;

 HELP()
 BEGIN
  LOCAL CHS;
  
  LOCAL HLPCOLR:="Red light may help preserve night vision";

  PRINT(); 
  CHOOSE(CHS,WABTHLP(1),CHOICES);
  PRINT(CHOICES(CHS));
  CASE
   IF CHS==1 THEN ABOUT() END;
   IF CHS==2 THEN INFO() END;
   IF CHS==4 THEN PRINT(HLPCOLR) END;
 
   DEFAULT
    LIGHTELF();
    //BACKSTORY();
  END;
  WAIT;
 END;

 EXPORT Z_LIGHTS()
 BEGIN
  LOCAL CHS;
  //SCRID();
  REPEAT
   CHOOSE(CHS,CRID,CHOICES);
   CASE
    IF CHS==1 THEN HELP()   END;
    IF CHS==2 THEN INFO()   END;
    IF CHS==3 THEN LIGHTSTEADY() END;
    IF CHS==4 THEN LIGHTCOLR()   END;
    IF CHS==5 THEN LIGHTBLINK()  END;
    IF CHS==6 THEN LIGHTBLINK()  END;
 
    DEFAULT
   END;
  UNTIL CHS==0;
//I HAD CONSIDERED A WAKEUP ALARM. BUT AUTO DIMMING OFSCREEN


 END;
Is there a way to un-dim the screen after a programmed delay? Then I could add a wake-up function.
Version 0.2 has some new functionality that you will hopefully never need.
It would be nice if someone that reads Morse code could check it out, as I haven't checked out its readability.
Code:


 LOCAL CRID:="Z LIGHTS V0.2 © 2015 StephenG1CMZ";
 LOCAL NL:=CHAR(10);

 EXPORT ACT_TIME;//:={};
 EXPORT ACT_TIME_SOS;//:={};
 EXPORT WPM:=3;

 LOCAL DOTT;

 LOCAL COLRNAME:={"RED","GREEN","BLUE","WHITE"};
 LOCAL COLRGB:={#FF0000h,#00FF00h,#0000FFh,#FFFFFFh};
 
 LOCAL LIGHTON:=" ON: Tap Esc to exit";
 LOCAL LIGHTT:="Tap a key to see elapsed time s";
 LOCAL WABTHLP:={"ABOUT/Help"};
 LOCAL WBCN:={"Beacon"};
 LOCAL WBLNKLIGHT:={"Blink Light"};
 LOCAL WCOLR:={"Colour"};
 LOCAL WSTDYLIGHT:={"Steady Light"};
 LOCAL WWPM:={"Words per minute (WPM)"};
 LOCAL CHOICES:={WABTHLP(1),"INFO",WSTDYLIGHT(1),WCOLR(1),WBLNKLIGHT(1),"SOS",WWPM(1)};
 LOCAL LGL:="No liability is accepted.";
 LOCAL COLR:=#FFFFFFh;
 LOCAL TS;

 CLS()
 BEGIN
  RECT_P(0,0,320-45,240,COLR);
  RECT_P(0,20,320,240,COLR);
 END;

 SCRID()
 BEGIN
  IF 1 THEN
   TEXTOUT_P(CRID,0,0,0,0,320,COLR);
  END;
 END;

  LIGHTELF()
  BEGIN
   LOCAL ELFST:={"Use of lights may have health and legal consequences.
The user is responsible.
"+LGL};
   RETURN MSGBOX(ELFST(1),1);
  END;

 EXPORT ABOUT()
 BEGIN
  LOCAL ST:="StephenG1CMZ is a programmer and can work to your requirements."+NL;
  LOCAL SZ:="LIGHTS provides useful practical results.
Ask, if you have specific requirements."+NL;
  LOCAL THANX:=""; 
  
  PRINT(); PRINT(CRID);
  PRINT(ST+NL+SZ);
  PRINT(THANX);
  PRINT(LGL);
  WAIT;

  LIGHTELF();
 END;

 EXPORT INFO()
 BEGIN
  LIGHTELF();
 END;

 AT(TS)
 BEGIN
  
  //RETURN {HH,MM,SS} ; 
  RETURN TS;

 END;

 EXPORT LIGHTCOLR()
 BEGIN
  LOCAL CHS;

  CHOOSE(CHS,"",COLRNAME);
  IF CHS THEN
    COLR:=COLRGB(CHS);
  END;
 END;

 EXPORT LIGHTSTEADY()
 BEGIN
  LOCAL WR;
  LOCAL DUN:=0;
 
  CLS();
  TS:=Time;
  ACT_TIME:={WSTDYLIGHT,AT(TS)};
  SCRID();
  TEXTOUT_P(TS+LIGHTON,0,180);
  TEXTOUT_P(LIGHTT,0,220);
  TEXTOUT_P("DEMO TEXT",0,100,7);
  
  REPEAT
   TEXTOUT_P((Time-TS),0,200,0,#FFFFFFh,320,0);
   WR:=WAIT(−1);
   IF TYPE(WR)==0 THEN 
    IF WR==4 THEN
     DUN:=1;
    END;
   END;
  UNTIL DUN; //WR==4;
 END;

 EXPORT LIGHTBLINK()
 BEGIN
  TS:=Time;
  ACT_TIME:={WBLNKLIGHT,AT(TS)};
  REPEAT
   RECT_P(0,20,320,240,0,COLR);
   TEXTOUT_P(TS+LIGHTON,0,180);
   TEXTOUT_P(Time-TS,0,200,0,#FFFFFFh,320,0);
   TEXTOUT_P("DEMO TEXT",0,100,7);
   SCRID();
   WAIT(1);
   RECT_P(0,20,320,240,0,0);
   WAIT(1);
  UNTIL GETKEY==4;//CHECK BOTH TBD
 END;

 SIGOFF()
 BEGIN
  RECT_P(0,20,320,240,0,0);
 END;

 SIGON()
 BEGIN
  RECT_P(0,20,320,240,0,COLR);

 END;

 DAH()
 BEGIN
  SIGON();
  WAIT(3*DOTT);
  SIGOFF();
  WAIT(DOTT);
 END;

 DIT()
 BEGIN
  SIGON();
  WAIT(DOTT);
  SIGOFF();
  WAIT(DOTT); 
 END;

 EXPORT LIGHT_SOS()
 BEGIN
  LOCAL OK;
  LOCAL OKC:="OK TO CONFIRM?";
  LOCAL MYWPM:=MAX(MIN(WPM,50),1);
  //LOCAL BAUD:=ROUND(0.83*MYWPM,0);//APPROX
  DOTT:=1.2/MYWPM;
 
  OK:=MSGBOX(MYWPM+" WPM"+NL+".="+DOTT+" s"+NL+OKC,1);
  IF OK THEN
   TS:=Time;
   ACT_TIME_SOS:={"SOS",AT(TS)};
   CLS();
   TEXTOUT_P(TS,0,0);
   //INTERWORD GAP
   //SEPERATES , REPOSITION
   SIGOFF();
   OK:=WAIT(7*DOTT);
   REPEAT
    DIT(); DIT(); DIT(); //S
    DAH(); DAH(); DAH(); //O
    DIT(); DIT(); DIT(); //S
    OK:=WAIT(3*DOTT); //INTERLETTER GAP
   UNTIL GETKEY==4; 
  END;
 END;

 ASK_WPM()
 BEGIN
  LOCAL OK;
  LOCAL TTL:="WORDS PER MINUTE";
  LOCAL LBL:="WPM";
  LOCAL HLP:="1..25 RECOMMENDED";
  OK:=INPUT(WPM,TTL,LBL,HLP,5,5);
  IF OK THEN
   WPM:=MAX(WPM,1);
  END;
 END;

HELP()
 BEGIN
  LOCAL CHS;
  LOCAL HLPCHC:=CONCAT(CHOICES,{"VARIABLES"});
  LOCAL HLPCOLR:="Red light may help preserve night vision";
  LOCAL CNW:="Connectivity Not Working";
  LOCAL HLPVARS:="
ACT_TIME:
ACT_TIME_SOS:
 Activation time

WPM: WORDS PER MINUTE
 @Home:
 WPM:=n n==1..25";
  REPEAT
   PRINT(); 
   CHOOSE(CHS,WABTHLP(1),HLPCHC);
   IF CHS THEN
    PRINT(HLPCHC(CHS));
    CASE
     IF CHS==1 THEN ABOUT() END;
     IF CHS==2 THEN INFO() END;
     IF CHS==4 THEN PRINT(HLPCOLR) END;
     IF CHS==6 THEN PRINT(CNW) END;
     IF CHS==8 THEN PRINT(HLPVARS) END;
     DEFAULT
      LIGHTELF();
      //BACKSTORY();
     END;
     WAIT;
    END;
   UNTIL CHS==0;
  WAIT;
 END;

 EXPORT Z_LIGHTS()
 BEGIN
  LOCAL CHS;
  //SCRID();
  REPEAT
   CHOOSE(CHS,CRID,CHOICES);
   CASE
    IF CHS==1 THEN HELP()   END;
    IF CHS==2 THEN INFO()   END;
    IF CHS==3 THEN LIGHTSTEADY() END;
    IF CHS==4 THEN LIGHTCOLR()   END;
    IF CHS==5 THEN LIGHTBLINK()  END;
    //IF CHS==6 THEN LIGHTBLINK()  END;
    IF CHS==6 THEN LIGHT_SOS()   END;
    IF CHS==7 THEN ASK_WPM()     END;
 
    DEFAULT
   END;
  UNTIL CHS==0;
//I HAD CONSIDERED A WAKEUP ALARM. BUT AUTO DIMMING OFSCREEN


 END;
Version 0.3 includes a cheat mode (edit the HINTS BOOLEAN as you wish)
Code:

 LOCAL CRID:="Z LIGHTS V0.3 © 2015 StephenG1CMZ";
 LOCAL NL:=CHAR(10);

 //CUSTOMISE
 LOCAL HINTS:=1; //CHEAT

 EXPORT ACT_TIME;//:={};
 EXPORT ACT_TIME_SOS;//:={};
 EXPORT WPM:=3;

 LOCAL DOTT;

 LOCAL COLRNAME:={"RED","GREEN","BLUE","WHITE"};
 LOCAL COLRGB:={#FF0000h,#00FF00h,#0000FFh,#FFFFFFh};
 
 LOCAL LIGHTON:=" ON: Tap Esc to exit";
 LOCAL LIGHTT:="Tap a key to see elapsed time s";
 LOCAL WABTHLP:={"ABOUT/Help"};
 LOCAL WBCN:={"Beacon"};//UNUSED
 LOCAL WBLNKLIGHT:={"Blink Light"};
 LOCAL WCOLR:={"Colour"};
 LOCAL WSTDYLIGHT:={"Steady Light"};
 LOCAL WWPM:={"Words Per Minute (WPM)"};
 LOCAL CHOICES:={WABTHLP(1),"INFO",WSTDYLIGHT(1),WCOLR(1),WBLNKLIGHT(1),"SOS",WWPM(1)};
 LOCAL LGL:="No liability is accepted.";
 LOCAL COLR:=#FFFFFFh;
 LOCAL TS;

 CLS()
 BEGIN
  RECT_P(0,0,320-45,240,COLR);
  RECT_P(0,20,320,240,COLR);
 END;

 SCRID()
 BEGIN
  IF 1 THEN
   TEXTOUT_P(CRID,0,0,0,0,320,COLR);
  END;
 END;

  LIGHTELF()
  BEGIN
   LOCAL ELFST:={"Use of lights may have health and legal consequences.
The user is responsible.
"+LGL};
   RETURN MSGBOX(ELFST(1),1);
  END;

 EXPORT ABOUT()
 BEGIN
  LOCAL ST:="StephenG1CMZ is a programmer and can work to your requirements."+NL;
  LOCAL SZ:="LIGHTS provides useful practical results.
Ask, if you have specific requirements."+NL;
  LOCAL THANX:=""; 
  
  PRINT(); PRINT(CRID);
  PRINT(ST+NL+SZ);
  PRINT(THANX);
  PRINT(LGL);
  WAIT;

  LIGHTELF();
 END;

 EXPORT INFO()
 BEGIN
  LIGHTELF();
 END;

 AT(TS)
 BEGIN 
  //RETURN {HH,MM,SS} ; 
  RETURN TS;
 END;

 EXPORT LIGHTCOLR()
 BEGIN
  LOCAL CHS;

  CHOOSE(CHS,"",COLRNAME);
  IF CHS THEN
    COLR:=COLRGB(CHS);
  END;
 END;

 EXPORT LIGHTSTEADY()
 BEGIN
  LOCAL WR;
  LOCAL DUN:=0;
 
  CLS();
  TS:=Time;
  ACT_TIME:={WSTDYLIGHT,AT(TS)};//MUST CONTAIN LIST
  SCRID();
  TEXTOUT_P(TS+LIGHTON,0,180);
  TEXTOUT_P(LIGHTT,0,220);
  TEXTOUT_P("DEMO TEXT",0,100,7);
  
  REPEAT
   TEXTOUT_P((Time-TS),0,200,0,#FFFFFFh,320,0);
   WR:=WAIT(−1);
   IF TYPE(WR)==0 THEN 
    IF WR==4 THEN
     DUN:=1;
    END;
   END;
  UNTIL DUN; //WR==4;
 END;

 EXPORT LIGHTBLINK()
 BEGIN
  TS:=Time;
  ACT_TIME:={WBLNKLIGHT,AT(TS)};//MUST CONTAIN LIST
  REPEAT
   RECT_P(0,20,320,240,0,COLR);
   TEXTOUT_P(TS+LIGHTON,0,180);
   TEXTOUT_P(Time-TS,0,200,0,#FFFFFFh,320,0);
   TEXTOUT_P("DEMO TEXT",0,100,7);
   SCRID();
   WAIT(1);
   RECT_P(0,20,320,240,0,0);
   WAIT(1);
  UNTIL GETKEY==4;//CHECK BOTH TBD
 END;

 SIGOFF()
 BEGIN
  LOCAL WD:=GROBW_P();
  LOCAL HT:=GROBH_P();

  RECT_P(0,20,WD,HT,0,0);
 END;

 SIGON()
 BEGIN
  LOCAL WD:=GROBW_P();
  LOCAL HT:=GROBH_P();
  
  RECT_P(0,20,WD,HT,0,COLR);
 END;

 DAH()
 BEGIN
  LOCAL WDC:=GROBW_P/2;
  LOCAL HTC:=GROBH_P/2;
  SIGON();
  IF HINTS THEN
   RECT_P(WDC-15,HTC-5,WDC+15,HTC+5,0,0);
  END;
  WAIT(3*DOTT);
  SIGOFF();
  WAIT(DOTT);
 END;

 DIT()
 BEGIN
  LOCAL WDC:=GROBW_P/2;
  LOCAL HTC:=GROBH_P/2;
  SIGON();
  IF HINTS THEN
   ARC_P(WDC,HTC,5,0);
  END;
  WAIT(DOTT);
  SIGOFF();
  WAIT(DOTT); 
 END;

 EXPORT LIGHT_SOS()
 BEGIN
  LOCAL OK;
  LOCAL OKC:="OK TO CONFIRM?";
  LOCAL MYWPM:=MAX(MIN(WPM,50),1);
  //LOCAL BAUD:=ROUND(0.83*MYWPM,0);//APPROX
  DOTT:=1.2/MYWPM;
 
  OK:=MSGBOX(MYWPM+" WPM"+NL+".="+DOTT+" s"+NL+OKC,1);
  IF OK THEN
   TS:=Time;
   ACT_TIME_SOS:={{"SOS"},AT(TS)};//MUST CONTAIN LIST
   CLS();
   TEXTOUT_P(TS,0,0);
   //INTERWORD GAP
   //SEPERATES , REPOSITION
   SIGOFF();
   OK:=WAIT(7*DOTT);
   REPEAT
    DIT(); DIT(); DIT(); //S
    DAH(); DAH(); DAH(); //O
    DIT(); DIT(); DIT(); //S
    OK:=WAIT(3*DOTT); //INTERLETTER GAP
   UNTIL GETKEY==4; 
  END;
 END;

 ASK_WPM()
 BEGIN
  LOCAL OK;
  LOCAL TTL:=WWPM(1);
  LOCAL LBL:="WPM";
  LOCAL HLP:="1..25 RECOMMENDED";
  OK:=INPUT(WPM,TTL,LBL,HLP,5,5);
  IF OK THEN
   WPM:=MAX(WPM,1);
  END;
 END;

HELP()
 BEGIN
  LOCAL CHS;
  //LOCAL HLPCHC:=CONCAT(CHOICES,{"VARIABLES"});
  LOCAL HLPCOLR:="Red light may help preserve night vision";
  LOCAL CNW:="Connectivity Not Working";
  LOCAL HLPVARS:="
ACT_TIME:
ACT_TIME_SOS:
 Activation time

WPM: "+WWPM(1)+"
 @Home:
 WPM:=n [n==1..25]";
 
  LOCAL SEL:={1,1,0,1,0,1,0};//SELECT CHOICES W HLP
  LOCAL SELCHOICES:=EXECON("IFTE(&2,&1,CHAR(0))",CHOICES,SEL);//SYN:DIDIER
  LOCAL HLPCHC:=CONCAT(SELCHOICES,{"VARIABLES"});

  REPEAT
   PRINT(); 
   CHOOSE(CHS,WABTHLP(1),HLPCHC);
   IF CHS THEN
    PRINT(HLPCHC(CHS));
    CASE
     IF CHS==1 THEN ABOUT(); WAIT END;
     IF CHS==2 THEN INFO(); WAIT END;
     IF CHS==4 THEN PRINT(HLPCOLR); WAIT END;
     IF CHS==6 THEN PRINT(CNW); WAIT END;
     IF CHS==8 THEN PRINT(HLPVARS); WAIT END;
     DEFAULT
     END;
    END;
   UNTIL CHS==0;
  WAIT;
 END;

 EXPORT Z_LIGHTS()
 BEGIN
  LOCAL CHS;
  //SCRID();
  REPEAT
   CHOOSE(CHS,CRID,CHOICES);
   CASE
    IF CHS==1 THEN HELP()   END;
    IF CHS==2 THEN INFO()   END;
    IF CHS==3 THEN LIGHTSTEADY() END;
    IF CHS==4 THEN LIGHTCOLR()   END;
    IF CHS==5 THEN LIGHTBLINK()  END;
    //IF CHS==6 THEN LIGHTBLINK()  END;
    IF CHS==6 THEN LIGHT_SOS()   END;
    IF CHS==7 THEN ASK_WPM()     END;
 
    DEFAULT
   END;
  UNTIL CHS==0;

//FINALLY
//I HAD CONSIDERED A WAKEUP ALARM. BUT AUTO DIMMING OFSCREEN
//MUST CONTAIN LIST:
//SO LIST ED CAN BE USED TO SHOW OLD CONTENTS

 END;
Z_LIGHTS V0.3 appears to reveal a change to the programmed user interface between 8151
11586 (both running on Android, but on different phones). 8151 behaviour is as intended.

For example, run the main Z_LiGHTS routine, choose a nice green colour, then select "SOS".
After confirming WPM, the light displays an SOS sequence.
Important: Don't blame me if you do that outside of an appropriate test environment. Smile
Press Escape, and you return to the menu, where you can select a different colour or a steady light (torch).

In 11586, Press Escape and you see the menu including SOS, then WPM, then the menu including SOS ... And you seem to have to interrupt execution with ON to select other menu options.

Is anyone else seeing this? Or can suggest what has changed?
The cause appears to be a bug in 11586, not present in 8151 (both on Android).

In the main program, a loop on CHOOSE is examining the choose variable CHS, expecting it to be 0 if the user Escapes without selecting a choice... This seems to be the documented behaviour in the on-device help in both versions.
In 8151 as expected 0 is returned.
In 11586 the previous value is repeated.

Changing the logic so that CHOOSE returns a boolean and using that boolean to exit fixes the change in behaviour and works in both systems.
Version 0.4 implements the above fix in the main outer loop and works in both 8151 and 11586 (Android).

Code:



 LOCAL CRID:="Z LIGHTS V0.4 © 2017 StephenG1CMZ";
 LOCAL NL:=CHAR(10);

 //V0.4 TESTED ON 8151 AND 11586 (ANDROID)

 //CUSTOMISE
 LOCAL HINTS:=1; //CHEAT

 EXPORT ACT_TIME;//:={};
 EXPORT ACT_TIME_SOS;//:={};
 EXPORT WPM:=3;

 LOCAL DOTT;

 LOCAL COLRNAME:={"RED","GREEN","BLUE","WHITE"};
 LOCAL COLRGB:={#FF0000h,#00FF00h,#0000FFh,#FFFFFFh};
 
 LOCAL LIGHTON:=" ON: Tap Esc to exit";
 LOCAL LIGHTT:="Tap a key to see elapsed time s";
 LOCAL WABTHLP:={"ABOUT/Help"};
 LOCAL WBCN:={"Beacon"};//UNUSED
 LOCAL WBLNKLIGHT:={"Blink Light"};
 LOCAL WCOLR:={"Colour"};
 LOCAL WSTDYLIGHT:={"Steady Light"};
 LOCAL WWPM:={"Words Per Minute (WPM)"};
 LOCAL CHOICES:={WABTHLP(1),"INFO",WSTDYLIGHT(1),WCOLR(1),WBLNKLIGHT(1),"SOS",WWPM(1)};
 LOCAL LGL:="No liability is accepted.";
 LOCAL COLR:=#FFFFFFh;
 LOCAL TS;

 CLS()
 BEGIN
  RECT_P(0,0,320-45,240,COLR);
  RECT_P(0,20,320,240,COLR);
 END;

 SCRID()
 BEGIN
  IF 1 THEN
   TEXTOUT_P(CRID,0,0,0,0,320,COLR);
  END;
 END;

  LIGHTELF()
  BEGIN
   LOCAL ELFST:={"Use of lights may have health and legal consequences.
The user is responsible.
"+LGL};
   RETURN MSGBOX(ELFST(1),1);
  END;

 EXPORT ABOUT()
 BEGIN
  LOCAL ST:="StephenG1CMZ is a programmer and can work to your requirements."+NL;
  LOCAL SZ:="LIGHTS provides useful practical results.
Ask, if you have specific requirements."+NL;
  LOCAL THANX:=""; 
  
  PRINT(); PRINT(CRID);
  PRINT(ST+NL+SZ);
  PRINT(THANX);
  PRINT(LGL);
  WAIT;

  LIGHTELF();
 END;

 EXPORT INFO()
 BEGIN
  LIGHTELF();
 END;

 AT(TS)
 BEGIN 
  //RETURN {HH,MM,SS} ; 
  RETURN TS;
 END;

 EXPORT LIGHTCOLR()
 BEGIN
  LOCAL CHS;

  CHOOSE(CHS,"",COLRNAME);
  IF CHS THEN
    COLR:=COLRGB(CHS);
  END;
 END;

 EXPORT LIGHTSTEADY()
 BEGIN
  LOCAL WR;
  LOCAL DUN:=0;
 
  CLS();
  TS:=Time;
  ACT_TIME:={WSTDYLIGHT,AT(TS)};//MUST CONTAIN LIST
  SCRID();
  TEXTOUT_P(TS+LIGHTON,0,180);
  TEXTOUT_P(LIGHTT,0,220);
  TEXTOUT_P("DEMO TEXT",0,100,7);
  
  REPEAT
   TEXTOUT_P((Time-TS),0,200,0,#FFFFFFh,320,0);
   WR:=WAIT(−1);
   IF TYPE(WR)==0 THEN 
    IF WR==4 THEN
     DUN:=1;
    END;
   END;
  UNTIL DUN; //WR==4;
 END;

 EXPORT LIGHTBLINK()
 BEGIN
  TS:=Time;
  ACT_TIME:={WBLNKLIGHT,AT(TS)};//MUST CONTAIN LIST
  REPEAT
   RECT_P(0,20,320,240,0,COLR);
   TEXTOUT_P(TS+LIGHTON,0,180);
   TEXTOUT_P(Time-TS,0,200,0,#FFFFFFh,320,0);
   TEXTOUT_P("DEMO TEXT",0,100,7);
   SCRID();
   WAIT(1);
   RECT_P(0,20,320,240,0,0);
   WAIT(1);
  UNTIL GETKEY==4;//CHECK BOTH TBD
 END;

 SIGOFF()
 BEGIN
  LOCAL WD:=GROBW_P();
  LOCAL HT:=GROBH_P();

  RECT_P(0,20,WD,HT,0,0);
 END;

 SIGON()
 BEGIN
  LOCAL WD:=GROBW_P();
  LOCAL HT:=GROBH_P();
  
  RECT_P(0,20,WD,HT,0,COLR);
 END;

 DAH()
 BEGIN
  LOCAL WDC:=GROBW_P/2;
  LOCAL HTC:=GROBH_P/2;
  SIGON();
  IF HINTS THEN
   RECT_P(WDC-15,HTC-5,WDC+15,HTC+5,0,0);
  END;
  WAIT(3*DOTT);
  SIGOFF();
  WAIT(DOTT);
 END;

 DIT()
 BEGIN
  LOCAL WDC:=GROBW_P/2;
  LOCAL HTC:=GROBH_P/2;
  SIGON();
  IF HINTS THEN
   ARC_P(WDC,HTC,5,0);
  END;
  WAIT(DOTT);
  SIGOFF();
  WAIT(DOTT); 
 END;

 EXPORT LIGHT_SOS()
 BEGIN
  LOCAL OK;
  LOCAL OKC:="OK TO CONFIRM?";
  LOCAL MYWPM:=MAX(MIN(WPM,50),1);
  //LOCAL BAUD:=ROUND(0.83*MYWPM,0);//APPROX
  DOTT:=1.2/MYWPM;
 
  OK:=MSGBOX(MYWPM+" WPM"+NL+".="+DOTT+" s"+NL+OKC,1);
  IF OK THEN
   TS:=Time;
   ACT_TIME_SOS:={{"SOS"},AT(TS)};//MUST CONTAIN LIST
   CLS();
   TEXTOUT_P(TS,0,0);
   //INTERWORD GAP
   //SEPERATES , REPOSITION
   SIGOFF();
   OK:=WAIT(7*DOTT);
   REPEAT
    DIT(); DIT(); DIT(); //S
    DAH(); DAH(); DAH(); //O
    DIT(); DIT(); DIT(); //S
    OK:=WAIT(3*DOTT); //INTERLETTER GAP
   UNTIL GETKEY==4; 
  END;
 END;

 ASK_WPM()
 BEGIN
  LOCAL OK;
  LOCAL TTL:=WWPM(1);
  LOCAL LBL:="WPM";
  LOCAL HLP:="1..25 RECOMMENDED";
  OK:=INPUT(WPM,TTL,LBL,HLP,5,5);
  IF OK THEN
   WPM:=MAX(WPM,1);
  END;
 END;

HELP()
 BEGIN
  LOCAL CHS;
  //LOCAL HLPCHC:=CONCAT(CHOICES,{"VARIABLES"});
  LOCAL HLPCOLR:="Red light may help preserve night vision";
  LOCAL CNW:="Connectivity Not Working";
  LOCAL HLPVARS:="
ACT_TIME:
ACT_TIME_SOS:
 Activation time

WPM: "+WWPM(1)+"
 @Home:
 WPM:=n [n==1..25]";
 
  LOCAL SEL:={1,1,0,1,0,1,0};//SELECT CHOICES W HLP
  LOCAL SELCHOICES:=EXECON("IFTE(&2,&1,CHAR(0))",CHOICES,SEL);//SYN:DIDIER
  LOCAL HLPCHC:=CONCAT(SELCHOICES,{"VARIABLES"});

  REPEAT
   PRINT(); 
   CHOOSE(CHS,WABTHLP(1),HLPCHC);
   IF CHS THEN
    PRINT(HLPCHC(CHS));
    CASE
     IF CHS==1 THEN ABOUT(); WAIT END;
     IF CHS==2 THEN INFO(); WAIT END;
     IF CHS==4 THEN PRINT(HLPCOLR); WAIT END;
     IF CHS==6 THEN PRINT(CNW); WAIT END;
     IF CHS==8 THEN PRINT(HLPVARS); WAIT END;
     DEFAULT
     END;
    END;
   UNTIL CHS==0;
  WAIT;
 END;

 EXPORT Z_LIGHTS()
 BEGIN
  LOCAL CHS,OK;
  //SCRID();
  REPEAT
   OK:=CHOOSE(CHS,CRID,CHOICES);
   // PRINT("(DIAGNOSTIC) "+CHS);WAIT(3);
   //WORKAROUND BUG IN 11586 (ANDROID)

   //IN 8151 OK NOT REQUIRED: CHS RETURNS 0 ON ESCAPE
   //WORKAROUND:
   //IN TBD OK REQUIRED: CHS REPEATS PREVIOUS VALUE ON ESCAPE
   IF OK THEN //WORKAROUND
    CASE  
     IF CHS==1 THEN HELP()   END;
     IF CHS==2 THEN INFO()   END;
     IF CHS==3 THEN LIGHTSTEADY() END;
     IF CHS==4 THEN LIGHTCOLR()   END;
     IF CHS==5 THEN LIGHTBLINK()  END;
     IF CHS==6 THEN LIGHT_SOS()   END;
     IF CHS==7 THEN ASK_WPM()     END; 
     DEFAULT
    END;//CASE
   END;//IF
  UNTIL OK==0;//WORKAROUND

//FINALLY
//I HAD CONSIDERED A WAKEUP ALARM. BUT AUTO DIMMING OFSCREEN


 END;

(Some inner loops not yet fixed).
I now have a version in Python:
https://my.numworks.com/python/steveg1cmz
(just the torch/beacon, no morse code yet)
There are now two versions in Python:
torch (for platforms with keydown, like Numworks on Chromebook, or on an Android with an external keyboard) is preferred.
Or there's torchknob for the no-buttons version (for Numworks on Android, which lacks keydown).
Only the original HP PPL currently offers Morse code.
Reference URL's