Merge pull request #2 from espruino/master

Conflict resolution
pull/25/head
Akinboyewa Akindolani 2019-11-12 14:23:17 +00:00 committed by GitHub
commit d6179b955f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 521 additions and 22 deletions

View File

@ -337,5 +337,52 @@
{"name":".tfmodel","url":"gesture-tfmodel.js","evaluate":true},
{"name":"*gesture","url":"gesture-icon.js","evaluate":true}
]
},
{ "id": "pparrot",
"name": "Party Parrot",
"icon": "party-parrot.png",
"description": "Party with a parrot on your wrist",
"tags": "party,parrot,lol",
"type":"app",
"storage": [
{"name":"+pparrot","url":"party-parrot.json"},
{"name":"-pparrot","url":"party-parrot.js"},
{"name":"*pparrot","url":"party-parrot-icon.js","evaluate":true}
]
},
{
"id": "blescan",
"name": "BLE Scanner",
"icon": "blescan.png",
"description": "Scan for advertising BLE devices",
"tags" : "bluetooth",
"storage" : [
{"name":"+blescan","url":"blescan.json"},
{"name":"-blescan","url":"blescan.js"},
{"name":"*blescan","url":"blescan-icon.js", "evaluate":true}
]
},
{ "id": "mmonday",
"name": "Manic Monday Tone",
"icon": "manic-monday-icon.png",
"description": "The Bangles make a comeback",
"tags": "sound",
"storage": [
{"name":"+mmonday","url":"manic-monday.json"},
{"name":"-mmonday","url":"manic-monday.js"},
{"name":"*mmonday","url":"manic-monday-icon.js","evaluate":true}
]
},
{ "id": "jbells",
"name": "Jingle Bells",
"icon": "jbells.png",
"description": "Play Jingle Bells",
"tags": "sound",
"type":"app",
"storage": [
{"name":"+jbells","url":"jbells.json"},
{"name":"-jbells","url":"jbells.js"},
{"name":"*jbells","url":"jbells-icon.js","evaluate":true}
]
}
]

1
apps/blescan-icon.js Normal file
View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4ATmIABrdbAgQrmAAYvEAAYtkF5QxcEZAvLGDAhJF5oxWFhYAFCBFaFzQsHAAk3CQmE1wwRFxiPFMY4uBwiSRI4uEQo4GIAAIVBxTCRFwoABJITvNrYTHRqIuCAAIvPxQSBBQwvQL6aMCBQ7sQVIQuGdIjqIGCIOEm4XHForqFIAYHBm4vTFxYMDAQKeHDIwvVRAoEDdRAvPE5QcHAoTqJDQ5eZAwS7DIZovWAodaRQLqGF6bhDABouCXYIAQF+6PUrQUQd7oMKF6wbLApYaIF45gSAgxeUF5olDBIICECJIvTm4wLAAoPHm4vTC4OK12EGJYLFI5IvJGAuE1wABGAycIBRQuKF4ouCAAIvPIgOFF6QwEL6c3IRAuMGA+EWw4GIwuusAuTeQzqGF4r0LF6AwIm4mEAA03FzAwJLAxbKFygwLd5IuaMRwthGBYvKFzQxJF5AtdGZAvEFcYA/AH4AvA=="))

52
apps/blescan.js Normal file
View File

@ -0,0 +1,52 @@
// ble-scanner
// Scan the airwaves every three seconds (which seems safe for a large number of devices)
// Using the menu feature, display a scrollable list of BLE devices on the watch
// Dummy menu item to display until we find something
const NODEVICE = 'No devices found';
const SCAN_INTERVAL = 3000;
const menu = {
};
menu[NODEVICE] = {
value : "",
onchange : () => {}
};
function draw() {
Bangle.menu(menu);
}
function scan() {
NRF.findDevices(devices => {
for (let device of devices) {
// Only display devices that advertise a name
if (device.name) {
// Remove no devices found message if it is present
if (menu[NODEVICE]) {
delete menu[NODEVICE];
}
menu[device.name] = {
value : device.rssi,
onchange : () => {}
};
}
}
draw();
}, { active: true });
}
function waitMessage() {
E.showMessage('scanning');
}
scan();
waitMessage();
setInterval(scan, SCAN_INTERVAL);

7
apps/blescan.json Normal file
View File

@ -0,0 +1,7 @@
{
"name": "BLE Scanner",
"type":"app",
"icon": "*blescan",
"src": "-blescan"
}

