Project - Digiclock

This project shows how to transform the time into a stylish digital clock.
First, a timely branch...

Reboot your ESP device, reconnect the Editor window, change the 'File to Run' name to '/program/digiclock.bas', then Save it.
Clear out previous editor contents, enter CLS on the first line, followed by HTML date$ on the next line, Save it, switch to Output and Run it.

If the date is current it means your ESP has Internet access and can reach an NTP Time Server to aquire the current date and time.
If the date shows  01/01/70  it means your ESP does NOT have internet access so is therefore stuck forever in 01/01/70  'Groundhog Day'.

For security sake, I choose to deliberately isolate my ESP wifi network from the Internet, so I am unable to sync time from an NTP time server.
I could access a local intranet time server on the same ESP wifi subnet by entering its address in the NTP Server window of Config Tab.
I could add a Real Time Clock (RTC) module to maintain independent time in isolation (will be dealt with in a subsequent chapter).
Or it is possible to use the 'Sync Time' button from the File Manager tab of the AnnexToolKit  (which will the require clicking the nearby 'Connect to ESP' button a couple of times to re-make the connection), but this needs to be done every time the device reboots back into Groundhog Day.
Another solution is to run the following javascript snippet supplied by CiccioCB which set's ESP time from the browser date and time, so is needed at the top of all scripts which need 'current date and time' (including our new digiclock - but I will omit it here for the sake of clarity).

set_date
wlog time$    'for debug purposes   
print time$    'for debug purposes  
end

sub set_date
local a$
a$ = ""
a$ = a$ + |function getdate() {|
a$ = a$ + |var x = new Date();|
a$ = a$ + |var d = x.getDate();|
a$ = a$ + |var m = x.getMonth();|
a$ = a$ + |var y = x.getFullYear() - 2000;|
a$ = a$ + |var h = x.getHours();|
a$ = a$ + |var mi= x.getMinutes();|
a$ = a$ + |var s = x.getSeconds();|
a$ = a$ + |var msg = "settime " + y + "," + m + "," + d + "," + h + "," + mi + "," + s;|
'a$ = a$ + |alert(msg);|
a$ = a$ + |connection.send("cmd:immediatx" + msg);|
a$ = a$ + |}|
jscript a$
jscall "getdate()"
end sub
'------------ End -------------


Timely diversion over, so now we can return back to the future...
The first thing to do is wrap our time$ in a 'self-centering' div:
cls
a$ = a$ + |<div style='display: table; margin-right: auto; margin-left: auto; text-align: center;'>|
a$ = a$ +  time$
a$ = a$ + |</div>|
html a$

When you Save and Run that, you will see it does indeed display the time - but the displayed time is just a frozen moment of history.
We need a timer mechanism for periodically displaying the current time$ in the div without flickering... achieved with a line of js from CiccioCB:
cls
a$ = a$ + |<div id='clock' style='display: table; margin-right: auto; margin-left: auto; text-align: center;'>|
a$ = a$ +  time$    
a$ = a$ + |</div>|
html a$
timer0 1000, clock   'jumps to refresh every second
wait

