Merge branch 'master' into unlibrify-message-widgets

pull/2376/head
Gordon Williams 2022-12-09 10:34:38 +00:00 committed by GitHub
commit cd785f34aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 632 additions and 913 deletions

View File

@ -1,2 +1,3 @@
0.01: Create astrocalc app
0.02: Store last GPS lock, can be used instead of waiting for new GPS on start
0.03: Use 'modules/suncalc.js' to avoid it being copied 8 times for different apps

View File

@ -9,7 +9,7 @@
* Calculate the Sun and Moon positions based on watch GPS and display graphically
*/
const SunCalc = require("suncalc.js");
const SunCalc = require("suncalc"); // from modules folder
const storage = require("Storage");
const LAST_GPS_FILE = "astrocalc.gps.json";
let lastGPS = (storage.readJSON(LAST_GPS_FILE, 1) || null);

View File

@ -1,7 +1,7 @@
{
"id": "astrocalc",
"name": "Astrocalc",
"version": "0.02",
"version": "0.03",
"description": "Calculates interesting information on the sun and moon cycles for the current day based on your location.",
"icon": "astrocalc.png",
"tags": "app,sun,moon,cycles,tool,outdoors",
@ -9,7 +9,6 @@
"allow_emulator": true,
"storage": [
{"name":"astrocalc.app.js","url":"astrocalc-app.js"},
{"name":"suncalc.js","url":"suncalc.js"},
{"name":"astrocalc.img","url":"astrocalc-icon.js","evaluate":true},
{"name":"first-quarter.img","url":"first-quarter-icon.js","evaluate":true},
{"name":"last-quarter.img","url":"last-quarter-icon.js","evaluate":true},

View File

@ -1,328 +0,0 @@
/*
(c) 2011-2015, Vladimir Agafonkin
SunCalc is a JavaScript library for calculating sun/moon position and light phases.
https://github.com/mourner/suncalc
*/
(function () { 'use strict';
// shortcuts for easier to read formulas
var PI = Math.PI,
sin = Math.sin,
cos = Math.cos,
tan = Math.tan,
asin = Math.asin,
atan = Math.atan2,
acos = Math.acos,
rad = PI / 180;
// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
// date/time constants and conversions
var dayMs = 1000 * 60 * 60 * 24,
J1970 = 2440588,
J2000 = 2451545;
function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
function fromJulian(j) { return (j + 0.5 - J1970) * dayMs; }
function toDays(date) { return toJulian(date) - J2000; }
// general calculations for position
var e = rad * 23.4397; // obliquity of the Earth
function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }
function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }
function azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }
function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }
function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }
function astroRefraction(h) {
if (h < 0) // the following formula works for positive altitudes only.
h = 0; // if h = -0.08901179 a div/0 would occur.
// formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
// 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad:
return 0.0002967 / Math.tan(h + 0.00312536 / (h + 0.08901179));
}
// general sun calculations
function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }
function eclipticLongitude(M) {
var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
P = rad * 102.9372; // perihelion of the Earth
return M + C + P + PI;
}
function sunCoords(d) {
var M = solarMeanAnomaly(d),
L = eclipticLongitude(M);
return {
dec: declination(L, 0),
ra: rightAscension(L, 0)
};
}
var SunCalc = {};
// calculates sun position for a given date and latitude/longitude
SunCalc.getPosition = function (date, lat, lng) {
var lw = rad * -lng,
phi = rad * lat,
d = toDays(date),
c = sunCoords(d),
H = siderealTime(d, lw) - c.ra;
return {
azimuth: azimuth(H, phi, c.dec),
altitude: altitude(H, phi, c.dec)
};
};
// sun times configuration (angle, morning name, evening name)
var times = SunCalc.times = [
[-0.833, 'sunrise', 'sunset' ],
[ -0.3, 'sunriseEnd', 'sunsetStart' ],
[ -6, 'dawn', 'dusk' ],
[ -12, 'nauticalDawn', 'nauticalDusk'],
[ -18, 'nightEnd', 'night' ],
[ 6, 'goldenHourEnd', 'goldenHour' ]
];
// adds a custom time to the times config
SunCalc.addTime = function (angle, riseName, setName) {
times.push([angle, riseName, setName]);
};
// calculations for sun times
var J0 = 0.0009;
function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); }
function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; }
function solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); }
function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); }
function observerAngle(height) { return -2.076 * Math.sqrt(height) / 60; }
// returns set time for the given sun altitude
function getSetJ(h, lw, phi, dec, n, M, L) {
var w = hourAngle(h, phi, dec),
a = approxTransit(w, lw, n);
return solarTransitJ(a, M, L);
}
// calculates sun times for a given date, latitude/longitude, and, optionally,
// the observer height (in meters) relative to the horizon
SunCalc.getTimes = function (date, lat, lng, height) {
height = height || 0;
var lw = rad * -lng,
phi = rad * lat,
dh = observerAngle(height),
d = toDays(date),
n = julianCycle(d, lw),
ds = approxTransit(0, lw, n),
M = solarMeanAnomaly(ds),
L = eclipticLongitude(M),
dec = declination(L, 0),
Jnoon = solarTransitJ(ds, M, L),
i, len, time, h0, Jset, Jrise;
var result = {
solarNoon: new Date(fromJulian(Jnoon)),
nadir: new Date(fromJulian(Jnoon - 0.5))
};
for (i = 0, len = times.length; i < len; i += 1) {
time = times[i];
h0 = (time[0] + dh) * rad;
Jset = getSetJ(h0, lw, phi, dec, n, M, L);
Jrise = Jnoon - (Jset - Jnoon);
result[time[1]] = new Date(fromJulian(Jrise) - (dayMs / 2));
result[time[2]] = new Date(fromJulian(Jset) + (dayMs / 2));
}
return result;
};
// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas
function moonCoords(d) { // geocentric ecliptic coordinates of the moon
var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude
M = rad * (134.963 + 13.064993 * d), // mean anomaly
F = rad * (93.272 + 13.229350 * d), // mean distance
l = L + rad * 6.289 * sin(M), // longitude
b = rad * 5.128 * sin(F), // latitude
dt = 385001 - 20905 * cos(M); // distance to the moon in km
return {
ra: rightAscension(l, b),
dec: declination(l, b),
dist: dt
};
}
SunCalc.getMoonPosition = function (date, lat, lng) {
var lw = rad * -lng,
phi = rad * lat,
d = toDays(date),
c = moonCoords(d),
H = siderealTime(d, lw) - c.ra,
h = altitude(H, phi, c.dec),
// formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
pa = atan(sin(H), tan(phi) * cos(c.dec) - sin(c.dec) * cos(H));
h = h + astroRefraction(h); // altitude correction for refraction
return {
azimuth: azimuth(H, phi, c.dec),
altitude: h,
distance: c.dist,
parallacticAngle: pa
};
};
// calculations for illumination parameters of the moon,
// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and
// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
// Function updated from gist: https://gist.github.com/endel/dfe6bb2fbe679781948c
SunCalc.getMoonIllumination = function (date) {
let month = date.getMonth();
let year = date.getFullYear();
let day = date.getDate();
let c = 0;
let e = 0;
let jd = 0;
let b = 0;
if (month < 3) {
year--;
month += 12;
}
++month;
c = 365.25 * year;
e = 30.6 * month;
jd = c + e + day - 694039.09; // jd is total days elapsed
jd /= 29.5305882; // divide by the moon cycle
b = parseInt(jd); // int(jd) -> b, take integer part of jd
jd -= b; // subtract integer part to leave fractional part of original jd
b = Math.round(jd * 8); // scale fraction from 0-8 and round
if (b >= 8) b = 0; // 0 and 8 are the same so turn 8 into 0
return {phase: b};
};
function hoursLater(date, h) {
return new Date(date.valueOf() + h * dayMs / 24);
}
// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article
SunCalc.getMoonTimes = function (date, lat, lng, inUTC) {
var t = date;
if (inUTC) t.setUTCHours(0, 0, 0, 0);
else t.setHours(0, 0, 0, 0);
var hc = 0.133 * rad,
h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc,
h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx;
// go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)
for (var i = 1; i <= 24; i += 2) {
h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc;
h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc;
a = (h0 + h2) / 2 - h1;
b = (h2 - h0) / 2;
xe = -b / (2 * a);
ye = (a * xe + b) * xe + h1;
d = b * b - 4 * a * h1;
roots = 0;
if (d >= 0) {
dx = Math.sqrt(d) / (Math.abs(a) * 2);
x1 = xe - dx;
x2 = xe + dx;
if (Math.abs(x1) <= 1) roots++;
if (Math.abs(x2) <= 1) roots++;
if (x1 < -1) x1 = x2;
}
if (roots === 1) {
if (h0 < 0) rise = i + x1;
else set = i + x1;
} else if (roots === 2) {
rise = i + (ye < 0 ? x2 : x1);
set = i + (ye < 0 ? x1 : x2);
}
if (rise && set) break;
h0 = h2;
}
var result = {};
if (rise) result.rise = hoursLater(t, rise);
if (set) result.set = hoursLater(t, set);
if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true;
return result;
};
// export as Node module / AMD module / browser variable
if (typeof exports === 'object' && typeof module !== 'undefined') module.exports = SunCalc;
else if (typeof define === 'function' && define.amd) define(SunCalc);
else global.SunCalc = SunCalc;
}());