BIN
apps/blescan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -3,13 +3,11 @@ g.clear();
var minuteDate = new Date();
var secondDate = new Date();
function line(angle, r1,r2) {
function seconds(angle, r) {
var a = angle*Math.PI/180;
g.drawLine(
120+Math.sin(a)*r1,
120-Math.cos(a)*r1,
120+Math.sin(a)*r2,
120-Math.cos(a)*r2);
var x = 120+Math.sin(a)*r;
var y = 120-Math.cos(a)*r;
g.fillRect(x-1,y-1,x+1,y+1);
}
function hand(angle, r1,r2) {
var a = angle*Math.PI/180;
@ -28,20 +26,20 @@ function hand(angle, r1,r2) {
function drawAll() {
g.clear();
g.setColor(0,0,0.3);
g.setColor(0,0,0.6);
for (var i=0;i<60;i++)
line(360*i/60, 92, 95);
seconds(360*i/60, 90);
secondDate = minuteDate = new Date();
onSecond();
onMinute();
}
function onSecond() {
g.setColor(0,0,0.3);
line(360*secondDate.getSeconds()/60, 92, 95);
g.setColor(0,0,0.6);
seconds(360*secondDate.getSeconds()/60, 90);
g.setColor(1,0,0);
secondDate = new Date();
line(360*secondDate.getSeconds()/60, 92, 95);
seconds(360*secondDate.getSeconds()/60, 90);
g.setColor(1,1,1);
}
@ -49,11 +47,11 @@ function onSecond() {
function onMinute() {
g.setColor(0,0,0);
hand(360*minuteDate.getHours()/12, -10, 50);
hand(360*minuteDate.getMinutes()/60, -10, 85);
hand(360*minuteDate.getMinutes()/60, -10, 82);
oldMinute = new Date();
g.setColor(1,1,1);
hand(360*minuteDate.getHours()/12, -10, 50);
hand(360*minuteDate.getMinutes()/60, -10, 85);
hand(360*minuteDate.getMinutes()/60, -10, 82);
}
setInterval(onSecond,1000);

1
apps/jbells-icon.js Normal file
View File

@ -0,0 +1 @@
E.toArrayBuffer(atob("MDCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAAAABEAAAAAAAAAAAAAAAAAAAAAERAAAAAAAREAAAAAAAAAAAAAAAAAAAABERAAAAAAAREQAAAAAAAAAAAAAAAQAAAREREAAAAAERERAAABAAAAAAAAAAARERERERFMwAzEERERERERAAAAAAAAAAARERERERHMzMzMERERERERAAAAAAAAAAARERERERHMzdzMERERERERAAAAAAAAAAERERERER3d3d3d0REREREREAAAAAAAAAEREREWYe7u3d3u7hZhEREREAAAAAAAABERFmZmHu7u3d3u7uFmZmEREQAAAAAAARFmZmZm3u7u3d3u7u1mZmZmERAAAAAAFmZmZmZh7u7u7u7u7u4WZmZmZmYAAAAABmZmZmZk7u7u7u7u7u5GZmZmZmAAAAAAAABmZmZt7u7u7u7u7u7WZmZmAAAAAAAAAAAGZmZu7u7u7u7u7u7mZmZgAAAAAAAAAAAAZmYO7u7u7u7u7u7gZmYAAAAAAAAAAAAABmAO7u7u7u7u7u7gBmAAAAAAAAAAAAAAAAAO7u7u7u7u7u7gAAAAAAAAAAAAAAAAAAAO7u7u7u7u7u7gAAAAAAAAAAAAAAAAAAAO7u7u7u7u7u7gAAAAAAAAAAAAAAAAAAAO7u7u7u7u7u7gAAAAAAAAAAAAAAAAAADu7u7u7u7u7u7uAAAAAAAAAAAAAAAAAA7u7u7u7u7u7u7u4AAAAAAAAAAAAAAAAO7u7u7u7u7u7u7u7gAAAAAAAAAAAAAAAO7u7u7u7u7u7u7u7gAAAAAAAAAAAAAADu7u7u7u7u7u7u7u7uAAAAAAAAAAAAAA7u7u7u7u7u7u7u7u7u4AAAAAAAAAAAAO7u7u7u7u7u7u7u7u7u7gAAAAAAAAAADjM+7u7u7u7u7u7u7u7uM+AAAAAAAAAADuMzMz7u7u7u7u7u7jMzPuAAAAAAAAAA7u7u4zMzMzMzMzMzMzPu7u4AAAAAAAAA7u7u7u7uMzMzMzM+7u7u7u4AAAAAAAAADu7u7u7u7u7u7u7u7u7u7uAAAAAAAAAAAADu7u7u7u7u7u7u7u7uAAAAAAAAAAAAAAAAAA7u7u7u7u7u4AAAAAAAAAAAAAAAAAAAAAAABEREREAAAAAAAAAAAAAAAAAAAAAAAAAABEREREAAAAAAAAAAAAAAAAAAAAAAAAAADd3d3dAAAAAAAAAAAAAAAAAAAAAAAAAAAN3d3QAAAAAAAAAAAAAAAAAAAAAAAAAAAA3d0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="))

38
apps/jbells.js Normal file
View File

@ -0,0 +1,38 @@
E.showMessage("Jingle Bells");
var eventEmitter = new Object();
function strofa(notes, times, current, next){
eventEmitter.on(current, () => {
if (notes.length == 0) {
eventEmitter.emit(next);
return;
}
let note = notes.shift();
let time = times.shift();
Bangle.beep(time, note).then(() => {
setTimeout(() => {
eventEmitter.emit(current);
}, time);
});
});
}
var one = [2637, 2637, 2637, 2637, 2637, 2637, 2637, 3135, 2093, 2349, 2637];
var one_t = [160, 160, 320, 160, 160, 320, 160, 160, 160, 160, 320];
var two = [2793, 2793, 2793, 2637, 2637, 2637, 2349, 2349, 2349, 2637, 2349, 3135];
var two_t = [160, 160, 320, 160, 160, 320, 160, 160, 160, 160, 320, 320];
var three = [2637, 2637, 2637, 2637, 2637, 2637, 2637, 3135, 2093, 2349, 2637];
var three_t = [160, 160, 320, 160, 160, 320, 160, 160, 160, 160, 320];
var four = [2793, 2793, 2793, 2637, 2637, 2637, 3135, 2793, 2637, 2349, 2093];
var four_t = [160, 160, 320, 160, 160, 320, 160, 160, 160, 160, 320];
strofa(one, one_t, "one", "two");
strofa(two, two_t, "two", "three");
strofa(three, three_t, "three", "four");
strofa(four, four_t, "four", "stop");
eventEmitter.emit("one");

5
apps/jbells.json Normal file
View File

@ -0,0 +1,5 @@
{
"name":"Jingle Bells","type":"app",
"icon":"*jbells",
"src":"-jbells"
}

BIN
apps/jbells.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("MDABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"))

BIN
apps/manic-monday-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

46
apps/manic-monday.js Normal file
View File

@ -0,0 +1,46 @@
// made using https://www.espruino.com/Making+Music
// Manic Monday tone by The Bangles
var SPEAKER_PIN = D18;
function freq(f) {
if (f===0) digitalWrite(SPEAKER_PIN, 0);
else analogWrite(SPEAKER_PIN, 0.5, {freq: f});
}
freq(1000);
freq(1500);
freq(0);
var pitches = {
'G': 207.65,
'a': 220.00,
'b': 246.94,
'c': 261.63,
'd': 293.66,
'e': 329.63,
'f': 369.99,
'g': 392.00,
'A': 440.00,
'B': 493.88,
'C': 523.25,
'D': 587.33,
'E': 659.26,
'F': 698.46
};
function step() {
var ch = tune[pos];
if (ch !== undefined) pos++;
if (ch in pitches) freq(pitches[ch]);
else freq(0); // off
}
var tune = "aggffefed";
var pos = 0;
setWatch(() => {
var playing = setInterval(step, 500);
if(playing === 0) clearInterval(playing);
}, BTN1);
E.showMessage('BTN1 to start', 'Manic Monday');

5
apps/manic-monday.json Normal file
View File

@ -0,0 +1,5 @@
{
"name":"Manic Monday tone",
"icon": "*mmonday",
"src":"-mmonday"
}

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4A/AH4A5wNcp8AgEswFdFktVFYMAp9QudPgwGBldWF0ErEoPJz3J5PI4YDB4WlMwMrFz1cgF05Gl4fI5ICC5OfAYN0gGHFzhcBLYOeAYQABA4RhC5IQBriMcEQV6GgiXCRgPCBYUALzZTDF4i5Bq0xqA9BuYvcqwgBL4WkK4K9BgElrmArskp/JvOfHAIuXwJeE0oyCYYVcveArj8BCAQKBF64eBK4IfBz4DBAwJVBrmBF4KZBvRACgGHXq7tDMIulQoKOBwGAgCQBBYMrSC8AknJ0phDR4gvDOAN6TYouU1kAuZdCYQYCB4YvBd4IBBR4SbDlYvUlclLYqPCEgKbBwIuBqzvDL4TxULwItD0owC5HDAYMrgC9BrouCHgSbCFyYhBFwy/E5NPMAMxkgOEpMG1gvSbYIvBdgRaB5DzDAQOlKoLtEAQJeU/wuBbgQfEeQYGCvRACNokALycAlfCU4OfeAQsCEoRfCK4IKBBgY3BFyWBJYLlBGYLpDMBJeFp8HFyKqBuYaCuaREcYbBCNAwUCwIuSvJYBE4ZhBzwtN4T2BRyUAp4YCD4ZMBYYgwCMpAvRXYK8BFgaKCboYACLQozEOQQuSJIYfGdwqLFAwYvQFwIfCL4gfEG54vORg/I4elAQIJE0gGF5GfCYQJCX5ysHLYgCCLYYQDSYprCkgvM1kAp6sLGCVWgGsF5UrF4IAGpNPlYJIAAQMEBIjAMq0GkqRBAb9cYJgA/AH4A/AH4A/ABA"))

22
apps/party-parrot.js Normal file
View File

@ -0,0 +1,22 @@
var imgs = [
atob("qE5xH+AH4A/AH4A/AH4A/AHeBq1WlcAAAUrqwJBwJM/IQJLEABBUBw5N8IotPAAhRHJu+HJolPvWe4XJAAvCz1zkhRDeuuBdIdzzxLGAA+eUwUreeacDJqCkDuah0JwUkJoTiBdg4AJKAZO2z0kA4KjH4RbGUAcAqxOtwJOCHgY6Dp5FEz1PBQUAuYLCvQIDlesJ1eHlaWGJ4YJEzwIDAARlCCYkAwLtucopPH4SdCldWqxmCp5PGlbttGwJPMTwVWrgACW4aqDLwSgqTxBHBkjiE5I/CJwYABNIeeud6KYSgp1iFBTwzoCvQ7BAoQ+CJ4qgCLwS4EUFDuCTwwAHdw4ABXQ4RDd2JPReAV6CQigqaYMkJxpPNuYSId1AyFJ61PCYskgErd25PUeAWsJ8/Cd8Lwow7uRAAITBlZPIvRPIeEjuSAANPCgJOFDpJPCgBPjlcAkhOQ5N6eA5PwwLQIABY8CJ4ptJJ8usGALuSeBCeCNo5iDT0kA4RPSHoUrJwlPDo96BYOBJ0GHTwRPUUAbxBXhYQBlesJ8CACJ63CkhQCAQNzB5DujdoaCKeJ5rLBwTuhZ4VzAQN6J6nJDIQaKf4WHT0TPBFAMkJ6oZDTxDujJwQwCZATwVDISeJvTuhwLtCJIaGLKBwXJEgMr1hOhP4igCp7xWVRTuf1lWEQNzZZAJGADFzdz5ODSpDMBBYLyWAAwgBlaedJwZCJKAUkzzudTzpONZ4gQBzyjYvRPewKPCHhuekhRCKQNzAAJUTNwWsJzsAbx/CvRREDCIADp8AlZPaJyajEudPKYQZTCwJPaJy6mFdyafcJzgAWJ7ROz5NzGYJPWJ2nJvQ0BwJOUw8rJ2fJzxPXqwYBvROxAAI2BqyeUC4NPJ2fJuY4Bw5PSwLt0eAqgTlafCAGo4BleBJ6gA5lZPRqxP7eJY"),
atob("qE5xH+AH4A/AH4A/ABOBq0AAAcrq2B1hK/JgcrJogAFmOBwJN9mJMKAAtWdH8rrliAA1cm8GB4b13wLpDm9ixoALsQTCegJO1JoUxJpoADmLy2JwdcJqBQ4wMGGwKcCrgABUQ1irk3mM3MAgZCeONWTolieYZOFIoQAClZdClagydoU3IoVcIYagDLAcGKQcrCYqgu1iDBgyVDHYjkDmKTCwAABAwVcCYiguTwRFDJ5CeCmJIBAAOAdYQTEUFyHCJwbmEJ4ZDCqxPDrlWBAKkDUFyeCm5PEJAcrdwkGJwjsDDINisSmBlesJ9SFCsRPFUQQEDH4WAJwjwCgxmFeFZPCJw4AFUoSfGDQwQCUFOsg0AmJPaWIagCmKhowIsBrhPNMAJPOxs3KFRPCGYgAJlZPQxsxBANWJ8wzCJxqNDwBPICYxQCUEyNBgxPOriMCJwmADYJPHsUGEwOsd003J51iJ5AbKMgZPmrhPOxqWBlbwEdwQbIMgZPjGYViJ57wGdwYbJT9JPQRYSgDNQTuIWgdW66f2xs3RgRQBKoQTKJ4SfjaZg8KHoMxDJpdCJ/LxCAAUxCJqfkd6gABdgQYNJ9VcJ6WNdoU3CBiuCJ8eBaxqPJgy3Olafl/wnBgBPTKAKeNxs3E4OseHZfQE4KgkeAUrJ8eNmJQl1gmBUE0GKAWBJ8HXlZQCsRQkFIdW1hQfqwlCmLxksU3FQUrUT5PDgE3KEiiGJ8AlCKE2NrjzgJ4VimJTCsSipULgfBlYlBm7zDKMx8CKDWBDoNcOwcGKIUGmM3KkShDwLucEwlcKIalCeUQlBlaeamInIrk3lcrVgYAfrigY1i7CcMIAQUDDtCcESgodoUrJ2WNsQ3BqyeWduQAClaHB65OR1kGT2rwXdwVcJ+rwCJ6Tu4J4dWJ6MrCoMxAGxPUCoQA5mLvUAHZIJA=="),
atob("qE5xH+AH4A/AH4A/AH4A/AEOswMrgAACleB1hJ/AAeBqxMDAAsrq1WwJN+TQgALKPesTYkyq9eAAtXlhR9TghMBwYAKr0yewZQ1JwcyJphRIqxOzTgZNPAAdXDAShxToZOUUQTyy1hOCdaChKeN6dZAAcseN+BGAMybQgABcg4KKeIZPsJwUrHIczA4L1Fr0yBIQTBBYdeXQK5BBYRPrqxGFxLXCgEsIYoAFJIOJLIdeNASgqTwUzSoZPELIZDCldWAAIMDCYj6BCARQo1iNBdohPIHodcAARQCmSfFCQhQnTwTXBAAjWCHgdXAgNWJ4dcewSaBNooaCqxPmTw4ABrygCmSmDTwigEfoRSBDYYaCUEqeJKIY7DdwwACBIMzDJAVCJ8iEFABbuHeAcsxIVHq6gmGYRONRIRPJlYWMJ0WsaZSfSgAWJljwkwIyBq5PlmQMB1hPhqwlBrxONxLlCd6WDq5PkQQRPOwczCQJPIlmJJ9wkBJ6FeeBAIBmZmMJ/1WDZkyJ++DlkAlbuGDZYNBqxOh/wzNUBieCmQVKCgRPiwJPSHQRQDXRpkDJ8tXJ6A7CeIKeCNJZPm1jUNAA0zKAQCBlhjOJ80rJ6ODljsCTxgSDlesKESHCG5qNHW56gmqxPUwdXCyKzCwJPkRBw9GCqCgClZQhwLZCUCdeCiKzCKEJPDligTACUzFYRQf1krEgTxUKC1WKLxPDgFXKE1eFgZRdqwiDKFMsKL5PCq4kCmZQmKI0rKTGBJ4QjDlleKNqkX1krNgIjBmQgCmZRpmY0BKLCgCJAVXEAcyrwACUlUrKCZPClggDUQYADUs5REKCdWIY1eq7FEq71naYahTUAUyOY7wpKA1WUDQAxmTxUUAUzxODxIAFA4IJCAQg7ODgojGAgYSCwcrKCgVClgA1HAJPTeAQA5lafUAHZIJA"),
atob("qE5xH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AdwOBlcAAAsrq2BJn+BqxMHKX5NFJhgAFqxO5TYcruug0HLAAoIBvdQCIZN11icDqBLHAA+gMYRQ0TgcrvhNOAAaiCeWWBTgZNSKAuBJ17rDvZOVeQK4C1hOxdaYAFvbxvdgZOGbgMlLCF8DwSgrJxSKCKALvRUFmslbsJJ4YMG0F1qElld10ATGgGBJ9BOCvaLHHYgNEIoqsBKAIJFUFDtCurbIvhPHcgcrAAL9DBQclUFDtCGQIAJIIUAcYQHDq2ArmAqxsDfIL2BKFAxCvhPK0F7uoODSYVWrgACwBXCLwYQDlaekE4ROKAA97CwJODAAJuCfwYABuqglwKeNAA9QMoJPFrjwDAAjxBlesd0hOSHgeAJwjwDWRCgh1guBqBPTHYKfHOBIIBqxPhEgN7J6yfFJ5VQBILwgwJPWWwJPK0DwpJ66LBd6OgJ8TvXuoXBJ6HLBINWJ8VQJ6d8HYROEwD5BkpP/bYpPFrgIBuoUHqEAlZPiZxAAMHYWAdw18CY91BYOsJ8WgJ6d7UAzuBN5JPCwJPivagUC4MrJwoeJJ4VcJ72BJ4UrJ6igCKALtCqASJqDvhJ4bwVHodWTwQcJ0AQCJz3+QASCMABclDYd1MBmBJ76ABkrYCvZPUR4QABBxInCT0DuCJYJ3CeKt1NJZdClesd0RKBFIbxVqEldtusdwJJDvgqBqDxVTxjtgdwd8Fgd7KC77MT0H+TwLQGKAT4CJ/9WTwxQGupPbd4QABldWq2B1hPbTwwvDVYJRCUbRxDAAhTCJyusSRowEktQAAKhXvd1qBSHKKmBdxIwFuotFUjQjBvgkElZPWlaOCABRPFChwAPEYpPSqy9GAGlWJ6JO7UJgA=="),
atob("qE5xH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AtwNWlcAAAUrq2BJP5MJAApS/JoRMJAApR7JotPumfAA10VQlWJ2+AHwZMB4nDABHEz9PeoesJ2icDp5NLKIpkCKGesG4UlJoJOBKJQJBBYT1BeQRQwwJOCTgI/Bb4V0KAxIBp8llb+BCYlWJ2V0IYbzCgBCBJwgKDBoefkoFCUFuBGISWEIglPBI8rAAIYDCYeAJ2hPJcgmArmAqylGJ9ZODz5OEJ5IICq1cAAZQGlZOuJoiWFVQIICcgRPFrhLCuklAgOBJ0+AlZOJJAYABAwgUBJwtcDwMr4itCeE+sJwV0dgoAKU4UrwBPFeARuBUAMr1jslJyhPBIAMlJ5auCeEotCJyRPBMwRPLeAVWJ0eAE4NPJqLvR4iglwIlBFgQATH4ROFJ4qgmFYUAdqRPSWASghTwclJ6qPDJ4srBIIQGwCejT63DksAlZPHp4iD4gQCT0SfXb4ZPFA4N0CIl0eECeCZgSfWeA4hCz4QHJ7usEANPOgQtFeCagDOYV0OIpPCeDruCugkCZoqgUlbtDkpwGB4UAJ7mATYXEQoNPeC3EXYVWTwS/HJ8ErD4IlBeDXDEAQABNxBPfPQTqCEoSgXIIhtJf4ZOawIeBkomDUDYbCNhJPCwBOZwB6Hz8lK4oAT4lPNZRcCwJOheL10DJHEO4LuZdgUAugoHPAQ2JADDubToZOHAATVBBpb6YgGsJy1WdhJQIlYQMTylWJ05QEUQOfejd0EAOBJzElRh/EFwRRDAATuWkrBBJysrbaufKIhqCd1ydCJyZREQYIACDizuWJzLUDdoLyBDSq9CJ6eBJzYAbJ4WsTyuf4gAzT6usCoKfBp4AzlY4BwBPRCoQA5qxPRJ3ZQMA==")
];
function drawImg (i) {
g.drawImage({
width: 80, height: 57, bpp: 8,
buffer: require("heatshrink").decompress(imgs[i])
}, 0, 0, {scale: 3});
}
var currImg = 0;
g.clear();
drawImg(currImg);
setInterval(function() {
currImg = (currImg + 1) % imgs.length;
drawImg(currImg);
}, 200);

5
apps/party-parrot.json Normal file
View File

@ -0,0 +1,5 @@
{
"name":"Party Parrot","type":"app",
"icon":"*pparrot",
"src":"-pparrot"
}

BIN
apps/party-parrot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1001 B

View File

@ -15,12 +15,12 @@ Bangle.HID = E.toUint8Array(atob("BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQ
}
setTimeout(function() {
NRF.setServices({}, adv);
if (s.ble) NRF.wake();
else NRF.sleep();
// we just reset, so BLE should be on
if (!s.ble) NRF.sleep(); // disable advertising if BLE should be off
},10);
if (!s.vibrate) Bangle.buzz=()=>Promise.resolve();
if (!s.beep) Bangle.beep=()=>Promise.resolve();
if (!s.vibrate) Bangle.buzz=Promise.resolve;
if (!s.beep) Bangle.beep=Promise.resolve;
Bangle.setLCDTimeout(s.timeout);
if (!s.timeout) Bangle.setLCDPower(1);
E.setTimeZone(s.timezone);

View File

@ -11,7 +11,7 @@ uploadApp : app => {
Puck.write("\x03reset();\n", (result) => {
if (result===null) return reject("");
setTimeout(() => { // wait for reset
Puck.write("\x10E.showMessage('Uploading...')\n"+fileContents+"load()\n",(result) => {
Puck.write("\x10E.showMessage('Uploading...')\n"+fileContents+"\x10E.showMessage('Hold BTN3\\nto reload')\n",(result) => {
if (result===null) return reject("");
resolve();
});
@ -38,7 +38,7 @@ removeApp : app => { // expects an app structure
}).join("");
console.log("removeApp", cmds);
return new Promise((resolve,reject) => {
Puck.write("\x03"+cmds+"\x10load()\n",(result) => {
Puck.write("\x03"+cmds+"\x10E.showMessage('Hold BTN3\\nto reload')\n",(result) => {
if (result===null) return reject("");
resolve();
});
@ -63,5 +63,21 @@ setTime : () => {
resolve();
});
});
},
watchConnectionChange : cb => {
var connected = Puck.isConnected();
//TODO Switch to an event listener when Puck will support it
var interval = setInterval(() => {
if (connected === Puck.isConnected()) return;
connected = Puck.isConnected();
cb(connected);
}, 1000);
//stop watching
return () => {
clearInterval(interval);
};
}
};

View File

@ -35,6 +35,9 @@
<a href="https://banglejs.com" class="navbar-brand mr-2"><img src="img/banglejs-logo-sml.png" alt="Bangle.js">&nbsp;&nbsp;App Loader</a>
<!-- <a href="#" class="btn btn-link">...</a> -->
</section>
<section class="navbar-section">
<button class="btn" id="connectmydevice">Connect</button>
</section>
<!--<section class="navbar-section">
<div class="input-group input-inline">
<input class="form-input" type="text" placeholder="search">

View File

@ -252,6 +252,7 @@ function getInstalledApps() {
// Get apps
Comms.getInstalledApps().then(appIDs => {
appsInstalled = appIDs;
handleConnectionChange(true);
refreshMyApps();
refreshLibrary();
}).catch(err => {
@ -259,10 +260,15 @@ function getInstalledApps() {
});
}
var connectMyDeviceBtn = document.getElementById("connectmydevice");
document.getElementById("myappsrefresh").addEventListener("click",event=>{
getInstalledApps();
});
function handleConnectionChange(connected) {
connectMyDeviceBtn.style.display = connected ? 'none' : '';
}
document.getElementById("myappsrefresh").addEventListener("click", getInstalledApps);
connectMyDeviceBtn.addEventListener("click", getInstalledApps);
Comms.watchConnectionChange(handleConnectionChange);
// =========================================== About

4
testing/README.md Normal file
View File

@ -0,0 +1,4 @@
Testing
=======
Bits of code that could maybe be apps, but that aren't finished yet

3
testing/map/README.md Normal file
View File

@ -0,0 +1,3 @@
This code can take an image file, split it into tiles, and then render those tiles on the watch - making them fit with the GPS data.
Problem is right now I can't automate getting the rendered area of map, so can't turn it into a very useful tool for BangleApps.

View File

@ -0,0 +1,83 @@
require("Storage").write('+map',{
name:"Map",
icon:"*map",
src:"-map"
});
require("Storage").write('*map',require("heatshrink").decompress(atob("mEwghC/AH4AWh//mcwBZIWI/4ABmYABBZAgIC4oyDBYggIC4wABBYoX/C90imcykYXUkYBB+YyDC5E/F5EykQXKHwYVCL4YXNkQ+BC4wICHgIvJ+QVBC4oYBkUvO5QXCU4wXBF5INCCwqMDAYTXUC6xHNC5Z3LI5UyF6oADF9ZfL+fTAIIUCkUjR5397s9C4LxBC4MykfzDYYvI7vdC4cyDIciO5c97s/C4QABF4IBBC5QvEAAk/+ZdBC5JfEX6XzmaPEa7oX8+AGBgYXHBYQXHBAoXFCowXCEA4yCBZIA/AH4AO")));
require("Storage").write("-map",`
var s = require("Storage");
var hs = require("heatshrink");
var map = {
imgx : 831,
imgy : 656,
tilesize : 64,
scale : 20000,
lat : 51.7075,
lon : -1.2948
};
map.center = Bangle.project({lat:map.lat,lon:map.lon});
var lat = map.lat, lon = map.lon;
var fix = {};
function redraw() {
var cx = g.getWidth()/2;
var cy = g.getHeight()/2;
var p = Bangle.project({lat:lat,lon:lon});
var ix = (p.x-map.center.x)*4096/map.scale + (map.imgx/2) - cx;
var iy = (map.center.y-p.y)*4096/map.scale + (map.imgy/2) - cy;
//console.log(ix,iy);
var tx = 0|(ix/map.tilesize);
var ty = 0|(iy/map.tilesize);
var ox = (tx*map.tilesize)-ix;
var oy = (ty*map.tilesize)-iy;
for (var x=ox,ttx=tx;x<g.getWidth();x+=map.tilesize,ttx++) {
for (var y=oy,tty=ty;y<g.getHeight();y+=map.tilesize,tty++) {
var img = s.read("t"+ttx+"x"+tty);
//print(x,y,ttx,tty,"t"+ttx+"x"+tty,img?"ok":"-");
if (img) g.drawImage(hs.decompress(img),x,y);
else g.clearRect(x,y,x+map.tilesize-1,y+map.tilesize-1);
}
}
g.setColor(1,0,0);
/*g.fillRect(cx-10,cy-1,cx+10,cy+1);
g.fillRect(cx-1,cy-10,cx+1,cy+10);*/
if (fix.fix)
g.fillRect(cx-2,cy-2,cx+2,cy+2);
}
redraw();
var fix;
Bangle.on('GPS',function(f) {
fix=f;
g.clearRect(0,0,240,8);
g.setColor(1,1,1);
g.setFont("6x8");
g.setFontAlign(0,0);
var txt = fix.satellites+" satellites";
if (!fix.fix)
txt += " - NO FIX";
g.drawString(txt,120,4);
if (fix.fix) {
var p = Bangle.project({lat:lat,lon:lon});
var q = Bangle.project(fix);
var cx = g.getWidth()/2;
var cy = g.getHeight()/2;
var ix = (q.x-p.x)*4096/map.scale + cx;
var iy = (q.y-p.y)*4096/map.scale + cy;
g.fillRect(ix-2,iy-2,ix+2,iy+2);
}
});
Bangle.setGPSPower(1);
redraw();
setWatch(function() {
if (!fix.fix) return;
lat = fix.lat;
lon = fix.lon;
redraw();
}, BTN2, {repeat:true});
`);

155
testing/map/maploader.html Normal file
View File

@ -0,0 +1,155 @@
<html>
<head>
</head>
<body>
<script src="https://espruino.github.io/EspruinoWebTools/heatshrink.js"></script>
<script src="https://espruino.github.io/EspruinoWebTools/imageconverter.js"></script>
<!--<script src="https://espruino.github.io/EspruinoWebTools/uart.js"></script>-->
<script src="file:///home/gw/workspace/EspruinoWebTools/uart.js"></script>
<p>An online map loader for Espruino...</p>
Scale <input type="text" id="scale" value="20000"></input><br/>
Geo URI <input type="text" id="uri" value="geo:51.7079,-1.2926?z=16"></input><br/>
<button id="geturl">Get URL</button><a name="url"></a><br/>
<input type="file" id="fileLoader"/><br/>
<img id="mapimg"/><br/>
<canvas id="canvas" style="display:none;"></canvas>
<button id="upload" style="display:none;">Upload</button>
<pre id="log"></pre>
<!--
We can request this directly, eg:
https://render.openstreetmap.org/cgi-bin/export?bbox=-1.27,51.64,-1.26,51.65&scale=20000&format=png
https://render.openstreetmap.org/cgi-bin/export?bbox=-1.2731999999999999,51.6472,-1.2632,51.6572&scale=20000&format=png
then we need:
var map = {
imgx : 361,
imgy : 343,
tilesize : 64,
scale : 20000, // scale
lat : 51.65270, // coords of center
lon : -1.27052
};
find lat/lon? https://help.openstreetmap.org/questions/2702/extracting-coordinates-by-clicking-on-an-openstreetmap
-->
<script>
TILESIZE = 64;
var img;
var tiles = [];
function log(x) {
document.getElementById("log").innerText += x+"\n";
console.log(x);
}
function getURL() {
var uri = document.getElementById("uri").value;
var latlon = uri.match("geo:(-?[0-9\.]+),(-?[0-9\.]+)?");
if (latlon==null) {
log("Invalid URI!");
return;
}
var map = {
imgx :img?img.width:0,
imgy : img?img.height:0,
lat : parseFloat(latlon[1]),
lon : parseFloat(latlon[2]),
tilesize : TILESIZE,
scale : parseInt(document.getElementById("scale").value)
};
log(JSON.stringify(map,null,2));
var s = 0.005;
var x1 = map.lon-s,
x2 = map.lon+s,
y1 = map.lat-s,
y2 = map.lat+s;
var url = "https://render.openstreetmap.org/cgi-bin/export?bbox="+x1+","+y1+","+x2+","+y2+"&scale="+map.scale+"&format=png"
document.getElementById("url").href = url;
document.getElementById("url").innerText = url;
/*var mapimg = document.getElementById("mapimg");
mapimg.src = url;
mapimg.onload = function() {
log("Image loaded!");
}*/
}
function imageLoaded() {
if (img === undefined) return;
var options = { compression:true, mode:"web", output:"string"};
var canvas = document.getElementById("canvas")
canvas.width = TILESIZE*2;
canvas.height = TILESIZE;
canvas.style = "display:block;border:1px solid black;margin:8px;"
var ctx = canvas.getContext("2d");
console.log(img.width+"x"+img.height);
var w = Math.round(img.width / TILESIZE);
var h = Math.round(img.height / TILESIZE);
console.log("->"+w+"x"+h);
for (var y=0;y<h;y++) {
for (var x=0;x<w;x++) {
ctx.fillStyle = 'black';
ctx.fillRect(0,0,TILESIZE,TILESIZE);
ctx.drawImage(img,-x*TILESIZE,-y*TILESIZE);
var imageData = ctx.getImageData(0, 0, TILESIZE, TILESIZE);
var rgba = imageData.data;
options.rgbaOut = rgba;
options.width = TILESIZE;
options.height = TILESIZE;
var imgstr = imageconverter.RGBAtoString(rgba, options);
ctx.putImageData(imageData,TILESIZE,0);
var compress = 'require("heatshrink").decompress('
if (!imgstr.startsWith(compress)) throw "Data in wrong format";
imgstr = imgstr.slice(compress.length,-1);
tiles.push({
name:"t"+x+"x"+y,
value:imgstr
});
}
}
log("Tiling finished. "+tiles.length+" tiles");
document.getElementById("upload").style.display = "block";
}
function handleFileSelect(event) {
if (event.target.files.length != 1) return;
var reader = new FileReader();
reader.onload = function(event) {
img = new Image();
img.onload = imageLoaded;
img.src = event.target.result;
};
reader.readAsDataURL(event.target.files[0]);
};
document.getElementById('fileLoader').addEventListener('change', handleFileSelect, false);
document.getElementById('geturl').addEventListener('click', getURL);
document.getElementById('upload').addEventListener('click', function() {
UART.write("\x03s=require('Storage');\n", function() {
log("Connected");
function upload() {
if (!tiles.length) {
log("Success!");
return;
}
var tile = tiles.shift();
log("Uploading "+tile.name);
UART.eval('s.write('+JSON.stringify(tile.name)+','+tile.value+')',function(r) {
log("Returned "+r);
upload();
});
}
upload();
});
}, false);
</script>
</body>
</html>