Skip to content

Commit 910f160

Browse files
author
thyttan
committed
Merge branch 'kineticscroll' into app-loader
2 parents ad82d64 + 89e4349 commit 910f160

File tree

17 files changed

+433
-8
lines changed

17 files changed

+433
-8
lines changed

apps/kineticscroll/ChangeLog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33
0.03: Better scrolling behaviour
44
0.04: Fix incorrect appRect handling (missing back buttons and doubled menu titles)
55
0.05: Bring in change from the firmware implementation forwarding the type of touch (short/long).
6+
0.06: Disregard long touches since they make it easy to unintentionally select
7+
menu entries.
8+
0.07: Add "ram" keyword to see if it gets snappier.

apps/kineticscroll/boot.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(function() {
2-
E.showScroller = function(options) {
2+
E.showScroller = function(options) {"ram";
33
/* options = {
44
h = height
55
c = # of items
@@ -42,6 +42,7 @@
4242
};
4343

4444
const touchHandler = (_,e)=>{
45+
if (e.type) return; // e.type == 0 for swift touches or 2 for longer ones.
4546
let R = Bangle.appRect;
4647
if (e.y<R.y-4) return;
4748
velocity = 0;

apps/kineticscroll/metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{ "id": "kineticscroll",
22
"name": "Kinetic Scroll",
33
"shortName":"Kinetic Scroll",
4-
"version": "0.05",
4+
"version": "0.06",
55
"description": "Replacement for the system scroller with kinetic scrolling.",
66
"icon": "app.png",
77
"type": "bootloader",

apps/lightswitch/ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
0.08: Ensure boot code doesn't allocate and leave a gloval variable named 'settings'
99
0.09: Handle lightswitch logic running before its widget has loaded
1010
0.10: Minor code improvements
11+
0.11: Fix issue where backlight is not turned on.

apps/lightswitch/lib.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ exports = {
1010
unlockSide: "",
1111
tapSide: "right",
1212
tapOn: "always",
13+
isOn: true
1314
}, require("Storage").readJSON("lightswitch.json", true) || {});
1415

1516
// cache lock status
1617
var locked = Bangle.isLocked();
1718

1819
// check to unlock
19-
if (locked && data.dir === w.unlockSide) Bangle.setLocked();
20+
if (locked && data.dir === w.unlockSide) {
21+
Bangle.setLocked();
22+
if (w.isOn) Bangle.setLCDPower(true);
23+
}
2024

2125
// check to flash
2226
if (data.dir === w.tapSide && (w.tapOn === "always" || locked === (w.tapOn === "locked"))) require("lightswitch.js").flash();
@@ -38,13 +42,14 @@ exports = {
3842
isOn: true
3943
}, require("Storage").readJSON("lightswitch.json", true) || {});
4044

41-
// chack if locked, backlight off or actual value lower then minimal flash value
45+
// check if locked, backlight off or actual value lower then minimal flash value
4246
if (Bangle.isLocked() || !w.isOn || w.value < w.minFlash) {
4347

4448
// set inner bulb and brightness
4549
var setBrightness = function(w, value) {
4650
if (w.drawInnerBulb) w.drawInnerBulb(value);
4751
Bangle.setLCDBrightness(value);
52+
Bangle.setLCDPower(true);
4853
};
4954

5055
// override timeout if defined

apps/lightswitch/metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"id": "lightswitch",
33
"name": "Light Switch Widget",
44
"shortName": "Light Switch",
5-
"version": "0.10",
5+
"version": "0.11",
66
"description": "A fast way to switch LCD backlight on/off, change the brightness and show the lock status. All in one widget.",
77
"icon": "images/app.png",
88
"screenshots": [

apps/lightswitch/widget.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
} else {
122122
// activate backlight
123123
this.isOn = true;
124+
Bangle.setLCDPower(true);
124125
// redraw complete widget icon
125126
this.drawIcon(false);
126127
}

apps/zambretti/app-icon.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/zambretti/app.js

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
/**
2+
* https://web.archive.org/web/20110610213848/http://www.meteormetrics.com/zambretti.htm
3+
*/
4+
5+
const storage = require('Storage');
6+
const Layout = require("Layout");
7+
8+
let height;
9+
let mainScreen = false;
10+
11+
const ZAMBRETTI_FORECAST = {
12+
A: /*LANG*/'Settled Fine',
13+
B: /*LANG*/'Fine Weather',
14+
C: /*LANG*/'Becoming Fine',
15+
D: /*LANG*/'Fine Becoming Less Settled',
16+
E: /*LANG*/'Fine, Possibly showers',
17+
F: /*LANG*/'Fairly Fine, Improving',
18+
G: /*LANG*/'Fairly Fine, Possibly showers, early',
19+
H: /*LANG*/'Fairly Fine Showery Later',
20+
I: /*LANG*/'Showery Early, Improving',
21+
J: /*LANG*/'Changeable Mending',
22+
K: /*LANG*/'Fairly Fine, Showers likely',
23+
L: /*LANG*/'Rather Unsettled Clearing Later',
24+
M: /*LANG*/'Unsettled, Probably Improving',
25+
N: /*LANG*/'Showery Bright Intervals',
26+
O: /*LANG*/'Showery Becoming more unsettled',
27+
P: /*LANG*/'Changeable some rain',
28+
Q: /*LANG*/'Unsettled, short fine Intervals',
29+
R: /*LANG*/'Unsettled, Rain later',
30+
S: /*LANG*/'Unsettled, rain at times',
31+
T: /*LANG*/'Very Unsettled, Finer at times',
32+
U: /*LANG*/'Rain at times, worse later.',
33+
V: /*LANG*/'Rain at times, becoming very unsettled',
34+
W: /*LANG*/'Rain at Frequent Intervals',
35+
X: /*LANG*/'Very Unsettled, Rain',
36+
Y: /*LANG*/'Stormy, possibly improving',
37+
Z: /*LANG*/'Stormy, much rain',
38+
};
39+
40+
const ZAMBRETTI_FALLING = {
41+
1050: 'A',
42+
1040: 'B',
43+
1024: 'C',
44+
1018: 'H',
45+
1010: 'O',
46+
1004: 'R',
47+
998: 'U',
48+
991: 'V',
49+
985: 'X',
50+
};
51+
52+
const ZAMBRETTI_STEADY = {
53+
1033: 'A',
54+
1023: 'B',
55+
1014: 'E',
56+
1008: 'K',
57+
1000: 'N',
58+
994: 'P',
59+
989: 'S',
60+
981: 'W',
61+
974: 'X',
62+
960: 'Z',
63+
};
64+
65+
const ZAMBRETTI_RISING = {
66+
1030: 'A',
67+
1022: 'B',
68+
1012: 'C',
69+
1007: 'F',
70+
1000: 'G',
71+
995: 'I',
72+
990: 'J',
73+
984: 'L',
74+
978: 'M',
75+
970: 'Q',
76+
965: 'T',
77+
959: 'Y',
78+
947: 'Z',
79+
};
80+
81+
function correct_season(letter, dir) {
82+
const month = new Date().getMonth() + 1;
83+
const location = require("Storage").readJSON("mylocation.json",1)||{"lat":51.5072,"lon":0.1276,"location":"London"};
84+
const northern_hemisphere = location.lat > 0;
85+
const summer = northern_hemisphere ? (month >= 4 && month <= 9) : (month >= 10 || month <= 3);
86+
87+
let corr = 0;
88+
if (dir < 0 && !summer) { // Winter falling
89+
corr = +1;
90+
} else if (dir > 0 && summer) { // Summer rising
91+
corr = -1;
92+
}
93+
return letter == 'A' || letter == 'Z' ? letter : String.fromCharCode(letter.charCodeAt(0)+corr);
94+
}
95+
96+
function get_zambretti_letter(pressure, dir) {
97+
let table = (() => {
98+
if (dir < 0) { // Barometer Falling
99+
return ZAMBRETTI_FALLING;
100+
} else if (dir == 0) { // Barometer Steady
101+
return ZAMBRETTI_STEADY;
102+
} else { // Barometer Rising
103+
return ZAMBRETTI_RISING;
104+
}
105+
})();
106+
107+
const closest = Object.keys(table).reduce(function(prev, curr) {
108+
return (Math.abs(curr - pressure) < Math.abs(prev - pressure) ? curr : prev);
109+
});
110+
111+
return correct_season(table[closest], dir);
112+
}
113+
114+
function loadSettings() {
115+
const settings = require('Storage').readJSON("zambretti.json", true) || {};
116+
height = settings.height;
117+
}
118+
119+
function showMenu() {
120+
const menu = {
121+
"" : {
122+
title : "Zambretti Forecast",
123+
},
124+
"< Back": () => {
125+
E.showMenu();
126+
layout.forgetLazyState();
127+
show();
128+
},
129+
/*LANG*/"Exit": () => load(),
130+
/*LANG*/"Settings": () =>
131+
eval(require('Storage').read('zambretti.settings.js'))(() => {
132+
loadSettings();
133+
showMenu();
134+
}),
135+
'Plot history': () => {E.showMenu(); plot();},
136+
};
137+
E.showMenu(menu);
138+
}
139+
140+
const layout = new Layout({
141+
type:"v", c: [
142+
{type:"txt", font:"9%", label:/*LANG*/"Zambretti Forecast", bgCol:g.theme.bgH, fillx: true, pad: 1},
143+
{type:"txt", font:"12%", id:"forecast", filly: 1, wrap: 1, width: Bangle.appRect.w, pad: 1},
144+
{type:"h", c:[
145+
{type: 'v', c:[
146+
{type:"txt", font:"9%", label:/*LANG*/"Pressure", pad: 3, halign: -1},
147+
{type:"txt", font:"9%", label:/*LANG*/"Difference", pad: 3, halign: -1},
148+
{type:"txt", font:"9%", label:/*LANG*/"Temperature", pad: 3, halign: -1},
149+
]},
150+
{type: 'v', c:[
151+
{type:"txt", font:"9%", id:"pressure", pad: 3, halign: -1},
152+
{type:"txt", font:"9%", id:"diff", pad: 3, halign: -1},
153+
{type:"txt", font:"9%", id:"temp", pad: 3, halign: -1},
154+
]}
155+
]},
156+
]
157+
}, {lazy:true});
158+
159+
function draw(temperature) {
160+
const history3 = storage.readJSON("zambretti.log.json", true) || []; // history of recent 3 hours
161+
const pressure_cur = history3[history3.length-1].p;
162+
const pressure_last = history3[0].p;
163+
const diff = pressure_cur - pressure_last;
164+
const pressure_sea = pressure_cur * Math.pow(1 - (0.0065 * height) / (temperature + (0.0065 * height) + 273.15),-5.257);
165+
166+
layout.forecast.label = ZAMBRETTI_FORECAST[get_zambretti_letter(pressure_sea, diff)];
167+
layout.pressure.label = Math.round(pressure_sea);
168+
layout.diff.label = diff;
169+
layout.temp.label = require("locale").number(temperature,1);
170+
layout.render();
171+
//layout.debug();
172+
173+
mainScreen = true;
174+
Bangle.setUI({
175+
mode: "custom",
176+
btn: (n) => {mainScreen = false; showMenu();},
177+
});
178+
}
179+
180+
function show() {
181+
Bangle.getPressure().then(p =>{if (p) draw(p.temperature);});
182+
}
183+
184+
function plot() {
185+
const interval = 15; // minutes
186+
const history3 = require('Storage').readJSON("zambretti.log.json", true) || []; // history of recent 3 hours
187+
188+
const now = new Date()/(1000);
189+
let curtime = now-3*60*60; // 3h ago
190+
const data = [];
191+
while (curtime <= now) {
192+
// find closest value in history for this timestamp
193+
const closest = history3.reduce((prev, curr) => {
194+
return (Math.abs(curr.ts - curtime) < Math.abs(prev.ts - curtime) ? curr : prev);
195+
});
196+
data.push(closest.p);
197+
curtime += interval*60;
198+
}
199+
200+
Bangle.setUI({
201+
mode: "custom",
202+
back: () => showMenu(),
203+
});
204+
205+
g.reset().setFont("6x8",1);
206+
require("graph").drawLine(g, data, {
207+
axes: true,
208+
x: 4,
209+
y: Bangle.appRect.y+8,
210+
height: Bangle.appRect.h-20,
211+
gridx: 1,
212+
gridy: 1,
213+
miny: Math.min.apply(null, data)-1,
214+
maxy: Math.max.apply(null, data)+1,
215+
title: /*LANG*/"Barometer history (mBar)",
216+
ylabel: y => y,
217+
xlabel: i => {
218+
const t = -3*60 + interval*i;
219+
if (t % 60 === 0) {
220+
return "-" + t/60 + "h";
221+
}
222+
return "";
223+
},
224+
});
225+
}
226+
227+
g.reset().clear();
228+
loadSettings();
229+
Bangle.loadWidgets();
230+
231+
if (height === undefined) {
232+
// setting of height required
233+
eval(require('Storage').read('zambretti.settings.js'))(() => {
234+
loadSettings();
235+
show();
236+
});
237+
} else {
238+
show();
239+
}
240+
Bangle.drawWidgets();
241+
242+
// Update every 15 minutes
243+
setInterval(() => {
244+
if (mainScreen) {
245+
show();
246+
}
247+
}, 15*60*1000);

apps/zambretti/app.png

716 Bytes
Loading

0 commit comments

Comments
 (0)