mirror of https://github.com/espruino/BangleApps
Solar Clock: Added comments
parent
36772a6fa7
commit
c169d42455
|
@ -1,3 +1,12 @@
|
|||
/**
|
||||
* Adrian Kirk 2021-07
|
||||
*
|
||||
* Solar Clock
|
||||
*
|
||||
* Using your current or chosen location the solar watch face shows the Sun's sky position,
|
||||
* time and date. Also allows you to wind backwards and forwards in time to see the sun's position
|
||||
**/
|
||||
|
||||
const DateUtils = require("solar_date_utils.js");
|
||||
const Math2 = require("solar_math_utils.js");
|
||||
const GraphicUtils = require("solar_graphic_utils.js");
|
||||
|
@ -5,6 +14,11 @@ const Colors = require("solar_colors.js");
|
|||
const LocationUtils = require("solar_location.js");
|
||||
const Locale = require('locale');
|
||||
|
||||
/**
|
||||
* The screen info data structure stores all of the
|
||||
* relevant screen information, such as the sun's position
|
||||
* where the sunrise line is, etc
|
||||
*/
|
||||
var screen_info = {
|
||||
screen_width : g.getWidth(),
|
||||
screen_start_x : 0,
|
||||
|
@ -18,10 +32,16 @@ var screen_info = {
|
|||
sun_y : null,
|
||||
sunrise_y : null,
|
||||
}
|
||||
// we set up the image buffer with which we draw the sun with
|
||||
const img_width=40;
|
||||
const img_height=30;
|
||||
var img_buffer = Graphics.createArrayBuffer(img_width,img_height,8);
|
||||
var img = {width:img_width,height:img_height,bpp:8,transparent:0,buffer:img_buffer.buffer};
|
||||
/**
|
||||
* We use an image buffer to do the sun animation.
|
||||
* We pass around the img_info structure with the
|
||||
* image buffer data
|
||||
*/
|
||||
var img_info = {
|
||||
x: null,
|
||||
y: null,
|
||||
|
@ -36,6 +56,9 @@ var curr_mode = null;
|
|||
var last_sun_draw_time = null;
|
||||
var draw_full_cosine = true;
|
||||
|
||||
// The draw sun function is responsible for
|
||||
// drawing the whole sun animation which includes the
|
||||
// sun, the cosine curve and the sunrise line.
|
||||
function draw_sun(now, day_info) {
|
||||
|
||||
var now_fraction = (now.getTime() - day_info.day_start.getTime())/DateUtils.DAY_MILLIS;
|
||||
|
@ -110,6 +133,8 @@ function draw_sun(now, day_info) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// clear sun is called when there is a large change in the sun's
|
||||
// location, such as location change.
|
||||
function clear_sun(){
|
||||
if(img_info.x != null && img_info.y != null) {
|
||||
GraphicUtils.set_color(screen_info.screen_bg_color);
|
||||
|
@ -153,10 +178,14 @@ function write_date(now){
|
|||
}
|
||||
}
|
||||
|
||||
// The info panels mid way down the screen on the left and right
|
||||
const INFO_PANEL_LINE_Y1 = 90;
|
||||
const INFO_PANEL_LINE_Y2 = 105;
|
||||
var gps_status_requires_update = true;
|
||||
|
||||
// The GPS status panel shows the status of the GPS
|
||||
// when the location is know it shows the
|
||||
// longitude and latitude.
|
||||
function write_GPS_status(){
|
||||
if(!gps_status_requires_update)
|
||||
return;
|
||||
|
@ -198,6 +227,8 @@ const TWILIGHT_X_COORD = 200;
|
|||
const NO_TIME = "--:--";
|
||||
|
||||
var twilight_times_requires_update = true;
|
||||
// The right panel shows the sun rise and sunset times.
|
||||
// we make provision for when there is no times available
|
||||
function write_twilight_times(){
|
||||
if(!twilight_times_requires_update)
|
||||
return;
|
||||
|
@ -314,8 +345,10 @@ location.addUpdateListener(
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
// day info is responsible for populating the day_info structure
|
||||
// The day_info structure holds the sun set and sunset times
|
||||
// The function also has to detect when the end of the solar
|
||||
// day has been reached and flip the day over.
|
||||
function dayInfo(now) {
|
||||
if (day_info == null || now > day_info.day_end) {
|
||||
var coords = location.getCoordinates();
|
||||
|
@ -342,7 +375,8 @@ function time_now() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// The main loop called everytime we want to refresh the
|
||||
// clock
|
||||
function draw_clock(){
|
||||
var start_time = Date.now();
|
||||
var now = time_now();
|
||||
|
@ -370,6 +404,11 @@ function log_memory_used() {
|
|||
);
|
||||
}
|
||||
|
||||
// Button has a short press action of resetting the offet
|
||||
// and a long press set the GPS up for refreshing the current
|
||||
// position.
|
||||
// To accomodate the long and short press we record when the press
|
||||
// starts and time to when it is released
|
||||
var button1pressStart = null;
|
||||
function button1pressed(){
|
||||
if(button1pressStart == null) {
|
||||
|
@ -377,6 +416,8 @@ function button1pressed(){
|
|||
}
|
||||
//console.log("button 1 pressed for:" + (Date.now() - button1pressStart));
|
||||
if(BTN1.read()){
|
||||
// we look every 100 ms to see if the button is still pressed
|
||||
// (to makes the button responsive)
|
||||
setTimeout(button1pressed,100);
|
||||
} else {
|
||||
var buttonPressTime = Date.now() - button1pressStart;
|
||||
|
@ -396,12 +437,18 @@ function button1pressed(){
|
|||
}
|
||||
}
|
||||
|
||||
// button 3 kicks off a the change to the next location
|
||||
function button3pressed() {
|
||||
console.log("button 3 pressed");
|
||||
time_offset = 0;
|
||||
location.nextLocation();
|
||||
}
|
||||
|
||||
// button 4 moves the offset back
|
||||
// keeping the button pressed repeats
|
||||
// to give the sun the continuous animation
|
||||
// to achieve this we put in a call back
|
||||
// to see if its still presses after 50 ms.
|
||||
function button4pressed(){
|
||||
time_offset -= DateUtils.HOUR_MILLIS/4;
|
||||
draw_clock();
|
||||
|
@ -414,6 +461,11 @@ function button4pressed(){
|
|||
)
|
||||
}
|
||||
|
||||
// button 5 moves the offset forward
|
||||
// keeping the button pressed repeats
|
||||
// to give the sun the continuous animation
|
||||
// to achieve this we put in a call back
|
||||
// to see if its still presses after 50 ms.
|
||||
function button5pressed(){
|
||||
time_offset += DateUtils.HOUR_MILLIS/4;
|
||||
draw_clock();
|
||||
|
@ -485,6 +537,12 @@ Bangle.drawWidgets();
|
|||
|
||||
start_timers();
|
||||
|
||||
// When button 2 is pressed we return to the
|
||||
// launcher. We run through a shutdown sequence
|
||||
// we shutdown the location object, which
|
||||
// shut down the GPS (if running)
|
||||
// we deference the location and controller to
|
||||
// to free up memory before the jump is made.
|
||||
function button2pressed(){
|
||||
controller = null;
|
||||
|
||||
|
@ -494,6 +552,7 @@ function button2pressed(){
|
|||
Bangle.showLauncher();
|
||||
}
|
||||
setWatch(button2pressed, BTN2,{repeat:false,edge:"falling"});
|
||||
// we are timing button 1 so we put a callback in the the rising edge.
|
||||
setWatch(button1pressed, BTN1,{repeat:true,edge:"rising"});
|
||||
setWatch(button3pressed, BTN3,{repeat:true,edge:"falling"});
|
||||
setWatch(button4pressed, BTN4,{repeat:true,edge:"rising"});
|
||||
|
|
|
@ -75,6 +75,7 @@ function draw_partial_sun(time, day_info, screen_info,img_info){
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
function draw_random_background(screen_info,
|
||||
img_info,
|
||||
rgb_init,
|
||||
|
@ -106,6 +107,13 @@ function draw_random_background(screen_info,
|
|||
screen_info.sun_y - draw_info.offset_y,
|
||||
screen_info.sun_radius+1);
|
||||
}
|
||||
|
||||
/**
|
||||
* SolarControllerImpl to SolarMode is a Strategy pattern.
|
||||
* The sun animation is very different through the different
|
||||
* sectors of the day so the correct strategy is selected
|
||||
* for the day sector
|
||||
*/
|
||||
class SolarMode {
|
||||
test(time, day_info, screen_info){ throw "test undefined";}
|
||||
draw(time, day_info, screen_info, img_buffer_info){
|
||||
|
@ -136,6 +144,7 @@ class DayLightMode extends SolarMode {
|
|||
time > day_info.sunrise_date &&
|
||||
sun_height >= screen_info.sun_radius * 2 + SUNSET_START_HEIGHT;
|
||||
}
|
||||
// The corona is larger the closer you are to solar noon
|
||||
_calc_corona_radius(now, day_info){
|
||||
if(now < day_info.sunset_date &&
|
||||
now > day_info.sunrise_date){
|
||||
|
@ -227,18 +236,25 @@ class SolarControllerImpl {
|
|||
toString(){
|
||||
return "SolarControllerImpl";
|
||||
}
|
||||
// The mode method is responsible for selecting the
|
||||
// correct mode to the time given.
|
||||
mode(time, day_info, screen_info){
|
||||
// first we test the last selection
|
||||
// to see if its still valid
|
||||
if(this.last != null){
|
||||
if(this.last.test(time,day_info,screen_info)){
|
||||
return this.last;
|
||||
}
|
||||
}
|
||||
// next we step through the different modes and test then
|
||||
// one by one.
|
||||
for(var i=0; i<this.solar_modes.length; i++){
|
||||
if(this.solar_modes[i].test(time,day_info,screen_info) ){
|
||||
this.last = this.solar_modes[i];
|
||||
return this.last;
|
||||
}
|
||||
}
|
||||
// Otherwise we use the default
|
||||
//console.log("defaulting");
|
||||
this.last = this.default_mode;
|
||||
return this.last;
|
||||
|
|
|
@ -36,6 +36,8 @@ const DateUtils = {
|
|||
DAY_MILLIS : _DAY_MILLIS,
|
||||
HOUR_MILLIS : _HOUR_MILLIS,
|
||||
MIN_MILLIS: _MIN_MILLIS,
|
||||
// calculate the sunrise and sunset information using the NOAA
|
||||
// equations.
|
||||
sunrise_sunset: (now,longitude,latitude, utc_offset)=>{
|
||||
|
||||
var sod_julian = _start_of_julian_day(now);
|
||||
|
|
|
@ -31,7 +31,7 @@ const GraphicUtils = {
|
|||
|
||||
draw_info.buff.reset();
|
||||
draw_info.buff.setColor(line_colour[0],line_colour[1],line_colour[2]);
|
||||
first = true;
|
||||
var first = true;
|
||||
for(var x=from_x; x<to_x;x++){
|
||||
var radians = Math2.TWO_PI *((x-screen_info.screen_start_x) - screen_info.screen_centre_x)/(screen_info.screen_width);
|
||||
var y = screen_info.screen_centre_y - screen_info.screen_height * Math.cos(radians)/2;
|
||||
|
|
Loading…
Reference in New Issue