View File

@ -1 +1,3 @@
0.01: New App!
0.02: Use 'modules/suncalc.js' to avoid it being copied 8 times for different apps
Add a 'time' clockinfo that also displays a percentage of day left

View File

@ -1,32 +1,68 @@
(function() {
// get today's sunlight times for lat/lon
var sunrise, sunset;
var sunrise, sunset, date;
var SunCalc = require("suncalc"); // from modules folder
const locale = require("locale");
function calculate() {
var SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js");
const locale = require("locale");
var location = require("Storage").readJSON("mylocation.json",1)||{};
location.lat = location.lat||51.5072;
location.lon = location.lon||0.1276;
location.location = location.location||"London";
var times = SunCalc.getTimes(new Date(), location.lat, location.lon);
sunrise = locale.time(times.sunrise,1);
sunset = locale.time(times.sunset,1);
location.lon = location.lon||0.1276; // London
date = new Date(Date.now());
var times = SunCalc.getTimes(date, location.lat, location.lon);
sunrise = times.sunrise;
sunset = times.sunset;
/* do we want to re-calculate this every day? Or we just assume
that 'show' will get called once a day? */
}
function show() {
this.interval = setTimeout(()=>{
this.emit("redraw");
this.interval = setInterval(()=>{
this.emit("redraw");
}, 60000);
}, 60000 - (Date.now() % 60000));
}
function hide() {
clearInterval(this.interval);
this.interval = undefined;
}
return {
name: "Bangle",
items: [
{ name : "Sunrise",
get : () => ({ text : sunrise,
img : atob("GBiBAAAAAAAAAAAAAAAYAAA8AAB+AAD/AAAAAAAAAAAAAAAYAAAYAAQYIA4AcAYAYAA8AAB+AAD/AAH/gD///D///AAAAAAAAAAAAA==") }),
show : calculate, hide : () => {}
get : () => { calculate();
return { text : locale.time(sunrise,1),
img : atob("GBiBAAAAAAAAAAAAAAAYAAA8AAB+AAD/AAAAAAAAAAAAAAAYAAAYAAQYIA4AcAYAYAA8AAB+AAD/AAH/gD///D///AAAAAAAAAAAAA==") }},
show : show, hide : hide
}, { name : "Sunset",
get : () => ({ text : sunset,
img : atob("GBiBAAAAAAAAAAAAAAB+AAA8AAAYAAAYAAAAAAAAAAAAAAAYAAAYAAQYIA4AcAYAYAA8AAB+AAD/AAH/gD///D///AAAAAAAAAAAAA==") }),
show : calculate, hide : () => {}
get : () => { calculate();
return { text : locale.time(sunset,1),
img : atob("GBiBAAAAAAAAAAAAAAB+AAA8AAAYAAAYAAAAAAAAAAAAAAAYAAAYAAQYIA4AcAYAYAA8AAB+AAD/AAH/gD///D///AAAAAAAAAAAAA==") }},
show : show, hide : hide
}, { name : "Time", // Time in day (uses v/min/max to show percentage through day)
get : () => {
calculate();
let day = true;
let v = 0;
let d = date.getTime();
let dayLength = sunset.getTime()-sunrise.getTime();
if (d < sunrise.getTime()) {
day = false; // early morning
v = 100 - Math.round(100 * (sunrise.getTime()-d) / (86400000-dayLength));
} else if (d > sunset.getTime()) {
day = false; // evening
v = Math.round(100 * (d-sunset.getTime()) / (86400000-dayLength));
} else { // day!
v = Math.round(100 * (d-sunrise.getTime()) / dayLength);
}
return { text : locale.time(date,1), v : v, min : 0, max : 100,
img : day ? atob("GBiBAAAYAAAYAAAYAAgAEBwAOAx+MAD/AAH/gAP/wAf/4Af/4Of/5+f/5wf/4Af/4AP/wAH/gAD/AAx+MBwAOAgAEAAYAAAYAAAYAA==") : atob("GBiBAAfwAA/8AAP/AAH/gAD/wAB/wAB/4AA/8AA/8AA/8AAf8AAf8AAf8AAf8AA/8AA/8AA/4AB/4AB/wAD/wAH/gAf/AA/8AAfwAA==")
}
},
show : show, hide : hide
}
]
};

View File

@ -1,6 +1,6 @@
{ "id": "clkinfosunrise",
"name": "Sunrise Clockinfo",
"version":"0.01",
"version":"0.02",
"description": "For clocks that display 'clockinfo' (messages that can be cycled through using the clock_info module) this displays sunrise and sunset based on the location from the 'My Location' app",
"icon": "app.png",
"type": "clkinfo",

View File

@ -6,3 +6,4 @@
0.06: better contrast for light theme, use fg color instead of dithered for ring
0.07: Use default Bangle formatter for booleans
0.08: fix idle timer always getting set to true
0.09: Use 'modules/suncalc.js' to avoid it being copied 8 times for different apps

View File

@ -1,4 +1,4 @@
var SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js");
var SunCalc = require("suncalc"); // from modules folder
const storage = require('Storage');
const locale = require("locale");
const SETTINGS_FILE = "daisy.json";

View File

@ -1,6 +1,6 @@
{ "id": "daisy",
"name": "Daisy",
"version":"0.08",
"version":"0.09",
"dependencies": {"mylocation":"app"},
"description": "A beautiful digital clock with large ring guage, idle timer and a cyclic information line that includes, day, date, steps, battery, sunrise and sunset times",
"icon": "app.png",

View File

@ -11,7 +11,8 @@
"custom": "custom.html",
"storage": [
{"name":"espruinoprog.app.js","url":"app.js"},
{"name":"espruinoprog.img","url":"app-icon.js","evaluate":true},
{"name":"espruinoprog.img","url":"app-icon.js","evaluate":true}
], "data": [
{"name":"espruinoprog.json"}
]
}

View File

@ -11,7 +11,8 @@
"storage": [
{"name":"hourstrike.app.js","url":"app.js"},
{"name":"hourstrike.boot.js","url":"boot.js"},
{"name":"hourstrike.img","url":"app-icon.js","evaluate":true},
{"name":"hourstrike.img","url":"app-icon.js","evaluate":true}
], "data" : [
{"name":"hourstrike.json","url":"hourstrike.json"}
]
}

View File

@ -12,3 +12,4 @@
0.26: BJS2: Swipe down to rotate 180 degree
0.27: BJS2: Changed swipe down to swipe up
0.28: Reverted changes to implementation of 0.25
0.29: Use 'modules/suncalc.js' to avoid it being copied 8 times for different apps

View File

@ -46,7 +46,7 @@ var offsets = require("Storage").readJSON("hworldclock.settings.json") || [];
//=======Sun
setting = require("Storage").readJSON("setting.json",1);
E.setTimeZone(setting.timezone); // timezone = 1 for MEZ, = 2 for MESZ
SunCalc = require("hsuncalc.js");
SunCalc = require("suncalc"); // from modules folder
const LOCATION_FILE = "mylocation.json";
var rise = "read";
var set = "...";
@ -141,11 +141,9 @@ function getCurrentTimeFromOffset(dt, offset) {
function updatePos() {
coord = require("Storage").readJSON(LOCATION_FILE,1)|| {"lat":0,"lon":0,"location":"-"}; //{"lat":53.3,"lon":10.1,"location":"Pattensen"};
if (coord.lat != 0 && coord.lon != 0) {
//pos = SunCalc.getPosition(Date.now(), coord.lat, coord.lon);
times = SunCalc.getTimes(Date.now(), coord.lat, coord.lon);
rise = "^" + times.sunrise.toString().split(" ")[4].substr(0,5);
set = "v" + times.sunset.toString().split(" ")[4].substr(0,5);
//noonpos = SunCalc.getPosition(times.solarNoon, coord.lat, coord.lon);
} else {
rise = null;
set = null;

View File

@ -1,298 +0,0 @@
/* Module suncalc.js
(c) 2011-2015, Vladimir Agafonkin
SunCalc is a JavaScript library for calculating sun/moon position and light phases.
https://github.com/mourner/suncalc
PB: Usage:
E.setTimeZone(2); // 1 = MEZ, 2 = MESZ
SunCalc = require("suncalc.js");
pos = SunCalc.getPosition(Date.now(), 53.3, 10.1);
times = SunCalc.getTimes(Date.now(), 53.3, 10.1);
rise = times.sunrise; // Date object
rise_str = rise.getHours() + ':' + rise.getMinutes(); //hh:mm
*/
var exports={};
// shortcuts for easier to read formulas
var PI = Math.PI,
sin = Math.sin,
cos = Math.cos,
tan = Math.tan,
asin = Math.asin,
atan = Math.atan2,
acos = Math.acos,
rad = PI / 180;
// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
// date/time constants and conversions
var dayMs = 1000 * 60 * 60 * 24,
J1970 = 2440588,
J2000 = 2451545;
function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
function fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); } // PB: onece removed + 0.5; included it again 4 Jan 2021
function toDays(date) { return toJulian(date) - J2000; }
// general calculations for position
var e = rad * 23.4397; // obliquity of the Earth
function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }
function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }
function azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }
function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }
function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }
function astroRefraction(h) {
if (h < 0) // the following formula works for positive altitudes only.
h = 0; // if h = -0.08901179 a div/0 would occur.
// formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
// 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad:
return 0.0002967 / Math.tan(h + 0.00312536 / (h + 0.08901179));
}
// general sun calculations
function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }
function eclipticLongitude(M) {
var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
P = rad * 102.9372; // perihelion of the Earth
return M + C + P + PI;
}
function sunCoords(d) {
var M = solarMeanAnomaly(d),
L = eclipticLongitude(M);
return {
dec: declination(L, 0),
ra: rightAscension(L, 0)
};
}
// calculates sun position for a given date and latitude/longitude
exports.getPosition = function (date, lat, lng) {
var lw = rad * -lng,
phi = rad * lat,
d = toDays(date),
c = sunCoords(d),
H = siderealTime(d, lw) - c.ra;
return {
azimuth: Math.round((azimuth(H, phi, c.dec) / rad + 180) % 360), // PB: converted to deg
altitude: Math.round( altitude(H, phi, c.dec) / rad) // PB: converted to deg
};
};
// sun times configuration (angle, morning name, evening name)
var times = [
[-0.833, 'sunrise', 'sunset' ]
];
// calculations for sun times
var J0 = 0.0009;
function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); }
function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; }
function solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); }
function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); }
function observerAngle(height) { return -2.076 * Math.sqrt(height) / 60; }
// returns set time for the given sun altitude
function getSetJ(h, lw, phi, dec, n, M, L) {
var w = hourAngle(h, phi, dec),
a = approxTransit(w, lw, n);
return solarTransitJ(a, M, L);
}
// calculates sun times for a given date, latitude/longitude, and, optionally,
// the observer height (in meters) relative to the horizon
exports.getTimes = function (date, lat, lng, height) {
height = height || 0;
var lw = rad * -lng,
phi = rad * lat,
dh = observerAngle(height),
d = toDays(date),
n = julianCycle(d, lw),
ds = approxTransit(0, lw, n),
M = solarMeanAnomaly(ds),
L = eclipticLongitude(M),
dec = declination(L, 0),
Jnoon = solarTransitJ(ds, M, L),
i, len, time, h0, Jset, Jrise;
var result = {
solarNoon: fromJulian(Jnoon),
nadir: fromJulian(Jnoon - 0.5)
};
for (i = 0, len = times.length; i < len; i += 1) {
time = times[i];
h0 = (time[0] + dh) * rad;
Jset = getSetJ(h0, lw, phi, dec, n, M, L);
Jrise = Jnoon - (Jset - Jnoon);
result[time[1]] = fromJulian(Jrise);
result[time[2]] = fromJulian(Jset);
}
return result;
};
// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas
function moonCoords(d) { // geocentric ecliptic coordinates of the moon
var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude
M = rad * (134.963 + 13.064993 * d), // mean anomaly
F = rad * (93.272 + 13.229350 * d), // mean distance
l = L + rad * 6.289 * sin(M), // longitude
b = rad * 5.128 * sin(F), // latitude
dt = 385001 - 20905 * cos(M); // distance to the moon in km
return {
ra: rightAscension(l, b),
dec: declination(l, b),
dist: dt
};
}
getMoonPosition = function (date, lat, lng) {
var lw = rad * -lng,
phi = rad * lat,
d = toDays(date),
c = moonCoords(d),
H = siderealTime(d, lw) - c.ra,
h = altitude(H, phi, c.dec),
// formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
pa = atan(sin(H), tan(phi) * cos(c.dec) - sin(c.dec) * cos(H));
h = h + astroRefraction(h); // altitude correction for refraction
return {
azimuth: azimuth(H, phi, c.dec),
altitude: h,
distance: c.dist,
parallacticAngle: pa
};
};
// calculations for illumination parameters of the moon,
// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and
// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
getMoonIllumination = function (date) {
var d = toDays(date || new Date()),
s = sunCoords(d),
m = moonCoords(d),
sdist = 149598000, // distance from Earth to Sun in km
phi = acos(sin(s.dec) * sin(m.dec) + cos(s.dec) * cos(m.dec) * cos(s.ra - m.ra)),
inc = atan(sdist * sin(phi), m.dist - sdist * cos(phi)),
angle = atan(cos(s.dec) * sin(s.ra - m.ra), sin(s.dec) * cos(m.dec) -
cos(s.dec) * sin(m.dec) * cos(s.ra - m.ra));
return {
fraction: (1 + cos(inc)) / 2,
phase: 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI,
angle: angle
};
};
function hoursLater(date, h) {
return new Date(date.valueOf() + h * dayMs / 24);
}
// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article
getMoonTimes = function (date, lat, lng, inUTC) {
var t = new Date(date);
if (inUTC) t.setUTCHours(0, 0, 0, 0);
else t.setHours(0, 0, 0, 0);
var hc = 0.133 * rad,
h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc,
h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx;
// go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)
for (var i = 1; i <= 24; i += 2) {
h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc;
h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc;
a = (h0 + h2) / 2 - h1;
b = (h2 - h0) / 2;
xe = -b / (2 * a);
ye = (a * xe + b) * xe + h1;
d = b * b - 4 * a * h1;
roots = 0;
if (d >= 0) {
dx = Math.sqrt(d) / (Math.abs(a) * 2);
x1 = xe - dx;
x2 = xe + dx;
if (Math.abs(x1) <= 1) roots++;
if (Math.abs(x2) <= 1) roots++;
if (x1 < -1) x1 = x2;
}
if (roots === 1) {
if (h0 < 0) rise = i + x1;
else set = i + x1;
} else if (roots === 2) {
rise = i + (ye < 0 ? x2 : x1);
set = i + (ye < 0 ? x1 : x2);
}
if (rise && set) break;
h0 = h2;
}
var result = {};
if (rise) result.rise = hoursLater(t, rise);
if (set) result.set = hoursLater(t, set);
if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true;
return result;
};