clock:
jscall "_$('clock').innerHTML = """ + time$ + """"        ' updates the digital display
return

Eureka... a working digital clock
  now we can improve it's looks to suit our preferences.
But before we get involved with style, notice how easy it would be to compare current time$ to an alarm time in the 'clock' subroutine if wished.
Or decrement any previously declared 'countdown' variables to use as longer term delayed 'timers' for appropriate action when 0 is reached.


A few simple guidelines to give us some direction to go in...
In order to 're-paint' our displayed output, we'll partition our script into a top setup section to set up everything with appropriate defaults, then call a paint subroutine whenever we wish to repaint the screen with something different - and we can add other subroutines as needed. This is similar to the Arduino setup() and loop() functions which will be familiar to many users - the main difference being that whereas the arduino loop is continuously polling through itself, our Annex Wifi Basic quietly 'waits' for an appropriate interrupt to cause it to branch and take some action when triggered.  In our case, the timer0 causes a branch to the clock subroutine every second to update the displayed time.
Our paint subroutine only gets called once for the moment, but subsequent versions will be using it to repaint the screen on demand.
The paint subroutine is essentially just our self-centering div opened out over several lines to more easily accommodate our style and id.

NOTE Size and Position units.
'px' (pixel) size is absolute because it is dictated by screen resolution and the number of pixels.
'em' (emphasize) is relative to the font size: 1em is equal to the current font size, 0.5em is half size, 2em is double size, etc.
(evidently the default browser text size is 16px, thus making the default size of 1em = 16px)
Specifying absolute screen size and position in px units may make a big difference on low res displays but little difference on high res screens.
Specifying relative screen size and position in em units should make the same relative difference on any displays.
So I prefer to use em to make the output scaleable for different sized device screens according to their displayed font sizes.

NOTE:  Quotes
There are 3 different types of quote marks that can be used in the correct circumstances, but they all must be used as a matched pair.
Therefore any literal string that is opened with one type of quote needs to be closed by the same type else the string remains open.
Any type quotes can be used inside any others, but not vice versa, because a single-quote is interpreted by Basic to start a line of comment.
As a general guideline it is safest to encapsulate the entire html line in unambiguous (|) vertical bars (as the HTML Converter does), then use (") double-quotes inside of vertical bars, then use (') single-quotes inside of double-quotes if needed.

Anything contained within quotes becomes a hard-coded unchanging literal string.
If you wish to insert a changeable Basic variable into the literal string, you need to chop the string into 2 completely self-contained literal strings at the insertion point, add in your variable$, then append all 3 lumps back together again (as shown in the code above). 

NOTE: Any numeric variables must first be converted to ascii text strings before being included into the html text.

TIP: rather than hard code specific values into multiple locations in the script, better to define such values to a variable at the beginning of the script, then we can keep re-using the same variable name wherever and whenever needed, and just re-assign it different values as wished.

This project appends many different style statements to a variable called mystyle$ then uses that single var in the div style declaration.
You should be able to see how you can easily include other style variables if you wish (perhaps line-height % or box-shadow ). 

Enter a colour into fontgrad$ variable to get a background gradient (like below), which use the fontbak$ colour for the first gradient colour.
If the gradient doesn't appear, refer back to the browser compatibility comments at the start of Chapter 1, and either add the appropriate hoops to jump through to make it work for your specific browser, or download and use the Firefox freebie.  
Have fun experimenting with different style sizes and colours  (for colour names see:  https://www.w3schools.com/cssref/css_colors.asp )

 

Basic:
'Digiclock
fontsize$ = "4"                   'font size (in em)
fontcol$ = "black"               'font colour
fontbak$ = "white"              'font background colour
fontgrad$ = ""                     '2nd value for gradient if present - else use "" for solid fontbak$ background colour
if fontgrad$ <> "" then fontbak$ = "linear-gradient(" + fontbak$ + "," + fontgrad$ + ");"   'may need different syntax for your browser see:  https://www.w3schools.com/css/css3_gradients.asp
fontstyle$ = "normal"          'font style - normal,italic,oblique
fontweight$ = "normal"       'font weight - normal,bold
fontpad$ = "1.5"                  'font padding (in em)
bordsize$ = "1"                   'border thickness (in em)
bordrad$ = "4"                    'border corner radius (in em - dependent on border thickness
bordcol$ = "grey"                'border colour
y = 2                                   'div top position in em, so is dependent on font size
mystyle$ = "position:relative; top:" + str$(y) + "em;"
mystyle$ = mystyle$ + "font-size:" + fontsize$ + "em;"
mystyle$ = mystyle$ + "font-style:" + fontstyle$ + ";"
mystyle$ = mystyle$ + "font-weight:" + fontweight$ + ";"
mystyle$ = mystyle$ + "color:" + fontcol$ + ";"
mystyle$ = mystyle$ + "background:" + fontbak$ + ";"
mystyle$ = mystyle$ + "padding:." + fontpad$ + "em;"
mystyle$ = mystyle$ + "border:." + bordsize$ + "em solid " + bordcol$ + ";"
mystyle$ = mystyle$ + "border-radius:." + bordrad$ + "em;"
gosub paint
timer0 1000, clock   'jumps to refresh every second
wait

clock:
jscall "_$('clock').innerHTML = """ + time$ + """"        ' updates the digital display
return

paint:
cls
a$ = a$ + |<div id='clock' style='display: table; margin-right:auto;margin-left:auto;text-align:center;|
a$ = a$ + mystyle$
a$ = a$ + |'>|
a$ = a$ +  time$   
a$ = a$ + |</div>|
html a$
a$ = ""
return
---------- End -----------