View File

@ -2,7 +2,7 @@
"id": "hworldclock",
"name": "Hanks World Clock",
"shortName": "Hanks World Clock",
"version": "0.28",
"version": "0.29",
"description": "Current time zone plus up to three others",
"allow_emulator":true,
"icon": "app.png",
@ -15,11 +15,10 @@
"storage": [
{"name":"hworldclock.app.js","url":"app.js"},
{"name":"hworldclock.img","url":"hworldclock-icon.js","evaluate":true},
{"name":"hworldclock.settings.js","url":"settings.js"},
{"name":"hsuncalc.js","url":"hsuncalc.js"}
{"name":"hworldclock.settings.js","url":"settings.js"}
],
"data": [
{"name":"hworldclock.settings.json"},
{"name":"hworldclock.json"}
{"name":"hworldclock.json"}
]
}

View File

@ -622,7 +622,7 @@ s.pl = {};
endPerfLog("fullDraw", true);
if (!Bangle.uiRemove){
setUi();
setUi(); // Calls Bangle.setUI() (this comment also fixes lint warning)
let orig = Bangle.drawWidgets;
Bangle.drawWidgets = ()=>{};
Bangle.loadWidgets();

54
apps/lato/README.md Normal file
View File

@ -0,0 +1,54 @@
# Lato
A simple clock with the Lato font, with fast load and clock_info
![](screenshot1.png)
![](screenshot2.png)
![](screenshot3.png)
This clock is a Lato version of Simplest++. Simplest++ provided the
smallest example of a clock that supports 'fast load' and 'clock
info'. Lato takes this one step further and adds the lovely Lato
font. The clock is derived from Simplest++ and inspired by the
Pastel Clock.
## Usage
* When the screen is unlocked, tap at the bottom of the csreen on the information text.
It should change color showing it is selected.
* Swipe up or down to cycle through the info screens that can be displayed
when you have finished tap again towards the centre of the screen to unselect.
* Swipe left or right to change the type of info screens displayed (by default
there is only one type of data so this will have no effect)
* Settings are saved automatically and reloaded along with the clock.
## About Clock Info's
* The clock info modules enable all clocks to add the display of information to the clock face.
* The default clock_info module provides a display of battery %, Steps, Heart Rate and Altitude.
* Installing the [Sunrise ClockInfo](https://banglejs.com/apps/?id=clkinfosunrise) adds Sunrise and Sunset times into the list of info's.
## References
* [What is Fast Load and how does it work](http://www.espruino.com/Bangle.js+Fast+Load)
* [Clock Info Tutorial](http://www.espruino.com/Bangle.js+Clock+Info)
* [How to load modules through the IDE](https://github.com/espruino/BangleApps/blob/master/modules/README.md)
## With Thanks
* Gordon for support
* David Peer for his work on BW Clock
Written by: [Hugh Barney](https://github.com/hughbarney) For support
and discussion please post in the [Bangle JS
Forum](http://forum.espruino.com/microcosms/1424/)

138
apps/lato/app.js Normal file

File diff suppressed because one or more lines are too long

BIN
apps/lato/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

1
apps/lato/icon.js Normal file
View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwwkA/4A/AH4AUiIAKCxXzC5c/C5PyC5cvC8PxC5cfLxNEABhgI+gXNp4X3//+9wAK96PJC6/zC5bvKC6//C5YWKC4nUoMUpoXS8lDn/zmlOC6NCA4ckC6Hkl4HD+QwCC5c+LoIsCoSKBMIPjC5tD//0olEp//mgXNmMRiYuBC4JjBBAYAK+MRj//CwIABBAgXkI5AXOiRyBC4J8BkIXN+dEoKnFiNEAYIXNa4sUC59EJAIACkIHBC5iMCoMTn/zmIuBSQIXODAMRAAKqDABikCAAqqBC8i8CAArCBC/n0C49PC5oA/AH4AIA=="))

16
apps/lato/metadata.json Normal file
View File

@ -0,0 +1,16 @@
{
"id": "lato",
"name": "Lato",
"version": "0.01",
"description": "A Lato Font clock with fast load and clock_info",
"readme": "README.md",
"icon": "app.png",
"screenshots": [{"url":"screenshot3.png"}],
"type": "clock",
"tags": "clock",
"supports": ["BANGLEJS2"],
"storage": [
{"name":"lato.app.js","url":"app.js"},
{"name":"lato.img","url":"icon.js","evaluate":true}
]
}

BIN
apps/lato/screenshot1..png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
apps/lato/screenshot2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
apps/lato/screenshot3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -81,3 +81,4 @@
0.57: Fix "unread Timeout" = off (previously defaulted to 60s)
0.58: Fast load messages without writing to flash
Don't write messages to flash until the app closes
0.59: Ensure we do write messages if messages app can't be fast loaded (see #2373)

View File

@ -18,8 +18,11 @@ exports.listener = function(type, msg) {
if (Bangle.CLOCK && msg.state && msg.title && appSettings.openMusic) loadMessages = true;
else return;
}
if (Bangle.load === load) {
if (Bangle.load === load || !Bangle.uiRemove) {
// no fast loading: store message to flash
/* FIXME: Maybe we need a better way of deciding if an app will
be fast loaded than just hard-coding a Bangle.uiRemove check.
Bangle.load could return a bool (as the load doesn't happen immediately). */
require("messages").save(msg);
} else {
if (!Bangle.MESSAGES) Bangle.MESSAGES = [];

View File

@ -1,7 +1,8 @@
{
"id": "messagegui",
"name": "Message UI",
"version": "0.58",
"shortName": "Messages",
"version": "0.59",
"description": "Default app to display notifications from iOS and Gadgetbridge/Android",
"icon": "app.png",
"type": "app",

View File

@ -19,3 +19,4 @@
0.16: make check_idle boolean setting work properly with new B2 menu
0.17: Use default Bangle formatter for booleans
0.18: fix idle option always getting defaulted to true
0.19: Use 'modules/suncalc.js' to avoid it being copied 8 times for different apps

View File

@ -2,7 +2,7 @@
"id": "pastel",
"name": "Pastel Clock",
"shortName": "Pastel",
"version": "0.18",
"version": "0.19",
"description": "A Configurable clock with custom fonts, background and weather display. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times",
"icon": "pastel.png",
"dependencies": {"mylocation":"app","weather":"app"},

View File

@ -1,4 +1,4 @@
var SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js");
var SunCalc = require("suncalc"); // from modules folder
require("f_latosmall").add(Graphics);
const storage = require('Storage');
const locale = require("locale");

View File

@ -12,7 +12,8 @@
"allow_emulator": true,
"storage": [
{"name":"presentor.app.js","url":"app.js"},
{"name":"presentor.img","url":"app-icon.js","evaluate":true},
{"name":"presentor.img","url":"app-icon.js","evaluate":true}
], "data": [
{"name":"presentor.json","url":"settings.json"}
]
}

View File

@ -1,3 +1,4 @@
0.01: first release
0.02: added option to buzz on prime, with settings
0.03: added option to debug settings and test fw 2.15.93 load speed ups
0.04: changed icon

View File

@ -1,4 +1,4 @@
# Prime Time Lato (clock)
# Prime Lato (clock)
A watchface that displays time and its prime factors in the Lato font.
For example when the time is 21:05, the prime factors are 5,421.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 710 B

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1 +1 @@
require("heatshrink").decompress(atob("mEwwIdah/wAof//4ECgYFB4AFBg4FB8AFBj/wh/4AoM/wEB/gFBvwCEBAU/AQP4gfAj8AgPwAoMPwED8AFBg/AAYIBDA4ngg4TB4EBApkPKgJSBJQIFTMgIFCJIIFDKoIFEvgFBGoMAnw7DP4IFEh+BAoItBg+DNIQwBMIaeCKoKxCPoIzCEgKVHUIqtFXIrFFaIrdFdIwAV"))
require("heatshrink").decompress(atob("mEw4X/AAIHB8cYttrJf4AR1gKJgdYBZMCBZdcBZMNsALKuALJhNABZMFwALJmvAAwkOqvAmtAkwSF83+uEV4EMOIpZBznWII5NB7mXGo5BB7Z0HkpBB6x0HFYXVNA4rC6pcFAANXDQhSFqgaEBZGYaBLfIaAUBBZUJNQ4jCm+cHZPcBZFXgdwzELBg1W/PAy/rBY3VPAOVTY863kAnaPHAH4A/ADAA=="))

View File

@ -1,6 +1,6 @@
{ "id": "primetimelato",
"name": "Prime Time Lato",
"version": "0.03",
"name": "Prime Lato",
"version": "0.04",
"type": "clock",
"description": "A clock that tells you the primes of the time in the Lato font",
"icon": "app.png",

View File

@ -13,3 +13,4 @@
0.13: convert var/function into let
0.14: cleanup code and fix fastload issue
0.15: fix draw before widget hide
0.16: Use 'modules/suncalc.js' to avoid it being copied 8 times for different apps

View File

@ -2,7 +2,7 @@
"id": "rebble",
"name": "Rebble Clock",
"shortName": "Rebble",
"version": "0.15",
"version": "0.16",
"description": "A Pebble style clock, with configurable background, three sidebars including steps, day, date, sunrise, sunset, long live the rebellion",
"readme": "README.md",
"icon": "rebble.png",
@ -14,7 +14,6 @@
"storage": [
{"name":"rebble.app.js","url":"rebble.app.js"},
{"name":"rebble.settings.js","url":"rebble.settings.js"},
{"name":"rebble.img","url":"rebble.icon.js","evaluate":true},
{"name":"suncalc","url":"suncalc.js"}
{"name":"rebble.img","url":"rebble.icon.js","evaluate":true}
]
}

View File

@ -11,7 +11,7 @@ Graphics.prototype.setFontKdamThmor = function(scale) {
{
let SunCalc = require("suncalc");
let SunCalc = require("suncalc"); // from modules folder
const SETTINGS_FILE = "rebble.json";
const LOCATION_FILE = "mylocation.json";
const GLOBAL_SETTINGS = "setting.json";

View File

@ -1,143 +0,0 @@
/*
(c) 2011-2015, Vladimir Agafonkin
SunCalc is a JavaScript library for calculating sun/moon position and light phases.
https://github.com/mourner/suncalc
edit for banglejs
*/
(function () { 'use strict';
// shortcuts for easier to read formulas
var PI = Math.PI,
sin = Math.sin,
cos = Math.cos,
tan = Math.tan,
asin = Math.asin,
atan = Math.atan2,
acos = Math.acos,
rad = PI / 180;
// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
// date/time constants and conversions
var dayMs = 1000 * 60 * 60 * 24,
J1970 = 2440588,
J2000 = 2451545;
function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
function fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); }
function toDays(date) { return toJulian(date) - J2000; }
// general calculations for position
var e = rad * 23.4397; // obliquity of the Earth
function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }
// general sun calculations
function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }
function eclipticLongitude(M) {
var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
P = rad * 102.9372; // perihelion of the Earth
return M + C + P + PI;
}
var SunCalc = {};
// sun times configuration (angle, morning name, evening name)
var times = SunCalc.times = [
[-0.833, 'sunrise', 'sunset' ],
[ -0.3, 'sunriseEnd', 'sunsetStart' ],
[ -6, 'dawn', 'dusk' ],
[ -12, 'nauticalDawn', 'nauticalDusk'],
[ -18, 'nightEnd', 'night' ],
[ 6, 'goldenHourEnd', 'goldenHour' ]
];
// calculations for sun times
var J0 = 0.0009;
function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); }
function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; }
function solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); }
function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); }
function observerAngle(height) { return -2.076 * Math.sqrt(height) / 60; }
// returns set time for the given sun altitude
function getSetJ(h, lw, phi, dec, n, M, L) {
var w = hourAngle(h, phi, dec),
a = approxTransit(w, lw, n);
return solarTransitJ(a, M, L);
}
// calculates sun times for a given date, latitude/longitude, and, optionally,
// the observer height (in meters) relative to the horizon
SunCalc.getTimes = function (date, lat, lng, height) {
height = height || 0;
var lw = rad * -lng,
phi = rad * lat,
dh = observerAngle(height),
d = toDays(date),
n = julianCycle(d, lw),
ds = approxTransit(0, lw, n),
M = solarMeanAnomaly(ds),
L = eclipticLongitude(M),
dec = declination(L, 0),
Jnoon = solarTransitJ(ds, M, L),
i, len, time, h0, Jset, Jrise;
var result = {
solarNoon: fromJulian(Jnoon),
nadir: fromJulian(Jnoon - 0.5)
};
for (i = 0, len = times.length; i < len; i += 1) {
time = times[i];
h0 = (time[0] + dh) * rad;
Jset = getSetJ(h0, lw, phi, dec, n, M, L);
Jrise = Jnoon - (Jset - Jnoon);
result[time[1]] = fromJulian(Jrise);
result[time[2]] = fromJulian(Jset);
}
return result;
};
// export as Node module / AMD module / browser variable
if (typeof exports === 'object' && typeof module !== 'undefined') module.exports = SunCalc;
else if (typeof define === 'function' && define.amd) define(SunCalc);
else window.SunCalc = SunCalc;
}());

54
apps/simplestpp/README.md Normal file
View File

@ -0,0 +1,54 @@
# Simplest++ Clock
The simplest working clock, with fast load and clock_info
![](screenshot1.png)
![](screenshot2.png)
![](screenshot3.png)
Simplest++ has 1 clock info menu that is displayed as a single line at the bottom of the screen.
This provides a working demo of how to use the clock_info modules.
## Usage
* When the screen is unlocked, tap at the bottom of the csreen on the information text.
It should change color showing it is selected.
* Swipe up or down to cycle through the info screens that can be displayed
when you have finished tap again towards the centre of the screen to unselect.
* Swipe left or right to change the type of info screens displayed (by default
there is only one type of data so this will have no effect)
* Settings are saved automatically and reloaded along with the clock.
## About Clock Info's
* The clock info modules enable all clocks to add the display of information to the clock face.
* The default clock_info module provides a display of battery %, Steps, Heart Rate and Altitude.
* Installing the [Sunrise ClockInfo](https://banglejs.com/apps/?id=clkinfosunrise) adds Sunrise and Sunset times into the list of info's.
## References
* [What is Fast Load and how does it work](http://www.espruino.com/Bangle.js+Fast+Load)
* [Clock Info Tutorial](http://www.espruino.com/Bangle.js+Clock+Info)
* [How to load modules through the IDE](https://github.com/espruino/BangleApps/blob/master/modules/README.md)
## With Thanks
* Gordon for support
* David Peer for his work on BW Clock
Written by: [Hugh Barney](https://github.com/hughbarney) For support
and discussion please post in the [Bangle JS
Forum](http://forum.espruino.com/microcosms/1424/)

108
apps/simplestpp/app.js Normal file
View File

@ -0,0 +1,108 @@
/**
*
* Simplestpp Clock
*
* The entire clock code is contained within the block below this
* supports 'fast load'
*
* To add support for clock_info_supprt we add the code marked at [1] and [2]
*
*/
{
// must be inside our own scope here so that when we are unloaded everything disappears
// we also define functions using 'let fn = function() {..}' for the same reason. function decls are global
let draw = function() {
var date = new Date();
var timeStr = require("locale").time(date,1);
var h = g.getHeight();
var w = g.getWidth();
g.reset();
g.setColor(g.theme.bg);
g.fillRect(Bangle.appRect);
g.setFont('Vector', w/3);
g.setFontAlign(0, 0);
g.setColor(g.theme.fg);
g.drawString(timeStr, w/2, h/2);
clockInfoMenu.redraw(); // clock_info_support
// schedule a draw for the next minute
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
draw();
}, 60000 - (Date.now() % 60000));
};
/**
* clock_info_support
* this is the callback function that get invoked by clockInfoMenu.redraw();
*
* We will display the image and text on the same line and centre the combined
* length of the image+text
*
*
*/
let clockInfoDraw = (itm, info, options) => {
g.reset().setFont('Vector',24).setBgColor(options.bg).setColor(options.fg);
//use info.text.toString(), steps does not have length defined
var text_w = g.stringWidth(info.text.toString());
// gap between image and text
var gap = 10;
// width of the image and text combined
var w = gap + (info.img ? 24 :0) + text_w;
// different fg color if we tapped on the menu
if (options.focus) g.setColor(options.hl);
// clear the whole info line
g.clearRect(0, options.y -1, g.getWidth(), options.y+24);
// draw the image if we have one
if (info.img) {
// image start
var x = (g.getWidth() / 2) - (w/2);
g.drawImage(info.img, x, options.y);
// draw the text to the side of the image (left/centre alignment)
g.setFontAlign(-1,0).drawString(info.text, x + 23 + gap, options.y+12);
} else {
// text only option, not tested yet
g.setFontAlign(0,0).drawString(info.text, g.getWidth() / 2, options.y+12);
}
};
// clock_info_support
// retrieve all the clock_info modules that are installed
let clockInfoItems = require("clock_info").load();
// clock_info_support
// setup the way we wish to interact with the menu
// the hl property defines the color the of the info when the menu is selected after tapping on it
let clockInfoMenu = require("clock_info").addInteractive(clockInfoItems, { x:64, y:132, w:50, h:40, draw : clockInfoDraw, bg : g.theme.bg, fg : g.theme.fg, hl : "#0ff"} );
// timeout used to update every minute
var drawTimeout;
g.clear();
// Show launcher when middle button pressed, add updown button handlers
Bangle.setUI({
mode : "clock",
remove : function() {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
// remove info menu
clockInfoMenu.remove();
delete clockInfoMenu;
}
});
// Load widgets
Bangle.loadWidgets();
draw();
setTimeout(Bangle.drawWidgets,0);
} // end of clock

BIN
apps/simplestpp/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 994 B

1
apps/simplestpp/icon.js Normal file
View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEw4X/AAIHBqOM997IGkq1AKIltVqt4BQ0DBQIAB4ALFktVv/9qtYBYvVA4Ulq4KEgNVwAEBgVVoALDgtcAoc1qAFDitgAocJqguEGoowDgVWBYuVGoUBFwgwCHgUNGgUNuBCCAYY6CBYcJCYUlDYYLCgJxCmozCBYcCG4UVG4QLDgBgCBZeXBY/WBYcC1WtvWqGoILEVAIACJoILQgf/+tf/7jBBYg7JL66DLTZazLZZbjLfZcA6oLFq4EDio8CHQReCGgQwEmpCCHgVVFIUCVAQAD6plCkouEA4VVv/9qoPCAAcDZYa/BAAstBQN4BQwABlWoBRAAr"))

View File

@ -0,0 +1,16 @@
{
"id": "simplestpp",
"name": "Simplest++ Clock",
"version": "0.01",
"description": "The simplest working clock, with fast load and clock_info, acts as a tutorial piece",
"readme": "README.md",
"icon": "app.png",
"screenshots": [{"url":"screenshot3.png"}],
"type": "clock",
"tags": "clock",
"supports": ["BANGLEJS2"],
"storage": [
{"name":"simplestpp.app.js","url":"app.js"},
{"name":"simplestpp.img","url":"icon.js","evaluate":true}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

2
apps/sunclock/ChangeLog Normal file
View File

@ -0,0 +1,2 @@
0.01: First commit
0.02: Use 'modules/suncalc.js' to avoid it being copied 8 times for different apps

View File

@ -19,13 +19,21 @@ var pos = {altitude: 20, azimuth: 135};
var noonpos = {altitude: 37, azimuth: 180};
let idTimeout = null;
function updatePos() {
function radToDeg(pos) {
return { // instead of mofidying suncalc
azimuth: Math.round((pos.azimuth / rad + 180) % 360),
altitude: Math.round( pos.altitude / rad)
};
}
coord = require("Storage").readJSON(LOCATION_FILE,1)|| {"lat":53.3,"lon":10.1,"location":"Pattensen"};
pos = SunCalc.getPosition(Date.now(), coord.lat, coord.lon);
pos = radToDeg(SunCalc.getPosition(Date.now(), coord.lat, coord.lon));
times = SunCalc.getTimes(Date.now(), coord.lat, coord.lon);
rise = times.sunrise.toString().split(" ")[4].substr(0,5);
set = times.sunset.toString().split(" ")[4].substr(0,5);
noonpos = SunCalc.getPosition(times.solarNoon, coord.lat, coord.lon);
noonpos = radToDeg(SunCalc.getPosition(times.solarNoon, coord.lat, coord.lon));
}
function drawSimpleClock() {

View File

@ -1,7 +1,7 @@
{
"id": "sunclock",
"name": "Sun Clock",
"version": "0.01",
"version": "0.02",
"description": "A clock with sunset/sunrise, sun height/azimuth",
"icon": "app.png",
"type": "clock",
@ -11,7 +11,6 @@
"allow_emulator": true,
"storage": [
{"name":"sunclock.app.js","url":"app.js"},
{"name":"sunclock.img","url":"app-icon.js","evaluate":true},
{"name":"suncalc.js","url":"suncalc.js"}
{"name":"sunclock.img","url":"app-icon.js","evaluate":true}
]
}

View File

@ -1,3 +1,4 @@
0.01: New App!
0.02: Add sunrise/sunset. Fix timer bugs.
0.03: Use default Bangle formatter for booleans
0.04: Use 'modules/suncalc.js' to avoid it being copied 8 times for different apps

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
"id": "timerclk",
"name": "Timer Clock",
"shortName":"Timer Clock",
"version":"0.03",
"version":"0.04",
"description": "A clock with stopwatches, timers and alarms build in.",
"icon": "app-icon.png",
"type": "clock",

View File

@ -19,4 +19,3 @@
0.20: Added weather condition with temperature to clkinfo.
0.21: Updated clkinfo icon.
0.22: Automatic translation of strings, some left untranslated.
>>>>>>> b37fcacd1 (weather - autotranslate strings)

1
bin/sanitycheck.js Executable file → Normal file
View File

@ -93,6 +93,7 @@ const INTERNAL_FILES_IN_APP_TYPE = { // list of app types and files they SHOULD
/* These are warnings we know about but don't want in our output */
var KNOWN_WARNINGS = [
"App gpsrec data file wildcard .gpsrc? does not include app ID",
"App owmweather data file weather.json is also listed as data file for app weather",
];
function globToRegex(pattern) {

View File

@ -1,17 +1,34 @@
/* Module suncalc.js
/*
(c) 2011-2015, Vladimir Agafonkin
SunCalc is a JavaScript library for calculating sun/moon position and light phases.
https://github.com/mourner/suncalc
PB: Usage:
E.setTimeZone(2); // 1 = MEZ, 2 = MESZ
SunCalc = require("suncalc.js");
pos = SunCalc.getPosition(Date.now(), 53.3, 10.1);
times = SunCalc.getTimes(Date.now(), 53.3, 10.1);
rise = times.sunrise; // Date object
rise_str = rise.getHours() + ':' + rise.getMinutes(); //hh:mm
Copyright (c) 2014, Vladimir Agafonkin
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var exports={};
(function () { 'use strict';
// shortcuts for easier to read formulas
@ -26,6 +43,7 @@ var PI = Math.PI,
// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
// date/time constants and conversions
var dayMs = 1000 * 60 * 60 * 24,
@ -33,7 +51,7 @@ var dayMs = 1000 * 60 * 60 * 24,
J2000 = 2451545;
function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
function fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); } // PB: onece removed + 0.5; included it again 4 Jan 2021
function fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); }
function toDays(date) { return toJulian(date) - J2000; }
@ -81,9 +99,13 @@ function sunCoords(d) {
};
}
var SunCalc = {};
// calculates sun position for a given date and latitude/longitude
exports.getPosition = function (date, lat, lng) {
SunCalc.getPosition = function (date, lat, lng) {
var lw = rad * -lng,
phi = rad * lat,
@ -93,19 +115,32 @@ exports.getPosition = function (date, lat, lng) {
H = siderealTime(d, lw) - c.ra;
return {
azimuth: Math.round((azimuth(H, phi, c.dec) / rad + 180) % 360), // PB: converted to deg
altitude: Math.round( altitude(H, phi, c.dec) / rad) // PB: converted to deg
azimuth: azimuth(H, phi, c.dec),
altitude: altitude(H, phi, c.dec)
};
};
// sun times configuration (angle, morning name, evening name)
var times = [
[-0.833, 'sunrise', 'sunset' ]
var times = SunCalc.times = [
[-0.833, 'sunrise', 'sunset' ],
[ -0.3, 'sunriseEnd', 'sunsetStart' ],
[ -6, 'dawn', 'dusk' ],
[ -12, 'nauticalDawn', 'nauticalDusk'],
[ -18, 'nightEnd', 'night' ],
[ 6, 'goldenHourEnd', 'goldenHour' ]
];
// adds a custom time to the times config
SunCalc.addTime = function (angle, riseName, setName) {
times.push([angle, riseName, setName]);
};
// calculations for sun times
var J0 = 0.0009;
function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); }
@ -128,7 +163,7 @@ function getSetJ(h, lw, phi, dec, n, M, L) {
// calculates sun times for a given date, latitude/longitude, and, optionally,
// the observer height (in meters) relative to the horizon
exports.getTimes = function (date, lat, lng, height) {
SunCalc.getTimes = function (date, lat, lng, height) {
height = height || 0;
@ -189,7 +224,7 @@ function moonCoords(d) { // geocentric ecliptic coordinates of the moon
};
}
getMoonPosition = function (date, lat, lng) {
SunCalc.getMoonPosition = function (date, lat, lng) {
var lw = rad * -lng,
phi = rad * lat,
@ -216,7 +251,7 @@ getMoonPosition = function (date, lat, lng) {
// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and
// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
getMoonIllumination = function (date) {
SunCalc.getMoonIllumination = function (date) {
var d = toDays(date || new Date()),
s = sunCoords(d),
@ -243,7 +278,7 @@ function hoursLater(date, h) {
// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article
getMoonTimes = function (date, lat, lng, inUTC) {
SunCalc.getMoonTimes = function (date, lat, lng, inUTC) {
var t = new Date(date);
if (inUTC) t.setUTCHours(0, 0, 0, 0);
else t.setHours(0, 0, 0, 0);
@ -296,3 +331,11 @@ getMoonTimes = function (date, lat, lng, inUTC) {
return result;
};
// export as Node module / AMD module / browser variable
if (typeof exports === 'object' && typeof module !== 'undefined') module.exports = SunCalc;
else if (typeof define === 'function' && define.amd) define(SunCalc);
else window.SunCalc = SunCalc;
}());